https://github.com/braton/fadapt/blob/master/ls/rls/SFTF.m is not correct and is the same as the https://github.com/braton/fadapt/blob/master/ls/rls/FTF.m . They are both unstabilized Fast Transversal.
I had a look at the code from the book you mention and his example ( chapter 14 partA.m ) his code only works for real signals and I don't know how to extend that to complex signals.
The stability am currently looking at seems to be due to quantization error. It's perfectly stable and well-behaved up until about 15,000 samples then all of a sudden it explodes and the numbers get huge. In real life tests I have also seen numbers getting incredibly small in absolute magnitude but I haven't looked into that.
I know QR, lattice and I assume all the sliding window versions are stable. QR is too expensive. Lattice I haven't figured out how to use because I am using blind adaption and I need the equalized value before I can tell you the desired value; it might be possible but I don't really know how a lattice description of the filter works. I was excited with sliding window fast array and seemed to be great in Matlab but when converting it over to C++ and trying it out in a real-life example it was terrible; so that's a no go. Fast Transversal works really well in real life but it's instability is a problem.
I have adapted your https://github.com/braton/fadapt/blob/master/ls/rls/FTF.m for blind constant modulus adaption.
The code from the book you mention using the rescue mechanism for FTF doesn't make sense for complex numbers so I'm not quite sure how to extend it to complex numbers. However with a bit of modification I seem to be able to get it to rescue before blows up. I'm not sure it's always going to work or whether it will fail in real life but in Matlab code it seems to be working so far. Here is the code with some simulation testing...
close all
clear all
%number of trials for smoothing
nTrials=30;
%length of signal
uLen=60000;
%channel noise
SNR = 20;
%channel
channel=zeros(64,1);
channel(round(numel(channel)/2))=1;
channel(numel(channel))=0.6+1i*0.2;
%create on air signal
var_v = 10^(-SNR/10);
signal_sent = (2*randi(2,uLen,1)-3).'+1i*(2*randi(2,uLen,1)-3).';
channel_noise = sqrt(var_v)*randn(1,uLen)+1i*sqrt(var_v)*randn(1,uLen);
signal_received=filter(channel,1,signal_sent+channel_noise);
%received signal
plot(signal_received,'.');
title('signal received example');
%run through some trials so we can smooth the output
learn_modifiedFTF=zeros(1,numel(signal_received));
for k=1:nTrials
disp(['trial ' num2str(k) ' of ' num2str(nTrials)] );
%create on air signal
var_v = 10^(-SNR/10);
signal_sent = (2*randi(2,uLen,1)-3).'+1i*(2*randi(2,uLen,1)-3).';
channel_noise = sqrt(var_v)*randn(1,uLen)+1i*sqrt(var_v)*randn(1,uLen);
signal_received=filter(channel,1,signal_sent+channel_noise);
%blind equalize
[w,y,errors]=modifiedFTF(signal_received,0.998,333,512);
learn_modifiedFTF = learn_modifiedFTF + abs(errors).^2;
end
%plot learning
learn_modifiedFTF = 10*log10(learn_modifiedFTF/nTrials);
figure;
plot(learn_modifiedFTF);
ylabel('E|e(i)|^2 in dB');
title('Blind FTF with rescue');
%plot some of a equalized signal
figure;
plot(y(6000:end),'.');
title('signal received after blind equalization example');
%FTF filter with I think rescue but not the stable version in the book.
%uses blind equalization and complex input.
%the book's code can't deal with complex signal and I don't know how to
%change to complex. I only understand RLS enough to be dangerous.
function [w,y,errors] = modifiedFTF( u,a,e,N )
% Initialization ----------------------------------------------------------
w=zeros(N,1);
uLen = length(u);
y = zeros(1,uLen);
uN = zeros(1,N);
wfpos = zeros(N,1);
wb = zeros(N,1);
gamma = 1;
rfpos = e*a^-2;
cNe = zeros(N+1,1);
rb = e*a^(-N-2);
wfpri = zeros(N,1);
errors = zeros(1,uLen);
%w(1)=1;%latest tap. only past used
w(round(N/2))=1;%center tap. both past and future used
% Filtering ---------------------------------------------------------------
for i=1:uLen
fpri = u(i)-uN*wfpri;
fpos = gamma*fpri;
rfpri = a*rfpos+fpri'*fpos;
gamma = gamma*a*rfpos/rfpri;
wfpri = wfpos+fpos*cNe(1:N);
cNe = [0;cNe(1:N)]+(fpri'/(a*rfpos))*[1;-wfpos];
bpri = a*rb*cNe(N+1)';
%check if things are falling apart
%the book in clearly for real numbers so I'm not sure how to extend for
%complex numbers. 1.0 fails some times. 0.05 so far I haven't seen fail
if (abs(bpri*gamma*cNe(N+1)')>0.05)
ind = num2str(i);
str = ['rescue used at iteration ',ind];
disp(str) % message
%reset most things but not the filter taps
gamma = 1;
cNe = 0*cNe;
wb = 0*wb;
wfpri = 0*wfpri;
rfpri = e*a^-2;
rb = e*a^(-N-2);
else
gamma = gamma/(1-bpri*gamma*cNe(N+1));
cNe = cNe-cNe(N+1)*[-wb;1];
bpos = gamma*bpri;
rb = a*rb+bpri'*bpos;
wb = wb+bpos*cNe(1:N);
end
uN = [u(i),uN(1:N-1)];%slide a new input in
y(i) = uN*w;%calc the point based on the filter
%either adapt to constant modulus or if you have carrier lock then go
%for the directed decision
if(abs(y(i))>0.00001)
d=y(i)/abs(y(i));%CM
%d=(sign(real(y(i)))+1i*sign(imag(y(i))))/sqrt(2);%needs carrier
else
d=y(i);
end
errors(i)=(d-y(i));%for user info
epos = gamma*(d-y(i));
w = w+epos*cNe(1:N);
wfpos = wfpri;
rfpos = rfpri;
end
end



But yes without stabilization most of these RTL filters all fail around 15,000 to 20,000 samples. Interesting but frustrating.
Cheers,
Jonti
https://github.com/braton/fadapt/blob/master/ls/rls/SFTF.m is not correct and is the same as the https://github.com/braton/fadapt/blob/master/ls/rls/FTF.m . They are both unstabilized Fast Transversal.
I had a look at the code from the book you mention and his example ( chapter 14
partA.m) his code only works for real signals and I don't know how to extend that to complex signals.The stability am currently looking at seems to be due to quantization error. It's perfectly stable and well-behaved up until about 15,000 samples then all of a sudden it explodes and the numbers get huge. In real life tests I have also seen numbers getting incredibly small in absolute magnitude but I haven't looked into that.
I know QR, lattice and I assume all the sliding window versions are stable. QR is too expensive. Lattice I haven't figured out how to use because I am using blind adaption and I need the equalized value before I can tell you the desired value; it might be possible but I don't really know how a lattice description of the filter works. I was excited with sliding window fast array and seemed to be great in Matlab but when converting it over to C++ and trying it out in a real-life example it was terrible; so that's a no go. Fast Transversal works really well in real life but it's instability is a problem.
I have adapted your https://github.com/braton/fadapt/blob/master/ls/rls/FTF.m for blind constant modulus adaption.
The code from the book you mention using the rescue mechanism for FTF doesn't make sense for complex numbers so I'm not quite sure how to extend it to complex numbers. However with a bit of modification I seem to be able to get it to rescue before blows up. I'm not sure it's always going to work or whether it will fail in real life but in Matlab code it seems to be working so far. Here is the code with some simulation testing...
But yes without stabilization most of these RTL filters all fail around 15,000 to 20,000 samples. Interesting but frustrating.
Cheers,
Jonti