Files
imdd_silas/Functions/Metrics/calc_gmi_bitwise.m
Silas Oettinghaus 5dbc48abc0 Many changes here and there. I lost track... :-(
Current work is on MLSE and SD Decoding etc. MLSE is currently not 100% working, the scalings are maybe off?!
2025-08-11 07:42:04 +02:00

94 lines
2.5 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
% Perbit 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 (bitwise 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