Diskrete Fouriertransformation (DFT)

  • Aufgrund einer Shoutbox-Diskussion letzens mit Mars fiel auf, dass eine diskrete Fouriertransformation wohl noch nicht wirklich groß in AutoIt geschrieben wurde.

    Also hab ich mich mal kurz rangesetzt.

    Im Grunde ist es nichts aufregendes sondern einfach eine klassische DFT.
    Vor allem ist es keine FFT. Daher keine Performancewunder erwarten.
    Evtl. bastel ich da nochmal eine bei Gelegenheit dazu (ist bloß immer schwierig mit dem Nachdenken hierzu, da AutoIt keinen nativen Datentyp für komplexe Zahlen hat).

    Ansonsten hier alles inkl. Beispiel:

  • Vielen Dank, jetzt wo ich die Lösung sehe, sehe ich auch meine Fehler :D

    Mit der Abtastfrequenz kann aber etwas nicht stimmen (glaube ich). Die taucht im Code nur bei "$aRet[$k][$eFrequency] = $k * $nFs / $N" auf, hat aber keinen Einfluss auf die anderen Werte (oder ich habe da etwas missverstanden, was auch gut sein kann).

    lg

    M

  • Die hat auch sonst keinen Einfluss.

    Im Grunde ist sie nur ein Skalierungsfaktor für die Ausgabefrequenz und Periodenlänge.

    Würde man z.B. stündlich einen Messwert nehmen und möchte am Ende aber die Periodenlänge in Tagen als Einheit haben, dann müsste man $nFs auf 1/24 (oder doch 24? :/ ) setzen.

  • Achso, ich glaube ich habe den Unterschied zwischen FT und DFT immernoch nicht verstanden.

    Was ich dachte ist folgendes: Die Abtastfrequenz gibt an welche Frequenzen im Array überprüft werden, also dass ich z.B. soetwas wie "alle Frequenzen von 0 bis 5 in 0.1er Schritten" ablaufen kann. Vermutlich ergibt das im Grenzwert wieder eine kontinuierliche FT. Das muss ich wohl nachlesen :/

    Ein Glück, dass ich mit Signalverarbeitung nichts am Hut habe, sonst hätte man mich für so viel Blödheit bestimmt schon verprügelt :part:

    lg

    M

  • Eine FT ist kontinuierlich. Also man hat stetige ("analoge") Wellenformen idealerweise bereits als Funktion vorliegen, welche man analytisch in den Frequenzraum transformieren kann.

    Das ist aber in der Regel nicht praxisrelevant, da man eher eine Ansammlung von Messwerten in periodischen Abständen vom Signal vorliegen hat ( = "diskrete" Werte -> man braucht nun eine DFT).

    Der Abstand dieser Messwerte ist die Abtastfrequenz (bzw. deren Reziproke).

    Wichtig ist die Abtastfrequenz vor allem bei der Frage bis zu welcher Frequenz man eigentlich das Signal auflösen/analysieren kann.
    Es leuchtet ein, dass man hochfrequente Signale nicht detektieren kann wenn die Abtastfrequenz niedrig ist.

    Die Antwort ist daher: Die Nyquist-Frequenz = Abtastfrequenz / 2 (deswegen läuft das Array bei mir nur bis $k = $N/2)

    Spannender wird es z.B. dann wenn der Abstand der Messwerte nicht gleich ist, sondern man Messwerte an verschiedenen Zeitpunkten hat.
    Dafür gibt es dann aber auch spezielle DFTs die damit umgehen können.

  • Was ich in der SB gepostet hatte: https://imgur.com/a/wrzZjAa

    Die Version hier (nach einigen kleinen Anpassungen) funktioniert schonmal deutlich besser. Peaks in den angeschauten Frequenzen sind sauber, deutlich und ohne übertriebenes Überschwingen.

    Inputdaten (mit dem bloßen Auge erkennt man hier höchstens, dass da "irgendwas schnell schwingt", die 2te Schwingung sieht man selbst mit scharfem Blick nicht):

    amplitude der DFT (angepasst, sodass man über Frequenzbereiche gezielt drüberlaufen kann, wobei "eine Arraylänge" immer 2PI entspricht)

    (die X-Achse ist etwas doof beschriftet, der erste Peak ist NICHT bei 0.85, sondern tatsächlich etwa bei 1.0, also da wo er hingehört)

    Danke nochmal für die Hilfe :thumbup:

    lg

    M

  • auch wenn ich nicht weiß was zu was genau das gut sein soll

    Das geht am besten mit einem einfachen Beispiel zu erklären.

    Vorher aber erst einmal die etwas trockenere Beschreibung:
    Irgendein beliebiges Signal - also im Grunde auch nur eine Funktion f(x) (meist ist x da die Zeit) - besteht vornehmlich aus überlagerten periodischen Co-/sinus Schwingungen. Beispiel: Musik - da sind ganz viele überlagerte Schwingungen drin.
    Wenn man sich das Signal grafisch darstellt, kann man mit scharfen Auge aber schlecht ermitteln, welche Töne nun genau gespielt wurden.

    Daher gibt es die Fourier-Transformation. Diese nimmt das Signal und "transformiert es in den Frequenzraum".
    Das Ergebnis hiervon ist nichts anderes, als dass es eine Funktion A(f) erzeugt - eine Funktion die die zugehörige Amplitude A für jede Frequenz f beinhaltet (siehe dem schönen Beispielbild über mir von Mars). Man kann also ermitteln, welche Frequenzen/Perioden für ein Signal maßgeblich sind und welche nicht.

    Anderes Beispiel: Wir sind doof und wissen nicht wie schnell sich die Erde um sich und die Sonne dreht. Wir möchten das aber dennoch wissen.
    Wir wissen zumindest, dass die Temperatur damit irgendwie im Zusammenhang steht (Winter/Sommer, Tag/Nacht).
    Also messen wir 20 Jahre lang jede Stunde die Temperatur vor unserem Haus.

    Wenn man sich diese Zeitreihe dann mal in einem Diagramm ansieht, sieht man schon deutlich, dass der Temperaturverlauf irgendwie periodisch verläuft.

    Lassen wir darüber eine Fouriertransformation laufen bekommen wir dann zwei deutliche Ausschläge im Ergebnis:
    Einmal bei 24h und einmal bei 8766h (= 365,25 Tage).
    Wir können also anhand der Daten mit der Fouriertransformation ableiten, dass ein Tag 24h dauert und die Erde 365,25 Tage benötigt um die Erde zu umrunden.
    Diese sind die beiden wesentlichen periodischen Einflüsse auf den Temperaturverlauf.

    Aber vielleicht finden wir ja noch viel mehr heraus? - Denn wirklich spannend sind die kleineren Nebenpeaks. Z.B. könnte es ja sein, dass wir auch einen kleinen Peak rund um die Periodenlänge 11 Jahre sehen. Dann würde man schauen, was diese Periode denn verursacht hat und käme z.B. auf den Sonnenzyklus.

    So kann man mit der Fouriertransformation Zusammenhänge aufdecken die man aus den direkten Ausgangsdaten selbst nicht herausgelesen hätte.

    Mars

    Plottest du das direkt aus AutoIt heraus? Falls ja - wie?

    Einmal editiert, zuletzt von AspirinJunkie (10. Juni 2022 um 07:28)

  • Plottest du das direkt aus AutoIt heraus? Falls ja - wie?

    Da muss ich dich direkt vorwarnen, das folgende ist keine UDF die es in die Öffentlichkeit geschafft hat. Sie ist in keinem guten Zustand und jedes Mal, wenn ich etwas plotten will baue ich genau die funktion die ich gerade brauche ein^^

    Die Funktion gibt es eigentlich nur, weil ich im Stil von _ArrayDisplay "schnell und einfach" eine Funktion haben wollte um Arrays anzusehen. Es gibt (auch hier im Forum) UDFs die Daten plotten können, ich schätze, wenn man es ernsthaft angeht sollte man mit so einer UDF eine Anzeige basteln...

    lg

    M