% Single User MIMO
% You need to have the Communications Toolbox installed to run this program
%Developed in MATLAB R2008b
%----------------------------------------------------
% This MATLAB program creates and runs a Single User MIMO system, with 2
% transmitter antennas and one receiver antenna. The following principles
% are used:
% 1. Alamouti Space-Time Block Code
% 2. Binary Phase Shift Keying (BPSK)
% 3. Rayleigh channel with flat fading
%The following charts are computed:
% 1. Signal to Noise Ratio versus Bit Error Rate (BER)
%----------------------------------------------------
clear
N = 15000; % number of bits or symbols
SNRdB = [-3:20]; % multiple SNR values
for ii = 1:length(SNRdB)
% Transmitter
bpsk_bitset = rand(1,N)>0.5; % generating 0,1 with equal probability
s = 2*bpsk_bitset-1; % BPSK modulation 0 -> -1; 1 -> 0
% Alamouti Space Time Block Code
x_vector = zeros(2,N); %2 rows of N columns, all values are zero. This is the transmitter vector.
x_vector(:,1:2:end) = (1/sqrt(2))*reshape(s,2,N/2); % [x1 x2 ...]
x_vector(:,2:2:end) = (1/sqrt(2))*(kron(ones(1,N/2),[-1;1]).*flipud(reshape(conj(s),2,N/2))); % [-x2* x1* ....]
rayleighchannel = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; % Rayleigh channel
rayleighchannel_vector = kron(reshape(rayleighchannel,2,N/2),ones(1,2)); % repeating the same channel for two symbols
n = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; % white gaussian noise, 0dB variance
% Channel and noise Noise addition
y = sum(rayleighchannel_vector.*x_vector,1) + 10^(-SNRdB(ii)/20)*n;
% Receiver
%we create a Y vector here
y_vector = kron(reshape(y,2,N/2),ones(1,2)); % [y1 y1 ... ; y2 y2 ...]
y_vector(2,:) = conj(y_vector(2,:)); % [y1 y1 ... ; y2* y2*...]
% forming the equalization matrix
H_arrayvector = zeros(2,N); %this is the 'H' vector, 2 rows of N columns, all values are zero
H_arrayvector(:,[1:2:end]) = reshape(rayleighchannel,2,N/2); % [h1 0 ... ; h2 0...]
H_arrayvector(:,[2:2:end]) = kron(ones(1,N/2),[1;-1]).*flipud(reshape(rayleighchannel,2,N/2)); % [h1 h2 ... ; h2 -h1 ...]
H_arrayvector(1,:) = conj(H_arrayvector(1,:)); % [h1* h2* ... ; h2 -h1 .... ]
hEqPower = sum(H_arrayvector.*conj(H_arrayvector),1);
Code_Data_SU = sum(H_arrayvector.*y_vector,1)./(hEqPower); % [h1*y1 + h2y2*, h2*y1 -h1y2*, ... ]
%Code_Data_SU(2:2:end) = conj(Code_Data_SU(2:2:end));
% receiver - hard decision decoding
bpsk_bitset_bar = real(Code_Data_SU)>0; %finding the real part of the Code_Data part, required for hard decision decoding.
% counting the errors
nErr(ii) = size(find([bpsk_bitset- bpsk_bitset_bar]),2); %This implements the equation to find the BER from the hard decision for BPSK.
%Simply find the hard decision and subtract from the BPSK actual value to
%find the Bit Error Rate.
end
SNRdB1 = -3:20;
for s = 1:length(SNRdB1)
SNR_Linear = 10^(SNRdB1(s)/10); %SNR dB to Linear conversion
% ddd = abs(Code_Data_SU);
Capacity_SU(1,s) = 0.5 * log(1 + (0.5 * SNR_Linear .* sum(abs(Code_Data_SU)))); %Capacity Equation
% Channel Capacity = (1/2) log(1 + (SNRH))
end
simBer = nErr/N; % simulated ber
SNRdB_Linear = 10.^(SNRdB/10);
%Calculating theoretical Alamouti code diversity
Alamouti_probability = 1/2 - 1/2(1+2./SNRdB_Linear).^(-1/2); %Here we calculate theoretical Alamouti based on formula, but it is not actually plotted in the cooperative MIMO case.
Theoretical_Alamouti = Alamouti_probability.^2.(1+2(1-Alamouti_probability)); %Theoretical Alamouti performance will always be better,
% but not necessary to plot it since we are comparing the
%simulated performance.
close all
figure(1);
semilogy(SNRdB,Theoretical_Alamouti,'c+-','LineWidth',2); %plots a semilogy plot of SNR versus BER
hold on
semilogy(SNRdB,simBer,'mo-','LineWidth',2);
axis([0 25 10^-5 0.5])
grid on
legend('theory (nTx=2, nRx=1, Alamouti)', 'sim (nTx=2, nRx=1, Alamouti)');
xlabel('SNR, dB');
ylabel('Bit Error Rate');
title('BER for BPSK modulation with Alamouti STBC (Rayleigh channel)');
figure(2);
hold on
plot(SNRdB1,Capacity_SU); %Plot the capacity of Single User MIMO.
%axis([SNRdB(1) max(SNRdB) 10^-5 0.5]);
grid on
xlabel('SNR dB');
ylabel('Instantaneous Capacity');
title(['Curves for comparison']);