before new database

This commit is contained in:
Silas Oettinghaus
2026-07-13 19:59:57 +02:00
parent ef0a74cb7f
commit f421348e5b
15 changed files with 2682 additions and 487 deletions

View File

@@ -42,6 +42,7 @@ classdef FFE < handle
dc_level_avg_bufferlength_a2
dc_level_update_blocklength_a2
dc_smoothing_a2
dc_level_decision_mode_a2
dc_level_weights_a2
% Adaptive DC-tracking loop
@@ -119,6 +120,7 @@ classdef FFE < handle
options.dc_level_avg_bufferlength_a2 = 0;
options.dc_level_update_blocklength_a2 = 0;
options.dc_smoothing_a2 = 0;
options.dc_level_decision_mode_a2 = "residual";
options.dc_level_weights_a2 = 0;
options.dc_tracking_mu = 0;
@@ -170,6 +172,11 @@ classdef FFE < handle
obj.dc_level_avg_bufferlength_a2 = floor(obj.dc_level_avg_bufferlength_a2);
obj.dc_level_update_blocklength_a2 = floor(obj.dc_level_update_blocklength_a2);
obj.dc_smoothing_a2 = min(max(obj.dc_smoothing_a2,0),1);
obj.dc_level_decision_mode_a2 = string(obj.dc_level_decision_mode_a2);
if ~any(obj.dc_level_decision_mode_a2 == ["residual", "tracked_levels"])
builtin("error","FFE:InvalidA2DecisionMode", ...
"dc_level_decision_mode_a2 must be 'residual' or 'tracked_levels'.");
end
obj.dc_tracking_buffer_len = floor(obj.dc_tracking_buffer_len);
obj.ffe_update_buffer_len = floor(obj.ffe_update_buffer_len);
obj.a2_level_weight_max = max(obj.a2_level_weight_max,0);
@@ -357,6 +364,8 @@ classdef FFE < handle
"A2 level-dependent MPI suppression requires obj.constellation to be set.");
end
dc_level_decision_mode_a2 = obj.dc_level_decision_mode_a2;
dc_level_track_decision_a2 = dc_level_decision_mode_a2 == "tracked_levels";
n_levels = numel(constellation);
if isscalar(obj.dc_level_weights_a2)
dc_level_weight_by_level = repmat(obj.dc_level_weights_a2,n_levels,1);
@@ -396,6 +405,7 @@ classdef FFE < handle
obj.debug_struct.dc_level_weight = NaN(1,n_symbols_debug);
obj.debug_struct.dc_level_valid_count = NaN(1,n_symbols_debug);
obj.debug_struct.dc_level_symbol_idx = NaN(1,n_symbols_debug);
obj.debug_struct.dc_level_decision_level = NaN(1,n_symbols_debug);
obj.debug_struct.dc_level_y_raw = NaN(1,n_symbols_debug);
if training
@@ -419,6 +429,7 @@ classdef FFE < handle
dc_level_weight = 0;
dc_level_valid_count = 0;
dc_level_symbol_idx = NaN;
dc_level_decision_level = NaN;
U = x(obj.order+sample-1:-1:sample);
if dc_avg_enabled
@@ -444,33 +455,60 @@ classdef FFE < handle
symbol_idx = NaN;
else
[~,symbol_idx] = min(abs(d_hat(symbol) - constellation));
dc_level_decision_level = constellation(symbol_idx);
end
else
if ~always_ideal_decision
[~,symbol_idx] = min(abs(y(symbol) - constellation)); % decision for closest constellation point
if dc_level_enabled && dc_level_track_decision_a2
% Tracked-level A2 moves the decision constellation; y itself stays unchanged.
dc_level_ramp_by_level = min(dc_level_valid_count_by_level / dc_level_buffer_len_a2,1);
dc_level_decision_constellation = constellation + ...
dc_level_weight_by_level .* dc_level_ramp_by_level .* dc_level_mpi_est_by_level;
[~,symbol_idx] = min(abs(y(symbol) - dc_level_decision_constellation));
dc_level_decision_level = dc_level_decision_constellation(symbol_idx);
else
[~,symbol_idx] = min(abs(y(symbol) - constellation)); % decision for closest constellation point
dc_level_decision_level = constellation(symbol_idx);
end
d_hat(symbol,1) = constellation(symbol_idx);
else
d_hat(symbol,1) = d(symbol);
[~,symbol_idx] = min(abs(d_hat(symbol) - constellation));
dc_level_decision_level = constellation(symbol_idx);
end
end
dc_level_symbol_idx = symbol_idx;
if dc_level_enabled
mpi_err = y_raw - d_hat(symbol);
dc_level_mpi_est = dc_level_mpi_est_by_level(symbol_idx);
dc_level_valid_count = dc_level_valid_count_by_level(symbol_idx);
dc_level_weight = dc_level_weight_by_level(symbol_idx) * ...
min(dc_level_valid_count / dc_level_buffer_len_a2,1);
y(symbol,1) = y_raw - dc_level_weight * dc_level_mpi_est;
if training
d_hat(symbol,1) = d(symbol);
if dc_level_track_decision_a2
dc_level_buffer_value = y_raw;
y(symbol,1) = y_raw;
if isnan(dc_level_decision_level)
dc_level_decision_level = constellation(symbol_idx) + ...
dc_level_weight * dc_level_mpi_est;
end
else
if ~always_ideal_decision
[~,symbol_idx] = min(abs(y(symbol) - constellation));
d_hat(symbol,1) = constellation(symbol_idx);
else
mpi_err = y_raw - d_hat(symbol);
dc_level_buffer_value = mpi_err;
y(symbol,1) = y_raw - dc_level_weight * dc_level_mpi_est;
if training
d_hat(symbol,1) = d(symbol);
else
if ~always_ideal_decision
[~,symbol_idx] = min(abs(y(symbol) - constellation));
d_hat(symbol,1) = constellation(symbol_idx);
dc_level_decision_level = constellation(symbol_idx);
else
d_hat(symbol,1) = d(symbol);
[~,symbol_idx] = min(abs(d_hat(symbol) - constellation));
dc_level_decision_level = constellation(symbol_idx);
end
end
end
@@ -488,10 +526,10 @@ classdef FFE < handle
dc_level_buffer_valid_count_by_level(dc_level_symbol_idx) - 1;
end
if isfinite(mpi_err)
dc_level_err_buffer(dc_level_symbol_idx,dc_level_err_buffer_pos) = mpi_err;
if isfinite(dc_level_buffer_value)
dc_level_err_buffer(dc_level_symbol_idx,dc_level_err_buffer_pos) = dc_level_buffer_value;
dc_level_err_sum_by_level(dc_level_symbol_idx) = ...
dc_level_err_sum_by_level(dc_level_symbol_idx) + mpi_err;
dc_level_err_sum_by_level(dc_level_symbol_idx) + dc_level_buffer_value;
dc_level_buffer_valid_count_by_level(dc_level_symbol_idx) = ...
dc_level_buffer_valid_count_by_level(dc_level_symbol_idx) + 1;
else
@@ -508,6 +546,11 @@ classdef FFE < handle
dc_level_mpi_est_by_level(dc_level_symbol_idx) = ...
dc_level_err_sum_by_level(dc_level_symbol_idx) / ...
dc_level_valid_count_by_level(dc_level_symbol_idx);
if dc_level_track_decision_a2
dc_level_mpi_est_by_level(dc_level_symbol_idx) = ...
dc_level_mpi_est_by_level(dc_level_symbol_idx) - ...
constellation(dc_level_symbol_idx);
end
end
else
dc_level_valid_count_by_level = dc_level_buffer_valid_count_by_level;
@@ -516,6 +559,11 @@ classdef FFE < handle
dc_level_mpi_est_by_level(dc_level_has_valid) = ...
dc_level_err_sum_by_level(dc_level_has_valid) ./ ...
dc_level_valid_count_by_level(dc_level_has_valid);
if dc_level_track_decision_a2
dc_level_mpi_est_by_level(dc_level_has_valid) = ...
dc_level_mpi_est_by_level(dc_level_has_valid) - ...
constellation(dc_level_has_valid);
end
end
end
end
@@ -675,6 +723,7 @@ classdef FFE < handle
obj.debug_struct.dc_level_weight(1,symbol) = dc_level_weight;
obj.debug_struct.dc_level_valid_count(1,symbol) = dc_level_valid_count;
obj.debug_struct.dc_level_symbol_idx(1,symbol) = dc_level_symbol_idx;
obj.debug_struct.dc_level_decision_level(1,symbol) = dc_level_decision_level;
obj.debug_struct.dc_level_y_raw(1,symbol) = y_raw;
if training