Przetwarzanie sygnałów w systemach MIMO
Autorzy: Paweł Turcza
Pliki: rozdzial_24.zip
Przyklad dekoder ML i MMSE w systemie MIMO
Przykład dekodowania strumienia danych w systemie MIMO (2, 2), tj. w systemie wyposażonym w dwie anteny nadawcze i dwie odbiorcze.
Program (plik mimo_bpsk.m) wyznacza bitowa stopę błędów (BER) osiąganą przez dekodery ML i MMSE w przypadku transmisji z modulacją BPSK dla kanału radiowego z zanikami Rayleigh'a. BER wyznaczany jest w funkcji stosunku sygnału-do-szumu (Eb_N0_dB). Celem oceny zysku wynikającego ze stosowania systemu konkretnego dekoder wyznaczone wartości BER(Eb/NO) zestawione są z wartościami teoretycznymi dla systemów SISO i MRC. Przyjęto, ze łączna moc emitowana przez anteny nadawcze, w obu wariantach systemu MIMO, jest równa mocy emitowanej przez pojedyncza antenę nadawcza systemu SISO. Przy porównywaniu systemów należny pamiętać, ze system MIMO pracuje z dwukrotnie większa przepustowością jak system SISO oraz MRC. Oznacza to, ze energia przypadająca na jeden transmitowany bit w systemie MIMO jest o polowe mniejsza jak w systemie SISO.
% Przyklad implementacji dekoderow ML i MMSE w systemie MIMO (2, 2)
clear; close all
randn('seed',0);
rand('seed',0);
N = 10^6; % liczba transmitowanych symboli
Eb_N0_dB = [0:25]; % Eb/N0 [dB]
nTx = 2;
nRx = 2;
fprintf('start symulacji\n');
% probki czasowe realizacji kanalu MIMO Rayleigha (nRx, nTx)
h = 1/sqrt(2)*[randn(nRx, nTx, N/nTx) + j*randn(nRx, nTx, N/nTx)];
% szum AWGN o wariancji 1 (0dB)
n = 1/sqrt(2)*[randn(nRx, N/nTx) + j*randn(nRx, N/nTx)];
% generacja strumienia danych (bit stream)
bs = rand(1,N)>0.5;
% modulacja BPSK 0 -> -1; 1 -> 0
s = 2*bs-1;
% przeksztalcenie sygnalu s w macierzy o wymiarach [nRx, nTx, N/NTx]
% celem transmisji przez kanal MIMO h
% najpierw powielenie nRx razy
x = repmat(s, nRx, 1);
% potem, rozdzialenie na NTx anten nadawczych
x = reshape(x, [nRx, nTx, N/nTx]);
% transmisja przez kanal h
r = sum(h.*x, 2);
r = squeeze(r);
for i = 1:length(Eb_N0_dB)
fprintf('------- Eb/N0 = %d [dB]\n', Eb_N0_dB(i));
% sygnal odbierany zaszumiony
y = r + 10^(-Eb_N0_dB(i)/20)*n;
%%dekoder ML
rVec = [];
% wszystkie mozliwe kombinacje bitow dla dwoch anten nadawczych i modulacji BPSK
x_ref = [1 1; ...
1 0; ...
0 1; ...
0 0 ];
% wyznacz odleglosci dla wszystkich kombinacji z x_ref
for k=1:size(x_ref, 1)
% modulacja BPSK 0 -> -1; 1 -> 0
s = 2*x_ref(k,:)-1;
x_hat = repmat(s, [nRx ,N/2]);
x_hat = reshape(x_hat, [nRx,nTx,N/nTx]);
z_hat = squeeze(sum(h.*x_hat, 2)) ;
J = sum(abs(y - z_hat), 1);
rVec = [rVec; J];
end
% znajdz kombinacje symboli dajaca najmniejszy blad
[jj dd] = min(rVec,[],1);
% konwertuj symbole na bity
bs_hat(1:2:N) = x_ref(dd, 1);
bs_hat(2:2:N) = x_ref(dd, 2);
% wyznacz BER
nErr_ML(i) = sum(bs ~= bs_hat);
fprintf('dekoder ML: BER= %.3d\n', nErr_ML(i)/N);
%%dekoder MMSE
% Utworzenie macierzy hInv = inv(h' * h + N_0^2*I)
% najpierw budujemy: [a b; c d] = h' * h + N_0^2*I
N0 = 10^(-Eb_N0_dB(i)/20);
a = sum( conj(h(:,1,:)) .* h(:,1,:), 1) + N0^2;
b = sum( conj(h(:,1,:)) .* h(:,2,:), 1);
c = sum( conj(h(:,2,:)) .* h(:,1,:), 1);
d = sum( conj(h(:,2,:)) .* h(:,2,:), 1) + N0^2;
% nastepnie: hInv=inv([a b; c d]) = 1/(ad-bc)[d -b;-c a]
hInv = zeros(2,2,N/nTx);
D = a.*d - b.*c; % ad-bc
hInv(1,1,:) = d./D;
hInv(1,2,:) = -b./D;
hInv(2,1,:) = -c./D;
hInv(2,2,:) = a./D;
% Utworzenie macierzy W = hInv * h'
W = zeros(2,2,N/nTx);
W(1,1,:) = sum( hInv(1,:,:) .* conj(h(1,:,:)), 2);
W(1,2,:) = sum( hInv(1,:,:) .* conj(h(2,:,:)), 2);
W(2,1,:) = sum( hInv(2,:,:) .* conj(h(1,:,:)), 2);
W(2,2,:) = sum( hInv(2,:,:) .* conj(h(2,:,:)), 2);
% dekoder strumienia z anteny 1
w1 = squeeze(W(1,:,:));
y1 = sum(w1.*y);
% dekoder strumienia z anteny 2
w2 = squeeze(W(2,:,:));
y2 = sum(w2.*y);
% polacz strumienie transmitowane przez anten 1 i 2 w jeden strumien
% odpowiadajacy strumieniowi oryginalnemu
y_hat = zeros(1,N);
y_hat(1:2:end) = y1;
y_hat(2:2:end) = y2;
% dekoder bpsk (kwantyzacja)
bs_hat = real(y_hat)>0;
% wyznacz BER
nErr_MMSE(i) = sum(bs ~= bs_hat);
fprintf('dekoder MMSE: BER= %.3d\n', nErr_ML(i)/N);
end
Ber_ML = nErr_ML/N;
Ber_MMSE = nErr_MMSE/N;
Eb_N0 = 10.^(Eb_N0_dB/10);
Ber_SISO = 0.5.*(1-1*(1+1./Eb_N0).^(-0.5));
p = 1/2 - 1/2*(1+1./Eb_N0).^(-1/2);
Ber_MRC_nRx2 = p.^2.*(1+2*(1-p));
figure;
title('Modulacja BPSK, kanal Rayleigha');
xlabel('Eb/No [dB]'); ylabel('BER');
semilogy(Eb_N0_dB, Ber_SISO, 'bp-', ...
Eb_N0_dB, Ber_MMSE, 'ro-', ...
Eb_N0_dB, Ber_ML,'mo-', ...
Eb_N0_dB, Ber_MRC_nRx2, 'kd-', 'LineWidth',2);
axis([0 25 10^-5 0.5]); grid on
legend( 'SISO (nTx=1,nRx=1)',
'MMSE (nTx=2, nRx=2)',
'ML (nTx=2, nRx=2)',
'MRC (nTx=1,nRx=2)');
Przyklad Kodowanie Alamoutiego
W przykładzie pokazano zasadę działania dekodera Alamoutiego w wersji z dwiema antenami nadawczymi i jedną anteną odbiorczą.
Program (plik alamouti_bpsk_r1.m) wyznacza bitowa stopę błędów (BER) osiąganą przez dekodery Alamoutiego w przypadku transmisji z modulacją BPSK dla kanału radiowego z zanikami Rayleigh'a. BER wyznaczany jest w funkcji stosunku sygnału-do-szumu (Eb_N0_dB). Celem oceny zysku wynikającego ze stosowania dekodera Alamoutiego , wyznaczone wartości BER(Eb/NO) zestawione są z wartościami teoretycznymi dla systemów SISO i MRC (dwie anteny odbiorcze). W programie przyjęto, że łączna moc emitowana przez anteny nadawcze jest równa mocy emitowanej przez pojedyncza antenę nadawcza systemu SISO i MRC. Oznacza to, że w przypadku systemu z kodowaniem Alamoutiego moc przypadająca na jedną antenę nadawczą jest o połowę mniejsza niż moc w systemie z dekoderem MRC.
% Przyklad kodowania Alamoutiego,
% modulacja BPSK, dwie anteny nadawcze, jedna odbiorcza
clear; close all
randn('seed',0);
rand('seed',0);
N = 10^6; % liczba transmitowanych symboli
Eb_N0_dB = [0:25]; % Eb/N0
% kanal z zanikami Rayleigh'a
h1 = 1/sqrt(2)*[randn(1,N/2) + j*randn(1,N/2)];
h2 = 1/sqrt(2)*[randn(1,N/2) + j*randn(1,N/2)];
% wektor szumu AWGN o wariancji 1 (0dB)
n1 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)];
% strumienia danych (bit stream)
bs = rand(1,N)>0.5;
% modulacja BPSK 0 -> -1; 1 -> 0
x = 2*bs-1;
% kodowanie Alamoutiego: antena 1: [x1, x2] -> [x1, x2*]
a1 = zeros(1,N);
a1(1:2:end) = x(1:2:end);
a1(2:2:end) = conj(x(2:2:end));
% kodowanie Alamoutiego: antena 2: [x1, x2] -> [x2, -x1*]
a2 = zeros(1,N);
a2(1:2:end) = x(2:2:end);
a2(2:2:end) = -conj(x(1:2:end));
% sygnal odbierany
r1 = a1/sqrt(2) .* kron(h1, [1 1]) + a2/sqrt(2) .* kron(h2, [1 1]);
% wyznaczenie BER dla roznych poziomow szumu
for i = 1:length(Eb_N0_dB)
% sygnal odbierany zaszumiony
y = r1 + 10^(-Eb_N0_dB(i)/20) * n1;
% rozdzielenie na dwie szczeliny
y1 = sqrt(2) * y(1:2:end);
y2 = sqrt(2) * y(2:2:end);
% dekoder Alamoutiego(2,1)
H2 = abs(h1).^2 + abs(h2).^2;
x1_hat = conj(h1) .* y1 - h2 .* conj(y2);
x2_hat = conj(h2) .* y1 + h1 .* conj(y2);
% utworz jeden strumien
x_hat(1:2:N) = x1_hat./H2;
x_hat(2:2:N) = x2_hat./H2;
% dekoder BPSK
bs_hat = real(x_hat) > 0;
% liczba blednie zdekodowanych symboli
nErr_A21(i) = sum(bs ~= bs_hat);
end
% wyznacza BER
Ber_Alamouti21 = nErr_A21/N;
% BER dla kanalu Rayleigh i modulacji BPSK
if(0)
% BER ze wzoru teoretycznego
Eb_N0_Lin = 10.^(Eb_N0_dB/10);
Ber_SISO = 1/2*(1-1./sqrt(1+1./Eb_N0_Lin));
else
% BER wyznaczony symulacyjnie
h = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %kanal
% sygnal odbierany
r = h .* x;
for i = 1:length(Eb_N0_dB)
% sygnal odbierany zaszumiony
y = r + 10^(-Eb_N0_dB(i)/20) * n1;
% dekoder BPSK
x_hat = y./h;
bs_hat = real(x_hat) > 0;
% liczba blednie zdekodowanych symboli
nErr_SISO(i) = sum(bs ~= bs_hat);
end
Ber_SISO = nErr_SISO/N;
end
% BER dla dekodera MRC, kanal Rayleigh, modulacja BPSK
if(0)
% BER ze wzoru teoretycznego
Eb_N0_Lin = 10.^(Eb_N0_dB/10);
p = 1/2 - 1/2*(1+1./Eb_N0_Lin).^(-1/2);
Ber_MRC_nRx2 = p.^2.*(1+2*(1-p));
else
% BER wyznaczony symulacyjnie
n2 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %szum AWGN
h1 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %kanal Tx->Rx1
h2 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %kanal Tx->Rx2
r1 = h1 .* x; % sygnal odbierany przez antene nr 1
r2 = h2 .* x; % sygnal odbierany przez antene nr 2
for i = 1:length(Eb_N0_dB)
% sygnal odbierany zaszumiony
y1 = r1 + 10^(-Eb_N0_dB(i)/20) * n1;
y2 = r2 + 10^(-Eb_N0_dB(i)/20) * n2;
% dekoder MRC
x_hat = (y1 .* conj(h1) + y2 .* conj(h2)) ./ (h1.*conj(h1) + h2.*conj(h2));
% dekoder BPSK
bs_hat = real(x_hat) > 0;
% liczba blednie zdekodowanych symboli
nErr_MRC_nRx2(i) = sum(bs ~= bs_hat);
end
Ber_MRC_nRx2 = nErr_MRC_nRx2/N;
end
figure;
title('Modulacja BPSK, kanal Rayleigha');
xlabel('Eb/No, dB'); ylabel('BER');
semilogy(Eb_N0_dB, Ber_SISO, 'bp-', ...
Eb_N0_dB, Ber_Alamouti21,'mo-', ...
Eb_N0_dB, Ber_MRC_nRx2,'kd-', 'LineWidth',2);
axis([0 25 10^-5 0.5]); grid on
legend( 'SISO (nTx=1, nRx=1)', ...
'Alamouti (nTx=2, nRx=1)', ...
'MRC (nTx=1, nRx=2)');