From 54255896477f456116cb63b517a3d9943b915d43 Mon Sep 17 00:00:00 2001 From: Adrian Iain Lam Date: Sun, 21 Oct 2018 17:02:20 +0100 Subject: [PATCH 1/1] BER/SNR plots for discrete BPSK over AWGN --- BPSK_BER_SNR_1000.svg | 203 ++++++++++++++++++++++++++++++ BPSK_BER_SNR_1000000.svg | 321 +++++++++++++++++++++++++++++++++++++++++++++++ SNRvsBER_BPSKdiscrete.m | 53 ++++++++ decodeNoisyBPSK.m | 3 + discreteAWGN.m | 3 + formatFigure.m | 8 ++ isOctave.m | 15 +++ randomPSK.m | 15 +++ 8 files changed, 621 insertions(+) create mode 100644 BPSK_BER_SNR_1000.svg create mode 100644 BPSK_BER_SNR_1000000.svg create mode 100644 SNRvsBER_BPSKdiscrete.m create mode 100644 decodeNoisyBPSK.m create mode 100644 discreteAWGN.m create mode 100644 formatFigure.m create mode 100644 isOctave.m create mode 100644 randomPSK.m diff --git a/BPSK_BER_SNR_1000.svg b/BPSK_BER_SNR_1000.svg new file mode 100644 index 0000000..1f4ce97 --- /dev/null +++ b/BPSK_BER_SNR_1000.svg @@ -0,0 +1,203 @@ + + +glps_renderer figure + +Creator: GL2PS 1.3.8, (C) 1999-2012 C. Geuzaine +For: Octave +CreationDate: Sun Oct 21 16:58:38 2018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0 +2 +4 +6 +8 +10 + + + + + + + + + + + + + + + + + + +1e-6 +1e-5 +1e-4 +1e-3 +1e-2 +1e-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$E_b/N_0$ (dB) +BER + + + + + + +Simulated +$Q\left(\sqrt{2 E_b / N_0}\right)$ + + + + diff --git a/BPSK_BER_SNR_1000000.svg b/BPSK_BER_SNR_1000000.svg new file mode 100644 index 0000000..9ff96eb --- /dev/null +++ b/BPSK_BER_SNR_1000000.svg @@ -0,0 +1,321 @@ + + + diff --git a/SNRvsBER_BPSKdiscrete.m b/SNRvsBER_BPSKdiscrete.m new file mode 100644 index 0000000..4a6c30d --- /dev/null +++ b/SNRvsBER_BPSKdiscrete.m @@ -0,0 +1,53 @@ +function SNRvsBER_BPSKdiscrete(numBits) + if nargin < 1 + numBits = 1000; + end + + if isOctave() + pkg load communications + end + + %% SNR: Eb/N0 + snr_db = 0:0.2:10; + snr = 10 .^ (snr_db ./ 10); + + %% Eb is assumed to be 1 + %% noise N ~ Gaussian(mean=0, variance=N0/2) + N0 = 1 ./ snr; + + ber = zeros(1, length(snr)); + + data = randomPSK(2, numBits); + + for i = 1:length(snr) + noisyData = discreteAWGN(data, N0(i)); + decodedData = decodeNoisyBPSK(noisyData); + + bitErrors = sum(data ~= decodedData); + ber(i) = bitErrors / numBits; + end + + fig1 = figure(1); + clf; + + %% Plot simulated results + semilogy(snr_db, ber, 'r', 'LineWidth', 2); + hold on; + + %% Plot theoretical curve + %% BPSK: bit error when noise N > sqrt(Eb) + %% Pr(N > sqrt(Eb)) + %% = Pr(Z > sqrt(Eb) / sqrt(N0/2)) + %% = Q(sqrt(2 * SNR)) + ber_th = qfunc(sqrt(2 * snr)); + semilogy(snr_db, ber_th, 'b', 'LineWidth', 1); + + grid on; + xlabel('$E_b/N_0$ (dB)'); + ylabel('BER'); + legend('Simulated', '$Q\left(\sqrt{2 E_b / N_0}\right)$'); + + formatFigure; + saveas(gcf, strcat('BPSK_BER_SNR_', num2str(numBits), '.svg')); + +end diff --git a/decodeNoisyBPSK.m b/decodeNoisyBPSK.m new file mode 100644 index 0000000..70ef8f8 --- /dev/null +++ b/decodeNoisyBPSK.m @@ -0,0 +1,3 @@ +function x = decodeNoisyBPSK(noisyData) + x = (noisyData > 0) - (noisyData <= 0); +end diff --git a/discreteAWGN.m b/discreteAWGN.m new file mode 100644 index 0000000..1aab2b9 --- /dev/null +++ b/discreteAWGN.m @@ -0,0 +1,3 @@ +function x = discreteAWGN(data, N0) + x = data + normrnd(0, sqrt(N0 / 2), 1, length(data)); +end diff --git a/formatFigure.m b/formatFigure.m new file mode 100644 index 0000000..7d5796a --- /dev/null +++ b/formatFigure.m @@ -0,0 +1,8 @@ +if ~isOctave() + set(gcf, 'defaultTextInterpreter', 'Latex'); + set(gcf, 'defaultLegendInterpreter', 'Latex'); + set(gca, 'TickLabelInterpreter', 'Latex'); +end +set(gca, 'FontSize', 14); +leg = findobj(gcf, 'Type', 'Legend'); +set(leg, 'FontSize', 14); diff --git a/isOctave.m b/isOctave.m new file mode 100644 index 0000000..1c9c190 --- /dev/null +++ b/isOctave.m @@ -0,0 +1,15 @@ +%% Taken from the GNU Octave Manual, (c) 1996-2016 John W. Eaton +%% https://octave.org/doc/v4.0.3/How-to-distinguish-between-Octave-and-Matlab_003f.html + +%% +%% Return: true if the environment is Octave. +%% +function retval = isOctave + persistent cacheval; % speeds up repeated calls + + if isempty (cacheval) + cacheval = (exist ("OCTAVE_VERSION", "builtin") > 0); + end + + retval = cacheval; +end diff --git a/randomPSK.m b/randomPSK.m new file mode 100644 index 0000000..7521bef --- /dev/null +++ b/randomPSK.m @@ -0,0 +1,15 @@ +function x = randomPSK(n, len) + % symbols: nth roots of unity + % i.e. solutions to polynomial x^n - 1 = 0 + symbols = roots([1 zeros(1, n-1) -1]); + + x = zeros(1, len); + for i = 1:len + x(i) = randomChoice(symbols); + end +end + +function x = randomChoice(arr) + i = randi(length(arr)); + x = arr(i); +end -- 2.7.4