PMD theory; S21 measures; NGMI theory

This commit is contained in:
Silas Oettinghaus
2026-03-25 10:26:50 +01:00
parent 5b90bc11a0
commit ed7c68d78b
34 changed files with 14156 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
% Parameters
symbols = [0, 1, 2, 3]; % PAM-4 symbols
P_X = [0.25, 0.25, 0.25, 0.25]; % Uniform probabilities
sigma2 = 0.1; % Noise variance
received_samples = [0.2, 1.1, 1.9, 2.8];% Received symbols (example)
gray_bits = [0 0; 0 1; 1 1; 1 0]; % Gray coding (bits per symbol)
m = size(gray_bits, 2); % Bits per symbol
N = length(received_samples); % Number of received samples
% Conditional probability function for AWGN
q_Y_given_X = @(y, x) (1 / sqrt(2 * pi * sigma2)) * exp(-(y - x).^2 / (2 * sigma2));
% Entropy term
H_X = -sum(P_X .* log2(P_X)); % Entropy of input distribution
% GMI computation
noise_impact_term = 0;
for k = 1:N
y_k = received_samples(k); % Current received sample
[~, closest_symbol_idx] = min(abs(symbols - y_k)); % Closest symbol index
closest_symbol = symbols(closest_symbol_idx); % Closest symbol
for i = 1:m
% Extract i-th bit for each symbol
bit_mask = gray_bits(:, i); % Binary column for i-th bit of all symbols
matching_symbols = symbols(bit_mask == gray_bits(closest_symbol_idx, i));
% Numerator: Sum over x in x_{b_{k, i}}
numerator = sum(q_Y_given_X(y_k, matching_symbols) .* P_X(ismember(symbols, matching_symbols)));
% Denominator: Sum over all x
denominator = sum(q_Y_given_X(y_k, symbols) .* P_X);
% Logarithmic contribution
noise_impact_term = noise_impact_term + log2(numerator / denominator);
end
end
% Normalize the noise impact term by N
noise_impact_term = noise_impact_term / N;
% GMI
GMI = H_X + noise_impact_term;
NGMI = GMI / m;
% Display the result
fprintf('GMI: %.4f bits\n', GMI);
fprintf('NGMI: %.4f bits\n', NGMI);

View File

@@ -0,0 +1,43 @@
% estimate_entropies.m
clear; rng(0);
%% 1) Parameters
M = 1e5; % number of Monte-Carlo samples
EbNo_dB = 0; % SNR per bit in dB
EbNo = 10^(EbNo_dB/10);
sigma2 = 1/(2*EbNo); % noise variance per real dimension
% 4-QAM constellation (row vector)
X = [1+1j, 1-1j, -1+1j, -1-1j];
N = numel(X);
PX = ones(1,N)/N; % uniform PMF
%% 2) Generate transmit symbols and AWGN
idx = randi(N,1,M); % 1×M random symbol indices
s = X(idx); % 1×M transmitted symbols
n = sqrt(sigma2)*(randn(1,M) + 1j*randn(1,M));
y = s + n; % 1×M received samples
%% 3) Compute p_{Y|X}(y|x) for each constellation point
% Create an N×M matrix where row n is |y - X(n)|^2
d2 = abs(bsxfun(@minus, X(:), y)).^2; % N×M
pYgX = (1/(pi*sigma2)) * exp(-d2 / sigma2); % N×M
%% 4) Estimate H(Y) = -E[ log2 p_Y(Y) ]
% Mixture density p_Y(y_m) = sum_n PX(n)*pYgX(n,m)
pY = PX * pYgX; % 1×M
HY = -mean(log2(pY)); % bits
%% 5) Estimate H(Y|X) = -E[ log2 p(Y|X) ]
% For each m, pick the row corresponding to the true idx(m)
linearIdx = sub2ind([N, M], idx, 1:M);
pYgX_true = pYgX(linearIdx); % 1×M
HYgX = -mean(log2(pYgX_true)); % bits
%% 6) Mutual information
I = HY - HYgX;
%% 7) Display
fprintf('Estimated H(Y) = %.4f bits\n', HY);
fprintf('Estimated H(Y|X) = %.4f bits\n', HYgX);
fprintf('Estimated I(X;Y) = %.4f bits\n', I);