Ich habe ein einfaches einpoliges Tiefpassfilter (zur Parameterglättung), das durch die folgende Formel erklärt werden kann:
Die von mir verwendete Architektur hat Zugriff auf SIMD-Befehle (Single-Instruction, Multiple-Data), mit denen mehrere vektorisierte Berechnungen parallel ausgeführt werden können. Ich möchte diese Funktion nutzen, bin mir aber nicht sicher, wie ich das für einen rekursiven Filter wie diesen machen soll. Das Problem ist, dass jede Berechnung ein vorheriges Ergebnis benötigt.
filters
infinite-impulse-response
user1132968
quelle
quelle
Antworten:
Unter der Annahme, dass Sie Vektoroperationen Elemente gleichzeitig ausführen , können Sie die Differenzgleichung für den einfachen einpoligen Filter ziemlich einfach um den Faktor M abrollen. Angenommen, Sie haben bereits alle Ausgaben bis zu y [ n ] berechnet . Dann können Sie die folgenden wie folgt berechnen: y [ n + 1 ]M. M. y[ n ]
Im Allgemeinen können Sie schreiben als:y[ n + k ]
Für jeden Abtastindex sieht dies wie ein FIR-Filter mit k + 1 Abgriffen aus: Ein Abgriff multipliziert den letzten Filterausgang y [ n ] und die anderen k Abgriffe multiplizieren die Filtereingänge x [ n + 1 ] , … , x [ n + k ] . Das Schöne ist, dass die für alle diese Abgriffe verwendeten Koeffizienten vorberechnet werden können, sodass Sie den rekursiven Filter in M M + 1 abrollen könnenn + k k + 1 y[ n ] k x [ n + 1 ] , … , x [ n + k ] M. M.+ 1 -tippen Sie auf parallele nicht rekursive Filter (diese Filter berechnen die Ausgangsabtastwerte ) und aktualisieren den Rückkopplungsterm alle M Ausgangsabtastwerte. Wenn also eine Anfangsbedingung y [ n ] gegeben ist (die als die letzte Ausgabe angenommen wird, die bei der vorherigen vektorisierten Iteration berechnet wurde), können Sie die nächsten M Ausgaben parallel berechnen .y[ n + 1 ] , … , y[ n + M.]] M. y[ n ] M.
Dieser Ansatz weist einige Einschränkungen auf:
quelle
Im Allgemeinen können Sie nur völlig unabhängige Berechnungssätze vektorisieren. In Ihrem IIR-Tiefpass ist jedoch jede Ausgabe von einer anderen abhängig (mit Ausnahme der ersten), sodass eine Vektorisierung nicht möglich ist.
Wenn Ihre Variable "a" groß genug ist, dass (1-a) ^ n schnell unter das gewünschte Grundrauschen oder den zulässigen Fehler abfällt, können Sie Ihre IIR durch eine kurze FIR-Filter-Näherung ersetzen und stattdessen diese Faltung vektorisieren. Aber das wird wahrscheinlich nicht schneller sein.
quelle
Sie können dies nur dann wirklich effektiv vektorisieren, wenn Sie mehr als ein Signal haben, auf das Sie denselben Filter anwenden möchten. Wenn es sich beispielsweise um ein Stereo-Audiosignal handelt, können Sie den linken und rechten Kanal parallel verarbeiten. Vier oder acht Kanäle parallel wären natürlich noch besser.
quelle
Wie wäre es, wenn Sie Gleichungen auf 4 Schritte erweitern und die Matrixmultiplikation verwenden? a ist konstant, so dass eine Matrix vorberechnet werden kann
quelle
Am effizientesten ist es, die Filterung mehrerer unabhängiger Streams parallel zu vektorisieren.
Wenn Sie nur einen einzigen langen Stream haben, können Sie den Stream auch in mehrere überlappende Abschnitte aufteilen und diese filtern, als wären sie unabhängige Streams.
Sie möchten eine Überlappung, da die ersten Stichproben jedes Streams falsch sind. Die Anzahl der zu verwerfenden Proben hängt vom Wert von a und der gewünschten Genauigkeit ab. Sie sollten ungefähr n Proben verwerfen, bei denen (1 / a) (1-a) ** n <eps ist, damit das Ergebnis auf eps * max (| x [i] |) genau ist.
Wenn beispielsweise a = 0,1 ist, ist der durch (1 / a) (1-a) ^ n verursachte Fehler in 128 Abtastwerten kleiner als das LSB in einer 16-Bit-Ganzzahl, während Sie für a = 0,9 nur verwerfen müssten etwa 6 Proben.
quelle