Current work is on MLSE and SD Decoding etc. MLSE is currently not 100% working, the scalings are maybe off?!
94 lines
2.5 KiB
Matlab
94 lines
2.5 KiB
Matlab
function [GMI,NGMI] = calc_gmi_bitwise(test_signal,reference_signal,options)
|
||
% https://cioffi-group.stanford.edu/doc/book/AppendixG.pdf
|
||
|
||
arguments(Input)
|
||
test_signal;
|
||
reference_signal;
|
||
options.skip_front = 0;
|
||
options.skip_end = 0;
|
||
options.returnErrorLocation = 0;
|
||
end
|
||
|
||
options.skip_end = abs(options.skip_end);
|
||
options.skip_front = abs(options.skip_front);
|
||
|
||
assert((options.skip_end+options.skip_front)<length(test_signal),"You can not skip more bits than overall length of data! Set skip_front or skip_end to lower value or check data_in");
|
||
|
||
if isa(reference_signal,'Signal')
|
||
reference_signal = reference_signal.signal;
|
||
end
|
||
|
||
if isa(test_signal,'Signal')
|
||
test_signal = test_signal.signal;
|
||
end
|
||
|
||
% TRIM
|
||
[test_signal,reference_signal]=trimseq(test_signal,reference_signal,options.skip_front,options.skip_end);
|
||
|
||
% CALC AIR
|
||
%%% new implementation of AIR
|
||
% Precompute
|
||
N = length(test_signal);
|
||
M = numel(unique(reference_signal));
|
||
nBits = log2(M);
|
||
levels = PAMmapper(M,0).levels / PAMmapper(M,0).scaling;
|
||
grayBits= PAMmapper(M,0).showBitMapping;
|
||
priors = ones(1,M)/M;
|
||
|
||
noise = test_signal-reference_signal;
|
||
sigma2 = var(noise);
|
||
|
||
% Allocate
|
||
LLR = zeros(N, nBits);
|
||
rxBits = zeros(N, nBits);
|
||
|
||
for n = 1:N
|
||
y = test_signal(n);
|
||
ll_table= -((y - levels).^2)/(2*sigma2) + log(priors); % M×1
|
||
|
||
% Per‐bit LLR
|
||
for b = 1:nBits
|
||
idx0 = grayBits(:,b)==0;
|
||
idx1 = grayBits(:,b)==1;
|
||
L0 = logsumexp(ll_table(idx0));
|
||
L1 = logsumexp(ll_table(idx1));
|
||
LLR(n,b) = L1 - L0;
|
||
end
|
||
end
|
||
|
||
tx_bits = PAMmapper(M,0,"eth_style",0).demap(reference_signal);
|
||
|
||
% Compute GMI (bit‐wise MI averaged over all symbols)
|
||
MI_bits = zeros(1,nBits);
|
||
for b = 1:nBits
|
||
r0 = LLR(tx_bits(:,b)==0,b);
|
||
r1 = LLR(tx_bits(:,b)==1,b);
|
||
I0 = mean( log2(1 + exp(r0)) );
|
||
I1 = mean( log2(1 + exp( -r1)) );
|
||
MI_bits(b) = 1 - 0.5*(I0 + I1);
|
||
end
|
||
|
||
GMI = sum(MI_bits); % in bits per symbol
|
||
NGMI = GMI / nBits; % normalized per bit
|
||
|
||
% Auxiliary nested helper for numerically stable log-sum-exp
|
||
function s = logsumexp(a)
|
||
% LOGSUMEXP Compute log(sum(exp(a))) in a numerically stable way
|
||
m = max(a);
|
||
s = m + log(sum(exp(a - m)));
|
||
end
|
||
|
||
|
||
function [data_,reference_]=trimseq(data,reference,skipstart,skip_end)
|
||
|
||
data_ = data(skipstart+1:end-skip_end,:);
|
||
|
||
delta_bits = length(reference) - length(data);
|
||
|
||
skip_end = delta_bits + skip_end;
|
||
|
||
reference_ = reference(skipstart+1:end-skip_end,:);
|
||
|
||
end
|
||
|
||
end |