Frage

Es fällt mir schwer zu verstehen, was ein einfaches Konzept sein sollte.Ich habe in MATLAB einen Vektor konstruiert, der reell und symmetrisch ist.Wenn ich die FFT in MATLAB durchführe, hat das Ergebnis einen signifikanten Imaginäranteil, obwohl die Symmetrieregeln der Fourier-Transformation besagen, dass die FT einer realen symmetrischen Funktion ebenfalls reell und symmetrisch sein sollte.Mein Beispielcode:

N = 1 + 2^8;
k = linspace(-1,1,N);

V = exp(-abs(k));

Vf1 = fft(fftshift(V));
Vf2 = fft(ifftshift(V));
Vf3 = ifft(fftshift(V));
Vf4 = ifft(ifftshift(V));
Vf5 = fft(V);
Vf6 = ifft(V);

disp([isreal(Vf1) isreal(Vf2) isreal(Vf3) isreal(Vf4) isreal(Vf5) isreal(Vf6)])

Ergebnis:

0 0 0 0 0 0

Keine Kombinationen von (i)fft oder (i)fftshift ergeben einen echten symmetrischen Vektor.Ich habe es sowohl mit geradem als auch mit ungeradem N versucht (N = 2^8 vs. N = 1+2^8).

Ich habe versucht, es mir anzusehen k+flip(k) und es gibt einige Residuen in der Größenordnung von eps(1), aber die Residuen sind auch symmetrisch und der Imaginärteil der FFT ergibt keinen Fuzz in der Größenordnung von eps(1), sondern eher mit einer Größe, die mit dem Realteil vergleichbar ist.

Was übersehe ich so offensichtlich?

Was mir völlig offensichtlich entgangen ist:

Die FFT ist kein Integral über der ganze Raum, Es wird also von einem periodischen Signal ausgegangen.Oben dupliziere ich den letzten Punkt in der Periode, in der ich eine gerade Zahl wähle N, und daher gibt es keine Möglichkeit, es zu verschieben, um die Nullfrequenz an den Anfang zu setzen, ohne eine gebrochene Indizierung, die nicht existiert.

Ein Wort zu meiner Wahl k.Es ist nicht willkürlich.Das eigentliche Problem, das ich zu lösen versuche, besteht darin, ein Modell-FTIR-Interferogramm zu erstellen, das ich dann per FFT durchführe, um ein Spektrum zu erhalten. k ist die Distanz, die das Interferometer zurücklegt und die in Wellenzahlen in Frequenz umgewandelt wird.Im eigentlichen Problem wird es verschiedene Skalierungsfaktoren geben, sodass die erzeugende Funktion V physikalisch sinnvolle Zahlen liefert.

War es hilfreich?

Lösung

@yvon ist absolut mit seinem Kommentar zur Symmetrie. Ihr Eingangssignal sieht symmetrisch aus, aber es ist nicht daran, dass Symmetrie mit dem Ursprung 0 zusammenhängt. Die Verwendung eines -Linspace in MATLAB zum Erstellen von Signalen ist meistens eine schlechte Wahl. Der Versuch, die Ergebnisse mit FFTShift zu reparieren, ist auch eine schlechte Idee.

Verwenden Sie stattdessen:

generasacodicetagpre.

Und Sie erhalten das Ergebnis, das Sie erwarten. Der imaginäre Teil der transformierten Werte ist jedoch nicht völlig null. Es gibt ein numerisches Geräusch.

generasacodicetagpre.

Antwort auf Yvons Frage:

Warum? >> n= 1 + 2 ^ 4 n= 17 >> x= LinSpace (-1,1, n) x= -1.0000 -0.8750 -0.7500 -0.6250 -0.5000 -0.3750 -0.2500 -0,1250 0 0.1250 0,2500 0,3750 0.5000 0,6250 0,7500 0.8750 1.0000 >> y= 2 * (0: n-1) / n-1 y= -1.0000 -0.8824 -0.7647 -0.8471 -0.7647 -0.4118 -0.2941 -0.1765 -0.2941 -0.1765 -0.0588 0.0588 0,1765 0.2941 0.0588 0.1765 0,6471 0,7647 0.8824 - Yvon 1

Ihr Beispiel ist keine symmetrische (auch) Funktion, sondern eine antisymmetrische (ungerade) Funktion. Dies macht jedoch keinen Unterschied.

für eine antisymmetrische Funktion der Länge n Die folgende Anweisung trifft zu:

generasacodicetagpre.

Der Index, den ich von 0 bis N-1 verläuft.

Lassen Sie uns sehen, dass er mit i= 2 passiert. Denken Sie daran, dass die Zählung mit 0 beginnt und endet mit 16.

generasacodicetagpre.

Das Problem ist, dass der Ursprung von Matlab-Vektoren um 1 beginnt. MODULO (periodische) Vektoren beginnen mit dem Ursprung 0. Dieser Unterschied führt zu vielen Missverständnissen.

eine andere Art der Erklärung, warum Linspace (-1, + 1, n) nicht korrekt ist:

Stellen Sie sich vor, Sie haben einen Vektor, der eine einzelne Periode einer periodischen Funktion hält, Zum Beispiel eine Cosinus-Funktion. Diese einzelne Periode ist eine unendliche Anzahl von Perioden. Der erste Wert Ihres Cosinus-Vektors darf nicht der letzte Wert Ihres Vektors sein. Genau das ist jedoch das, was Linspace (-1, + 1, n) tut. Dies führt dazu, dass der letzte Wert der Periode 1 der letzte Wert von 1 derselbe Wert wie das erste Beispiel der folgenden Periode 2 ist. Dies ist nicht das, was Sie wollen. Um diesen Fehler zu vermeiden, verwenden Sie t= 2 * (0: N-1) / N - 1. Die Entfernung t [i + 1] -t [i] ist 2 / n und der letzte Wert muss t [n-1 sein ]= 1 - 2 / n und nicht 1.

Antwort auf Yvons zweiter Kommentar

Was auch immer Sie in einen Eingabe-Vektor eines DFT / FFT angeben, durch Theorie, dass er als periodische Funktion interpretiert wird. Aber das ist nicht der Punkt.

dft führt eine Integration durch.

generasacodicetagpre.

Der erste Wert x (k= 0) beschreibt die Amplitude des ersten Integrationsintervalls der Länge 1 / n. Der zweite Wert x (k= 1) beschreibt die Amplitude des zweiten Integrationsintervalls der Länge 1 / n. Und so weiter.

Das sehr letzte Integrationsintervall der symmetrischen Funktion endet mit demselben Wert wie das erste Beispiel. Dies bedeutet, dass der Startpunkt des letzten Integrationsintervalls k= n-1= 1-1 / n ist. Ihr Eingabevektor hält die Startpunkte der Integrationsintervalle.

Daher ist der letzte Symmetrie-Punkt K= N ein Punkt der Funktion, es ist jedoch kein Startpunkt eines Integrationsintervalls, und es ist also kein Mitglied des Eingabevektors.

Andere Tipps

Es ist

Vf = fftshift(fft(ifftshift(V)));

Das heißt, Sie brauchen ifftshift im Zeitbereich, sodass Abtastwerte als solche einer symmetrischen Funktion interpretiert werden, und dann fftshift im Frequenzbereich, um die Symmetrie wieder deutlich zu machen.

Dies funktioniert nur für N seltsam.Für N Selbst das Konzept einer symmetrischen Funktion ergibt keinen Sinn:Es gibt keine Möglichkeit, das Signal so zu verschieben, dass es symmetrisch zum Ursprung ist (der Ursprung müsste „zwischen zwei Abtastwerten“ liegen, was unmöglich ist).

Zu deinem Beispiel V, gibt der obige Code Vf real und symmetrisch.Die folgende Abbildung wurde mit generiert semilogy(Vf), sodass sowohl kleine als auch große Werte sichtbar sind.(Natürlich können Sie die horizontale Achse so ändern, dass das Diagramm wie vorgesehen bei der Frequenz 0 zentriert ist;aber trotzdem wird der Graph als symmetrisch angesehen.)

enter image description here

Sie haben ein Problem bei der Umsetzung des Konzepts „Symmetrie“.Eine rein reelle, gerade (oder „symmetrische“) Funktion hat eine Fourier-Transformationsfunktion, die ebenfalls reell und gerade ist.„Gerade“ ist die Symmetrie in Bezug auf die y-Achse oder die t=0-Linie.

Bei der Implementierung eines Signals in Matlab beginnt man jedoch immer bei t=0.Das heißt, es gibt keine Möglichkeit, das Signal vor dem Ursprung der Zeit zu „definieren“.

Eine längere Suche im Internet führte mich zu folgendem Ergebnis:Korrekte Verwendung von fftshift und ifftshift bei der Eingabe von fft und ifft.

Wie Luis es getan hat wies darauf hin, du musst Leistung erbringen ifftshift bevor das Signal eingespeist wird fft.Der Grund wurde nie in Matlab dokumentiert, sondern nur in diesem Thread.Aus historischen Gründen wird AND ausgegeben Eingänge von fft Und ifft werden getauscht.Das heißt, statt bestellt bei -N/2 Zu N/2-1 (die natürliche Ordnung), nach der das Signal im Zeit- oder Frequenzbereich geordnet ist 0 Zu N/2-1 und dann -N/2 Zu -1.Das heißt, die richtig Weg zum Codieren ist fft( ifftshift(V) ), Aber die meisten Leute ignorieren dies meistens.Der Grund dafür, dass es stillschweigend ignoriert wird, anstatt große Probleme aufzuwerfen, liegt darin, dass die meisten Bedenken hinsichtlich der Amplitude des Signals und nicht der Phase geäußert wurden.Da die zirkuläre Verschiebung keinen Einfluss auf das Amplitudenspektrum hat, ist dies kein Problem (selbst für die Matlab-Leute, die die Dokumentationen geschrieben haben).

Um die Amplitudengleichheit zu überprüfen:

Vf2 = fft(ifftshift(V));
Vf5 = fft(V);
Va2 = abs(fftshift(Vf2));
Va5 = abs(fftshift(Vf5));

>> min(abs(Va2-Va5)<1e-10)

ans =

     1

Um zu sehen, wie sehr die Phase falsch ist -

Vp2 = angle(fftshift(Vf2));
Vp5 = angle(fftshift(Vf5));

Wie auch immer, wie ich im Kommentar geschrieben habe, gibt es nach dem Kopieren und Einfügen Ihres Codes in ein neues und sauberes Matlab Folgendes 0 1 0 1 0 0.

Zu Ihrer Frage zu N=gerade und N=ungerade: Meiner Meinung nach ist das Signal bei N=gerade nicht symmetrisch, da es auf beiden Seiten des Zeitursprungs eine ungleiche Anzahl von Punkten gibt.

Fügen Sie einfach die folgende Zeile hinzu, nachdem "k= gelinspace (-1,1, n);"

generasacodicetagpre.

Es entfernt das letzte Element des Arrays.Dies ist definiert als symmetrisches Array.

Betrachten Sie auch, dass Isreal (Komplex (1,0)) falsch ist !!! Die Isreal-Funktion prüft einfach auf das Speicherspeicherformat.So ist 1 + 0i im obigen Beispiel nicht echt.

Sie haben Ihre Funktion definieren, um nach echten Zahlen zu suchen (so)

generasacodicetagpre.

Endlich sollte Ihr Quellcode so etwas werden:

generasacodicetagpre.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top