QAM modulation: simulate in Matlab & Python

A generic complex baseband simulation technique, to simulate all M-ary QAM modulation techniques is given here. The given simulation code is very generic, and it plots both simulated and theoretical symbol error rates for all M-QAM modulation techniques.

Rectangular QAM from PAM constellation

There exist other constellation shapes (like circular, triangular constellations) that are more efficient (in terms of energy required to achieve same the error probability) than the standard rectangular constellation. Rectangular (symmetric or square) constellations are the preferred choice of implementation due to its simplicity in implementing modulation and demodulation.

In one of the earlier articles, I have discussed the method of constructing constellation for rectangular QAM modulation using Karnaugh-map walks, where the inherent property of Karnaugh-maps is exploited to construct Gray coded QAM symbols.

Any rectangular QAM constellation is equivalent to superimposing two Amplitude Shift Keying (ASK) signals (also called Pulse Amplitude Modulation – PAM) on quadrature carriers. For example, 16-QAM constellation points can be generated from two 4-PAM signals, similarly the 64-QAM constellation points can be generated from two 8-PAM signals.

Signal space constellations for 16-QAM and 64-QAM
Figure 1: Signal space constellations for 16-QAM and 64-QAM

The generic equation to generate PAM signals of dimension D is

equation for square QAM modulation using two PAM modulated symbols

For generating 16-QAM, the dimension D of PAM is set to D=\sqrt{16}=4. Thus for constructing a M-QAM constellation, the PAM dimension is set as D=\sqrt{M}. Matlab code for dynamically generating M-QAM constellation points based on Karnaugh map Gray code walk is given below. The resulting ideal constellations for Gray coded 16-QAM and 64-QAM are shown in Figure 1.

Matlab code

Full Matlab code available in the book Digital Modulations using Matlab – build simulation models from scratch

function [s,ref]=mqam_modulator(M,d)
%Function to MQAM modulate the vector of data symbols - d
%[s,ref]=mqam_modulator(M,d) modulates the symbols defined by the vector d
% using MQAM modulation, where M specifies order of M-QAM modulation and
% vector d contains symbols whose values range 1:M. The output s is modulated
% output and ref represents reference constellation that can be used in demod
if(((M˜=1) && ˜mod(floor(log2(M)),2))==0), %M not a even power of 2
  error('Only Square MQAM supported. M must be even power of 2');
end
  ref=constructQAM(M); %construct reference constellation
  s=ref(d); %map information symbols to modulated symbols
end

Python code

Full Matlab code available in the book Digital Modulations using Python

class QAMModem(Modem):
    # Derived class: QAMModem
    
    def __init__(self,M):
        
        if (M==1) or (np.mod(np.log2(M),2)!=0): # M not a even power of 2
            raise ValueError('Only square MQAM supported. M must be even power of 2')
        
        n = np.arange(0,M) # Sequential address from 0 to M-1 (1xM dimension)
        a = np.asarray([xˆ(x>>1) for x in n]) #convert linear addresses to Gray code
        D = np.sqrt(M).astype(int) #Dimension of K-Map - N x N matrix
        a = np.reshape(a,(D,D)) # NxN gray coded matrix
        oddRows=np.arange(start = 1, stop = D ,step=2) # identify alternate rows
        
        nGray=np.reshape(a,(M)) # reshape to 1xM - Gray code walk on KMap
        #Construction of ideal M-QAM constellation from sqrt(M)-PAM
        (x,y)=np.divmod(nGray,D) #element-wise quotient and remainder
        Ax=2*x+1-D # PAM Amplitudes 2d+1-D - real axis
        Ay=2*y+1-D # PAM Amplitudes 2d+1-D - imag axis
        constellation = Ax+1j*Ay
        Modem.__init__(self, M, constellation, name='QAM') #set the modem attributes

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
All books available in ebook (PDF) and Paperback formats

M-QAM demodulation (coherent detection)

Generally the two main categories of detection techniques, commonly applied for detecting the digitally modulated data are coherent detection and non-coherent detection.

In the vector simulation model for the coherent detection, the transmitter and receiver agree on the same
reference constellation for modulating and demodulating the information. The modulators generate the reference constellation for the selected modulation type. The same reference constellation should be used if coherent detection is selected as the method of demodulating the received data vector.

On the other hand, in the non-coherent detection, the receiver is oblivious to the reference constellation used at the transmitter. The receiver uses methods like envelope detection to demodulate the data.

The IQ detection technique is an example of coherent detection. In the IQ detection technique, the first step is to compute the pair-wise Euclidean distance between the given two vectors – reference array and the received symbols corrupted with noise. Each symbol in the received symbol vector (represented on a p-dimensional plane) should be compared with every symbol in the reference array. Next, the symbols, from the reference array, that provide the minimum Euclidean distance are returned.

Let x=(x1,x2,…,xp) and y=(y1,y2,…,yp) be two points in p-dimensional space. The Euclidean distance between them is given by

Pairwise Euclidean distance equation

The pair-wise Euclidean distance between two sets of vectors, say x and y, on a p-dimensional space, can be computed using the vectorized code. The vectorized code returns the ideal signaling points from matrix y that provides the minimum Euclidean distance. Since the vectorized implementation is devoid of nested for-loops, the program executes significantly faster for larger input matrices. The given code is very generic in the sense that it can be easily reused to implement optimum coherent receivers for any N-dimensional digital modulation technique (Please refer the books Digital Modulations using Matlab and Digital Modulations using Python for complete simulation code) .

Matlab code

Full Matlab code available in the book Digital Modulations using Matlab

function [dCap]= mqam_detector(M,r)
%Function to detect MQAM modulated symbols
%[dCap]= mqam_detector(M,r) detects the received MQAM signal points
%points - 'r'. M is the modulation level of MQAM
   if(((M˜=1) && ˜mod(floor(log2(M)),2))==0), %M not a even power of 2
      error('Only Square MQAM supported. M must be even power of 2');
   end
   ref=constructQAM(M); %reference constellation for MQAM
   [˜,dCap]= iqOptDetector(r,ref); %IQ detection
end

Python code

Full Matlab code available in the book Digital Modulations using Python

Performance simulation results

The simulation results for error rate performance of M-QAM modulations over AWGN channel and Rician flat-fading channel is given in the following figures.

Error rate performance of M-QAM modulations in AWGN channel
Figure 2: Error rate performance of M-QAM modulations in AWGN channel
Error rate performance of MQAM modulations in Rayleigh flat-fading channel
Figure 3: Error rate performance of 64-QAM modulation in Rician flat-fading channels having different values for Rician K-factors.

Rate this article: PoorBelow averageAverageGoodExcellent (14 votes, average: 3.93 out of 5)

Reference

[1] John G. Proakis, “Digital Communciations”, McGraw-Hill; 5th edition.↗

Related Topics

Digital Modulators and Demodulators - Complex Baseband Equivalent Models
Introduction
Complex baseband representation of modulated signal
Complex baseband representation of channel response
● Modulators for amplitude and phase modulations
 □ Pulse Amplitude Modulation (M-PAM)
 □ Phase Shift Keying Modulation (M-PSK)
 □ Quadrature Amplitude Modulation (M-QAM)
● Demodulators for amplitude and phase modulations
 □ M-PAM detection
 □ M-PSK detection
 □ M-QAM detection
 □ Optimum detector on IQ plane using minimum Euclidean distance
● M-ary FSK modulation and detection
 □ Modulator for M orthogonal signals
 □ M-FSK detection

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

19 thoughts on “QAM modulation: simulate in Matlab & Python”

  1. If I wanted to use this technique to construct a constellation for 64QAM would I use levels: {-7, -5, -3, -1, 1, 3, 5, 7}
    and for 256QAM {-11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11} ?

    Reply
    • Any given standards has its own way of negotiating the link. Lets see how it is done in LTE.

      LTE offers all possible combination of resource allocation that combines different time Domain, frequency Domain and the modulation schemes. The question now is how can the receiver know exactly in which time slot , at what frequency and in which modulation format the sender is sending the information. Without knowing this information, the receiver cannot decode the captured signal. LTE has standardized the art of knowing this information using the term “DCI(Downlink Control Indicator)”.

      DCI carries all the necessary information for decoding the received data at the receiver. It carries details like – “the exact resource block the carries data”, “the type of demodulation the receiver must use” , etc..,

      Not only in LTE, other wireless standards also has similar indicators. For example, in WCDMA R99 slot format and TFCI carries those information and in HSDPA HS-SCCH carries those information.

      You may refer this book for more details

      Reply
    • Any given standards has its own way of negotiating the link. Lets see how it is done in LTE.

      LTE offers all possible combination of resource allocation that combines different time Domain, frequency Domain and the modulation schemes. The question now is how can the receiver know exactly in which time slot , at what frequency and in which modulation format the sender is sending the information. Without knowing this information, the receiver cannot decode the captured signal. LTE has standardized the art of knowing this information using the term “DCI(Downlink Control Indicator)”.

      DCI carries all the necessary information for decoding the received data at the receiver. It carries details like – “the exact resource block the carries data”, “the type of demodulation the receiver must use” , etc..,

      Not only in LTE, other wireless standards also has similar indicators. For example, in WCDMA R99 slot format and TFCI carries those information and in HSDPA HS-SCCH carries those information.

      You may refer this book for more details
      https://amzn.to/2htw8ix

      Reply
  2. but if using k-map method, so we know the position of mapping point only. what about its phase and its amplitude? how to get it if i use k-map method?

    Reply
  3. do you have any book or journal which explain about constructing constellation using karnaugh map? because i am very interested with this method.
    If you have, please give me the link address. Thankyou…

    Reply
  4. are you sure bout this, because in table we can see that 00,01,11,10.
    Why not 00,01,10,11? i think it must be chronological.. cmiiw

    Reply
    • This is the mapping for M=4 QAM constellation using two variable K-map where the neighboring symbols differ only by one bit. Note: ’01’ and ’10’ are not neighbors in this square constellation as they are diametrically opposite, same goes for ’00’ and ’11’ too.

      Reply

Post your valuable comments !!!