- refactored
This commit is contained in:
Executable
+219
@@ -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
|
||||
Reference in New Issue
Block a user