FFT für Anfänger

Gast #2365510
Lesenswert?

Hallo zusammen,

Ich möchte auch eine FFT in c++ programmieren. Hierbei kommt es mir erst
mal nicht auf die Geschwindigkeit an. Ich habe versucht soviel wie
möglich zu lesen, jedoch beschreiben die Meisten das ganze immer so
kompliziert, das es keiner verstehen kann, daher versuche ich es über
diesen Weg.

Ich möchte für den Anfang ein FFT mit 150 Punkten erstellen.ich habe 
schöne  die Funktionswerte  in einem Array geschrieben.

Kann mir vielleicht jemand anhand dieses kleinen Beispiels vorrechnen 
oder mal erklären
wie ich die FFT  in c++ implementieren oder kennt man ein Classe ,das 
mir  weiterhilft.

bin für  jede Tipps  sehr Dankbar.


Grüsse

Sera
Gast #2365544
Lesenswert?

Hallo,
die FFT ist die schnelle Variante der DFT. Das Ergebnis ist (so glaube 
ich) das gleiche.

DFT:
Du hast Deine Werte in einem Array.
Erzeuge jetzt einfach ein 2. Array und fülle das mit einem Sinus mit zum 
Beispiel 1kHz.

Jetzt gehst Du mit einer Schleife über alle Werte und multiplizierst 
alle Werte aus dem 1. Array mit denen aus dem 2. und bildest die Summe.

Also a[0]*b[0] + a[1]*b[1] + ... + a[150]*b[150]
Das Ergebnis (/150) ist der 1kHz Frequenzanteil.

Allerdings nur der, der in Phase mit dem Sinus ist. Damit die Phase 
keine Rolle spielt, machst Du das gleiche noch mit dem Cosinus und 
bildest den quadratischen Mittelwert aus dem 1kHz Sinusergebnis und dem 
1kHz Cosinusergebnis, also wurzel(s*s + c*c)

Und jetzt das alles wiederholen bei der nächsten Frequenz, zum Beispiel 
1.1kHz ..
Gast #2365571
Lesenswert?

Hallo

die FFT ist eine schnelle Berechnung der DFT. Vor allem wenn die Anzahl 
der FFT eine Potenz von 2 ist also N = 2^r.
Bevor du dich an die FFT gibst solltest du daher zuerst die DFT komplett 
verstehen und dich dann an Sachen wie Butterfly, Twiddlefaktoren und 
Bitumkehrung geben. Ansonsten wird das nix mit der FFT
Gast #2365599
Lesenswert?

@Achim:
Auch wenn ich die Frage nicht gestellt habe,
vielen Dank für die Antwort.

Ich habe noch nirgends eine verständlichere Erklärung der DFT gelesen.
Die hätte in der Wikipedia durchaus ihre Berechtigung...

Gruß, FlorenZ
Gast #2366227
Lesenswert?

Danke Sehr Achim für dein Erklärung, sorry ich hat Internetproblem.
 Nach deiner Erklärung hab ich mit DFT noch mal beschäftigt und habe die 
Implementierung von DFT wie folgenden vorangegangen:
[c]

for( i=0;i<N;i++){   // N = 1024 : Anzahl der Punkte
  x[i]=f(x);          //  in Array schreibe ich die Funktionswerte
}
for(i=0; i<N;i++){
    a=0;
    b=0;
   for(i=0; i<N;i++){
     a=x[j]*cos((2*pi/N)*i*j);
     b=x[j]*sin((2*pi/N)*i*j);
    a+=a;
    b+=b;
  }
X[i]= sqrt(a*a+b*b);   // DFT Amplitudenwerte von Funktion
}

Kann man mir sagen ob es  richtig und  wie  kann ich  es verbessern 
falls da fehler ist.

PS:

> Das Ergebnis (/150) ist der 1kHz Frequenzanteil.
> Und jetzt das alles wiederholen bei der nächsten Frequenz, zum Beispiel
> 1.1kHz ..
Achim was meinst du hier das habe ich  nicht  verstanden , was du mit 
wiederhlen bei der nächsten Frequenzen meint.


Gruß
Sera
Gast #2366248
Lesenswert?

Ja, fast. Die innere Schleife muss natürlich j sein, nicht i.
Und die Aufsummierung muss anders erfolgen, sonst wird die Summe immer 
wieder zurückgesetzt.
1
for( i=0;i<N;i++){   // N = 1024 : Anzahl der Punkte
2
  x[i]=f(x);          //  in Array schreibe ich die Funktionswerte
3
}
4

5
for(i=0; i<N;i++){
6
    a=0;
7
    b=0;
8
    for(j=0; j<N;j ++){ 
9
        a+=x[j]*cos((2*pi/N)*i*j);
10
        b+=x[j]*sin((2*pi/N)*i*j);
11
    }
12
    X[i]= sqrt(a*a+b*b);   // DFT Amplitudenwerte von Funktion
13
}

>was du mit wiederhlen bei der nächsten Frequenzen meint.
Damit habe ich genau die äußere Schleife gemeint. Also die zweite der 
drei for-Schleifen mit Index i.
Gast #2366292
Lesenswert?

>und  noch eine frage  entspricht  X[0]  das gleiche Anteil von dem Signal?
genau.

>was  soll ich  da  änderen damit, ich die statt DFT nun FFT implementieren.
Soweit ich das in Erinnerung habe, ist die FFT eine Variante der DFT, 
bei der N immer ein zweier-Potenz ist.
Dadurch kann man den Algorithmus deutlich in der Geschwindigkeit 
optimieren und es sind nicht mehr i*j Schleifendurchgänge notwendig, 
sondern deutlich weniger.
Gast #2366985
Lesenswert?

Ein Frage: Wenn man über eine komplette Welle drübersummiert, ist das 
Ergebnis doch Null. Oder wird der Effekt genutzt, dass die Wellen 
interferieren? Ich denke mir, dass das Ergennis einfach immer positiv 
sein wird, wenn man eine Welle gleicher Frequenz draufmultipliziert, 
richtig?

Ausserdem: Wieviele Wellen Sinus und Cosinus sind in dem array jeweils 
enthalten?  Es kann ja nur für eine ganzzahlig aufgehen. Ist es eine 
komplette Welle für die höchste Frequenz oder eine für die niedrigste?

Ich denke mir, dass die anderen entsprechend ihrer Frequenz angepasst 
werden und damit viele nicht genau in das Array-Raster passen, was 
wieder leakage erzteugen dürfte, oder?

Wird dieser Effekt durch die Fensterfunktion auf die Eingangsdate 
komplett beseitigt? Oder müssen die Koeefizienten im Sinus Cosinus Array 
auch nochmal gefenstert werden, wie man das bei anderen FIR-Filtern 
macht? Oder wird das dann doppelt gemoppelt?

Dann weiter; Wie stellt man die Stelheit der Frequenzen ein? Macht es 
Sinn, für die längste Welle (die anderen sind ja gemäss Frequenz kürzer) 
nicht nur eine Welle in das Array zu nehmen, sondern mehr als eine? ich 
habe ein wenig herumprobiert und festgestellt, dass die Frequenzen 
selektiver werden und regelrechte Durchsacker entstehen, wenn man die 
Frequenzen durchfährt. ???

Danke für eure Antworten.
Persönliche Seite #2368542
Lesenswert?

Balu schrieb:
> Ausserdem: Wieviele Wellen Sinus und Cosinus sind in dem array jeweils
> enthalten?
Eine, die Grundwelle. Für die anderen Ordnungszahlen die entsprechenden 
Oberwellen.

> Ich denke mir, dass die anderen entsprechend ihrer Frequenz angepasst
> werden und damit viele nicht genau in das Array-Raster passen,
Ja

> was wieder leakage erzteugen dürfte, oder?
Du meinst, weil die Wellen nicht vollständig abschließen? Das ist 
zumindeste bei typischen Auflösungen der FFT unerheblich, weil der 
Beitrag des Restschwanzes minimal ist.

> Wird dieser Effekt durch die Fensterfunktion auf die Eingangsdate
> komplett beseitigt?
Ich würde sagen, das kommt auf die Fensterfunktion an. Je nachdem, wie 
die zum Rand ausläuft, hast Du sicher ein etwas anderes Verhalten.

>regelrechte Durchsacker entstehen
das sollte der oben beschriebene Randeffekt sein.

Welche FFT hast Du verwendet?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren