FFE with DC tap. But RLS does not work anymore

This commit is contained in:
Silas Oettinghaus
2026-05-22 15:28:37 +02:00
parent f883071dec
commit a91da3b97c

View File

@@ -25,6 +25,9 @@ classdef FFE < handle
dd_mode % 1 or 0 to set DD-mode on or off dd_mode % 1 or 0 to set DD-mode on or off
mu_dd %weight update in dd mode mu_dd %weight update in dd mode
epochs_dd epochs_dd
dd_len_fraction
mu_dc
e_dc
P % covariance matrix of rls P % covariance matrix of rls
@@ -55,6 +58,8 @@ classdef FFE < handle
options.dd_mode = 1; options.dd_mode = 1;
options.mu_dd = 1e-5; options.mu_dd = 1e-5;
options.epochs_dd = 5; options.epochs_dd = 5;
options.dd_len_fraction = 0.25;
options.mu_dc = 0;
options.decide = false; options.decide = false;
@@ -69,6 +74,7 @@ classdef FFE < handle
end end
obj.e = zeros(obj.order,1); obj.e = zeros(obj.order,1);
obj.e_dc = 0;
obj.error = 0; obj.error = 0;
end end
@@ -80,6 +86,7 @@ classdef FFE < handle
X = X.normalize("mode","rms"); X = X.normalize("mode","rms");
obj.constellation = unique(D.signal); obj.constellation = unique(D.signal);
obj.e_dc = 0;
delta = 0.05; delta = 0.05;
@@ -88,6 +95,7 @@ classdef FFE < handle
if obj.optmize_mus if obj.optmize_mus
obj.optimizeMus(X.signal,D.signal); obj.optimizeMus(X.signal,D.signal);
obj.e = zeros(obj.order,1); obj.e = zeros(obj.order,1);
obj.e_dc = 0;
obj.P = (1/delta) * eye(obj.order); obj.P = (1/delta) * eye(obj.order);
end end
@@ -101,7 +109,11 @@ classdef FFE < handle
n = X.length; n = X.length;
training = 0; training = 0;
showviz = 0; showviz = 0;
[signal,decision]=obj.equalize(X.signal, D.signal,obj.mu_dd,obj.epochs_dd,n,training,showviz); if obj.dd_mode
n_dd = obj.ddLength(n);
obj.equalize(X.signal, D.signal,obj.mu_dd,obj.epochs_dd,n_dd,training,showviz);
end
[signal,decision]=obj.applyCurrentTaps(X.signal,n);
% Output Signal % Output Signal
if obj.decide if obj.decide
@@ -163,7 +175,7 @@ classdef FFE < handle
U = x(obj.order+sample-1:-1:sample); U = x(obj.order+sample-1:-1:sample);
y(symbol,1) = (obj.e.*mask).' * U; % Calculating output of LMS __ * | y(symbol,1) = obj.e_dc + (obj.e.*mask).' * U; % Calculating output of LMS __ * |
if training if training
d_hat(symbol,1) = d(symbol); d_hat(symbol,1) = d(symbol);
@@ -217,6 +229,10 @@ classdef FFE < handle
end end
if obj.mu_dc ~= 0
obj.e_dc = obj.e_dc + obj.mu_dc * err(symbol);
end
end end
@@ -247,6 +263,28 @@ classdef FFE < handle
end end
function [y,d_hat] = applyCurrentTaps(obj,x,N)
x = [zeros(floor(obj.order/2),1); x; zeros(obj.order,1)];
for sample = 1 : obj.sps : N
symbol = (sample - 1) / obj.sps + 1;
U = x(obj.order+sample-1:-1:sample);
y(symbol,1) = obj.e_dc + obj.e.' * U;
[~,symbol_idx] = min(abs(y(symbol) - obj.constellation));
d_hat(symbol,1) = obj.constellation(symbol_idx);
end
end
function N_dd = ddLength(obj,N)
if isempty(obj.dd_len_fraction) || obj.dd_len_fraction <= 0 || obj.dd_len_fraction >= 1
N_dd = N;
return
end
N_dd = floor(N * obj.dd_len_fraction);
N_dd = max(obj.sps,N_dd);
N_dd = min(N,N_dd);
end
function optimizeMus(obj,x,d) function optimizeMus(obj,x,d)
switch obj.adaption_technique switch obj.adaption_technique
case adaption_method.lms case adaption_method.lms
@@ -256,12 +294,17 @@ classdef FFE < handle
case adaption_method.rls case adaption_method.rls
mu_range = [0.98, 0.99999]; mu_range = [0.98, 0.99999];
end end
mu_dc_range = [1e-5, 1e-1];
mu_tr_var = optimizableVariable("mu_tr",mu_range,"Transform","log"); mu_tr_var = optimizableVariable("mu_tr",mu_range,"Transform","log");
vars = mu_tr_var; vars = mu_tr_var;
if obj.dd_mode if obj.dd_mode
vars = [vars, optimizableVariable("mu_dd",mu_range,"Transform","log")]; vars = [vars, optimizableVariable("mu_dd",mu_range,"Transform","log")];
end end
optimize_mu_dc = obj.mu_dc ~= 0;
if optimize_mu_dc
vars = [vars, optimizableVariable("mu_dc",mu_dc_range,"Transform","log")];
end
obj.mu_optimization_iter = 0; obj.mu_optimization_iter = 0;
obj.mu_optimization = bayesopt(@(p)obj.muObjective(p,x,d),vars, ... obj.mu_optimization = bayesopt(@(p)obj.muObjective(p,x,d),vars, ...
"MaxObjectiveEvaluations",10, ... "MaxObjectiveEvaluations",10, ...
@@ -273,19 +316,39 @@ classdef FFE < handle
if obj.dd_mode if obj.dd_mode
obj.mu_dd = obj.mu_optimization.XAtMinObjective.mu_dd; obj.mu_dd = obj.mu_optimization.XAtMinObjective.mu_dd;
end end
fprintf("\nFFE mu opt done: mu_tr=%9.3e, mu_dd=%9.3e, metric=%9.3e\n", ... if optimize_mu_dc
obj.mu_tr,obj.mu_dd,obj.mu_optimization.MinObjective); obj.mu_dc = obj.mu_optimization.XAtMinObjective.mu_dc;
end
objective_db = 10*log10(obj.mu_optimization.MinObjective);
if obj.dd_mode && optimize_mu_dc
fprintf("\nFFE mu opt done: mu_tr=%9.3e, mu_dd=%9.3e, mu_dc=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB\n", ...
obj.mu_tr,obj.mu_dd,obj.mu_dc,obj.mu_optimization.MinObjective,objective_db);
elseif obj.dd_mode
fprintf("\nFFE mu opt done: mu_tr=%9.3e, mu_dd=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB\n", ...
obj.mu_tr,obj.mu_dd,obj.mu_optimization.MinObjective,objective_db);
elseif optimize_mu_dc
fprintf("\nFFE mu opt done: mu_tr=%9.3e, mu_dc=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB\n", ...
obj.mu_tr,obj.mu_dc,obj.mu_optimization.MinObjective,objective_db);
else
fprintf("\nFFE mu opt done: mu_tr=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB\n", ...
obj.mu_tr,obj.mu_optimization.MinObjective,objective_db);
end
end end
function objective = muObjective(obj,params,x,d) function objective = muObjective(obj,params,x,d)
old_debug = obj.save_debug; old_debug = obj.save_debug;
old_mu_dc = obj.mu_dc;
obj.save_debug = 1; obj.save_debug = 1;
if isprop(params,"mu_dc")
obj.mu_dc = params.mu_dc;
end
obj.e = zeros(obj.order,1); obj.e = zeros(obj.order,1);
obj.e_dc = 0;
obj.P = (1/0.05) * eye(obj.order); obj.P = (1/0.05) * eye(obj.order);
obj.debug_struct = struct(); obj.debug_struct = struct();
obj.equalize(x,d,params.mu_tr,obj.epochs_tr,obj.len_tr,1,0); obj.equalize(x,d,params.mu_tr,obj.epochs_tr,obj.len_tr,1,0);
if obj.dd_mode if obj.dd_mode
obj.equalize(x,d,params.mu_dd,obj.epochs_dd,numel(x),0,0); obj.equalize(x,d,params.mu_dd,obj.epochs_dd,obj.ddLength(numel(x)),0,0);
objective = mean(obj.debug_struct.error(end,:),"omitnan"); objective = mean(obj.debug_struct.error(end,:),"omitnan");
else else
objective = mean(obj.debug_struct.error_tr(end,:),"omitnan"); objective = mean(obj.debug_struct.error_tr(end,:),"omitnan");
@@ -293,15 +356,24 @@ classdef FFE < handle
if ~isfinite(objective) if ~isfinite(objective)
objective = inf; objective = inf;
end end
objective_db = 10*log10(objective);
obj.mu_optimization_iter = obj.mu_optimization_iter + 1; obj.mu_optimization_iter = obj.mu_optimization_iter + 1;
if obj.dd_mode optimize_mu_dc = isprop(params,"mu_dc");
fprintf("\rFFE mu opt %02d: mu_tr=%9.3e, mu_dd=%9.3e, metric=%9.3e", ... if obj.dd_mode && optimize_mu_dc
obj.mu_optimization_iter,params.mu_tr,params.mu_dd,objective); fprintf("\rFFE mu opt %02d: mu_tr=%9.3e, mu_dd=%9.3e, mu_dc=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB", ...
obj.mu_optimization_iter,params.mu_tr,params.mu_dd,params.mu_dc,objective,objective_db);
elseif obj.dd_mode
fprintf("\rFFE mu opt %02d: mu_tr=%9.3e, mu_dd=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB", ...
obj.mu_optimization_iter,params.mu_tr,params.mu_dd,objective,objective_db);
elseif optimize_mu_dc
fprintf("\rFFE mu opt %02d: mu_tr=%9.3e, mu_dc=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB", ...
obj.mu_optimization_iter,params.mu_tr,params.mu_dc,objective,objective_db);
else else
fprintf("\rFFE mu opt %02d: mu_tr=%9.3e, metric=%9.3e", ... fprintf("\rFFE mu opt %02d: mu_tr=%9.3e, MSE=%9.3e, MSE_dB=%7.2f dB", ...
obj.mu_optimization_iter,params.mu_tr,objective); obj.mu_optimization_iter,params.mu_tr,objective,objective_db);
end end
obj.save_debug = old_debug; obj.save_debug = old_debug;
obj.mu_dc = old_mu_dc;
end end
end end
end end