Simulate additive white Gaussian noise (AWGN) channel

In this article, the relationship between SNR-per-bit (Eb/N0) and SNR-per-symbol (Es/N0) are defined with respect to M-ary signaling schemes. Then the complex baseband model for an AWGN channel is discussed, followed by the theoretical error rates of various modulations over the additive white Gaussian noise (AWGN) channel. Finally, the complex baseband models for digital modulators and detectors developed in previous chapter of this book, are incorporated to build a complete communication system model.

If you would like to know more about the simulation and analysis of white noise, I urge you to read this article: White noise: Simulation & Analysis using Matlab.

Signal to noise ratio (SNR) definitions

Assuming a channel of bandwidth B, received signal power Pr and the power spectral density (PSD) of noise N0/2, the signal to noise ratio (SNR) is given by

\gamma = \displaystyle{\frac{P_r}{N_0 B}}

Let a signal’s energy-per-bit is denoted as Eb and the energy-per-symbol as Es, then γb=Eb/N0 and γs=Es/N0 are the SNR-per-bit and the SNR-per-symbol respectively.

For uncoded M-ary signaling scheme with k = log2(M) bits per symbol, the signal energy per modulated symbol is given by

E_s = k. E_b

The SNR per symbol is given by

\gamma_s = \displaystyle{ \frac{E_s}{N_0} = k. \frac{E_b}{N_0} = k. \gamma_b}

AWGN channel model

In order to simulate a specific SNR point in performance simulations, the modulated signal from the transmitter needs to be added with random noise of specific strength. The strength of the generated noise depends on the desired SNR level which usually is an input in such simulations. In practice, SNRs are specified in dB. Given a specific SNR point for simulation, let’s see how we can simulate an AWGN channel that adds correct level of white noise to the transmitted symbols.

simulation model for additive white Gaussian noise (awgn) channel
Figure 1: Simplified simulation model for awgn channel

Consider the AWGN channel model given in Figure 1. Given a specific SNR point to simulate, we wish to generate a white Gaussian noise vector \mathcal{N}(0,{\sigma}^2) of appropriate strength and add it to the incoming signal. The method described can be applied for both waveform simulations and the complex baseband simulations. In following text, the term SNR (γ) refers to γb = Eb/N0 when the modulation is of binary type (example: BPSK). For multilevel modulations such as QPSK and MQAM, the term SNR refers to γs = Es/N0.

(1) Assume, s is a vector that represents the transmitted signal. We wish to generate a vector r that represents the signal after passing through the AWGN channel. The amount of noise added by the AWGN channel is controlled by the given SNR – γ

(2) For waveform simulation model, let the given oversampling ratio is denoted as L. On the other hand, if you are using the complex baseband models, set L=1.

(3) Let N denotes the length of the vector s. The signal power for the vector s can be measured as,

equation for computing power of a signal

(4) The required power spectral density of the noise vector n is computed as

equation for required noise power spectral density for awgn channel

(5) Assuming complex IQ plane for all the digital modulations, the required noise variance (noise power) for generating Gaussian random noise is given by

equation for noise variance for awgn channel

(6) Generate the noise vector n drawn from normal distribution with mean set to zero and the standard deviation computed from the equation given above

equation for noise vector for real and complex additive white Gaussian noise channel

(7) Finally add the generated noise vector (n) to the signal (s)

equation for awgn noise channel

Matlab code

The following custom function written in Matlab, can be used for adding AWGN noise to an incoming signal. It can be used in waveform simulation as well as complex baseband simulation models.

%author - Mathuranathan Viswanathan (gaussianwaves.com
%This code is part of the books: Wireless communication systems using Matlab & Digital modulations using Matlab.

function [r,n,N0] = add_awgn_noise(s,SNRdB,L)
%Function to add AWGN to the given signal
%[r,n,N0]= add_awgn_noise(s,SNRdB) adds AWGN noise vector to signal
%'s' to generate a %resulting signal vector 'r' of specified SNR
%in dB. It also returns the noise vector 'n' that is added to the
%signal 's' and the spectral density N0 of noise added
%
%[r,n,N0]= add_awgn_noise(s,SNRdB,L) adds AWGN noise vector to
%signal 's' to generate a resulting signal vector 'r' of specified
%SNR in dB. The parameter 'L' specifies the oversampling ratio used
%in the system (for waveform simulation). It also returns the noise
%vector 'n' that is added to the signal 's' and the spectral
%density N0 of noise added
 s_temp=s;
 if iscolumn(s), s=s.'; end; %to return the result in same dim as 's'
 gamma = 10ˆ(SNRdB/10); %SNR to linear scale
 
 if nargin==2, L=1; end %if third argument is not given, set it to 1
 
 if isvector(s),
  P=L*sum(abs(s).ˆ2)/length(s);%Actual power in the vector
 else %for multi-dimensional signals like MFSK
  P=L*sum(sum(abs(s).ˆ2))/length(s); %if s is a matrix [MxN]
 end
 
 N0=P/gamma; %Find the noise spectral density
 if(isreal(s)),
  n = sqrt(N0/2)*randn(size(s));%computed noise
 else
  n = sqrt(N0/2)*(randn(size(s))+1i*randn(size(s)));%computed noise
 end
 
 r = s + n; %received signal
 
 if iscolumn(s_temp), r=r.'; end;%return r in original format as s
end

Python code

The following custom function written in Python 3, can be used for adding AWGN noise to an incoming signal. It can be used in waveform simulation as well as complex baseband simulation models.

# author - Mathuranathan Viswanathan (gaussianwaves.com
# This code is part of the book Digital Modulations using Python

from numpy import sum,isrealobj,sqrt
from numpy.random import standard_normal

def awgn(s,SNRdB,L=1):
    """
    AWGN channel
    Add AWGN noise to input signal. The function adds AWGN noise vector to signal 's' to generate a resulting signal vector 'r' of specified SNR in dB. It also
    returns the noise vector 'n' that is added to the signal 's' and the power spectral density N0 of noise added
    Parameters:
        s : input/transmitted signal vector
        SNRdB : desired signal to noise ratio (expressed in dB) for the received signal
        L : oversampling factor (applicable for waveform simulation) default L = 1.
    Returns:
        r : received signal vector (r=s+n)
"""
    gamma = 10**(SNRdB/10) #SNR to linear scale
    if s.ndim==1:# if s is single dimensional vector
        P=L*sum(abs(s)**2)/len(s) #Actual power in the vector
    else: # multi-dimensional signals like MFSK
        P=L*sum(sum(abs(s)**2))/len(s) # if s is a matrix [MxN]
    N0=P/gamma # Find the noise spectral density
    if isrealobj(s):# check if input is real/complex object type
        n = sqrt(N0/2)*standard_normal(s.shape) # computed noise
    else:
        n = sqrt(N0/2)*(standard_normal(s.shape)+1j*standard_normal(s.shape))
    r = s + n # received signal
return r

Theoretical symbol error rates for digital modulations in AWGN channel

Denoting the symbol error rate (SER) as P_s, SNR-per-bit as gamma_b=E_b/N_0 and SNR-per-symbol as gamma_s=E_s/N_0, the symbol error rates for various modulation schemes over AWGN channel are listed in Table 1 (refer [1]).

Table of Theoretical symbol error rate for various modulations in awgn channel.
Table 1: Theoretical symbol error rate for various modulations in AWGN channel

The theoretical symbol error rates are coded as a reusable function. In this implementation, erfc function is used instead of the Q function shown in the Table 4.1. The following equation describes the relationship between the erfc function and the Q function.

Q(x) = \frac{1}{2} erfc \left( \frac{x}{\sqrt{2}} \right)

Unified simulation model for performance simulation

In the previous chapter of the books, the code implementation for complex baseband models for various digital modulators and demodulator are given. Using these models, we can create a unified simulation code for simulating the performance of various modulation techniques over AWGN channel.

The complete simulation model for performance simulation over AWGN channel is given in Figure 2. The figure is illustrated for a coherent communication system model (applicable for MPSK/MQAM/MPAM modulations)

Complete simulation model for a communication system with AWGN channel
Figure 2: Complete simulation model for a communication system with AWGN channel

The Matlab code implementing the aforementioned simulation model is given in the books. Here, an unified approach is employed to simulate the performance of any of the given modulation technique – MPSK, MQAM, MPAM or MFSK (MFSK simulation technique is available in the following books: Digital Modulations using Python and Digital Modulations using Matlab).

This article is part of the following books
Digital Modulations using Matlab : Build Simulation Models from Scratch, ISBN: 978-1521493885
Digital Modulations using Python ISBN: 978-1712321638
Wireless communication systems in Matlab ISBN: 979-8648350779
All books available in ebook (PDF) and Paperback formats

The simulation code will automatically choose the selected modulation type, performs Monte Carlo simulation, computes symbol error rates and plots them against the theoretical symbol error rates. The simulated performance results obtained for MQAM and MPSK modulations are shown in the Figure 3 and Figure 4.

Simulated symbol error rate performance of M-QAM modulation over AWGN channel
Figure 3: Simulated symbol error rate performance of M-QAM modulation over AWGN channel
Simulated symbol error rate performance of M-PSK modulation over AWGN channel
Figure 4: Simulated symbol error rate performance of M-PSK modulation over AWGN channel

Rate this article: PoorBelow averageAverageGoodExcellent (27 votes, average: 4.33 out of 5)

References

[1] Andrea Goldsmith, Wireless Communications, Cambridge University Pres, first edition, August 8, 2005.↗

Books by the author

Wireless Communication Systems in Matlab
Wireless Communication Systems in Matlab
Second Edition(PDF)

PoorBelow averageAverageGoodExcellent (180 votes, average: 3.62 out of 5)

Digital modulations using Python
Digital Modulations using Python
(PDF ebook)

PoorBelow averageAverageGoodExcellent (134 votes, average: 3.56 out of 5)

digital_modulations_using_matlab_book_cover
Digital Modulations using Matlab
(PDF ebook)

PoorBelow averageAverageGoodExcellent (136 votes, average: 3.63 out of 5)

Hand-picked Best books on Communication Engineering
Best books on Signal Processing

45 thoughts on “Simulate additive white Gaussian noise (AWGN) channel”

  1. Sir, there is now a three-dimensional QAM signal, that is, the QAM signal has three coordinate components: x, y, and z. Suppose there are 100 symbols, and I represent them as 3 × 100 matrix. How do I add Gaussian white noise to it?

    Reply
  2. Please Sir, i need the Matlab Code Source of :

    We an Orthogonal frequency-division multiplexing (OFDM) transmitter composed of a total N = 256 sub-carriers and a prefix cyclic of L = 32 samples. Among these N sub-carriers, the 16 first ones are allocated to transmit 64-QAM symbols. The transmitted power can be normalized to 1W (but it doesn’t matter much for this exercise). The AWGN channel model is considered.

    Using MATLAB simulations, display the Bit Error Rate (BER) curve as function of Eb/No of the above OFDM system. Compare the obtained BER performance with the ones obtained when considering a 64-QAM single-carrier modulation (we wan to use the MATLAB function “berawgn” can be used to save time).

    Reply
  3. Hi Sir,
    Is this correct? If yes what does this mean?
    snr = 10
    y = awgn(randn(1,1000), snr , ‘measured’)
    What is the noise variance in this case?

    Reply
  4. Dear Sir Mathuranathan,

    I bought all your books, and I already understand passband and complex baseband simulation models, What I cannot get to know is why in your calculus of the Symbol Energy you assert that the oversampling factor is relevant only when the simulation is at waveform level but it musn’t be included when the simulation is complex baseband.

    Thank you very much.
    Regards

    Reply
    • In waveform level simulations, depending on the sampling frequency, each transmitted symbol is composed of #L number of sampled bits. Thus the oversampling factor for such simulation models is set to L.

      On the other hand, in the complex baseband model, we are not simulating bit-to-bit variations in the transmitted signal. Rather, we are interested in symbol-level simulation. Here, there is no sampling involved. Hence each transmitted symbol is equivalent to only one bit (at symbol sampling instant). Therefore, the oversampling factor L is set to 1.

      Reply
      • Thank you Mr Mathuranathan for your clear and quick reply. My misunderstood rose from the fact that in my simulations the difference between passband simulations and complex simulations is only the use or not of a carrier, which means that I always have some oversampling factor (much smaller in complex envelope).

        So, can we say that there exist three level of simulations?:

        Passband Simulations (OF = N)
        Complex Envelope (OF = M <<<< N)
        Symbol Level (OF = 1)

        Thank you very much

        Reply
  5. Dear Mathuranathan,

    Could you explain a bit deeper the difference between using complex baseband or passband simulations ir order to include or not the Oversampling Factor?.

    Thank you very much

    Reply
  6. Hi,

    I have the next question: the awgn object has a parameter called “SamplesPerSymbol”, where this parameter is used in the custom equation ?

    Thanks.

    Reply
    • The custom function given here, mimics the ‘awgn’ function given here : http://www.mathworks.com/help/comm/ref/awgn.html
      It computes the required noise from the given SNR that is defined as ‘SNR per sample’. So there is no connotation of ‘samplesPersymbol’ in this case.

      Whereas, the comm toolbox object that you are referring to is more sophisticated, that includes different arguments like EbNo, EsNo, SNR, BitsPerSymbol, SignalPower, SamplesPerSymbol, and Variance etc..,

      Of course, the function given here can be extended to include all these parameters above.

      Reply
  7. If I have multiple complex signals in parallel , e.g a 6x 5000 matrix. How can I add awgn noise to them using this function?

    Reply
  8. Nice code ….I want to ask about my specific problem…..
    I am building an end to end basic Communication transceiver.My signal at Transmitter before adding AWGN noise is over sampled by factor of 10.I am adding a noise as per your code without considering oversampling factor during noise addition.I have verified the channel block and at receiver processed the channel signal(catering the upsampling factor at receiver) but upon comparing BER curve with theoretical results (berawgn function) ,there is 4dB difference/offset in BER curves(My results are 4dB better than theoretical BER curve as per attachment)…..The only thing I am worried is about upsampling factor incorporation in AWGN block while my transmitter and receiver is bug free…..
    Please tell how to cater this upsampling factor during noise addition.

    Reply
    • That curve is expected, if you do not incorporate the oversampling factor in the code.
      To incorporate the oversampling factor (OF), change line 17 as in add_awgn_noise function as
      Esym=OF*sum(abs(x).^2)/(L); %Calculate actual symbol energy

      Reply
      • Thanks dear for your response.I did as per your suggestion but this time the ber performance becomes 6dB poor as per attachment below.Please suggest Whats wrong …Do I need to use
        Esym=sqrt(OF)*sum(abs(x).^2)/(L); %Calculate actual symbol energy
        instead.Thanks for ur time again.

        Reply
        • what is the format of the modulated signal from the transmitter ? Are you using a complex number representation to represent inphase and quadrature signal- Complex baseband equivalent model? In this case, you do not need a oversampling factor in the simulation.

          If the modulation signal is not in complex format, you can add noise as follows (I have verified it for all PSK modulations, QAM should be okay too). The only difference here is the noise sigma set to N0/2 (same as in the case of complex signal)

          SNR = 10ˆ(SNR_dB/10); %SNR to linear scale
          Esym=OF*sum(abs(x).^2)/(L); %Calculate actual symbol energy
          N0=Esym/SNR; %Find the noise spectral density
          noiseSigma = sqrt(N0/2) #note the factor N0/2
          n = noiseSigma*randn(1,L);%computed noise
          y = x+n

          Instead, if your simulation is a passband simulation, then the oversampling factor is relevant.

          Reply
          • Yes the transmitted signal is a complex signal and noise I added is both to real and imaginary part catering the No/2 factor you mentioned.
            Also,What I foresee about the possible mistake is that I am passing my vector named snrVecdB to berawgn function instead of Eb/No as berawgn function demands Eb/No instead of snr Vector.
            snrVecdB = -4:2:10; % in db
            bertheory= berawgn(snrVecdB(snrCount),’qam’,M);
            Remember it will matter as I am computing Es/No in simulation during adding noise in AWGN channel.

            Reply
  9. Dear Sir @Mathuranathan:disqus , How about the Bandwidth of the signal ,I guess we have to adjust the values of the noise power which located only within this banwidth right? … For AWGN case, when adding the noise , its distribution is Flat along the whole frequencies , so how much the noise power within the signal spectrum? our interest should be for the noise power values located within this bandwidth ,isn’t it? . I am very thankful for this great website which benefiting me a lot.

    Reply
    • If you first generate a real noise signal x, with zero mean and variance sigma^2 (so the power is sigma^2 too) and you use it in a simulation for a particular sample rate Fs, then the spectral density is sigma^2/(Fs/2). For band-limited noise, It’s clearer to most people I think if you first generate the noise power based on the density you want (and thus you need more power the bigger Fs is). Then you filter it with some filter (typically FIR to match some analog filter or the particular digital filter you are using) and choose the filter so that it has unity DC gain (sum of coefficients is 1). Then after you filter the white noise, it will have power = BW*sigma^2/(Fs/2), where BW is the one sided bandwidth of the filter (0 to cutoff freq). Note that one BW = Fs/2 (which is no filtering), you are still at sigma^2 but for any smaller BW, you have reduced the power.

      Reply
  10. Want to add simple Phase noise in my signal. when i am analyse the signals in frequency domain i do not get desired output. For the ideal signal, it shoud be only single peak whereas after adding noise it shoud be having some fluctuations. What is the mistake i am making?

    sig = cos(2*pi*30*t); %%%% original signal
    sig_fft = fft(sig);
    figure,plot(abs(sig_fft));
    sigma = 2
    sig2 = sig + sigma*randn(1,length(t)); %%%%% adding phase noise
    sig2_fft = fft(sig2);
    figure,plot(abs(sig2_fft));

    Reply
        • Usually, the phase noise is considered UNIFORM drawn from the interval [-pi,pi].
          Therefore phase noise needs to be from -pi to +pi and it can be drawn from a uniform distribution. Use rand function for uniform rvs instead of randn function which is for Gaussian rvs.

          The rand function must generate uniform phase from -pi to +pi. Read thorough the matlab doc on how to generate a uniform distribution in the interval [a,b] and substitute a by -pi and b by +pi.

          Reply
            • Hey Mathuranathan,
              As you told me i used rand to generate phase noise. However, when i see the graph in frequency domain the spectrum is not broading. Can you tell me what mistake i am making?

              sigma = 0.5;
              t = 0:0.01:1;
              sig = cos(2*pi*4*t); % original signal
              A = sigma *randn(1,length(t)); % standard deviation of phase noise, increase
              sig2 = (A).*cos(2*pi*4*t + sigma*rand(1,length(t))); % signal with phase noise & amplitud4e noise
              figure,plot(t,sig,’r’,t,sig2, ‘b’);
              figure, plot(abs(fft(sig,10*length(sig))));
              figure, plot(abs(fft(sig2,10*length(sig2))));
              return

              Reply
              • (A).*cos(2*pi*4*t + sigma*rand(1,length(t)))

                1) Implies you are randomizing the amplitude (A) too.
                2) why there is a sigma for uniform distribution (rand) ? Sigma quantifies a normal distribution (randn)
                function
                The rand function must generate a random number between -pi and pi. The code does not do that.

                Reply
          • Phase noise better not be uniform from -pi to pi. That much phase noise will ruin any comm system. If you want to see the PDF of what an example phase noise would look like and you have the Matlab Comm toolbox you can type:

            Nsamp = 1e5;
            Nhist = 1e3;
            hPhNoise = comm.PhaseNoise(‘Level’,[-60 -80], ‘FrequencyOffset’,[20 200], ‘SampleRate’,1024); % an example call from the doc pages
            y = step(hPhNoise, 1j*ones(Nsamp,1)); % instantiates phase noise on a trivial constant phasor which is complex (Matlab will complain if not complex)
            figure, hist((angle(y)-pi/2), Nhist)

            Sure enough the PDF is Gaussian. Why would that be? Because of the Law of Large Numbers – phase noise is the sum of a lot of little things going on with analog hardware that creates an imperfect sinusoid. So in fact mayank is correct about using randn and scaling it by sigma for phase noise. The problem is: though you can adjust a sigma to match an RMS phase noise spec, and then write code to use sigma*randn(1, N) to put in the argument of a cos or exp function, this will give white phase noise (independent with each time sample as is AWGN) when phase noise is never like this – it has a (more difficult to simulate) dBc/Hz spectrum that can only be viewed clearly on a log-log plot. So you have to filter the noise sequence before applying it to the argument. Again, if you have the Comm toolbox, there is a lot of info on doc comm.PhaseNoise. If you don’t have the toolbox (or even if you do), this link looked good: http://www.dsplog.com/2012/09/30/modeling-phase-noise-frequency-domain/

            Reply
            • That’s not necessarily true. Phase noise assumption depends on the context. For example, the oscillator phase can be made random from one symbol time to another and still a modulation technique like fsk can be detected non-coherently. If the context is not given, I would generally assume noise to be uniform

              Reply
              • Mathuranathan, Good point about context. I agree that a slowly varying random phase can be tolerated in an FSK system (or any comm system for that matter if it varies slowly enough and can be tracked out). This random phase can walk around all over the place and modulo 2 pi, it will over the very long term be uniform from 0 to 2 pi. My basic understanding of phase noise is this: in the analog domain it is a random process that has all frequency content in it, but has infinite power when integrated from 0 freq to any finite BW. The way I typically model it is to ignore the section from 0 freq up to the PLL BW if a PLL is used (or if it is not used as in a non-coherent FSK system that you mention, some low freq limit that has no effect on BER). And there is a high speed cut off based on filtering that is used. So one only needs to consider the phase noise density from f1 to f2 and typically when integrated between these two frequencies, you might end up with 1 deg RMS or 20 deg RMS (tolerated in BPSK but not 256 QAM) or whatever, but you will have a zero mean random sequence (because you are ignoring the 0 freq to f1 part) which means the random variable will have a PDF that is a certain shape and I maintain at that point, the shape is typically Gaussian and not uniform. I do agree that context matters though and I suppose I need to know a lot more about mayank’s exact simulation task before commenting any further. Did you try my example code that I posted?

                Reply
                • Dara_parsavand, Thanks for adding your insights and knowledge. Yes, I am aware of the phase noise function in the comm toolbox and I always use it in my simulations wherever required. Yes, as you mentioned, the phase level is all the more important for phase shift keying systems.

                  Reply
    • If the Eb/N0 values are given, the noise should be generated accordingly as follows.

      Actually, the above function calculates the symbol energy (Es) and adds noise to the incoming signal accordingly. The input argument SNR_dB is equivalent to Es/N0 in dB.

      If Eb/N0 is given, it needs to be converted to Es/N0 appropriately. Examples follows

      Es/N0 dB = 10*log10(2) + Eb/N0 dB; %in linear scale for QPSK , 1 symbol = 2bits
      Es/N0 dB = 10*log10(4) + Eb/N0 dB; %in linear scale for 16-QAM , 1 symbol = 4bits

      Generic case:
      Es/N0 dB = 10*log10(k) + Eb/N0 dB; %in linear scale for any modulation where 1 symbol = k bits

      Now call the function

      y = add_awgn_noise(x,EsN0dB); %where x is the variable that contains the modulated samples for which the noise needs to be added

      Reply

Post your valuable comments !!!