Gif stuff

nonlinear MLSE investigation
trying hard to implment ML-based pre Equalization to find the branch metrics
This commit is contained in:
Silas Oettinghaus
2025-10-24 16:58:06 +02:00
parent c33264a515
commit 7085ba0931
16 changed files with 1414 additions and 162 deletions

View File

@@ -277,14 +277,107 @@ classdef MLSE < handle
if debug
alpha_ = alpha - min(alpha) + eps;
figure();hold on;
n = 10;
scatter(1:n,obj.trellis_states(repmat([1:numel(obj.trellis_states)]',1,n)),abs(alpha_(:,end-n+1:end)),'Marker','o','LineWidth',1);
scatter(1:n,obj.trellis_states(viterbi_path(end-n+1:end)),500,'Marker','x','LineWidth',1,'MarkerEdgeColor','green');
% scatter(1:n,data_ref(end-n+1:end),500,'Marker','x','LineWidth',1,'MarkerEdgeColor','red');
yticks(obj.trellis_states);
ylim([min(obj.trellis_states)-1 max(obj.trellis_states)+1]);
% alpha_ = alpha - min(alpha) + eps;
% figure();hold on;
% n = 10;
% scatter(1:n,obj.trellis_states(repmat([1:numel(obj.trellis_states)]',1,n)),abs(alpha_(:,end-n+1:end)),'Marker','o','LineWidth',1);
% scatter(1:n,obj.trellis_states(viterbi_path(end-n+1:end)),500,'Marker','x','LineWidth',1,'MarkerEdgeColor','green');
% % scatter(1:n,data_ref(end-n+1:end),500,'Marker','x','LineWidth',1,'MarkerEdgeColor','red');
% yticks(obj.trellis_states);
% ylim([min(obj.trellis_states)-1 max(obj.trellis_states)+1]);
%% ----- Build true path from known sequence (data_ref) -----
% Memory length used by VA (L = length(obj.DIR)-1 symbols stored in state)
L = size(combs,2); % each row of combs is the L-tap state vector
N = length(data_in);
% Map each trellis level to an index (1..M)
[~, level_to_idx] = ismember(levels, levels); %#ok<ASGLU> % identity map
[ok_ref, ref_idx] = ismember(data_ref(:).', levels);
if ~all(ok_ref)
warning('Some data_ref symbols are not in "levels". True-path build may fail.');
end
% Precompute next_state(from_state, u_idx) LUT such that:
% combs(next_state,:) == [ combs(from_state,2:end) , levels(u_idx) ]
next_state = zeros(size(combs,1), numel(levels), 'uint32');
for from = 1:size(combs,1)
prefix = combs(from,2:end); % what must match in 'to' for a valid transition
for ui = 1:numel(levels)
target = [prefix, levels(ui)];
% find the unique 'to' whose state vector equals target
to = find(all(bsxfun(@eq, combs, target), 2), 1, 'first');
if isempty(to), to = 0; end
next_state(from, ui) = to;
end
end
% Initialize true path at n=1: pick any state with last_sym == data_ref(1)
% Prefer one whose suffix matches the first available history if L>1.
cand = find(last_sym == data_ref(1));
if isempty(cand)
% fallback: choose closest in amplitude (should not happen if levels match)
[~,ix] = min(abs(last_sym - data_ref(1)));
cand = ix;
end
true_state_path = zeros(1,N,'uint32');
true_state_path(1) = cand(1);
% Propagate forward using the known inputs data_ref(n)
for n = 2:N
ui = ref_idx(n); % index of the actual transmitted level at time n
from = true_state_path(n-1);
if from==0 || ui==0
true_state_path(n) = 0;
else
true_state_path(n) = next_state(from, ui);
if true_state_path(n)==0
% Safety fallback: if no valid transition found (should not happen)
% choose any to-state whose vector matches shift+current symbol
target = [combs(from,2:end), levels(ui)];
to = find(all(bsxfun(@eq, combs, target), 2), 1, 'first');
if isempty(to), to = from; end
true_state_path(n) = to;
end
end
end
%% ----- Collect branch metrics along decoded vs. true path -----
bm_decoded = nan(1,N);
bm_true = nan(1,N);
% n=1 in your code stores pm into bm_fw(:,:,1); real BMs start at n>=2
for n = 2:N
% Decoded path: to = viterbi_path(n), from = survivor that fed it
to_d = viterbi_path(n);
from_d = pm_survivor_fw_idx(to_d, n);
bm_decoded(n) = bm_fw(to_d, from_d, n);
% True path: transition true_state_path(n-1) -> true_state_path(n)
to_t = true_state_path(n);
from_t = true_state_path(n-1);
if to_t>0 && from_t>0
bm_true(n) = bm_fw(to_t, from_t, n);
end
end
% Convert to "cost" for intuitive plotting (your BM is a log-likelihood)
cost_dec = -bm_decoded;
cost_true= -bm_true;
%% ----- Plot a short window for clarity -----
win = max(2, N-20000):N; % last 200 samples (adjust as needed)
figure('Color','w'); hold on; grid on; box on;
plot(win, cost_true(win), 'LineWidth',1.2, 'DisplayName','True path cost (BM)');
plot(win, cost_dec(win), 'LineWidth',1.2, 'DisplayName','Decoded path cost (BM)');
xlabel('Time index n'); ylabel('Branch cost'); title('Branch metrics along true vs decoded path');
legend('Location','best');
%% ----- Optional: overlay symbol levels for the same window -----
yyaxis right
plot(win, data_in(win), ':', 'LineWidth',0.8, 'DisplayName','y(n)');
ylabel('Amplitude');
end
VITERBI_ESTIMATION_SYMBOLS(1:length(data_in)) = first_sym(viterbi_path);
@@ -564,11 +657,6 @@ classdef MLSE < handle
end
function s = logsumexp(a,dim)
% returns log(sum(exp(a),dim)) safely
amax = max(a,[],dim);
s = amax + log(sum(exp(a - amax), dim));
end
end
end