## Bit Error Rate Analysis Techniques

This topic describes how to compute error statistics for various communications systems.

### Computation of Theoretical Error Statistics

The biterr function, discussed in the Compute SERs and BERs Using Simulated Data section, can help you gather empirical error statistics, but validating your results by comparing them to the theoretical error statistics is good practice. For certain types of communications systems, closed-form expressions exist for the computation of the bit error rate (BER) or an approximate bound on the BER. The functions listed in this table compute the closed-form expressions for the BER or a bound on it for the specified types of communications systems.

Type of Communications SystemFunction
Uncoded AWGN channel berawgn
Coded AWGN channel bercoding
Uncoded AWGN channel with imperfect synchronization bersync

The analytical expressions used in these functions are discussed in Analytical Expressions Used in BER Analysis. The reference pages of these functions also list references to one or more books containing the closed-form expressions implemented by the function.

### Theoretical Performance Results

#### Plot Theoretical Error Rates

This example uses the bercoding function to compute upper bounds on BERs for convolutional coding with a soft-decision decoder.

coderate = 1/4; % Code rate

Create a structure, dspec, with information about the distance spectrum. Define the energy per bit to noise power spectral density ratio (${\mathit{E}}_{\mathit{b}}/{\mathit{N}}_{0}$) sweep range and generate the theoretical bound results.

dspec.dfree = 10; % Minimum free distance of code
dspec.weight = [1 0 4 0 12 0 32 0 80 0 192 0 448 0 1024 ...
0 2304 0 5120 0]; % Distance spectrum of code
EbNo = 3:0.5:8;
berbound = bercoding(EbNo,'conv','soft',coderate,dspec);

Plot the theoretical bound results.

semilogy(EbNo,berbound)
xlabel('E_b/N_0 (dB)');
ylabel('Upper Bound on BER');
title('Theoretical Bound on BER for Convolutional Coding');
grid on;

#### Compare Theoretical and Empirical Error Rates

Using the berawgn function, compute the theoretical symbol error rates (SERs) for pulse amplitude modulation (PAM) over a range of ${\mathit{E}}_{\mathit{b}}/{\mathit{N}}_{0}$ values. Simulate 8 PAM with an AWGN channel, and compute the empirical SERs. Compare the theoretical and then empirical SERs by plotting them on the same set of axes.

Compute and plot the theoretical SER using berawgn.

rng('default') % Set random number seed for repeatability
M = 8;
EbNo = 0:13;
[ber,ser] = berawgn(EbNo,'pam',M);

semilogy(EbNo,ser,'r');
legend('Theoretical SER');
title('Theoretical Error Rate');
xlabel('E_b/N_0 (dB)');
ylabel('Symbol Error Rate');
grid on;

Compute the empirical SER by simulating an 8 PAM communications system link. Define simulation parameters and preallocate variables needed for the results. As described in [1], because ${\mathit{N}}_{0}=2×{\left({\mathit{N}}_{\mathrm{Variance}}\right)}^{2}$, add 3 dB to the ${\mathit{E}}_{\mathit{b}}/{\mathit{N}}_{0}$ value when converting ${\mathit{E}}_{\mathit{b}}/{\mathit{N}}_{0}$ values to SNR values.

n = 10000; % Number of symbols to process
k = log2(M); % Number of bits per symbol
snr = EbNo+3+10*log10(k); % In dB
ynoisy = zeros(n,length(snr));
z = zeros(n,length(snr));
errVec = zeros(3,length(EbNo));

Create an error rate calculator System object™ to compare decoded symbols to the original transmitted symbols.

errcalc = comm.ErrorRate;

Generate a random data message and apply PAM. Normalize the channel to the signal power. Loop the simulation to generate error rates over the range of SNR values.

x = randi([0 M-1],n,1); % Create message signal
y = pammod(x,M); % Modulate
signalpower = (real(y)'*real(y))/length(real(y));

for jj = 1:length(snr)
reset(errcalc)
ynoisy(:,jj) = awgn(real(y),snr(jj),'measured'); % Add AWGN
z(:,jj) = pamdemod(complex(ynoisy(:,jj)),M); % Demodulate
errVec(:,jj) = errcalc(x,z(:,jj)); % Compute SER from simulation
end

Compare the theoretical and empirical results.

hold on;
semilogy(EbNo,errVec(1,:),'b.');
legend('Theoretical SER','Empirical SER');
title('Comparison of Theoretical and Empirical Error Rates');
hold off;

### Performance Results via Simulation

#### Section Overview

This section describes how to compare the data messages that enter and leave a communications system simulation and how to compute error statistics using the Monte Carlo technique. Simulations can measure system performance by using the data messages before transmission and after reception to compute the BER or SER for a communications system. To explore physical layer components used to model and simulate communications systems, see PHY Components.

Curve fitting can be useful when you have a small or imperfect data set but want to plot a smooth curve for presentation purposes. To explore the use of curve fitting when computing performance results via simulation, see the Curve Fitting for Error Rate Plots section.

#### Compute SERs and BERs Using Simulated Data

The example shows how to compute SERs and BERs using the biterr and symerr functions, respectively. The symerr function compares two sets of data and computes the number of symbol errors and the SER. The biterr function compares two sets of data and computes the number of bit errors and the BER. An error is a discrepancy between corresponding points in the two sets of data.

The two sets of data typically represent messages entering a transmitter and recovered messages leaving a receiver. You can also compare data entering and leaving other parts of your communications system (for example, data entering an encoder and data leaving a decoder).

If your communications system uses several bits to represent one symbol, counting symbol errors is different from counting bit errors. In either the symbol- or bit-counting case, the error rate is the number of errors divided by the total number of transmitted symbols or bits, respectively.

Typically, simulating enough data to produce at least 100 errors provides accurate error rate results. If the error rate is very small (for example, ${10}^{-6}$ or less), using the semianalytic technique might compute the result more quickly than using a simulation-only approach. For more information, see the Performance Results via Semianalytic Technique section.

Compute Error Rates

Use the symerr function to compute the SERs for a noisy linear block code. Apply no digital modulation, so that each symbol contains a single bit. When each symbol is a single bit, the symbol errors and bit errors are the same.

After artificially adding noise to the encoded message, compare the resulting noisy code to the original code. Then, decode and compare the decoded message to the original message.

m = 3; % Set parameters for Hamming code
n = 2^m-1;
k = n-m;
msg = randi([0 1],k*200,1); % Specify 200 messages of k bits each
code = encode(msg,n,k,'hamming');
codenoisy = bsc(code,0.95); % Add noise
newmsg = decode(codenoisy,n,k,'hamming'); % Decode and correct errors

Compute the SERs.

[~,noisyVec] = symerr(code,codenoisy);
[~,decodedVec] = symerr(msg,newmsg);

The error rate decreases after decoding because the Hamming decoder correct errors based on the error-correcting capability of the decoder configuration. Because random number generators produce the message and noise is added, results vary from run to run. Display the SERs.

disp(['SER in the received code: ',num2str(noisyVec(1))])
SER in the received code: 0.94571
disp(['SER after decoding: ',num2str(decodedVec(1))])
SER after decoding: 0.9675

Comparing SER and BER

These commands show the difference between symbol errors and bit errors in various situations.

Create two three-element decimal vectors and show the binary representation. The vector a contains three 2-bit symbols, and the vector b contains three 3-bit symbols.

bpi = 3; % Bits per integer
a = [1 2 3];
b = [1 4 4];
int2bit(a,bpi)
ans = 3×3

0     0     0
0     1     1
1     0     1

int2bit(b,bpi)
ans = 3×3

0     1     1
0     0     0
1     0     0

Compare the binary values of the two vectors and compute the number of errors and the error rate by using the biterr and symerr functions.

format rat % Display fractions instead of decimals
[snum,srate] = symerr(a,b)
snum =
2

srate =
2/3

snum is 2 because the second and third entries have bit differences. srate is 2/3 because the total number of symbols is 3.

[bnum,brate] = biterr(a,b)
bnum =
5

brate =
5/9

bnum is 5 because the second entries differ in two bits, and the third entries differ in three bits. brate is 5/9 because the total number of bits is 9. By definition, the total number of bits is the number of entries in a for symbol error computations or b for bit error computations times the maximum number of bits among all entries of a and b, respectively.

### Performance Results via Semianalytic Technique

The technique described in the Performance Results via Simulation section can work for a large variety of communications systems but can be prohibitively time-consuming for small error rates (for example, 10-6 or less). The semianalytic technique is an alternative way to compute error rates. The semianalytic technique can produce results faster than a nonanalytic method that uses simulated data.

For more information on implementing the semianalytic technique using a combination of simulation and analysis to determine the error rate of a communications system, see the semianalytic function.

### Error Rate Plots

#### Section Overview

Error rate plots can be useful when examining the performance of a communications system and are often included in publications. This section discusses and demonstrates tools you can use to create error rate plots, modify them to suit your needs, and perform curve fitting on the error rate data and the plots.

#### Creation of Error Rate Plots Using semilogy Function

In many error rate plots, the horizontal axis indicates Eb/N0 values in dB, and the vertical axis indicates the error rate using a logarithmic (base 10) scale. For examples that create such a plot using the semilogy function, see Compare Theoretical and Empirical Error Rates and Plot Theoretical Error Rates.

#### Curve Fitting for Error Rate Plots

Curve fitting can be useful when you have a small or imperfect data set but want to plot a smooth curve for presentation purposes. The berfit function includes curve-fitting capabilities that help your analysis when the empirical data describes error rates at different Eb/N0 values. This function enables you to:

• Customize various relevant aspects of the curve-fitting process, such as a list of selections for the type of closed-form function used to generate the fit.

• Plot empirical data along with a curve that berfit fits to the data.

• Interpolate points on the fitted curve between Eb/N0 values in your empirical data set to smooth the plot.

• Collect relevant information about the fit, such as the numerical values of points along the fitted curve and the coefficients of the fit expression.

Note

The berfit function is intended for curve fitting or interpolation, not extrapolation. Extrapolating BER data beyond an order of magnitude below the smallest empirical BER value is inherently unreliable.

#### Use Curve Fitting on Error Rate Plot

This example simulates a simple differential binary phase shift keying (DBPSK) communications system and plots error rate data for a series of ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values. It uses the berfit and berconfint functions to fit a curve to a set of empirical error rates.

Initialize Simulation Parameters

Specify the input signal message length, modulation order, range of ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values to simulate, and the minimum number of errors that must occur before the simulation computes an error rate for a given ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ value. Preallocate variables for final results and interim results.

Typically, for statistically accurate error rate results, the minimum number of errors must be on the order of 100. This simulation uses a small number of errors to shorten the run time and to illustrate how curve fitting can smooth a set of results.

siglen = 100000; % Number of bits in each trial
M = 2; % DBPSK is binary
EbN0vec = 0:5; % Vector of EbN0 values
minnumerr = 5; % Compute BER after only 5 errors occur
numEbN0 = length(EbN0vec); % Number of EbN0 values

ber = zeros(1,numEbN0); % Final BER values
berVec = zeros(3,numEbN0); % Updated BER values
intv = cell(1,numEbN0); % Cell array of confidence intervals

Create an error rate calculator System object™.

errorCalc = comm.ErrorRate;

Loop the Simulation

Simulate the DBPSK-modulated communications system and compute the BER using a for loop to vary the ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ value. The inner while loop ensures that a minimum number of bit errors occur for each ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ value. Error rate statistics are saved for each ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ value and used later in this example when curve fitting and plotting.

for jj = 1:numEbN0
EbN0 = EbN0vec(jj);
snr = EbN0; % For binary modulation SNR = EbN0
reset(errorCalc)

while (berVec(2,jj) < minnumerr)
msg = randi([0,M-1],siglen,1); % Generate message sequence
txsig = dpskmod(msg,M); % Modulate
rxsig = awgn(txsig,snr,'measured'); % Add noise
decodmsg = dpskdemod(rxsig,M); % Demodulate
berVec(:,jj) = errorCalc(msg,decodmsg); % Calculate BER
end

Use the berconfint function to compute the error rate at a 98% confidence interval for the ${\mathrm{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values.

[ber(jj),intv1] = berconfint(berVec(2,jj),berVec(3,jj),0.98);
intv{jj} = intv1;
disp(['EbN0 = ' num2str(EbN0) ' dB, ' num2str(berVec(2,jj)) ...
' errors, BER = ' num2str(ber(jj))])
end
EbN0 = 0 dB, 18392 errors, BER = 0.18392
EbN0 = 1 dB, 14307 errors, BER = 0.14307
EbN0 = 2 dB, 10190 errors, BER = 0.1019
EbN0 = 3 dB, 6940 errors, BER = 0.0694
EbN0 = 4 dB, 4151 errors, BER = 0.04151
EbN0 = 5 dB, 2098 errors, BER = 0.02098

Use the berfit function to plot the best fitted curve, interpolating between BER points to get a smooth plot. Add confidence intervals to the plot.

fitEbN0 = EbN0vec(1):0.25:EbN0vec(end); % Interpolation values
berfit(EbN0vec,ber,fitEbN0);
hold on;
for jj=1:numEbN0
semilogy([EbN0vec(jj) EbN0vec(jj)],intv{jj},'g-+');
end
hold off;