Communication Technology

 

 

 

 

MMSE (Minimum Mean Square Error) - Matlab

 

This page is to show you some intuitive understandings about MMSE equalization. The original matlab code for this page is written by James Weng. I just modified it a little bit to get the type of plots that I want to get and change the function definition a little bit so that I can specify Precoding Matrix and Channel Matrix as parameters.

 

You may refer to MMSE page for deriving the mathematical representation of MMSE.

 

 

Example 01 >

Precoder = 1/2 * [1 1;1 -1];

Channel = [1 0;0 1];

Qam = 4;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 02 >

Precoder = 1/2 * [1 1;1 -1];

Channel = [1 0.5;0.5 1];

Qam = 4;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 03 >

Precoder = 1/sqrt(2) * [1 0;0 1];

Channel = [1 0;0 1];

Qam = 4;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 04 >

Precoder = 1/sqrt(2) * [1 0;0 1];

Channel = [1 0.5;0.5 1];

Qam = 4;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 05 >

Precoder = 1/2 * [1 1;1 -1];

Channel = [1 0.5;0.2 1];

Qam = 4;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 06 >

Precoder = 1/2 * [1 0;01];

Channel = [1 0.2;0.2 1];

Qam = 4;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 07 >

Precoder = 1/2 * [1 1;1 -1];

Channel = [1 0;0 1];

Qam = 16;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 08 >

Precoder = 1/2 * [1 1;1 -1];

Channel = [1 0;0 1];

Qam = 64;

snr = 20;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

Example 09 >

Precoder = 1/2 * [1 1;1 -1];

Channel = [1 0;0 1];

Qam = 64;

snr = 30;

 

fnDemoMmse(Qam,snr,Channel,Precoder);

 

 

 

fnDemoMmse.m

function [dummy] = main(m_qam, snr_dB,H,P)

% Demonstrate MMSE equalization

% Inputs:

%   m_qam:  QAM level. Square QAM only.

%           Default = 16QAM.

%   snr_dB: SNR per symbol in dB.

%           Default = 20dB;

 

dummy = 0;

 

if (nargin < 1)

   m_qam = 16;

end

if (nargin < 2)

   snr_dB = 20;

end

 

m_pam_i = floor(sqrt(m_qam + 1e-3)); % compute square root of QAM

m_pam_q = m_qam / m_pam_i;

 

sig_amp = sqrt(10^(snr_dB/10));  % Signal amplitude

 

n_sym_per_layer= 1000;           % Number of symbols per layer to simulate

 

n_layers = 2;                    % Number of layers

n_tx_ant = 2;                    % Number of Tx antennas

n_rx_ant = 2;

 

rand('state', 3200);             % set random generator state

 

% Transmitted symbols with normalized power

m_pwr = (m_qam - 1) / 3;         % average QAM power

v_tx_sym = sqrt(1/m_pwr) * fnGenQam(m_pam_i, m_pam_q, n_layers, n_sym_per_layer);

 

v_tx_sym_precoded = P * v_tx_sym;  % symbols after precoding

 

% Received signal + noise (normalized power).

v_noise = randn(n_rx_ant, n_sym_per_layer) + 1i * randn(n_rx_ant, n_sym_per_layer);

v_R = sig_amp * H * v_tx_sym_precoded + v_noise;  % Each column is a vector of R for the received signal vector

 

 

% MMSE equalizer. Assuming sig_amp, H, and P are known

G = sig_amp * H * P;

I = eye(n_rx_ant);

F = G' * inv(G * G' + I);

 

% Equalized symbols

v_Y = F * v_R;

 

figure(101);

subplot(2,2,1);

plot(real(v_tx_sym), imag(v_tx_sym), 'bo','MarkerFaceColor',[0 0 1],'MarkerSize',4);

iq_max = ceil( 1.1*max(real(reshape(v_tx_sym,1,[]))));

axis([-iq_max iq_max -iq_max iq_max]);

title('Tx QAM symbols');

 

subplot(2,2,2);

plot(real(v_tx_sym_precoded), imag(v_tx_sym_precoded), 'ro','MarkerFaceColor',[1 0 0],'MarkerSize',4);

iq_max = ceil( 1.1*max(real(reshape(v_tx_sym_precoded,1,[]))));

axis([-iq_max iq_max -iq_max iq_max]);

title('Tx QAM symbols after precoding');

 

subplot(2,2,3);

plot(real(v_R), imag(v_R), 'r.');

iq_max = ceil( 1.1*max(real(reshape(v_R,1,[]))));

axis([-iq_max iq_max -iq_max iq_max]);

title('Rx symbols');

 

subplot(2,2,4);

plot(real(v_Y), imag(v_Y), 'b.');

iq_max = ceil( 1.1*max(real(reshape(v_Y,1,[]))));

axis([-iq_max iq_max -iq_max iq_max]);

title('Equalized symbols');

 

 

% --------------------------------------------------------------------------------------

% Generate QAM symbols

function v_qam = fnGenQam(pam_i, pam_q, nx, ny)

v_qam= fnGenPam(pam_i, nx, ny) + 1i * fnGenPam(pam_q, nx, ny);

 

% Generate PAM symbols

function v_pam = fnGenPam(pam, nx, ny)

v_pam = rand(nx, ny) * pam;

v_pam = 2 * ceil(v_pam) - 1 - pam;