Seite 1 von 1

fft von Sinus

Verfasst: Dienstag 24. Februar 2015, 15:48
von GoldenerReiter
Hallo, ich habe ein problem mit der fft von numpy.
zum testen möchte ich das an einem einfachen Sinus ausprobieren

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 2*np.pi,100)
y = np.sin(x)
yf = np.fft.fft(y)
yf = np.abs(yf[0:len(yf)/2])
xf = np.linspace(0,1,len(yf))
plt.plot(xf,yf)
plt.show()
Als lösung bekomme ich einen Plot, wo ein ausschlag von 0-~0.04 auf der x-achse
und von 0-50 auf der y-achse

eigentlich habe ich erwartet, dass ich einen ausschlag bei 1 auf der x-achse und bis 1 auf der y-achse
was habe ich verkehrt gemacht?


Ps.: kann ich auch irgendwie Bilder einfügen? dann wäre das einfacher zu erklären

Re: fft von Sinus

Verfasst: Dienstag 24. Februar 2015, 17:58
von MagBen
Die Frequenz der Funktion f(x) = sin(x) ist nicht 1 sondern 1/(2 pi).
f(x) = sin(2 pi x) hat die Frequenz 1.

Wenn Du als y-Wert eine 1 erwartest, dann verwechselst Du Fourierreihe und Fouriertransformation. Die Fouriertransformierte von sin(2 pi x) ist die Delta-Funktion.

Auf meiner Webseite habe ich den Zusammenhang zwischen FFT, Fouriertransformation und Fourierreihe an einem Beispiel erläutert
http://www.magben.de/?h1=mathematik_fue ... schreibung
und Python Code dazu
http://www.magben.de/?h1=mathematik_fue ... urier_code

Auf Dein Beispiel angewendet könnte der Code etwa so aussehen:

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt

def fourier_transform(t, fkt):
    n = t.size
    dt = t[1]-t[0]
    
    f=np.linspace(-1/(2*dt), 1/(2*dt), n+1)[:-1]
    Fkt = np.fft.fft(fkt)*dt
    
    # swap first and second half of output-array
    Fkt2 = np.zeros(Fkt.shape, Fkt.dtype)
    Fkt2[:n/2] = Fkt[n/2:]
    Fkt2[n/2:] = Fkt[:n/2]
    
    return f, Fkt2

a=100 # Anzahl der Perioden
n=2**20 # fft mit 2**20 Werten ist viel schneller als fft mit 1 Mio Werten
x = np.linspace(0, a,n)
y = np.sin(2*np.pi*x)
xf, yf = fourier_transform(x,y)
plt.plot(xf,np.abs(yf))
plt.xlim(0,2)
plt.show()

Re: fft von Sinus

Verfasst: Mittwoch 25. Februar 2015, 08:15
von Sirius3
@MagBen: Deine Namen halten sich nicht an die Namenskonvention, Fkt wäre wohl besser fkt_transformed oder fourier_fkt und Fkt2 braucht man gar nicht.
In Zeile 8 suchst Du das endpoint-Argument von linspace. Für Zeile 12 gibt es zeros_like und für Zeiele 12-14 gibt es fftshift.

Code: Alles auswählen

def fourier_transform(t, fkt):
    dt = t[1]-t[0]
    f = np.linspace(-1/(2*dt), 1/(2*dt), t.size, endpoint=False)
    fourier_fkt = np.fft.fft(fkt) * dt
    return f, np.fft.fftshift(fourier_fkt)

Re: fft von Sinus

Verfasst: Mittwoch 25. Februar 2015, 08:43
von MagBen
Sirius3 hat geschrieben:Deine Namen halten sich nicht an die Namenskonvention, Fkt wäre wohl besser fkt_transformed oder fourier_fkt und Fkt2 braucht man gar nicht.
"Die Namenskonvention" von Python, der Domäne, objektorientiertes Programmieren, ... ?
In der Mathematik ist es Konvention die Fouriertransformierte von f als F zu bezeichnen.

Ich empfehle jedem sich zu allererst an der Namenskonvention seines Umfelds (Abteilung, Kunde, ...), dann an der Namenskonvention der Domäne und erst danach an der Namenskonvention der Programmiersprache zu orientieren.
Sirius3 hat geschrieben:Für Zeile 12 gibt es zeros_like und für Zeiele 12-14 gibt es fftshift.
Das kannte ich noch nicht, Danke für den Hinweis.

Re: fft von Sinus

Verfasst: Mittwoch 25. Februar 2015, 09:14
von Sirius3
@MagBen: Zum Glück kann man mit Python 3 auch griechische Buchstaben als Namen verwenden, sieht gleich viel schicker aus :twisted: :

Code: Alles auswählen

def ℱ(t, f):
    Δt = t[1] - t[0]
    ω = np.linspace(-1/(2*Δt), 1/(2*Δt), t.size, endpoint=False)
    F = np.fft.fft(f) * Δt
    return ω, np.fft.fftshift(F)
Deine Kunden im Forum sind zu allererst Leute, die sich mit Python beschäftigen, dann ist es doch ganz klar, dass man die Python-Namenskonvention benutzt.

Re: fft von Sinus

Verfasst: Mittwoch 25. Februar 2015, 10:21
von MagBen
Sirius3 hat geschrieben:Zum Glück kann man mit Python 3 auch griechische Buchstaben als Namen verwenden, sieht gleich viel schicker aus
Endlich mal ein Argument für Python 3. In IPython Notebooks könnte das richtig gut aussehen.

ω ist übrigens nicht die Frequenz, sondern die Kreisfrequenz: ω = 2 π f