Hallo,
wie lässt sich aus einer spektralen Kurve mit x Frequenz und y
Amplitude die Impulsantwort für einen FIR Filter berechnen?
Gibt es dafür eine Formel, ein Schlagwort und oder ein kostenloses
(online) Tool?
Moin,
ver schrieb:> wie lässt sich aus einer spektralen Kurve mit x Frequenz und y> Amplitude die Impulsantwort für einen FIR Filter berechnen?
Wenn du nur die Amplitude und nicht den Phasengang hast, wird's keine
eindeutige Loesung geben. Ansonsten geht das per (inverser)
Fouriertransformation.
Als kostenloses Tool gibt's z.b. GNU Octave oder irgendwelches
Python-basiertes Zeugs.
Gruss
WK
Okay, da hab ich wohl etwas zu schnell überflogen :/
Deine Kurve ist der Amplitudengang (also der Betrag des Frequenzganges,
siehe https://de.wikipedia.org/wiki/Frequenzgang)? Dann ist das die
Fouriertransformierte deiner Impulsantwort.
D.h. du müsstest die inverse Fouriertrafo (iFT) berechnen und dann die
Koeffizienten der Impulsantwort ablesen. Die Länge deiner Fourier Trafo
bestimmt deine Filterordnung.
Damit das ohne Phase (du hast ja anscheinend nur den Betrag der
komplexen Zahl, die die iFT erwartet) funktioniert musst du imo
ausnutzen, dass FIR Filter idR. eine lineare Phase haben. Dann kannst du
dir den Datensatz der Phase möglicherweise selbst generieren.
Was die Länge des Filters angeht, so bestimmst du die durch die Länge
der iFT. Du brauchst vermutlich eine Fensterfunktion, damit du keine
starken Oszillationen bekommst.
Stichworte sind
- FIR Filter design with window method
- FIR Filter system identification (siehe z.B.
https://de.mathworks.com/help/signal/ref/invfreqz.html)
Moin,
Jan K. schrieb:> funktioniert musst du imo> ausnutzen, dass FIR Filter idR. eine lineare Phase haben.
Kleiner "Funfact" am Rande: Die Regel, damit FIR Filter eine lineare
Phase haben, geht so: Die Werte der Koeffizienten muessen punkt- oder
achsensymmetrisch zur Mitte des Filters sein.
Hier bedeutet das: Wenn die Phase voellig wurscht ist und nur der
Amplitudengang zaehlt, dann wird ein FIR-Filter mit weniger
Koeffizienten auskommen, die sind aber wahrscheinlich nicht symmetrisch.
Wenn zum speziellen Amplitudengang noch eine lineare Phase gewuenscht
ist, dann wuerde ein FIR Filter "laenger", aber dafuer mit symmetrischen
Koeffizienten.
Gruss
WK
Marek N. schrieb:> Inverse Z-transformation liefert die diskrete Impulsantwort.
Die Frage ist, wie man die aus einer nicht-analytisch beschreibbaren
Punktemenge bestimmt. Hier muss IMO erst mal eine Ausgleichsfunktion
her, um die Messfehler rauszunehmen.
Dergute W. schrieb:> Hier bedeutet das: Wenn die Phase voellig wurscht ist und nur der> Amplitudengang zaehlt, dann wird ein FIR-Filter mit weniger> Koeffizienten auskommen,
Naja, viel kann man da aber i.d.R. nicht sparen
Danke, Ihr bietet mir ja jetzt ne Menge an.
Als Noob sind das gleich mehrere Berge vor mir.
Jürgen S. schrieb:> Marek N. schrieb:>> Inverse Z-transformation liefert die diskrete Impulsantwort.>> Die Frage ist, wie man die aus einer nicht-analytisch beschreibbaren> Punktemenge bestimmt. Hier muss IMO erst mal eine Ausgleichsfunktion> her, um die Messfehler rauszunehmen.
Welche Messfehler? Meine Kurve ist doch schön rund.
>> Dergute W. schrieb:>> Hier bedeutet das: Wenn die Phase voellig wurscht ist und nur der>> Amplitudengang zaehlt, dann wird ein FIR-Filter mit weniger>> Koeffizienten auskommen,> Naja, viel kann man da aber i.d.R. nicht sparen
Spart man nicht die Hälfte? Bzw. ist die phasenlineare Version nicht
symmetrisch gespiegelt und somit doppelt so lang?
Jan K. schrieb:> FIR Filter idR. eine lineare Phase haben. Dann kannst du> dir den Datensatz der Phase möglicherweise selbst generieren.
Also einfach linear von 0 bis 1?
So wirklich kapiere ich das alles noch nicht...
Siehe angehängte Abbildung:
Habe jetzt experimentell herausgefunden, dass wenn ich (A) einen Cosinus
mit gedämpfter Schwingung symmetrisch spiegel, (B) dies als
Coeffizienten für einen FIR Filter nehme, die Cutoff-Frequenz der
Frequenz des Cosinus entspricht (C) und bei schwacher Dämpfung eine Art
Bandpass entsteht bzw. sich schon fast eine Resonanz ausbildet.
Mit mehreren solcher gedämpften Cosinus in unterschiedlichen
Mischungsverhältnissen lässt sich eine komplizierteres Filter bauen.
Welche die jeweils richtige Dämpfung eines jeweiligen Cosinus für die im
ersten Post gezeigte Kurve ist, wenn ich für jeden Eintrag der Tabelle
einen Cosinus mit entsprechender Aplitude nehme, ist mir jedoch noch
nicht klar.
Und vermutlich ist diese experimentelle, naive Herandgehensweise
hinreichend ineffizient!?
* nochmal zur Erklärung der Abbildung:
(A) ist der gedämpfte Cosinus 440Hz (B) gespiegelt und als Koeffizienten
genutzt und (C) weißes Rauschen gefiltert mit dem Peak bzw Cutoff bei
440Hz.
Die Kurvenform im ersten Post möchte ich als Filterform.
Moin,
ver schrieb:> Und vermutlich ist diese experimentelle, naive Herandgehensweise> hinreichend ineffizient!?
Jepp :-)
Haeng' doch mal statt dem Bild deiner gewuenschten Filterfunktion die
gewuenschten Werte fuer die Amplitude (linear, dB, Neper ;-)? ) bei den
jeweils normierten Frequenzen als Tabelle, moeglichst als .txt file hier
an einen Post.
Gruss
WK
Moin,
Hier mal n Beispiel, wo ich mir aus deinem Bild im ersten Post halt mal
ein .txt file zusammengereimt habe, naemlich dieses hier:
1
#frequenz amplitude
2
0.0 0.0
3
0.1 0.316
4
0.2 0.447
5
0.3 0.548
6
0.4 0.632
7
0.5 0.707
8
0.6 0.775
9
0.7 0.836
10
0.75 1.0
11
0.8 0.836
12
0.9 0.5
13
1.0 0.0
Das speichere ich unter z.b. dem Namen firdata.txt ab.
(Da geht dann die Frequenz nicht von z.b. 0..20kHz sondern von 0..1,
damit das dann 0..20kHz "in Echt" ergibt, muesstest du dein Signal mit
40KHz abtasten und filtern)
Dann rufe ich GNU Octave auf, dort tipper ich dann mal z.b. folgende
Befehle, um aus den Daten aus dem Textfile ein FIR zu basteln (Ist
wahrscheinlich nicht die beste Option, aber so ungefaehr koennts gehen):
1
load firdata.txt
2
F=firdata(:,1)
3
H=firdata(:,2)
4
B=fir2(32, F, H)
5
freqz(B)
Der Frequenzgang schaut dann aus, wie auf dem Bild.
Die Koeffizienten waeren dann in B und sehen so aus:
0.000041516
-0.000120039
-0.000689309
0.000847593
-0.002759575
0.001142413
-0.003202075
-0.002525494
-0.004392716
-0.000398240
-0.023356514
0.020245775
-0.064699116
0.039641247
-0.113566500
-0.074860852
0.567899857
-0.074860852
-0.113566500
0.039641247
-0.064699116
0.020245775
-0.023356514
-0.000398240
-0.004392716
-0.002525494
-0.003202075
0.001142413
-0.002759575
0.000847593
-0.000689309
-0.000120039
0.000041516
Gruss
WK