new plots for Diss. Mostly AI gen. Few changes in actual codebase

This commit is contained in:
Silas Oettinghaus
2026-07-30 08:35:45 +02:00
parent 125d8508ca
commit 7a9deaeb0c
62 changed files with 6171 additions and 630 deletions

View File

@@ -45,6 +45,8 @@ classdef ML_MLSE_DUOBINARY < handle
valid
valid_to_idx
valid_from_idx
incoming_edge_idx
incoming_from_idx
w
% Fast lookup
@@ -124,6 +126,21 @@ classdef ML_MLSE_DUOBINARY < handle
end
[obj.valid_to_idx,obj.valid_from_idx] = find(obj.valid);
% Precompute compact incoming-transition lookup tables. Every
% trellis state has obj.S incoming transitions, so compare-select
% can operate on valid edges only instead of an nStates-by-nStates
% matrix for every symbol.
obj.incoming_edge_idx = zeros(obj.S, obj.nStates);
obj.incoming_from_idx = zeros(obj.S, obj.nStates, 'uint32');
incoming_count = zeros(obj.nStates, 1);
for edge_idx = 1:numel(obj.valid_to_idx)
to_idx = obj.valid_to_idx(edge_idx);
slot = incoming_count(to_idx) + 1;
obj.incoming_edge_idx(slot, to_idx) = edge_idx;
obj.incoming_from_idx(slot, to_idx) = obj.valid_from_idx(edge_idx);
incoming_count(to_idx) = slot;
end
% --- Initialize weights
if isempty(obj.w) || any(size(obj.w) ~= [obj.Nf+1,obj.nFeasible])
% obj.w = randn(obj.Nf+1,obj.nFeasible);
@@ -148,6 +165,8 @@ classdef ML_MLSE_DUOBINARY < handle
% TRAINING
% ==============================================================
fprintf('\n--- Training mode ---\n');
obj.ber = nan(1, obj.epochs_tr);
obj.ce = nan(1, obj.epochs_tr);
obj.equalize(X.signal, D.signal, obj.mu_tr, obj.epochs_tr, obj.len_tr, true);
obj.e_tr = obj.e;
@@ -155,6 +174,7 @@ classdef ML_MLSE_DUOBINARY < handle
% DECISION-DIRECTED / TESTING
% ==============================================================
fprintf('--- Decision-directed / detection mode ---\n');
obj.ber_dd = nan(1, obj.epochs_dd);
[y, y_vit] = obj.equalize(X.signal, D.signal, obj.mu_dd, obj.epochs_dd, X.length, false);
X_viterbi = X;
@@ -173,9 +193,18 @@ classdef ML_MLSE_DUOBINARY < handle
for epoch = 1:epochs
pm = zeros(obj.nStates,1);
pred = zeros(nSymbols,obj.nStates,'uint32');
pm_sto = nan(obj.nStates,nSymbols,'like',pm);
needTraceback = ~training || epoch == epochs;
if needTraceback
pred = zeros(nSymbols,obj.nStates,'uint32');
end
if debug && showPlots
pm_sto = nan(obj.nStates,nSymbols,'like',pm);
end
CE_accum = 0;
if training
CE_symbol = zeros(nSymbols,1);
CE_smooth = zeros(nSymbols,1);
end
start_sample = 1;
end_sample = N;
@@ -292,13 +321,24 @@ classdef ML_MLSE_DUOBINARY < handle
% ===================================================================
% DECODING MODE (Viterbi only)
% ===================================================================
% Compare-Select (always executed)
vmat=inf(obj.nStates,obj.nStates);
vmat(obj.valid)=v_tilde;
[pm_next,pred(symbol,:)]=min(vmat,[],2);
% Compare-select over valid incoming transitions only.
incoming_metrics = v_tilde(obj.incoming_edge_idx);
[pm_next, predecessor_slot] = min(incoming_metrics,[],1);
pm_next = pm_next.';
pm_next=pm_next-min(pm_next);
pm=pm_next;
pm_sto(:,symbol)=pm;
if needTraceback
linear_idx = predecessor_slot + (0:obj.nStates-1) .* obj.S;
pred(symbol,:) = obj.incoming_from_idx(linear_idx);
end
if debug && showPlots
pm_sto(:,symbol)=pm;
end
end
if training && ~needTraceback
obj.ce(epoch)=CE_accum/symbol;
continue
end
% --- Traceback