new plots for Diss. Mostly AI gen. Few changes in actual codebase
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user