Warum müssen wir während der Faltung eines Signals die Impulsantwort während des Prozesses umdrehen?
Warum müssen wir während der Faltung eines Signals die Impulsantwort während des Prozesses umdrehen?
Antworten:
Angepasst von einer Antwort auf eine andere Frage (wie in einem Kommentar erwähnt) in der Hoffnung, dass diese Frage nicht wiederholt vom Community Wiki als eine der Top-Fragen geworfen wird ....
Es gibt kein "Umkehren" der Impulsantwort durch ein lineares (zeitinvariantes) System. Die Ausgabe eines linearen zeitinvarianten Systems ist die Summe der skalierten und zeitverzögerten Versionen der Impulsantwort, nicht der "gekippten" Impulsantwort.
Wir zerlegen das Eingangssignal in eine Summe skalierter Einheitsimpulssignale. Die Systemantwort auf das Einheitsimpulssignal ist die Impulsantwort oder Impulsantwort
Ähnlich ist die einzige Eingangswert oder erstellt x [ 1 ] ( ⋯ , 0 , 0 , 0 , 1 , 0 , ⋯ ) = ⋯ 0 , 0 , 0 , x [ 1 ] , 0 , ⋯ erzeugt eine Antwort 0 , x [ 1 ] h [ 0 ] , x [ 1
Was ist die Ausgabe zum Zeitpunkt ?
Hier ist ein C / C ++ - Beispiel, das zeigt, dass die Faltung ohne umgekehrte Verwendung der Impulsantwort durchgeführt werden kann. Wenn Sie die convolve_scatter()
Funktion überprüfen , wird nirgendwo eine Variable negiert. Dies ist eine Streuungsfaltung, bei der jede Eingangsabtastung zu mehreren Ausgangsabtastungen im Speicher gestreut (summiert) wird, wobei Gewichtungen verwendet werden, die durch die Impulsantwort gegeben sind. Dies ist verschwenderisch, da die Ausgabebeispiele mehrmals gelesen und beschrieben werden müssen.
Normalerweise Faltung wird als getan Sammeln Faltung, wie in convolve_gather()
. Bei diesem Verfahren wird jede Ausgangsabtastung separat gebildet, indem Eingangsabtastungen mit der umgekehrten Impulsantwort als Gewichtungen zu diesen gesammelt (summiert) werden. Das Ausgabesample befindet sich in einem Prozessorregister, das währenddessen als Akkumulator verwendet wird. Dies ist normalerweise die Methode der Wahl, da für jedes gefilterte Sample nur ein Speicherschreibvorgang ausgeführt wird. Es gibt jetzt mehr Speicherlesevorgänge der Eingabe, aber nur so viele, wie Speicherlesevorgänge der Ausgabe bei der Streumethode vorhanden waren.
#include <stdio.h>
const int Nx = 5;
const int x[Nx] = {1, 0, 0, 0, 2};
const int Ny = 3;
const int y[Ny] = {1, 2, 3};
const int Nz = Nx+Ny-1;
int z[Nz];
void convolve_scatter() { // z = x conv y
for (int k = 0; k < Nz; k++) {
z[k] = 0;
}
for (int n = 0; n < Nx; n++) {
for (int m = 0; m < Ny; m++) {
z[n+m] += x[n]*y[m]; // No IR reversal
}
}
}
void convolve_gather() { // z = x conv y
for (int k = 0; k < Nz; k++) {
int accu = 0;
for (int m = 0; m < Ny; m++) {
int n = k+m - Ny + 1;
if (n >= 0 && n < Nx) {
accu += x[n]*y[Ny-m-1]; // IR reversed here
}
}
z[k] = accu;
}
}
void print() {
for (int k = 0; k < Nz; k++) {
printf("%d ", z[k]);
}
printf("\n");
}
int main() {
convolve_scatter();
print();
convolve_gather();
print();
}
Es faltet die Sequenzen zusammen:
1 0 0 0 2
1 2 3
und mit beiden Faltungsmethoden Ausgaben:
1 2 3 0 2 4 6
Ich kann mir niemanden vorstellen, der die Streumethode verwendet, es sei denn, der Filter variiert zeitlich. In diesem Fall führen die beiden Methoden zu unterschiedlichen Ergebnissen, und eine ist möglicherweise geeigneter.
Es wird nur für die punktweise Berechnung "umgedreht".
@Dilip erklärt, was das Faltungsintegral / die Faltungssummation darstellt. Um jedoch zu erklären, warum eine der beiden Eingabefunktionen (häufig h(t)
) zu Berechnungszwecken gekippt wird, betrachten Sie ein zeitdiskretes System mit Eingabe x[n]
und Impulsantwort h[n]
:
Sie könnten Ihre Eingabefunktion übernehmen x[n]
und für jede Nicht-Null * -Abtastung x[n]
die skalierte Impulsantwort von Abtastung n
und weiter berechnen, bis die zeitversetzte h[n]
Verzögerung auf Null zurückgeht (unter der Annahme einer Kausalität h[n]
). Dies würde kein 'Umdrehen' (oder genauer 'Zeitumkehr') von entweder x[n]
oder beinhalten h[n]
. Am Ende müssten Sie jedoch alle diese skalierten + verschobenen "Echos" der Impulsantwort für jede Nicht-Null addieren / überlagern x[n]
.
x[0]
k
h[n]
x[n]
, was ist x[0]h[0]
. Inkrementieren k
um eins verschiebt sich dann h[n]
um einen Zeitschritt nach rechts, sodass der h[n]
zweite Eintrag ( h[1]
) der Zeitumkehrung nun darauf liegt x[0]
und darauf wartet, multipliziert zu werden. Dies ergibt zum gewünschten x[0]h[1]
Zeitpunkt den gewünschten Beitrag n=1
, genau wie dies bei der vorherigen Methode der Fall gewesen wäre.x[n]
h[n]
y[n]
Am Index c [n] ist die Faltung von a [n] und b [n] so, dass:
"c [n] ist eine Summe aller Produkte (a [k] b [m]), so dass m + k = n," also m = n - k oder k = n - m, was bedeutet, dass eine der Sequenzen muss gekippt werden.
Warum verhält sich Faltung überhaupt so? Wegen seiner Verbindung mit multiplizierenden Polynomen.
Die Multiplikation zweier Polynome ergibt ein neues Polynom mit Koeffizienten. Die Koeffizienten des Produktpolynoms definieren den Vorgang der Faltung. In der Signalverarbeitung sind Transferfunktionen - Laplace-Transformationen oder Z-Transformationen - diese Polynome, wobei jeder Koeffizient einer anderen Zeitverzögerung entspricht. Die Übereinstimmung der Koeffizienten des Produkts und der Multiplikanden führt zu der Tatsache, dass "Multiplikation in einer Darstellung der Faltung in der transformierten Darstellung entspricht".
Während der Faltung muss überhaupt kein "Flip" der Impulsantwort auftreten ...
Wenn Sie jedoch eine Phasenänderung verhindern möchten, können Sie ein Signal mit einer Impulsantwort falten und dann die Impulsantwort umkehren und erneut falten, um die Phaseneffekte aufzuheben.
Bei der Offline-Verarbeitung können Sie das Signal nach der ersten Faltung genauso einfach umkehren, um zu derselben Schlussfolgerung zu gelangen (wie aus den Kommentaren hervorgeht).