Match analytical and simulation values of SER vs SNR curve.

10 次查看(过去 30 天)
% Parameters
M = 4; % MQAM order (e.g., 16-QAM)
N = 1e5; % Number of transmit symbols
% Define SNR range
SNR_dB_range = 0:10;
num_SNR_points = length(SNR_dB_range);
% Initialize SER array
SER_values = zeros(num_SNR_points, 1);
% Create MQAM constellation
constellation = createMQAM(M);
% Loop over each SNR value
for idx = 1:num_SNR_points
SNR_dB = SNR_dB_range(idx);
% Generate transmit symbols
transmitSymbols = generateSymbols(constellation, N);
% Transmit through AWGN channel
receivedSymbols = transmitSymbolsThroughAWGN(transmitSymbols, SNR_dB);
% Demodulate symbols
decodedSymbols = demodulateSymbols(receivedSymbols, constellation);
% Compute Symbol Error Rate
SER = computeSER(transmitSymbols, decodedSymbols);
% Store SER value
SER_values(idx) = SER;
% Compute Theoretical SER
SER_theoretical = computeTheoreticalSER(M, SNR_dB_range);
SER_theoretical_values = SER_theoretical;
end
% Plot SER vs SNR
figure;
semilogy(SNR_dB_range, SER_values, 'o-', 'DisplayName', 'Simulated SER');
hold on;
semilogy(SNR_dB_range, SER_theoretical_values, 'r--', 'DisplayName', 'Theoretical SER');
xlabel('SNR (dB)');
ylabel('Symbol Error Rate (SER)');
title('SER vs. SNR for MQAM');
legend;
grid on;
function constellation = createMQAM(M)
% Create an MQAM constellation manually
% M: Number of symbols (e.g., 16, 64, etc.)
% Check that M is a perfect square
k = sqrt(M);
if mod(k,1) ~= 0
error('M must be a perfect square');
end
% Generate constellation points
k = round(k); % Number of points per side
[X, Y] = meshgrid(linspace(-k+1, k-1, k), linspace(-k+1, k-1, k));
constellation = X(:) + 1i*Y(:);
end
function symbols = generateSymbols(constellation, N)
% Generate N random transmit symbols
% constellation: The MQAM constellation points
% N: Number of symbols to generate
numPoints = length(constellation);
indices = randi([1 numPoints], [N, 1]); % Randomly choose indices
symbols = constellation(indices); % Select symbols from the constellation
end
function received = transmitSymbolsThroughAWGN(symbols, SNR_dB)
% Transmit symbols through a SISO AWGN channel
% symbols: Transmit symbols
% SNR_dB: Signal-to-noise ratio in dB
% Convert SNR from dB to linear scale
SNR_linear = 10^(SNR_dB / 10);
% Calculate noise variance
noise_variance = 1 / SNR_linear;
% Generate noise
noise = sqrt(noise_variance / 2) * (randn(size(symbols)) + 1i*randn(size(symbols)));
% Received symbols
received = symbols + noise;
end
function decodedSymbols = demodulateSymbols(received, constellation)
% Demodulate symbols using minimum distance decoding
% received: Received symbols
% constellation: MQAM constellation points
numSymbols = length(received);
numPoints = length(constellation);
% Initialize decoded symbols
decodedSymbols = zeros(size(received));
for i = 1:numSymbols
% Compute distances to all constellation points
distances = abs(received(i) - constellation).^2;
% Find the closest constellation point
[~, idx] = min(distances);
decodedSymbols(i) = constellation(idx);
end
end
function SER = computeSER(originalSymbols, decodedSymbols)
% Compute symbol error rate
% originalSymbols: Transmit symbols
% decodedSymbols: Received and decoded symbols
numErrors = sum(originalSymbols ~= decodedSymbols);
totalSymbols = length(originalSymbols);
SER = numErrors / totalSymbols;
end
function SER_theoretical = computeTheoreticalSER(M, SNR_dB)
% Compute the theoretical SER for MQAM in AWGN
% M: Number of symbols (e.g., 16, 64, etc.)
% SNR_dB: SNR in dB
% Convert SNR from dB to linear scale
SNR_linear = 10.^(SNR_dB / 10);
% Compute theoretical SER
k = sqrt(M); % Number of points per side
if mod(k,1) ~= 0
error('M must be a perfect square');
end
% Calculate SER using the Q-function
SER_theoretical = 4*(1-1./sqrt(M))*qfunc(sqrt(3./(M-1)*SNR_linear));
end
In the above code when I plot the SER v/s SNR and compare the simulation and analytical values don't match. Can someone tell me what is the error in my code and how can I match the curves ?

采纳的回答

Aastha
Aastha 2024-9-16
编辑:Aastha 2024-9-16
As I understand, you want to compute the analytical and simulation SER values with respect to signal to noise ratio and compare them.
In the code, when the noise power "No" is being computed, the signal to noise ratio convention is taken with respect to unit signal power. However, in the function “createMQAM” the signal power is not normalized to be unit energy. This is causing the gap between the analytical and simulation SER curves.
To correct this inconsistency, you can compute the energy of the constellation and normalize it using this energy, so that the constellation is now unit energy. This step is crucial because the signal to noise ratio definition assumes unit signal power. Normalizing the constellation ensures that the simulation adheres to this definition.
You can add the following two lines in the “create MQAM constellation" section to make the constellation unit energy:
eConstellation = sqrt(mean(constellation.*conj(constellation)));
constellation = constellation ./ eConstellation;
On running the updated code, the analytical and simulation SER vs SNR curves match.
I hope this helps!

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Modulation 的更多信息

产品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by