1 function discretePSK_BER_SNR(M, numBits)
2 %% Set defaults for inputs
11 pkg load communications
15 EbN0 = 10 .^ (EbN0_db ./ 10);
21 EsN0 = EbN0 .* log2(M);
22 EsN0_db = 10 .* log10(EsN0);
24 plotlen = length(EbN0);
26 ber = zeros(1, plotlen);
28 data = randi([0, M - 1], 1, numBits);
29 txsig = pskmod(data, M, 0, 'gray');
32 rxsig = awgn(txsig, EsN0_db(i));
33 demodData = pskdemod(rxsig, M, 0, 'gray');
35 [bitErrors, ber(i)] = biterr(data, demodData);
41 %% Plot simulated results
42 semilogy(EbN0_db, ber, 'r', 'LineWidth', 2);
45 %% Plot theoretical curve
46 %% BPSK: bit error when noise Nr > sqrt(Eb)
48 %% = Pr(Z > sqrt(Eb) / sqrt(N0/2))
50 %% QPSK = 2 BPSKs, one real and one imaginary, each with one bit
51 %% so BER is the same as BPSK (assuming Gray code)
53 ber_th = qfunc(sqrt(2 * EbN0));
54 semilogy(EbN0_db, ber_th, 'b', 'LineWidth', 1);
55 legend('Simulated', 'Theoretical');
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');
69 title(strcat(num2str(M), '-PSK with Gray code'));
71 xlabel('$E_b/N_0$ (dB)');
75 saveas(gcf, strcat('BER_SNR_', num2str(M), 'PSK_', num2str(numBits), ...