Added baseband and passband simulations. Passband is buggy.
[4yp.git] / discretePSK_BER_SNR.m
CommitLineData
4dd65313
AIL
1function discretePSK_BER_SNR(M, numBits)
2 %% Set defaults for inputs
3 if nargin < 2
4 numBits = 1000;
5 end
6 if nargin < 1
7 M = 2;
8 end
9
10 if isOctave()
11 pkg load communications
12 end
13
14 EbN0_db = 0:0.2:10;
15 EbN0 = 10 .^ (EbN0_db ./ 10);
16
17 Es = 1;
18 Eb = Es / log2(M);
19 N0 = Eb ./ EbN0;
20
21 EsN0 = EbN0 .* log2(M);
22 EsN0_db = 10 .* log10(EsN0);
23
24 plotlen = length(EbN0);
25
26 ber = zeros(1, plotlen);
27
28 data = randi([0, M - 1], 1, numBits);
29 txsig = pskmod(data, M, 0, 'gray');
30
31 for i = 1:plotlen
32 rxsig = awgn(txsig, EsN0_db(i));
33 demodData = pskdemod(rxsig, M, 0, 'gray');
34
35 [bitErrors, ber(i)] = biterr(data, demodData);
36 end
37
38 fig1 = figure(1);
39 clf;
40
41 %% Plot simulated results
42 semilogy(EbN0_db, ber, 'r', 'LineWidth', 2);
43 hold on;
44
45 %% Plot theoretical curve
46 %% BPSK: bit error when noise Nr > sqrt(Eb)
47 %% Pr(Nr > sqrt(Eb))
48 %% = Pr(Z > sqrt(Eb) / sqrt(N0/2))
49 %%
50 %% QPSK = 2 BPSKs, one real and one imaginary, each with one bit
51 %% so BER is the same as BPSK (assuming Gray code)
52 if M == 2 || M == 4
53 ber_th = qfunc(sqrt(2 * EbN0));
54 semilogy(EbN0_db, ber_th, 'b', 'LineWidth', 1);
55 legend('Simulated', 'Theoretical');
56 else
57 %% Upper bound: R. Venkataramanan, Lent 2018, 3F4 Examples Paper 2
58 %% (Question 5), CUED.
59 %% Approximation: J.G. Proakis and M. Salehi, 2000, Contemporary
60 %% Communication Systems using MATLAB (Equations
61 %% 7.3.18 and 7.3.19), Brooks/Cole.
62 ber_ub = 2 * qfunc(sqrt(EbN0 * log2(M)) * sin(pi / M));
63 ber_ap = 2 * qfunc(sqrt(EbN0 * log2(M) * 2) * sin(pi / M)) / log2(M);
64 semilogy(EbN0_db, ber_ub, 'b', 'LineWidth', 1);
65 semilogy(EbN0_db, ber_ap, 'g', 'LineWidth', 1);
66 legend('Simulated', 'Upper bound', 'Approximation');
67 end
68
69 title(strcat(num2str(M), '-PSK with Gray code'));
70 grid on;
71 xlabel('$E_b/N_0$ (dB)');
72 ylabel('BER');
73
74 formatFigure;
75 saveas(gcf, strcat('BER_SNR_', num2str(M), 'PSK_', num2str(numBits), ...
76 '.svg'));
77end