MATLAB Code for Multi-User STBC (using Alamouti's Scheme)
clc; clear;
% Parameters
N = 1e4; % Symbols per user
U = 2; % Number of users
SNR_dB = 0:5:30;
alpha = 0.8; % Modification factor
power = [0.7 0.3]; % Power allocation (sum <= 1)
% Generate QPSK symbols for each user
data = cell(U,1);
s1 = cell(U,1);
s2 = cell(U,1);
for u = 1:U
data{u} = randi([0 3], N, 2);
s = pskmod(data{u}, 4, pi/4);
s1{u} = s(:,1);
s2{u} = s(:,2);
end
% Channels (independent Rayleigh per user)
h1 = cell(U,1);
h2 = cell(U,1);
for u = 1:U
h1{u} = (randn(N,1)+1j*randn(N,1))/sqrt(2);
h2{u} = (randn(N,1)+1j*randn(N,1))/sqrt(2);
end
SER = zeros(length(SNR_dB),U);
% SNR loop
for k = 1:length(SNR_dB)
SNR = 10^(SNR_dB(k)/10);
noise_var = 1/SNR;
n1 = sqrt(noise_var/2)*(randn(N,1)+1j*randn(N,1));
n2 = sqrt(noise_var/2)*(randn(N,1)+1j*randn(N,1));
% Superposed transmission (all users)
x1 = zeros(N,1);
x2 = zeros(N,1);
for u = 1:U
x1 = x1 + sqrt(power(u))*s1{u};
x2 = x2 + sqrt(power(u))*s2{u};
end
% Reception per user
for u = 1:U
r1 = h1{u}.*x1 + h2{u}.*x2 + n1;
r2 = -alpha*h1{u}.*conj(x2) + h2{u}.*conj(x1) + n2;
% Alamouti combining
s1_hat = conj(h1{u}).*r1 + h2{u}.*conj(r2);
s2_hat = conj(h2{u}).*r1 - alpha*h1{u}.*conj(r2);
denom = abs(h1{u}).^2 + abs(h2{u}).^2;
s1_hat = s1_hat ./ denom;
s2_hat = s2_hat ./ denom;
% Detection
s1_dec = pskdemod(s1_hat/sqrt(power(u)), 4, pi/4);
s2_dec = pskdemod(s2_hat/sqrt(power(u)), 4, pi/4);
SER(k,u) = mean( ...
s1_dec ~= data{u}(:,1) | s2_dec ~= data{u}(:,2));
end
end
% Plot
figure;
semilogy(SNR_dB, SER(:,1),'o-', ...
SNR_dB, SER(:,2),'s-','LineWidth',2);
grid on;
xlabel('SNR (dB)');
ylabel('Symbol Error Rate');
legend('User 1','User 2');
title('Multi-User Modified Alamouti STBC');
Output
After Applying Successive Interference Cancelling (SIC)
Successive Interference Cancellation (SIC)
In Successive Interference Cancellation (SIC), the receiver decodes the strongest signal first and then subtracts it from the received signal to reduce interference for the weaker signal. The received signal is a superposition of both users' signals:
Received Signal = h1 * Signal1 + h2 * Signal2 + Noise
The receiver knows the modulation scheme (e.g., Frequency Modulation or QPSK), which allows it to decode the strongest signal. Once decoded, the receiver subtracts the strong signal from the mixture using the channel coefficient (h1). This leaves the weak user's signal with less interference, making it easier to decode the weak signal. Thus, SIC enables better reception of weaker signals by cancelling out the interference from stronger ones.
clc; clear;
% Parameters
N = 1e4; % Symbols per user
U = 2; % Number of users
SNR_dB = 0:5:30; % SNR values in dB
alpha = 0.8; % Modification factor
power = [0.7 0.3]; % Power allocation (sum <= 1)
% Generate QPSK symbols for each user
data = cell(U,1);
s1 = cell(U,1);
s2 = cell(U,1);
for u = 1:U
data{u} = randi([0 3], N, 2);
s = pskmod(data{u}, 4, pi/4);
s1{u} = s(:,1);
s2{u} = s(:,2);
end
% Channels (independent Rayleigh per user)
h1 = cell(U,1);
h2 = cell(U,1);
for u = 1:U
h1{u} = (randn(N,1) + 1j*randn(N,1)) / sqrt(2);
h2{u} = (randn(N,1) + 1j*randn(N,1)) / sqrt(2);
end
SER = zeros(length(SNR_dB), U);
% SNR loop
for k = 1:length(SNR_dB)
SNR = 10^(SNR_dB(k)/10); % Current SNR
noise_var = 1/SNR; % Noise variance
n1 = sqrt(noise_var/2)*(randn(N,1) + 1j*randn(N,1)); % Noise for signal 1
n2 = sqrt(noise_var/2)*(randn(N,1) + 1j*randn(N,1)); % Noise for signal 2
% Calculate SNR per user
snr_user = power ./ (noise_var * ones(1, U)); % SNR per user (using allocated power)
[~, user_order] = sort(snr_user, 'descend'); % Sort users by SNR (strongest first)
% Superposed transmission (all users)
x1 = zeros(N,1);
x2 = zeros(N,1);
for u = 1:U
x1 = x1 + sqrt(power(u)) * s1{u};
x2 = x2 + sqrt(power(u)) * s2{u};
end
% Reception per user with SIC
for u = 1:U
r1 = h1{u} .* x1 + h2{u} .* x2 + n1; % Received signal for user u
r2 = -alpha * h1{u} .* conj(x2) + h2{u} .* conj(x1) + n2; % Received signal for user u
% SIC Process: Decode strongest signal first
if u == user_order(1) % Strongest signal (first decoded)
% Decode user with strongest signal using Alamouti
s1_hat = conj(h1{u}) .* r1 + h2{u} .* conj(r2);
s2_hat = conj(h2{u}) .* r1 - alpha * h1{u} .* conj(r2);
denom = abs(h1{u}).^2 + abs(h2{u}).^2;
s1_hat = s1_hat ./ denom;
s2_hat = s2_hat ./ denom;
% Demodulate and detect symbols
s1_dec = pskdemod(s1_hat / sqrt(power(u)), 4, pi/4);
s2_dec = pskdemod(s2_hat / sqrt(power(u)), 4, pi/4);
SER(k,u) = mean(s1_dec ~= data{u}(:,1) | s2_dec ~= data{u}(:,2));
% Subtract the decoded signal contribution (interference removal)
x1 = x1 - sqrt(power(u)) * s1{u};
x2 = x2 - sqrt(power(u)) * s2{u};
end
end
% After strongest signal is decoded and subtracted, decode weaker signal(s)
for u = 2:U
if u == user_order(2) % Weaker signal (second decoded)
% Decode user with weaker signal (using Alamouti or other method)
r1 = h1{u} .* x1 + h2{u} .* x2 + n1;
r2 = -alpha * h1{u} .* conj(x2) + h2{u} .* conj(x1) + n2;
% Alamouti combining for weaker signal
s1_hat = conj(h1{u}) .* r1 + h2{u} .* conj(r2);
s2_hat = conj(h2{u}) .* r1 - alpha * h1{u} .* conj(r2);
denom = abs(h1{u}).^2 + abs(h2{u}).^2;
s1_hat = s1_hat ./ denom;
s2_hat = s2_hat ./ denom;
% Demodulate and detect symbols
s1_dec = pskdemod(s1_hat / sqrt(power(u)), 4, pi/4);
s2_dec = pskdemod(s2_hat / sqrt(power(u)), 4, pi/4);
SER(k,u) = mean(s1_dec ~= data{u}(:,1) | s2_dec ~= data{u}(:,2));
end
end
end
% Plot Symbol Error Rate (SER)
figure;
semilogy(SNR_dB, SER(:,1), 'o-', 'LineWidth', 2);
hold on;
semilogy(SNR_dB, SER(:,2), 's-', 'LineWidth', 2);
grid on;
xlabel('SNR (dB)');
ylabel('Symbol Error Rate');
legend('User 1', 'User 2');
title('Multi-User Modified Alamouti STBC with SIC');