Files
matlab/common/pflms.old.m
T
jens b31f3e7435 - added
git-svn-id: http://moon:8086/svn/matlab/trunk@153 801c6759-fa7c-4059-a304-17956f83a07c
2021-03-22 20:28:22 +00:00

212 lines
7.2 KiB
Matlab
Executable File

% 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
% -------------------------------------------------------------------------