- refactored

This commit is contained in:
2022-06-30 13:32:40 +02:00
parent 77cd5261b1
commit 776932e5d1
144 changed files with 0 additions and 38 deletions
+133
View File
@@ -0,0 +1,133 @@
% Frequency LMS Adaptive Filter -FLMS-
% ------------------------------------
%
% Aufruf:
% Function [ys,ee,wf,fpo]=flms(x,d,alpha,N,C,L,wi)
%
% Parameter:
% x : Eingangsvektor
% d : Referenzvektor
% alpha: konstante Schrittweite 0 < alpha <= 1.0
% N : Anzahl Filterkoeffizienten
% C : FFT-Länge, idealerweise eine Zweier-Potenz (0=Auto)
% L : Länge eines Verarbeitungsblocks (idealerweise C=L+N=2N)
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% ee : Adaptitionsfehler
% ys : Filterausgang
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl benötigten der Floating-Point Operationen
% -------------------------------------------------------------------------
% Datum : 20.7.2001
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : flms.m
% Benötigte Dateien: dspfft.m, dspifft.m
%
% -------------------------------------------------------------------------
function [ys,ee,wf,fpo]=flms(x,d,alpha,N,C,L,wi)
% -------------------------------------------------------------------------
% Überprüfen der Parameter
% -------------------------------------------------------------------------
if (N ~= fix(N)),
error('Fehler: N muss eine ganze Zahl sein!');
end;
if (C ~= fix(C)),
error('Fehler: C muss eine ganze Zahl sein!');
end;
if (L ~= fix(L)),
error('Fehler: L muss eine ganze Zahl sein!');
end;
% -------------------------------------------------------------------------
% Automatik-Auswahl
% -------------------------------------------------------------------------
% Falls C=0 => Automatische Wahl von C=2^r
% Anahme: C = L + N
if (C==0)
C = 2^ceil(log2(L+N-1))
end;
% -------------------------------------------------------------------------
% FLMS Parameter
% -------------------------------------------------------------------------
gamma = 1.0/C; % Sicherheitskonstante vermeidet Division durch Null
lambda = 0.6; % Vergessensfaktor
% -------------------------------------------------------------------------
% Initialisierungen
% -------------------------------------------------------------------------
Lx = length(x); % Länge des Eingangsvektors
K = Lx/L; % Anzahl Verarbeitungsblöcke
ee=zeros(Lx,1); % Fehlervektor
ys=zeros(Lx,1); % Filterausgang, Schaetzung von d
wf = zeros(C,1); % Filter im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
WS = zeros(C,1); % Filterkoeff. im Frequenzbereich
X = zeros(C,1); % Eingangsvektor im Frequenzbereich
mu = zeros(C,1); % Variable Schrittweite
yy = zeros(C,1); % Filterausgang im Zeitbereich
YS = zeros(C,1); % Filterausgang im Frequenzbereich
xzp = zeros(Lx+C-L,1); % Eingangsvektor mit C-L führenden Nullen
xzp(C-L+1:Lx+C-L) = x; % Einfügen von Np führenden Nullen an den Eingangsvektor
% Anfangswerte der Filterkoeffienten in den Frequenzbereich transformieren
WS(1:C) = dspfft(wi(1:N),C);
% -------------------------------------------------------------------------
% Algorithmus Start
% -------------------------------------------------------------------------
flops(0);
for k=1:K,
kL = (k-1)*L;
% Transformation des aktuellen Eingangsvektors in den Frequenzbereich
X(1:C) = dspfft(xzp(kL+1:kL+C),C);
% Schnelle FFT-Faltung
YS = WS(1:C).*X(1:C) *C;
% Transformation des Filterausgangs in den Zeitbereich
yy = real(dspifft(YS,C));
% Abspeichern der letzten L Werte des Filterausgangs
ys(kL+1:kL+L) = yy(C-L+1:C);
% Berechnung des Fehlers e(k)
ee(kL+1:kL+L) = d(kL+1:kL+L) - ys(kL+1:kL+L);
% Transformation des Fehlers in den Frequenzbereich
E = dspfft([zeros(C-L,1); ee(kL+1:kL+L)],C);
% Schätzung der mittleren Eingangsleistung Px(k) aus x(k)
PX = abs((1-lambda)*conj(X(1:C)).*X(1:C) *C + lambda*PX);
% Berechnung der variablen Schrittweite mu(k)
% mu(k) wird niemals grösser als eins
mu(1:C) = (alpha*gamma) ./(PX+gamma);
% Filterkoeffizenten-Update
WS(1:C) = WS(1:C) + mu(1:C) .* conj(X(1:C)) .* E *C;
% Projektion der Filterkoeffizienten
wf(1:C) = real(dspifft(WS(1:C),C));
WS(1:C) = dspfft(wf(1:N),C);
end;
wf = [wf(1:C-L+1) ; zeros(L-1,1)]; % Filterkoeffizienten am Ende der Adaption
fpo=flops;
% -------------------------------------------------------------------------
% Ende FLMS.M
% -------------------------------------------------------------------------
+60
View File
@@ -0,0 +1,60 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% Fast LMS Algorithm %
% %
% Written By: Sundar Sankaran and A. A. (Louis) Beex %
% DSP Research Laboratory %
% Dept. of Electrical and Comp. Engg %
% Virginia Tech %
% Blacksburg VA 24061-0111 %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
randn('seed', 0) ;
rand('seed', 0) ;
NoOfData = 8000 ; % Set no of data points used for training
M = 32 ; % Set the adaptive filter order
Mu = 0.01 ; % Set the step-size constant
Gamma = 0.9 ; % Forgetting factor
Delta = 0.01 ; % R_est initialized to Delta*I
u = randn(NoOfData, 1) ;% Input assumed to be white
h = rand(M, 1) ; % System picked randomly
d = filter(h, 1, u) ; % Generate output (desired signal)
% Initialize fast-lms
W = zeros(2*M,1) ;
p = Delta*ones(2*M,1) ;
y = zeros(M, 1) ;
e = zeros(M, 1) ;
for k = 2 : floor(length(u)/M) - 1 ;
U = fft(u((k-1)*M:(k+1)*M-1)) ;
Y = ifft(U.*W) ;
y(k*M:(k+1)*M-1) = real(Y(M+1:2*M)) ;
e(k*M:(k+1)*M-1) = d(k*M:(k+1)*M-1) - y(k*M:(k+1)*M-1) ;
E = fft([zeros(M,1); e(k*M:(k+1)*M-1)]) ;
p = Gamma*p+(1-Gamma)*abs(U).^2 ;
p_inv = 1./p ;
PHI = ifft(p .* conj(U) .* E) ;
phi = real(PHI(1 : M )) ;
W = W + Mu / (2*M) * fft([phi; zeros(M,1)]) ;
end ;
% Plot results
figure ;
plot(20*log10(abs(e))) ;
title('Learning Curve') ;
xlabel('Iteration Number') ;
ylabel('Output Estimation Error in dB') ;
+99
View File
@@ -0,0 +1,99 @@
%===================================================================
%-------------------------------------------------------------------
%
% Adaptive Filter
%
% Simulationen
%
% [ee,w,dd,calc,Px]=flms2(mu,N,C,L,x,d,w_start)
%
% FLMS-Algorithmus
%
% ee = Fehlersignal
% w = Filterkoeffizienten am Ende der Adaption
% dd = Filterausgang, Schaetzung von d
% calc = Rechenzeit
% Px = Schaetzung des Leistungsdichtespektrums vom x
% mu = Schrittweite
% N = Anz. Filterkoeffizienten = Filterordnung+1
% X = Filtereingang x[.]
% d = erwuenschtes Signal d[.]
% w_start = Startwerte Filterkoeffizienten
%
%-------------------------------------------------------------------
%
% author: Markus Hofbauer
% ISI, ETH Zuerich (Switzerland)
%
% created: 7/2000
%
%
%-------------------------------------------------------------------
%
% File : flms2.m
%
% Startfile: sim5.m
%
%-------------------------------------------------------------------
%===================================================================
function [ee,w,dd,calc,PX]=flms2(mu,N,C,L,x,d,w_start)
% Initialisierungen
ee=zeros(lge(x),1); % Fehlervektor
dd=zeros(lge(x),1); % Filterausgang, Schaetzung von d
WS = zeros(C,1); % Gewichtsvektor im Frequenzbereich
w = zeros(C,1); % Gewichtsvektor im Zeitbereich
PX = C*ones(C,1); % Schaetzung des Leistungsdichtespektrums
X = zeros(C,1); % Eingangsvektor im Frequenzbereich
%% FLMS Parameter
numblk = floor(lge(x)/L); % Anzahl Verarbeitungsbloecke
begin=ceil(C/L)-1; % erster Blockindex
gamma = 0.6; % Vergessensfaktor
tic; % Stopuhr laeuft
%-------------------------------------------------------------------
% FLMS Update Loop
%-------------------------------------------------------------------
for j = begin: numblk-1
% DFT von x, Laenge C
X = fft(x((j+1)*L-C+1:(j+1)*L)); % aktuellster Wert
% des Blockes: (j+1)*L
% Filterung im Frequenzbereich
YS = (X .* WS);
ys = real(ifft(YS)); % IDFT, Filterausgang im Zeitbereich
% Fehlersignal im Zeitbereich
ee(j*L+1:(j+1)*L) = d(j*L+1:(j+1)*L) - ys(C-L+1:C);
% Overlap-Save-Verfahren: nur die letzten L Werte von ys
% werden verwendet um eine lineare Faltung zu erhalten
% Fehlersignal im Frequenzbereich
E = fft([zeros(C-L,1); ee(j*L+1:(j+1)*L)]);
% Update von PX
PX=abs((1-gamma)*conj(X).*X+ gamma * PX);
% Update von WS
WS = WS + mu * conj(X)./(PX+0.001) .* E ; % Adaption von WS
% Projektion (letzten L-1 Werte von w zu Null setzten)
w = real(ifft(WS));
WS = fft(w(1:C-L+1),C);
dd(j*L+1:(j+1)*L) = ys(C-L+1:C); % Abspeichern der Schaetzung
end;
calc=toc; % Stopuhr angehalten
w = [w(1:C-L+1) ; zeros(L-1,1)]; % Filterkoeffizienten am Ende der Adaption
+108
View File
@@ -0,0 +1,108 @@
%===================================================================
%-------------------------------------------------------------------
%
% Adaptive Filter
%
% Simulationen
%
% [ee,w,dd,calc,Px]=flms2(mu,N,C,L,x,d,w_start)
%
% FLMS-Algorithmus
%
% ee = Fehlersignal
% w = Filterkoeffizienten am Ende der Adaption
% dd = Filterausgang, Schaetzung von d
% calc = Rechenzeit
% Px = Schaetzung des Leistungsdichtespektrums vom x
% mu = Schrittweite
% N = Anz. Filterkoeffizienten = Filterordnung+1
% X = Filtereingang x[.]
% d = erwuenschtes Signal d[.]
% w_start = Startwerte Filterkoeffizienten
%
%-------------------------------------------------------------------
%
% author: Markus Hofbauer
% ISI, ETH Zuerich (Switzerland)
%
% created: 7/2000
%
%
%-------------------------------------------------------------------
%
% File : flms2.m
%
% Startfile: sim5.m
%
%-------------------------------------------------------------------
%===================================================================
function [ee,w,dd,calc,PX,u]=flms2(mu,N,C,L,x,d,w_start)
% Initialisierungen
ee=zeros(lge(x),1); % Fehlervektor
dd=zeros(lge(x),1); % Filterausgang, Schaetzung von d
WS = zeros(C,1); % Gewichtsvektor im Frequenzbereich
w = zeros(C,1); % Gewichtsvektor im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
X = zeros(C,1); % Eingangsvektor im Frequenzbereich
u = zeros(C,1);
%% FLMS Parameter
numblk = floor(lge(x)/L); % Anzahl Verarbeitungsbloecke
begin=ceil(C/L)-1; % erster Blockindex
gamma = 0.97; % Vergessensfaktor
alpha = 1.0; % 0 < alpha < 1
tic; % Stopuhr laeuft
dspMul = C
dspShift = log2(dspMul)
%-------------------------------------------------------------------
% FLMS Update Loop
%-------------------------------------------------------------------
for j = begin: numblk-1
% DFT von x, Laenge C
X = dspfft(x((j+1)*L-C+1:(j+1)*L),C); % aktuellster Wert
% des Blockes: (j+1)*L
% Filterung im Frequenzbereich
YS = ((X*dspMul) .* (WS*dspMul));
ys = real(dspifft(YS,C)); % IDFT, Filterausgang im Zeitbereich
% Fehlersignal im Zeitbereich
ee(j*L+1:(j+1)*L) = d(j*L+1:(j+1)*L) - ys(C-L+1:C);
% Overlap-Save-Verfahren: nur die letzten L Werte von ys
% werden verwendet um eine lineare Faltung zu erhalten
% Fehlersignal im Frequenzbereich
E = dspfft([zeros(C-L,1); ee(j*L+1:(j+1)*L)],C);
% Update von PX
PX=abs((1-gamma)*conj(X).*X*dspMul + gamma * PX);
% umax = alpha
u = (alpha*mu/dspMul) ./(PX+mu/dspMul);
% Update von WS
WS = WS + u .* conj(X).* E ; % Adaption von WS
% Projektion (letzten L-1 Werte von w zu Null setzten)
w = real(dspifft(WS,C));
WS = dspfft(w(1:C-L+1),C);
dd(j*L+1:(j+1)*L) = ys(C-L+1:C); % Abspeichern der Schaetzung
end;
calc=toc; % Stopuhr angehalten
w = [w(1:C-L+1) ; zeros(L-1,1)]; % Filterkoeffizienten am Ende der Adaption
+142
View File
@@ -0,0 +1,142 @@
% Frequency LMS Adaptive Filter -FLMS- (DEBUG)
% --------------------------------------------
%
% Aufruf:
% Function [ys,ee,wf,fpo]=flms_d(x,d,alpha,N,C,L,wi)
%
% Parameter:
% x : Eingangsvektor
% d : Referenzvektor
% alpha: konstante Schrittweite 0 < alpha <= 1.0
% N : Anzahl Filterkoeffizienten
% C : FFT-Länge, idealerweise eine Zweier-Potenz (0=Auto)
% L : Länge eines Verarbeitungsblocks (idealerweise C=L+N=2N)
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% ee : Adaptitionsfehler
% ys : Filterausgang
% wf : Filterkoeffizienten am Ende der Adaption
% fpo : Anzahl benötigten der Floating-Point Operationen
%
% Zu Debug-Zwecken werden folgende Variablen als Binär-Dateien gespeichert:
% wf.dat : Filterkoeffizienten am Ende der Adaption (Länge N)
% -------------------------------------------------------------------------
% Datum : 20.7.2001
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : flms_d.m
% Benötigte Dateien: dspfft.m, dspifft.m
%
% -------------------------------------------------------------------------
function [ys,ee,wf,fpo]=flms_d(x,d,alpha,N,C,L,wi)
% -------------------------------------------------------------------------
% Überprüfen der Parameter
% -------------------------------------------------------------------------
if (N ~= fix(N)),
error('Fehler: N muss eine ganze Zahl sein!');
end;
if (C ~= fix(C)),
error('Fehler: C muss eine ganze Zahl sein!');
end;
if (L ~= fix(L)),
error('Fehler: L muss eine ganze Zahl sein!');
end;
% -------------------------------------------------------------------------
% Automatik-Auswahl
% -------------------------------------------------------------------------
% Falls C=0 => Automatische Wahl von C=2^r
% Anahme: C = L + N
if (C==0)
C = 2^ceil(log2(L+N-1))
end;
% -------------------------------------------------------------------------
% FLMS Parameter
% -------------------------------------------------------------------------
gamma = 1.0/C; % Sicherheitskonstante vermeidet Division durch Null
lambda = 0.6; % Vergessensfaktor
% -------------------------------------------------------------------------
% Initialisierungen
% -------------------------------------------------------------------------
Lx = length(x); % Länge des Eingangsvektors
K = Lx/L; % Anzahl Verarbeitungsblöcke
ee=zeros(Lx,1); % Fehlervektor
ys=zeros(Lx,1); % Filterausgang, Schaetzung von d
wf = zeros(C,1); % Filter im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
WS = zeros(C,1); % Filterkoeff. im Frequenzbereich
X = zeros(C,1); % Eingangsvektor im Frequenzbereich
mu = zeros(C,1); % Variable Schrittweite
yy = zeros(C,1); % Filterausgang im Zeitbereich
YS = zeros(C,1); % Filterausgang im Frequenzbereich
xzp = zeros(Lx+C-L,1); % Eingangsvektor mit C-L führenden Nullen
xzp(C-L+1:Lx+C-L) = x; % Einfügen von Np führenden Nullen an den Eingangsvektor
% Anfangswerte der Filterkoeffienten in den Frequenzbereich transformieren
%WS(1:C) = dspfft(wi(1:N),C);
% -------------------------------------------------------------------------
% Algorithmus Start
% -------------------------------------------------------------------------
flops(0);
for k=1:K,
kL = (k-1)*L;
% Transformation des aktuellen Eingangsvektors in den Frequenzbereich
X(1:C) = dspfft(xzp(kL+1:kL+C),C);
% Schnelle FFT-Faltung
YS = WS(1:C).*X(1:C) *C;
% Transformation des Filterausgangs in den Zeitbereich
yy = real(dspifft(YS,C));
% Abspeichern der letzten L Werte des Filterausgangs
ys(kL+1:kL+L) = yy(C-L+1:C);
% Berechnung des Fehlers e(k)
ee(kL+1:kL+L) = d(kL+1:kL+L) - ys(kL+1:kL+L);
% Transformation des Fehlers in den Frequenzbereich
E = dspfft([zeros(C-L,1); ee(kL+1:kL+L)],C);
% Schätzung der mittleren Eingangsleistung Px(k) aus x(k)
PX = abs((1-lambda)*conj(X(1:C)).*X(1:C) *C + lambda*PX);
% Berechnung der variablen Schrittweite mu(k)
% mu(k) wird niemals grösser als eins
mu(1:C) = (alpha*gamma) ./(PX+gamma);
% Filterkoeffizenten-Update
WS(1:C) = WS(1:C) + mu(1:C) .* conj(X(1:C)) .* E *C;
% Projektion der Filterkoeffizienten
wf(1:C) = real(dspifft(WS(1:C),C));
WS(1:C) = dspfft(wf(1:N),C);
end;
wf = [wf(1:C-L+1) ; zeros(L-1,1)]; % Filterkoeffizienten am Ende der Adaption
% Speichern der Koeffizienten in Datei (Genauigkeit Float32)
fid = fopen('wf.dat','wb');
fwrite(fid,wf,'float32');
fclose(fid);
fpo=flops;
% -------------------------------------------------------------------------
% Ende FLMS_D.M
% -------------------------------------------------------------------------
+48
View File
@@ -0,0 +1,48 @@
% LMS-Algorithmus
% ---------------
% function [ys,e,wf,fpo] = lms(x,d,N,mu,wi)
%
% Parameter:
% x : Eingangssignal
% d : erwünschtes Signal (Referenzsignal)
% N : Filterordnung
% mu : konstante Schrittweite
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% ys : Schätzung des erwünschten Signals d aus x
% e : Fehler d - y
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl benötigten der Floating-Point Operationen
% -------------------------------------------------------------------------
% Datum : 20.7.2001
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : lms.m
% Benötigte Dateien: keine
%
% -------------------------------------------------------------------------
function [ys,e,wf,fpo] = lms(x,d,N,mu,wi)
% -------------------------------------------------------------------------
% Initialisierung LMS
% -------------------------------------------------------------------------
wf = wi;
y = zeros(length(x),1);
e = zeros(length(x),1);
flops(0);
% -------------------------------------------------------------------------
% LMS Adaptation
% -------------------------------------------------------------------------
for n = N : length(x)
xs = x(n:-1:n-N+1);
ys(n) = xs'*wf;
e(n) = d(n) - ys(n);
wf = wf + mu*e(n)*xs;
end ;
fpo = flops;
% -------------------------------------------------------------------------
% Ende lms.m
+53
View File
@@ -0,0 +1,53 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% LMS Algorithm %
% %
% Written By: Sundar Sankaran and A. A. (Louis) Beex %
% DSP Research Laboratory %
% Dept. of Electrical and Comp. Engg %
% Virginia Tech %
% Blacksburg VA 24061-0111 %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
randn('seed', 0) ;
rand('seed', 0) ;
NoOfData = 8000 ; % Set no of data points used for training
Order = 32 ; % Set the adaptive filter order
Mu = 0.01 ; % Set the step-size constant
x = randn(NoOfData, 1) ;% Input assumed to be white
h = rand(Order, 1) ; % System picked randomly
d = filter(h, 1, x) ; % Generate output (desired signal)
% Initialize LMS
w = zeros(Order,1) ;
% LMS Adaptation
for n = Order : NoOfData
D = x(n:-1:n-Order+1) ;
d_hat(n) = w'*D ;
e(n) = d(n) - d_hat(n) ;
w = w + Mu*e(n)*D ;
w_err(n) = norm(h - w) ;
end ;
% Plot results
figure ;
plot(20*log10(abs(e))) ;
title('Learning Curve') ;
xlabel('Iteration Number') ;
ylabel('Output Estimation Error in dB') ;
figure ;
semilogy(w_err) ;
title('Weight Estimation Error') ;
xlabel('Iteration Number') ;
ylabel('Weight Error in dB') ;
+67
View File
@@ -0,0 +1,67 @@
%===================================================================
%-------------------------------------------------------------------
%
% Adaptive Filter
%
% Simulationen
%
% [E,W,w,DD]=lms(mu, N, X, D, w_start)
%
% LMS-Algorithmus
%
% E = Fehlersignal E[.]
% W = Filterkoeffizienten im zeitlichen Verlauf
% w = Filterkoeffizienten am Ende der Adaption
% DD = Filterausgang, Schaetzung von D
% mu = Schrittweite
% N = Anz. Filterkoeffizienten = Filterordnung+1
% X = Filtereingang X[.]
% D = erwuenschtes Signal D[.]
% w_start = Startwerte Filterkoeffizienten
%
%-------------------------------------------------------------------
%
% author: Peter Wellig, Martin Haenggi, Markus Hofbauer
% ISI, ETH Zuerich (Switzerland)
%
% created: 7/2000
%
%
%-------------------------------------------------------------------
%
% File : lms.m
%
% Startfile: simX.m
%
%-------------------------------------------------------------------
%===================================================================
function [E,W,w,DD]=lms2(mu, N, X, D, w_start)
% Initialisierungen
adaptlen=length(X);
w = w_start;
W=zeros(N,adaptlen);
DD=zeros(adaptlen,1);
E=zeros(adaptlen,1);
% Loop
flops(0);
for i=N:adaptlen
W(:,i) = w;
x = X(i:-1:i-N+1); % Eingangsvektor (x[k],x[k-1],..,x[k-N+1])
y = x'*w; % Filterausgang
e = D(i)-y; % Fehler
w = w+mu*e*x; % Aufdatierung der Filterkoeffizienten
E(i) = e;
DD(i) = y;
end;
flops
+33
View File
@@ -0,0 +1,33 @@
function lms_eval(N, mu)
% lms_eval(N, mu)
% Example: lms_eval(1000, 0.01)
h = [0 0 0 1 0 0 0 0];
w = randn(1, length(h));
z_h = zeros(length(h)-1, 1);
z_w = zeros(length(h)-1, 1);
x = zeros(1, length(h));
e_last = 0;
p = 1.0;
for n=1:N,
xs = 0.1*randn();
p = 0.99*p + 0.01*xs*xs;
x = [xs x(1:length(x)-1)];
d = x*h';
y = x*w';
e = d - y;
w = w + mu*e*x*(1/(0.001+p));
e_last = 0.5*e_last + 0.5*e*e;
_e(n) = e_last;
_p(n) = p;
end
plot(1:N, _e, 1:N, _p); grid;
w=w'
+48
View File
@@ -0,0 +1,48 @@
% NLMS-Algorithmus
% ---------------
% function [ys,e,wf,fpo] = nlms(x,d,N,mu,wi)
%
% Parameter:
% x : Eingangssignal
% d : erwünschtes Signal (Referenzsignal)
% N : Filterordnung
% mu : konstante Schrittweite
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% ys : Schätzung des Referenzsignals d aus x
% e : Fehler d - ys
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl der benötigten Floating-Point Operationen
% -------------------------------------------------------------------------
% Datum : 20.7.2001
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : nlms.m
% Benötigte Dateien: keine
%
% -------------------------------------------------------------------------
function [ys,e,wf,fpo] = nlms(x,d,N,mu,wi)
% -------------------------------------------------------------------------
% Initialisierung NLMS
% -------------------------------------------------------------------------
wf = wi;
ys = zeros(length(x),1);
e = zeros(length(x),1);
flops(0);
% -------------------------------------------------------------------------
% NLMS Adaptation
% -------------------------------------------------------------------------
for n = N : length(x)
xs = x(n:-1:n-N+1);
ys(n) = xs'*wf;
e(n) = d(n) - ys(n);
wf = wf + mu*e(n)*xs/(xs'*xs+0.001);
end ;
fpo = flops;
% -------------------------------------------------------------------------
% Ende nlms.m
+51
View File
@@ -0,0 +1,51 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% Normalized LMS Algorithm %
% %
% Written By: Sundar Sankaran and A. A. (Louis) Beex %
% DSP Research Laboratory %
% Dept. of Electrical and Comp. Engg %
% Virginia Tech %
% Blacksburg VA 24061-0111 %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
randn('seed', 0) ;
rand('seed', 0) ;
NoOfData = 8000 ; % Set no of data points used for training
Order = 32 ; % Set the adaptive filter order
Mu = 1.0 ; % Set the step-size constant
x = randn(NoOfData, 1) ;% Input assumed to be white
h = rand(Order, 1) ; % System picked randomly
d = filter(h, 1, x) ; % Generate output (desired signal)
% Initialize NLMS
w = zeros(Order,1) ;
% NLMS Adaptation
for n = Order : NoOfData
D = x(n:-1:n-Order+1) ;
d_hat(n) = w'*D ;
e(n) = d(n) - d_hat(n) ;
w = w + Mu*e(n)*D/(D'*D) ;
w_err(n) = norm(h - w) ;
end ;
% Plot results
figure ;
plot(20*log10(abs(e))) ;
title('Learning Curve') ;
xlabel('Iteration Number') ;
ylabel('Output Estimation Error in dB') ;
figure ;
semilogy(w_err) ;
title('Weight Estimation Error') ;
xlabel('Iteration Number') ;
ylabel('Weight Error in dB') ;
+210
View File
@@ -0,0 +1,210 @@
% Partitioned Frequency LMS Adaptive Filter -PFLMS-
% -------------------------------------------------
% Aufruf:
% Function [dd,e,wf,fpo]=pflms(x,d,mu,N,C,P,S,L,wi)
%
% Parameter:
% x : Eingangsvektor
% d : Referenzvektor
% mu : zeitabhängiger Schrittweitenvektor 0 < mu <= 1.0
% N : Anzahl Filterkoeffizienten (Hinweis: N = P*S*L)
% C : FFT-Länge, idealerweise eine Zweier-Potenz (0=Auto)
% P : Anzahl der Filterpartitionen
% S : Anzahl der Filtersegmente
% L : Länge eines Verarbeitungsblocks (idealerweise C=L+N/P=2N/P)
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% e : Adaptitionsfehler
% dd : Filterausgang
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl benötigten der Floating-Point Operationen
% -------------------------------------------------------------------------
% Datum : 27.3.2002
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : pflms.m
%
% -------------------------------------------------------------------------
function [dd,e,wf,fpo]=pflms(x,d,mu,N,C,P,S,L,wi)
% -------------------------------------------------------------------------
% Überprüfen der Parameter
% -------------------------------------------------------------------------
if (N ~= fix(N)),
error('Fehler: N muss eine ganze Zahl sein!');
end;
if (C ~= fix(C)),
error('Fehler: C muss eine ganze Zahl sein!');
end;
if (P ~= fix(P)),
error('Fehler: P muss eine ganze Zahl sein!');
end;
if (S ~= fix(S)),
error('Fehler: S muss eine ganze Zahl sein!');
end;
if (L ~= fix(L)),
error('Fehler: L muss eine ganze Zahl sein!');
end;
% -------------------------------------------------------------------------
% Automatik-Auswahl
% -------------------------------------------------------------------------
% Falls P=0 => Automatische Wahl von P
% Anahme: L+N/P = 2N/P
if (P==0),
P = N/L;
if (rem(N,L) ~= 0)
error('Fehler: Quotient aus N und L muss eine ganze Zahl sein! (N = P*S*L)');
end;
end;
% Falls C=0 => Automatische Wahl von C=2^r
% Anahme: C = L + N/P
if (C==0)
C = 2^ceil(log2(L+N/P-1));
end;
% -------------------------------------------------------------------------
% FLMS Parameter
% -------------------------------------------------------------------------
gamma = 1.0/C; % Sicherheitskonstante vermeidet Division durch Null
lambda = 0.4; % Vergessensfaktor
% -------------------------------------------------------------------------
% Initialisierungen
% -------------------------------------------------------------------------
Lx = length(x); % Länge des Eingangsvektors
Np = S*L; % Teilfilter hat die Länge Np = S*L = N/P
K = Lx/L; % Anzahl Verarbeitungsblöcke
e=zeros(Lx,1); % Fehlervektor
dd=zeros(Lx,1); % Filterausgang, Schaetzung von d
wp = zeros(Np,P); % P Teilfilter im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
WSp = zeros(C,P); % P Teilfilter im Frequenzbereich
X = zeros(C,S*P); % Eingangsvektor im Frequenzbereich
mu_px = zeros(C,P*S); % Variable Schrittweite
dd_ = zeros(C,1); % Filterausgang im Zeitbereich
DD = zeros(C,1); % Filterausgang im Frequenzbereich
xzp = zeros(Lx+S*L,1); % Eingangsvektor mit S*L führenden Nullen
% -------------------------------------------------------------------------
% Tabellen zur effizienten MatLab-Implementierung
% -------------------------------------------------------------------------
pidTbl = [2:P*S]; % Index auf P*S vergangene Eingangsvektoren
pidTbl(P*S) = 1; % Reihenfolge: x(k-1),x(k-2),..,x(k-P*S-1),x(k)
pStbl = [0:P*S-1]; % Tabelle zur korrekten Adressierung der Eingangsvektoren...
pStbl(1) = P*S; % ...bei der Filterung und Update der Koeffizienten.
pjiTbl = [2:P]; % Index auf Teilfilter, welches bei der effizienten...
pjiTbl(P) = 1; % ...Projektion bearbeitet wird
xzp(C-L+1:Lx+C-L) = x; % Einfügen von Np führenden Nullen an den Eingangsvektor
pid = 1; % Aktueller Index zeigt auf Eingangsvektor x(0)
pji = 1; % Aktueller Index zeigt auf Teilfilter w_0
% -------------------------------------------------------------------------
% Anfangswerte der Filterkoeffienten partitionieren
% und in den Frequenzbereich transformieren wi_p(k) => WS_p(k)
% -------------------------------------------------------------------------
for p=1:P,
SLp = (p-1)*N/P;
wp(1:Np,p) = wi(SLp+1:SLp+N/P);
WSp(1:C,p) = 1/C*fft(wp(1:Np,p),C);
end;
% -------------------------------------------------------------------------
% Algorithmus Start
% -------------------------------------------------------------------------
flops(0);
for k=1:K,
kL = (k-1)*L;
% Transformation des aktuellen Eingangsvektors in den Frequenzbereich
X(1:C,pid) = 1/C*fft(xzp(kL+1:kL+C),C);
% Partitioned FFT-Faltung
% Faltung des ersten Teilfilters mit aktuellem Eingangsvektor
pS = pid;
DD = WSp(1:C,1).*X(1:C,pid) *C;
% Faltung der restlichen Teilfilters mit vergangenen Eingangsvektoren
for p=2:P,
% Ermittlung des korrekten Index 'pS' aus Tabelle
for i = 1:S,
pS = pStbl(pS);
end;
% Summation der einzelnen Filterausgänge
DD = DD + WSp(1:C,p).*X(1:C,pS) *C;
end;
% Transformation des Filterausgangs in den Zeitbereich
dd_ = real(ifft(DD,C))*C;
% Abspeichern der letzten L Werte des Filterausgangs
dd(kL+1:kL+L) = dd_(C-L+1:C);
% Berechnung des Fehlers e(k)
e(kL+1:kL+L) = d(kL+1:kL+L) - dd(kL+1:kL+L);
% Transformation des Fehlers in den Frequenzbereich
E = 1/C*fft([zeros(C-L,1); e(kL+1:kL+L).*mu(kL+1:kL+L)],C);
% Schätzung der mittleren Eingangsleistung Px(k) aus x(k)
PX = abs(lambda*conj(X(1:C,pid)).*X(1:C,pid) *C + (1-lambda)*PX);
% Berechnung der variablen Schrittweite mu(k)
% mu(k) wird niemals grösser als eins
mu_px(1:C,pid) = (gamma/P)./(PX+gamma);
% Filterkoeffizenten-Update
pS = pid;
for p=1:P,
% Aktualisierung des p-ten Teilfilters
WSp(1:C,p) = WSp(1:C,p) + mu_px(1:C,pS) .* conj(X(1:C,pS)) .* E *C;
% Ermittlung des korrekten Index 'pS' aus Tabelle
for i = 1:S,
pS = pStbl(pS);
end;
end;
% Aufwändig: Projektion jedes p-ten Teilfilters wp pro k-ter Iteration
% for p=1:P,
% wp(1:C,p) = real(dspifft(WSp(1:C,p),C));
% WSp(1:C,p) = dspfft(wp(1:Np,p),C);
% end;
% Effizient: Projektion eines pji-ten Teilfilters alternierend pro k-ter Iteration
wp(1:C,pji) = C*real(ifft(WSp(1:C,pji),C)); % pji = 0,1,..,P-1,0,1,..P-1,..
WSp(1:C,pji) = 1/C*fft(wp(1:Np,pji),C);
pji = pjiTbl(pji); % Nächster Index pji auf Eingangsvektor aus Tabelle
pid = pidTbl(pid); % Nächster Index pid auf Teilfilter aus Tabelle
end;
% Komposition des Gesamtfilters aus den P Teilfiltern
for p=1:P,
wf((p-1)*Np+1:p*Np) = wp(1:Np,p);
end;
fpo=flops;
% -------------------------------------------------------------------------
% Ende PFLMS.M
% -------------------------------------------------------------------------
+211
View File
@@ -0,0 +1,211 @@
% Partitioned Frequency LMS Adaptive Filter -PFLMS-
% -------------------------------------------------
% Aufruf:
% Function [ys,ee,wf,fpo]=pflms(x,d,alpha,N,C,P,S,L,wi)
%
% Parameter:
% x : Eingangsvektor
% d : Referenzvektor
% alpha: konstante Schrittweite 0 < alpha <= 1.0
% N : Anzahl Filterkoeffizienten (Hinweis: N = P*S*L)
% C : FFT-Länge, idealerweise eine Zweier-Potenz (0=Auto)
% P : Anzahl der Filterpartitionen
% S : Anzahl der Filtersegmente
% L : Länge eines Verarbeitungsblocks (idealerweise C=L+N/P=2N/P)
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% ee : Adaptitionsfehler
% ys : Filterausgang
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl benötigten der Floating-Point Operationen
% -------------------------------------------------------------------------
% Datum : 20.7.2001
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : pflms.m
% Benötigte Dateien: dspfft.m, dspifft.m
%
% -------------------------------------------------------------------------
function [ys,ee,wf,fpo]=pflms(x,d,alpha,N,C,P,S,L,wi)
% -------------------------------------------------------------------------
% Überprüfen der Parameter
% -------------------------------------------------------------------------
if (N ~= fix(N)),
error('Fehler: N muss eine ganze Zahl sein!');
end;
if (C ~= fix(C)),
error('Fehler: C muss eine ganze Zahl sein!');
end;
if (P ~= fix(P)),
error('Fehler: P muss eine ganze Zahl sein!');
end;
if (S ~= fix(S)),
error('Fehler: S muss eine ganze Zahl sein!');
end;
if (L ~= fix(L)),
error('Fehler: L muss eine ganze Zahl sein!');
end;
% -------------------------------------------------------------------------
% Automatik-Auswahl
% -------------------------------------------------------------------------
% Falls P=0 => Automatische Wahl von P
% Anahme: L+N/P = 2N/P
if (P==0),
P = N/L;
if (rem(N,L) ~= 0)
error('Fehler: Quotient aus N und L muss eine ganze Zahl sein! (N = P*S*L)');
end;
end;
% Falls C=0 => Automatische Wahl von C=2^r
% Anahme: C = L + N/P
if (C==0)
C = 2^ceil(log2(L+N/P-1));
end;
% -------------------------------------------------------------------------
% FLMS Parameter
% -------------------------------------------------------------------------
gamma = 1.0/C; % Sicherheitskonstante vermeidet Division durch Null
lambda = 0.6; % Vergessensfaktor
% -------------------------------------------------------------------------
% Initialisierungen
% -------------------------------------------------------------------------
Lx = length(x); % Länge des Eingangsvektors
Np = S*L; % Teilfilter hat die Länge Np = S*L = N/P
K = Lx/L; % Anzahl Verarbeitungsblöcke
ee=zeros(Lx,1); % Fehlervektor
ys=zeros(Lx,1); % Filterausgang, Schaetzung von d
wp = zeros(Np,P); % P Teilfilter im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
WSp = zeros(C,P); % P Teilfilter im Frequenzbereich
X = zeros(C,S*P); % Eingangsvektor im Frequenzbereich
mu = zeros(C,P*S); % Variable Schrittweite
yy = zeros(C,1); % Filterausgang im Zeitbereich
YS = zeros(C,1); % Filterausgang im Frequenzbereich
xzp = zeros(Lx+S*L,1); % Eingangsvektor mit S*L führenden Nullen
% -------------------------------------------------------------------------
% Tabellen zur effizienten MatLab-Implementierung
% -------------------------------------------------------------------------
pidTbl = [2:P*S]; % Index auf P*S vergangene Eingangsvektoren
pidTbl(P*S) = 1; % Reihenfolge: x(k-1),x(k-2),..,x(k-P*S-1),x(k)
pStbl = [0:P*S-1]; % Tabelle zur korrekten Adressierung der Eingangsvektoren...
pStbl(1) = P*S; % ...bei der Filterung und Update der Koeffizienten.
pjiTbl = [2:P]; % Index auf Teilfilter, welches bei der effizienten...
pjiTbl(P) = 1; % ...Projektion bearbeitet wird
xzp(C-L+1:Lx+C-L) = x; % Einfügen von Np führenden Nullen an den Eingangsvektor
pid = 1; % Aktueller Index zeigt auf Eingangsvektor x(0)
pji = 1; % Aktueller Index zeigt auf Teilfilter w_0
% -------------------------------------------------------------------------
% Anfangswerte der Filterkoeffienten partitionieren
% und in den Frequenzbereich transformieren wi_p(k) => WS_p(k)
% -------------------------------------------------------------------------
for p=1:P,
SLp = (p-1)*N/P;
wp(1:Np,p) = wi(SLp+1:SLp+N/P);
WSp(1:C,p) = 1/C*fft(wp(1:Np,p),C);
end;
% -------------------------------------------------------------------------
% Algorithmus Start
% -------------------------------------------------------------------------
flops(0);
for k=1:K,
kL = (k-1)*L;
% Transformation des aktuellen Eingangsvektors in den Frequenzbereich
X(1:C,pid) = 1/C*fft(xzp(kL+1:kL+C),C);
% Partitioned FFT-Faltung
% Faltung des ersten Teilfilters mit aktuellem Eingangsvektor
pS = pid;
YS = WSp(1:C,1).*X(1:C,pid) *C;
% Faltung der restlichen Teilfilters mit vergangenen Eingangsvektoren
for p=2:P,
% Ermittlung des korrekten Index 'pS' aus Tabelle
for i = 1:S,
pS = pStbl(pS);
end;
% Summation der einzelnen Filterausgänge
YS = YS + WSp(1:C,p).*X(1:C,pS) *C;
end;
% Transformation des Filterausgangs in den Zeitbereich
yy = real(ifft(YS,C))*C;
% Abspeichern der letzten L Werte des Filterausgangs
ys(kL+1:kL+L) = yy(C-L+1:C);
% Berechnung des Fehlers e(k)
ee(kL+1:kL+L) = d(kL+1:kL+L) - ys(kL+1:kL+L);
% Transformation des Fehlers in den Frequenzbereich
E = 1/C*fft([zeros(C-L,1); ee(kL+1:kL+L)],C);
% Schätzung der mittleren Eingangsleistung Px(k) aus x(k)
PX = abs((1-lambda)*conj(X(1:C,pid)).*X(1:C,pid) *C + lambda*PX);
% Berechnung der variablen Schrittweite mu(k)
% mu(k) wird niemals grösser als eins
mu(1:C,pid) = (alpha*gamma/P) ./(PX+gamma);
% Filterkoeffizenten-Update
pS = pid;
for p=1:P,
% Aktualisierung des p-ten Teilfilters
WSp(1:C,p) = WSp(1:C,p) + mu(1:C,pS) .* conj(X(1:C,pS)) .* E *C;
% Ermittlung des korrekten Index 'pS' aus Tabelle
for i = 1:S,
pS = pStbl(pS);
end;
end;
% Aufwändig: Projektion jeden p-ten Teilfilters wp pro k-ter Iteration
% for p=1:P,
% wp(1:C,p) = real(dspifft(WSp(1:C,p),C));
% WSp(1:C,p) = dspfft(wp(1:Np,p),C);
% end;
% Effizient: Projektion eines Teilfilters alternierend pro k-ter Iteration
wp(1:C,pji) = C*real(ifft(WSp(1:C,pji),C));
WSp(1:C,pji) = 1/C*fft(wp(1:Np,pji),C);
pji = pjiTbl(pji); % Nächster Index auf Eingangsvektor aus Tabelle
pid = pidTbl(pid); % Nächster Index auf Teilfilter aus Tabelle
end;
% Komposition des Gesamtfilters aus den P Teilfiltern
for p=1:P,
wf((p-1)*Np+1:p*Np) = wp(1:Np,p);
end;
fpo=flops;
% -------------------------------------------------------------------------
% Ende PFLMS.M
% -------------------------------------------------------------------------
+97
View File
@@ -0,0 +1,97 @@
% pflms2(mu,N,C,P,S,L,x,d,w_start)
function [ee,w,dd,PX,u]=pflms2(mu,N,C,P,S,L,x,d,w_start)
Lx = length(x);
Np = S*L;
K = Lx/L;
% FLMS Parameter
gamma = 0.6; % Vergessensfaktor
alpha = 1.0 % 0 < alpha < 1
beta = mu/C
% Initialisierungen
ee=zeros(Lx,1); % Fehlervektor
dd=zeros(Lx,1); % Filterausgang, Schaetzung von d
wp = zeros(C,P); % Gewichtsvektor im Frequenzbereich
w = zeros(P*S*L,1); % Gewichtsvektor im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
WSp = zeros(C,P);
X = zeros(C,S*P);
u = zeros(C,P*S);
ys = zeros(C,1);
YS = zeros(C,1);
xzp = zeros(Lx+S*L,1);
pidTbl = [2:P*S];
pidTbl(P*S) = 1;
pStbl = [0:P*S-1];
pStbl(1) = P*S;
pjiTbl = [2:P];
pjiTbl(P) = 1;
xzp(C-L+1:Lx+C-L) = x;
pid = 1;
pji = 1;
flops(0);
for k=1:K,
kL = (k-1)*L;
X(1:C,pid) = dspfft(xzp(kL+1:kL+C),C);
pS = pid;
YS = WSp(1:C,1).*X(1:C,pid) *C;
for p=2:P,
for i = 1:S
pS = pStbl(pS);
end;
YS = YS + WSp(1:C,p).*X(1:C,pS) *C;
end;
ys = real(dspifft(YS,C));
dd(kL+1:kL+L) = ys(C-L+1:C);
ee(kL+1:kL+L) = d(kL+1:kL+L) - ys(C-L+1:C);
E = dspfft([zeros(C-L,1); ee(kL+1:kL+L)],C);
PX = abs((1-gamma)*conj(X(1:C,pid)).*X(1:C,pid) *C + gamma*PX);
% umax = alpha
u(1:C,pid) = (alpha*beta) ./(PX+beta);
% Update
pS = pid;
for p=1:P,
WSp(1:C,p) = WSp(1:C,p) + u(1:C,pS) .* conj(X(1:C,pS)) .* E *C;
for i = 1:S
pS = pStbl(pS);
end;
end;
% Teuer: Projektion jeden p-ten Teilfilters wp pro k-ter Iteration
% for p=1:P,
% wp(1:C,p) = real(dspifft(WSp(1:C,p),C));
% WSp(1:C,p) = dspfft(wp(1:Np,p),C);
% end;
% Billig: Projektion eines Teilfilters alternierend pro k-ter Iteration
wp(1:C,pji) = real(dspifft(WSp(1:C,pji),C));
WSp(1:C,pji) = dspfft(wp(1:Np,pji),C);
pji = pjiTbl(pji);
pid = pidTbl(pid);
end;
flops
% Return estimated filter weights
for p=1:P,
w((p-1)*Np+1:p*Np) = wp(1:Np,p);
end;
+219
View File
@@ -0,0 +1,219 @@
% Partitioned Frequency LMS Adaptive Filter -PFLMS- (Debug Version)
% -----------------------------------------------------------------
% Aufruf:
% Function [ys,ee,wf,fpo]=pflms_d(x,d,alpha,N,C,P,S,L,wi)
%
% Parameter:
% x : Eingangsvektor
% d : Referenzvektor
% alpha: konstante Schrittweite 0 < alpha <= 1.0
% N : Anzahl Filterkoeffizienten (Hinweis N = P*S*L)
% C : FFT-Länge (idealerweise eine Zweier-Potenz)
% P : Anzahl der Filterpartitionen
% S : Anzahl der Filtersegmente
% L : Länge eines Verarbeitungsblocks (idealerweise C=L+N/P=2N/P)
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% ee : Adaptitionsfehler
% ys : Filterausgang
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl benötigten der Floating-Point Operationen
%
% Zu Debug-Zwecken werden folgende Variablen als Binär-Dateien gespeichert:
% wf.dat : Filterkoeffizienten am Ende der Adaption (Länge N)
% -------------------------------------------------------------------------
% Datum : 20.7.2001
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : pflms_d.m
% Benötigte Dateien: dspfft.m, dspifft.m
%
% -------------------------------------------------------------------------
function [ys,ee,wf,fpo]=pflms_d(x,d,alpha,N,C,P,S,L,wi)
% -------------------------------------------------------------------------
% Überprüfen der Parameter
% -------------------------------------------------------------------------
if (N ~= fix(N)),
error('Fehler: N muss eine ganze Zahl sein!');
end;
if (C ~= fix(C)),
error('Fehler: C muss eine ganze Zahl sein!');
end;
if (P ~= fix(P)),
error('Fehler: P muss eine ganze Zahl sein!');
end;
if (S ~= fix(S)),
error('Fehler: S muss eine ganze Zahl sein!');
end;
if (L ~= fix(L)),
error('Fehler: L muss eine ganze Zahl sein!');
end;
% -------------------------------------------------------------------------
% Automatik-Auswahl
% -------------------------------------------------------------------------
% Falls P=0 => Automatische Wahl von P
% Anahme: L+N/P = 2N/P
if (P==0),
P = N/L
if (rem(N,L) ~= 0)
error('Fehler: Quotient aus N und L muss eine ganze Zahl sein! (N = P*S*L)');
end;
end;
% Falls C=0 => Automatische Wahl von C=2^r
% Anahme: C = L + N/P
if (C==0)
C = 2^ceil(log2(L+N/P-1))
end;
% -------------------------------------------------------------------------
% FLMS Parameter
% -------------------------------------------------------------------------
gamma = 1.0/C; % Sicherheitskonstante vermeidet Division durch Null
lambda = 0.6; % Vergessensfaktor
% -------------------------------------------------------------------------
% Initialisierungen
% -------------------------------------------------------------------------
Lx = length(x); % Länge des Eingangsvektors
Np = S*L; % Teilfilter hat die Länge Np = S*L = N/P
K = Lx/L; % Anzahl Verarbeitungsblöcke
ee=zeros(Lx,1); % Fehlervektor
ys=zeros(Lx,1); % Filterausgang, Schaetzung von d
wp = zeros(C,P); % P Teilfilter im Zeitbereich
wf = zeros(P*S*L,1); % Gesamtfilter im Zeitbereich
PX = zeros(C,1); % Schaetzung des Leistungsdichtespektrums
WSp = zeros(C,P); % P Teilfilter im Frequenzbereich
X = zeros(C,S*P); % Eingangsvektor im Frequenzbereich
mu = zeros(C,P*S); % Variable Schrittweite
yy = zeros(C,1); % Filterausgang im Zeitbereich
YS = zeros(C,1); % Filterausgang im Frequenzbereich
xzp = zeros(Lx+S*L,1); % Eingangsvektor mit S*L führenden Nullen
% -------------------------------------------------------------------------
% Tabellen zur effizienten MatLab-Implementierung
% -------------------------------------------------------------------------
pidTbl = [2:P*S]; % Index auf P*S vergangene Eingangsvektoren
pidTbl(P*S) = 1; % Reihenfolge: x(k-1),x(k-2),..,x(k-P*S-1),x(k)
pStbl = [0:P*S-1]; % Tabelle zur korrekten Adressierung der Eingangsvektoren...
pStbl(1) = P*S; % ...bei der Filterung und Update der Koeffizienten.
pjiTbl = [2:P]; % Index auf Teilfilter, welches bei der effizienten...
pjiTbl(P) = 1; % ...Projektion bearbeitet wird
xzp(C-L+1:Lx+C-L) = x; % Einfügen von Np führenden Nullen an den Eingangsvektor
% Start
pid = 1; % Aktueller Index zeigt auf Eingangsvektor x(0)
pji = 1; % Aktueller Index zeigt auf Teilfilter w_0
% -------------------------------------------------------------------------
% Anfangswerte der Filterkoeffienten partitionieren
% und in den Frequenzbereich transformieren wi_p(k) => WS_p(k)
% -------------------------------------------------------------------------
%for p=1:P,
% SLp = (p-1)*N/P;
% wp(p,1:N/P) = wi(SLp+1:SLp+N/P);
% WSp(p,1:C) = dspfft(wp(p,1:C),C);
%end;
% -------------------------------------------------------------------------
% Algorithmus Start
% -------------------------------------------------------------------------
flops(0);
for k=1:K,
kL = (k-1)*L;
% Transformation des aktuellen Eingangsvektors in den Frequenzbereich
X(1:C,pid) = dspfft(xzp(kL+1:kL+C),C);
% Partitioned FFT-Faltung
% Faltung des ersten Teilfilters mit aktuellem Eingangsvektor
pS = pid;
YS = WSp(1:C,1).*X(1:C,pid) *C;
% Faltung der restlichen Teilfilters mit vergangenen Eingangsvektoren
for p=2:P,
% Ermittlung des korrekten Index 'pS' aus Tabelle
for i = 1:S,
pS = pStbl(pS);
end;
% Summation der einzelnen Filterausgänge
YS = YS + WSp(1:C,p).*X(1:C,pS) *C;
end;
% Transformation des Filterausgangs in den Zeitbereich
yy = real(dspifft(YS,C));
% Abspeichern der letzten L Werte des Filterausgangs
ys(kL+1:kL+L) = yy(C-L+1:C);
% Berechnung des Fehlers e(k)
ee(kL+1:kL+L) = d(kL+1:kL+L) - ys(kL+1:kL+L);
% Transformation des Fehlers in den Frequenzbereich
E = dspfft([zeros(C-L,1); ee(kL+1:kL+L)],C);
% Schätzung der mittleren Eingangsleistung Px(k) aus x(k)
PX = abs((1-lambda)*conj(X(1:C,pid)).*X(1:C,pid) *C + lambda*PX);
% Berechnung der variablen Schrittweite mu(k)
% mu(k) wird niemals grösser als eins
mu(1:C,pid) = (alpha*gamma/P) ./(PX+gamma);
% Filterkoeffizenten-Update
pS = pid;
for p=1:P,
% Aktualisierung des p-ten Teilfilters
WSp(1:C,p) = WSp(1:C,p) + mu(1:C,pS) .* conj(X(1:C,pS)) .* E *C;
% Ermittlung des korrekten Index 'pS' aus Tabelle
for i = 1:S,
pS = pStbl(pS);
end;
end;
% Aufwändig: Projektion jeden p-ten Teilfilters wp pro k-ter Iteration
% for p=1:P,
% wp(1:C,p) = real(dspifft(WSp(1:C,p),C));
% WSp(1:C,p) = dspfft(wp(1:Np,p),C);
% end;
% Effizient: Projektion eines Teilfilters alternierend pro k-ter Iteration
wp(1:C,pji) = real(dspifft(WSp(1:C,pji),C));
WSp(1:C,pji) = dspfft(wp(1:Np,pji),C);
pji = pjiTbl(pji); % Nächster Index auf Eingangsvektor aus Tabelle
pid = pidTbl(pid); % Nächster Index auf Teilfilter aus Tabelle
end;
% Komposition des Gesamtfilters aus den P Teilfiltern
for p=1:P,
wf((p-1)*Np+1:p*Np) = wp(1:Np,p);
end;
fpo=flops;
% Speichern der Koeffizienten in Datei (Genauigkeit Float32)
fid = fopen('wf.dat','wb');
fwrite(fid,wf,'float32');
fclose(fid);
% -------------------------------------------------------------------------
% Ende PFLMS_D.M
+96
View File
@@ -0,0 +1,96 @@
% pflmss(mu,N,C,P,S,L,x,d,w_start)
function [ee,w,dd,calc,PX]=pflmss(mu,N,C,P,S,L,x,d,w_start)
Lx = length(x);
Np = S*L;
K = Lx/L;
% Initialisierungen
%% FLMS Parameter
gamma = 0.6; % Vergessensfaktor
ee=zeros(Lx,1); % Fehlervektor
dd=zeros(Lx,1); % Filterausgang, Schaetzung von d
wp = zeros(C,P); % Gewichtsvektor im Frequenzbereich
w = zeros(P*S*L,1); % Gewichtsvektor im Zeitbereich
PX = ones(C,1); % Schaetzung des Leistungsdichtespektrums
WSp = zeros(C,P);
X = zeros(C,S*P);
U = zeros(C,S*P);
ys = zeros(C,1);
YS = zeros(C,1);
xzp = zeros(Lx+S*L,1);
pidTbl = [2:P*S];
pidTbl(P*S) = 1;
pStbl = [0:P*S-1];
pStbl(1) = P*S;
pjiTbl = [2:P];
pjiTbl(P) = 1;
xzp(C-L+1:Lx+C-L) = x;
tic; % Stopuhr laeuft
pid = 1;
pji = 1;
flops(0);
for k=1:K,
kL = (k-1)*L;
X(1:C,pid) = fft(xzp(kL+1:kL+C),C);
pS = pid;
YS = WSp(1:C,1).*X(1:C,pid);
for p=2:P,
for i = 1:S
pS = pStbl(pS);
end;
YS = YS + WSp(1:C,p).*X(1:C,pS);
end;
ys = real(ifft(YS,C));
dd(kL+1:kL+L) = ys(C-L+1:C);
ee(kL+1:kL+L) = d(kL+1:kL+L) - ys(C-L+1:C);
E = fft([zeros(C-L,1); ee(kL+1:kL+L)]);
PX = abs((1-gamma)*conj(X(1:C,pid)).*X(1:C,pid) + gamma*PX);
U(1:C,pid) = mu ./ (PX+0.001);
% Update
pS = pid;
for p=1:P,
WSp(1:C,p) = WSp(1:C,p) + U(1:C,pS) .* conj(X(1:C,pS)) .* E;
for i = 1:S
pS = pStbl(pS);
end;
end;
% Teuer: Projektion jeden p-ten Teilfilters wp pro k-ter Iteration
% for p=1:P,
% wp(1:C,p) = real(ifft(WSp(1:C,p)));
% WSp(1:C,p) = fft(wp(1:Np,p),C);
% end;
% Billig: Projektion eines Teilfilters alternierend pro k-ter Iteration
wp(1:C,pji) = real(ifft(WSp(1:C,pji)));
WSp(1:C,pji) = fft(wp(1:Np,pji),C);
pji = pjiTbl(pji);
pid = pidTbl(pid);
end;
flops
% Return estimated filter weights
for p=1:P,
w((p-1)*Np+1:p*Np) = wp(1:Np,p);
end;
calc = toc;
+55
View File
@@ -0,0 +1,55 @@
% RLS-Algorithmus
% ---------------
% function [dd,e,wf,fpo] = rls(x,d,N,mu,rho,wi)
%
% Parameter:
% x : Eingangssignal
% d : erwünschtes Signal (Referenzsignal)
% N : Filterordnung
% mu : konstante Schrittweite
% rho : Vergessensfaktor
% wi : Startwerte der Filterkoeffizienten im Zeitbereich
%
% Rückgabewerte:
% dd : Schätzung d' des Referenzsignals d aus x
% e : Fehler d - d'
% wf : Filterkoeffizienten am Ende der Adaption im Zeitbereich
% fpo : Anzahl der benötigten Floating-Point Operationen
% -------------------------------------------------------------------------
% Datum : 27.3.2002
% Autor : Jens Ahrensfeld
% Thema : Diplomarbeit
% Datei : rls.m
%
% -------------------------------------------------------------------------
function [dd,e,wf,fpo] = rls(x,d,N,mu,rho,wi)
% -------------------------------------------------------------------------
% Initialisierung RLS
% -------------------------------------------------------------------------
wf = wi;
dd = zeros(length(x),1);
e = zeros(length(x),1);
eta = 1000000;
R_ = eta * eye(N); % inverse Autokorrelationsmatrix R
flops(0);
% -------------------------------------------------------------------------
% RLS Adaptation
% -------------------------------------------------------------------------
for n = N : length(x)
xs = x(n:-1:n-N+1); % Eingangsvektor
dd(n) = xs' * wf; % Filterung
e(n) = d(n) - dd(n); % a priori-Fehler
z = R_ * xs; % gefilterter Datenvektor z
vn = 1/(rho + xs'*z); % Normierungskonstante
zn = vn*z; % Normierung
wf = wf + mu*e(n)*zn; % Aktualisierung der Filterkoeffizienten
R_ = 1/rho * (R_ - zn*xs'*R_); % Aktualisierung der inversen
% Autokorrelationsmatrix R
end ;
fpo = flops;
% -------------------------------------------------------------------------
% Ende rls.m
+60
View File
@@ -0,0 +1,60 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% RLS Algorithm %
% %
% Written By: Sundar Sankaran and A. A. (Louis) Beex %
% DSP Research Laboratory %
% Dept. of Electrical and Comp. Engg %
% Virginia Tech %
% Blacksburg VA 24061-0111 %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
randn('seed', 0) ;
rand('seed', 0) ;
NoOfData = 8000 ; % Set no of data points used for training
Order = 32 ; % Set the adaptive filter order
Lambda = 0.98 ; % Set the forgetting factor
Delta = 0.001 ; % R initialized to Delta*I
x = randn(NoOfData, 1) ;% Input assumed to be white
h = rand(Order, 1) ; % System picked randomly
d = filter(h, 1, x) ; % Generate output (desired signal)
% Initialize RLS
P = Delta * eye ( Order, Order ) ;
w = zeros ( Order, 1 ) ;
% RLS Adaptation
for n = Order : NoOfData ;
u = x(n:-1:n-Order+1) ;
pi_ = u' * P ;
k = Lambda + pi_ * u ;
K = pi_'/k;
e(n) = d(n) - w' * u ;
w = w + K * e(n) ;
PPrime = K * pi_ ;
P = ( P - PPrime ) / Lambda ;
w_err(n) = norm(h - w) ;
end ;
% Plot results
figure ;
plot(20*log10(abs(e))) ;
title('Learning Curve') ;
xlabel('Iteration Number') ;
ylabel('Output Estimation Error in dB') ;
figure ;
semilogy(w_err) ;
title('Weight Estimation Error') ;
xlabel('Iteration Number') ;
ylabel('Weight Error in dB') ;
+71
View File
@@ -0,0 +1,71 @@
%===================================================================
%-------------------------------------------------------------------
%
% Adaptive Filter
%
% Simulationen
%
% [E,W,w,inv_R]=rls(N,X,D,w_start,rho)
%
% RLS-Algorithmus
%
% E = Fehlersignal E[.]
% W = Filterkoeffizienten im zeitlichen Verlauf
% w = Filterkoeffizienten am Ende der Adaption
% inv_R = Inverse deterministische Korrelationsmatrix
% nach Adaptionsende
% N = Anz. Filterkoeffizienten = Filterordnung+1
% X = Filtereingang X[.]
% D = erwuenschtes Signal D[.]
% w_start = Startwerte Filterkoeffizienten
% rho = Vergessensfaktor
%
%-------------------------------------------------------------------
%
% author: Markus Hofbauer
% ISI, ETH Zuerich (Switzerland)
%
% created: 7/2000
%
%
%-------------------------------------------------------------------
%
% File : rls.m
%
% Startfile: simX.m
%
%-------------------------------------------------------------------
%===================================================================
function [E,W,w,inv_R]=rls(N,X,D,w_start,rho)
p0=1000000; % Initialisierung von
inv_R=p0*eye(N); % inv_R
adaptlen=length(X);
w= w_start;
W=zeros(N,adaptlen);
E=zeros(adaptlen,1);
%-------------------------------------------------------------------
% RLS Update Loop
%-------------------------------------------------------------------
for i=N:adaptlen
W(:,i)=w;
x = X(i:-1:i-N+1); % Eingangsvektor (x[k],x[k-1],..,x[k-N+1])
y=x'*w; % Filterausgang
e=D(i)-y; % Fehler
c=1/(rho+x'*inv_R*x);
inv_R=1/rho*(inv_R-c*inv_R*x*x'*inv_R); % Aufdatierung von inv_R
w=w+inv_R*e*x; % Aufdatierung von w
E(i)=e;
end;