Hilberttransformation
-
Moin,
ich möchte zu einer reellen Zeitreihe, vorhanden in einem vector<double>, die komplexe Erweiterung, sprich die Hilberttransformierte bilden. Das ganze will ich im Frequenzbereich veranstalten. Die FFT habe ich gebildet (nach Numerical Recipes), sie liegt also in komplexer Form vor, und nun? Wie programmiere ich denn nun H {X {i omega } } = - i * sgn(omega) * X {i omega } ?
Bin für jeden Hinweis dankbar.
Gruß,
Weilor
-
-
Danke für die Antwort, aber was eine Hilberttrafo macht und wie sie aussieht, ist mir schon klar. Was ich bräuchte, wäre mal ein Stück Code, wie ich die obige Rechnung ausführe.
Sprich, wie programmiere ich c * (-i) * sgn(omega), wenn c aus vector<double> realteil und vector<double> imaginaerteil besteht?Gruß,
Weilor
-
http://www.willemer.de/informatik/cpp/mathlib.htm
// suche nach "Komplexe Zahlen"
da findest hoffentlich die ersten infos, die du suchst
-
Wenn du die Komplexe Zahl z=a + j*b hast ( a(0..N) und b(0..N) sind das Ergebnis deiner FFT ) und diese mit j multipliziert:
j * (a+jb)
= a*j + j*jb
= a*j - b= -b + a*j
Wie du siehst musst du bei der Mutilplikation mit j nur Real und Imaginärteil vertauschen und den neuen Realteil mit -1 multiplizieren.
Du kannst dir die Multiplikation mit j also als eine Rotation des Vektor [a,b] um 90° in der Gaußschen Zahlenebene vorstellen. => [-b,a]
-------------------------------------------------
Versuche auch grad die Hilberttransformation durchzuführen, d.h.
Signal x(t) -> FFT -> Elemente ( 0..N/2 ) mit j multiplizieren ) -> iFFT = x_(t)
Die Daten x(t) werden von meinem Programm in Echtzeit von einer IO-Karte eingelesen.
1.Frage: Fensterbreite der FFT
Muss diese mindestens so groß sein, dass eine voll Schwingung der geringsten Frequenz, die analysiert werden soll, hineinpasst?2. Frage: Ich will die Fenster überlappen lassen.
Um die spektralen Eigenschaften zu verbessern, verwende ich Hamming bzw Hanningfenster.
Also aktueller Teil von x(t) im Fenster = y(t)
Multiplikation mit Fensterfunktion: z(t) = y(t) * Hamming bzw. Hanning
FFT durchführen: Z(jw) = FFT ( z(t) )
Signal um 90° verschieben
Z90(jw) = j * Z(jw)Und Zurücktransformieren in Zeitbereich
z90(t) = iFFT (Z90(jw ))Allerdings weiss ich nicht, wie ich das Ergebnis der iFFT nun wieder zu einem Zeitsignal zusammensetze, da sich die Fenster ja überlappt haben!?!
PS:
Die Phasenverschiebung ginge auch mit einer Faltung im Zeitbereich, dauert für meine Echtzeitanwendung allerdings zu lange.
-
Danke für deine Antwort.
Habs jetzt hingekriegt, allerdings verlangt die Hilbertrafo Multiplikation mit (-i). Dann kriegst du in der komplexen Zahlenebene auch eine Verschiebung um +90° (im mathematischen Sinne) anschaulich hin.
Hatte gestern einen leichten Grippeanfall und stand etwas aufem Schlauch...
Faltung im Zeitbereich hatte ich schon realisiert. Dauer der Berechnung für meine Zeitreihe: ca 2,5s. Bildung der FFT und wieder zurück: weniger als 100ms... Hat sich gelohnt, würde ich sagen.1.Frage: Fensterbreite der FFT
Muss diese mindestens so groß sein, dass eine voll Schwingung der geringsten Frequenz, die analysiert werden soll, hineinpasst?Die Fensterbreite bestimmt nur die Genauigkeit des Spektrums, je höher, desto genauer (s. leakage).
2. Frage: Ich will die Fenster überlappen lassen.Um die spektralen Eigenschaften zu verbessern...
Wenn du das Spektrum jetzt wieder zurücktransformierst, kriegst du imho irgendwas idealisiertes, aber sicherlich etwas, was mit deinem Ausgangssignal nur noch wenig zu tun hat.
Beste Grüße,
Weilor
-
100 ms? Bei welcher Fenstergröße?
Lad dir mal die FFT Bibliothek von www.fftw.org runter! Extrem hoch optimiert...
-
Okay, 75 Hilberttrafos in deutlich weniger als 1s, schnell genug auf jeden Fall.
-
Hat jemand von euch die Hilberttransformation schon einmal "stückchenweise" berechnet? Komme da nicht ganz klar.
Ich unterteile mein Signal in Fenster a nData Samples. ( z.B: 50 ). Davon berechne ich die FFT mit einer Breite von nFFT=1024. D.h ich fülle 1024-50=974 Nullen ein ( ZeroPadding ).
Jetzt die Hilbertrafo mit H(i) = -j * sgn (nFFT/2 - i ).
Davon iFFT. Die Ergebnisse der iFFT muss ich nun wieder zu einem Signal zusammensetzen. ( Overlap - Add - Verfahren ).
AlsoOut(0..1023)=Out(0..1023) + iFFT( 0..1023 )
Beim nächsten Fenster dann....
Out(nData..nData+1023)=Out(nData..nData+1023) + iFFT( 0..1023 )
usw.Im dem resultierenen HilbertSignal sind jedoch Sprungstellen in der Breite des Fensters drin. Ich vermute ma, das liegt daran, dass ich als Fenster ein Rechteckfenster verwendet habe. Wenn ich aber eine Fensterfunktion verwende, ist mir nicht klar, wie ich anschließend aus den Einzel-iFFTs mein Signal wieder zusammensetzen soll?!?