TASK_06_PROGRAM_merged
TASK_06_PROGRAM_merged
%---------Input Fields------------------------
nSym = 10e5; % Number of symbols to transmit
N = [1,2,20]; % number of diversity branches
EbN0dBs = -20:2:36; % Eb/N0 range in dB for simulation
MOD_TYPE_OPTIONS = {'BPSK', 'QPSK', '16QAM', '64QAM'}; % Modulation
types available
M_VALUES = [2, 4, 16, 64]; % Corresponding M values for modulation
types
k = log2(M_VALUES); % Bits per symbol for each modulation scheme
figure;
for nRx = N % simulate for each # of received branches
ser_MRC = zeros(1,numel(EbN0dBs)); % simulated symbol error rates
ser_EGC = zeros(1,numel(EbN0dBs));
ser_SC = zeros(1,numel(EbN0dBs));
q = 1;
%---------- Transmitter -----------
d = ceil(2 * rand(1, nSym)); % uniform random symbols for BPSK
s = modulate('BPSK', 2, d); % Initial modulation (BPSK)
s_diversity = kron(ones(nRx, 1), s); % nRx signal branches
for EbN0dB = EbN0dBs
h = sqrt(1/2) * (randn(nRx, nSym) + 1j * randn(nRx, nSym)); %
Rayleigh flat-fading
signal = h .* s_diversity; % effect of channel on the
modulated signal
gamma = 10.^(EbN0dB/10); % for AWGN noise addition
P = sum(abs(signal).^2, 2) ./ nSym; % calculate power in each
branch of signal
N0 = P / gamma; % required noise spectral density for each
branch
% Scale each row of noise with the calculated noise spectral
density
noise = (randn(size(signal)) + 1j * randn(size(signal))) .*
sqrt(N0/2);
r = signal + noise; % received signal branches
1
% Calculate SNR and choose modulation scheme
SNR = 10*log10(P ./ N0); % in dB
modulation_idx = select_modulation(SNR); % Select modulation
index
M = M_VALUES(modulation_idx); % Corresponding M value
MOD_TYPE = MOD_TYPE_OPTIONS{modulation_idx}; % Corresponding
modulation type
% Modulate using the selected scheme
s = modulate(MOD_TYPE, M, d);
s_diversity = kron(ones(nRx, 1), s); % Update diversity
branches
% MRC processing assuming perfect channel estimates
s_MRC = sum(conj(h) .* r, 1) ./ sum(abs(h).^2, 1); % detector
decisions
d_MRC = demodulate(MOD_TYPE, M, s_MRC); % demodulation
decisions
% EGC processing assuming perfect channel estimates
h_phases = exp(-1j * angle(h)); % estimated channel phases
s_EGC = sum(h_phases .* r, 1) ./ sum(abs(h), 1); % detector
decisions
d_EGC = demodulate(MOD_TYPE, M, s_EGC); % demodulation
decisions
% SC processing assuming perfect channel estimates
[h_max, idx] = max(abs(h), [], 1); % max |h| values along all
branches
h_best = h(sub2ind(size(h), idx, 1:size(h, 2))); % best path's
h estimate
y = r(sub2ind(size(r), idx, 1:size(r, 2))); % selected output
s_SC = y .* conj(h_best) ./ abs(h_best).^2; % detector
decisions
d_SC = demodulate(MOD_TYPE, M, s_SC); % demodulation decision
% Error rates computation
ser_MRC(q) = sum(d_MRC ~= d) / nSym;
ser_EGC(q) = sum(d_EGC ~= d) / nSym;
ser_SC(q) = sum(d_SC ~= d) / nSym;
2
q = q + 1;
end
% Plotting
semilogy(EbN0dBs, ser_MRC, 'b-', 'lineWidth', 1.5); hold on;
semilogy(EbN0dBs, ser_EGC, 'r--', 'lineWidth', 1.5);
semilogy(EbN0dBs, ser_SC, 'g-.', 'lineWidth', 1.5);
end
xlim([-20, 36]); ylim([0.00001, 1.1]);
xlabel('Eb/N0(dB)'); ylabel('Symbol Error Rate (P_s)');
title('Receive diversity schemes in Rayleigh flat-fading with Adaptive
Modulation');
%======== Function Definitions ===========
function [s, ref] = modulate(MOD_TYPE, M, d)
% Wrapper function to call various digital modulation techniques
switch lower(MOD_TYPE)
case 'bpsk'
[s, ref] = mpsk_modulator(2, d);
case 'qpsk'
[s, ref] = mpsk_modulator(M, d);
case '16qam'
[s, ref] = mqam_modulator(16, d);
case '64qam'
[s, ref] = mqam_modulator(64, d);
otherwise
error('Invalid Modulation specified');
end
end
function [s, ref] = mpsk_modulator(M, d)
ref_i = 1/sqrt(2)*cos(((1:1:M)-1)/M*2*pi);
ref_q = 1/sqrt(2)*sin(((1:1:M)-1)/M*2*pi);
ref = ref_i + 1i*ref_q;
s = ref(d); % M-PSK Mapping
end
function [s, ref] = mqam_modulator(M, d)
% QAM modulator
3
ref = qammod(0:M-1, M, 'UnitAveragePower', true); % QAM reference
points
s = ref(d); % M-QAM Mapping
end
function [dCap] = demodulate(MOD_TYPE, M, r)
% Wrapper function to call various digital demodulation techniques
switch lower(MOD_TYPE)
case 'bpsk'
dCap = mpsk_detector(2, r); % M=2
case 'qpsk'
dCap = mpsk_detector(M, r);
case '16qam'
dCap = mqam_detector(16, r);
case '64qam'
dCap = mqam_detector(64, r);
otherwise
error('Invalid Modulation specified');
end
end
function [dCap] = mpsk_detector(M, r)
% Function to detect MPSK modulated symbols
ref_i = 1/sqrt(2)*cos(((1:1:M)-1)/M*2*pi);
ref_q = 1/sqrt(2)*sin(((1:1:M)-1)/M*2*pi);
ref = ref_i + 1i*ref_q; % reference constellation for MPSK
[~, dCap] = iqOptDetector(r, ref); % IQ detection
end
function [dCap] = mqam_detector(M, r)
% QAM detector
ref = qammod(0:M-1, M, 'UnitAveragePower', true); % QAM reference
points
dCap = qamdemod(r, M, 'UnitAveragePower', true); % QAM detection
end
function [idealPoints, indices] = iqOptDetector(received, ref)
x = [real(received); imag(received)]'; % received vec. in
cartesian form
4
y = [real(ref); imag(ref)]'; % reference vec. in cartesian form
[idealPoints, indices] = minEuclideanDistance(x, y);
end
function [idealPoints, indices] = minEuclideanDistance(x, y)
% Compute the pairwise minimum distance between two vectors
[m, p1] = size(x);
[n, p2] = size(y);
if p1 ~= p2
error('Dimension Mismatch: x and y must have same dimension');
end
X = sum(x .* x, 2);
Y = sum(y .* y, 2)';
d = X(:, ones(1, n)) + Y(ones(1, m), :) - 2 * x * y'; % Squared
Euclidean Dist.
[~, indices] = min(d, [], 2); % Find the minimum value along DIM=2
idealPoints = y(indices, :);
indices = indices.';
end
function modulation_idx = select_modulation(SNR)
% Function to select modulation based on SNR
if SNR < 0
modulation_idx = 1; % BPSK
elseif SNR < 10
modulation_idx = 2; % QPSK
elseif SNR < 20
modulation_idx = 3; % 16QAM
else
modulation_idx = 4; % 64QAM
end
end