Die Fourier-Reihen-Entwicklung periodischer Funktionen lässt sich an konkreten Beispielen veranschaulichen. In der praktischen Anwendung werden diese Entwicklungen häufig numerisch mit der Fast Fourier Transform (FFT) berechnet, die eine effiziente Implementierung der diskreten Fourier-Transformation darstellt.
Beispiel: Rechteckwelle
Eine periodische Rechteckwelle mit Periode \(L\) und Amplitude \(A\) dient als klassisches Beispiel für die Fourier-Entwicklung. Die Rechteckwelle springt abrupt zwischen zwei Werten und besitzt daher Unstetigkeiten, die sich in einem charakteristischen Konvergenzverhalten der Fourier-Reihe widerspiegeln.
Die Fourier-Reihe der Rechteckwelle lautet: \[
f(x) = \frac{4A}{\pi}\sum_{n=1,3,5,\ldots}^{\infty} \frac{1}{n}\sin\left(\frac{2\pi n x}{L}\right)
\]
Diese Darstellung zeigt, dass nur die ungeraden Harmonischen zum Signal beitragen. Die Koeffizienten fallen mit \(1/n\) ab, was auf die Unstetigkeiten der Funktion zurückzuführen ist. Je höher die Ordnung der harmonischen Komponente, desto geringer ihr Beitrag zur Gesamtfunktion.
Python-Implementierung
Die numerische Berechnung und Visualisierung von Fourier-Reihen lässt sich mit Python durchführen. Das folgende Programm approximiert eine Rechteckwelle durch eine endliche Fourier-Reihe.
import numpy as npimport matplotlib.pyplot as plt# Beispiel: Fourier-Reihe einer Rechteckwelledef square_wave_fourier(x, L, A, N_terms):""" Approximiert eine Rechteckwelle durch Fourier-Reihe. Parameters: x: Array der x-Werte L: Periode A: Amplitude N_terms: Anzahl der Terme in der Reihe """ f = np.zeros_like(x)for n inrange(1, N_terms+1, 2): # nur ungerade n f += (4*A/(np.pi*n)) * np.sin(2*np.pi*n*x/L)return f# Visualisierungx = np.linspace(0, 2, 1000)L =1.0A =1.0fig, axes = plt.subplots(2, 2, figsize=(7, 4))for i, N inenumerate([1, 3, 10, 50]): ax = axes[i//2, i%2] f_approx = square_wave_fourier(x, L, A, N) ax.plot(x, f_approx, label=f'Harmonische bis $n = {N}$') ax.set_xlabel('x') ax.set_ylabel('f(x)') ax.set_title(f'Harmonische bis $n = {N}$') ax.grid(True, alpha=0.3) ax.legend() ax.set_ylim([-1.5, 1.5])plt.tight_layout()plt.show()
Die Visualisierung zeigt die Konvergenz der Fourier-Reihe mit wachsender Zahl von Harmonischen (da nur ungerade Harmonische beitragen, enthält die Partialsumme bis \(n = N\) etwa \(N/2\) Terme). Mit der Grundschwingung allein erhält man eine grobe Annäherung durch eine einfache Sinusfunktion. Mit den Harmonischen bis \(n = 3\) beginnt sich bereits die charakteristische Form der Rechteckwelle abzuzeichnen. Bis \(n = 10\) ist die Approximation deutlich besser, und bis \(n = 50\) ist die Rechteckwelle nahezu perfekt reproduziert. An den Unstetigkeiten tritt jedoch das Gibbs-Phänomen auf, ein charakteristisches Überschwingen, das auch bei beliebig vielen Termen nicht verschwindet.
Abbildung 1 zeigt dieses Verhalten im Detail: Im Ausschnitt um die Sprungstelle bei \(x = L/2\) wird das Überschwingen mit wachsender Termzahl zwar immer schmaler und rückt näher an den Sprung heran, seine Höhe bleibt jedoch konstant bei etwa 9 % der Sprunghöhe.
Code
import numpy as npimport matplotlib.pyplot as pltdef square_wave_fourier(x, L, A, N_terms):"""Approximiert eine Rechteckwelle durch eine Fourier-Partialsumme.""" f = np.zeros_like(x)for n inrange(1, N_terms +1, 2): # nur ungerade n f += (4* A / (np.pi * n)) * np.sin(2* np.pi * n * x / L)return fL =1.0A =1.0# Ausschnitt um die Sprungstelle bei x = L/2x = np.linspace(0.42, 0.58, 10000)fig, ax = plt.subplots(figsize=(7, 4))# Exakte Rechteckwelleax.plot([0.42, 0.5], [A, A], 'k--', linewidth=1.5)ax.plot([0.5, 0.5], [A, -A], 'k--', linewidth=1.5)ax.plot([0.5, 0.58], [-A, -A], 'k--', linewidth=1.5, label='Rechteckwelle')# Partialsummen mit wachsender Termzahlfor N in [10, 50, 200]: ax.plot(x, square_wave_fourier(x, L, A, N), linewidth=1.5, label=f'Harmonische bis $n = {N}$')# Höhe des Überschwingens: (2/π) Si(π) ≈ 1.179, d.h. ca. 9 % der Sprunghöhe 2Agibbs_peak =1.17898* Aax.axhline(y=gibbs_peak, color='gray', linestyle=':', linewidth=1)ax.annotate('Überschwingen $\\approx 1{,}179\\,A$\n($\\approx 9\\,\\%$ der Sprunghöhe $2A$)', xy=(0.493, gibbs_peak), xytext=(0.435, 1.45), fontsize=10, arrowprops=dict(arrowstyle='->', color='gray'))ax.set_xlabel('$x$', fontsize=12)ax.set_ylabel('$f(x)$', fontsize=12)ax.set_title('Gibbs-Phänomen an der Sprungstelle $x = L/2$', fontsize=13)ax.set_xlim([0.42, 0.58])ax.set_ylim([-1.8, 1.8])ax.grid(True, alpha=0.3)ax.legend(fontsize=10, loc='lower left')plt.tight_layout()plt.show()
Abbildung 1: Das Gibbs-Phänomen an der Sprungstelle der Rechteckwelle: Das Überschwingen der Partialsummen wird mit zunehmender Termzahl schmaler, seine Höhe von etwa 9 % der Sprunghöhe bleibt jedoch bestehen
Fast Fourier Transform (FFT)
Die Fast Fourier Transform ist ein effizienter Algorithmus zur Berechnung der diskreten Fourier-Transformation. Statt der naiven Implementierung mit \(O(N^2)\) Rechenoperationen benötigt die FFT nur \(O(N \log N)\) Operationen. Diese dramatische Reduktion der Rechenlast macht die FFT zu einem der wichtigsten Algorithmen der numerischen Mathematik und ermöglicht die Echtzeitverarbeitung von Signalen.
Das folgende Beispiel demonstriert die Anwendung der FFT auf ein synthetisches Signal, das aus zwei überlagerten Sinusschwingungen besteht.
Abbildung 2: Zeitsignal aus zwei überlagerten Sinusschwingungen (links) und zugehöriges Amplitudenspektrum als Stem-Plot (rechts): Die diskreten Frequenzkomponenten bei 50 Hz und 120 Hz sind klar erkennbar
Das Zeitsignal in Abbildung 2 zeigt eine komplexe Überlagerung zweier Frequenzen, die im Zeitbereich schwer zu erkennen sind. Das Amplitudenspektrum als Stem-Plot macht hingegen die beiden diskreten Komponenten bei 50 Hz (Amplitude 1) und 120 Hz (Amplitude 0,5) unmittelbar sichtbar. Die FFT zerlegt das Signal in seine spektralen Bestandteile und liefert damit Aufschluss über die im Signal enthaltenen Frequenzen und ihre jeweiligen Amplituden.
Anwendung: Filterung im Frequenzbereich
Die Fourier-Transformation ermöglicht die Filterung von Signalen durch Manipulation im Frequenzbereich. Ein idealer Tiefpassfilter lässt alle Frequenzen unterhalb einer bestimmten Grenzfrequenz passieren und blockiert alle höheren Frequenzen vollständig.
Die Implementierung eines solchen Filters erfolgt in drei Schritten: Zunächst wird das Signal mittels FFT in den Frequenzbereich transformiert. Dann werden alle Frequenzkomponenten oberhalb der Grenzfrequenz auf null gesetzt. Schließlich wird das gefilterte Signal durch inverse FFT zurück in den Zeitbereich transformiert.
# Beispiel: Tiefpassfilter durch Fourier-Transformationdef lowpass_filter(signal, cutoff_freq, sample_rate):""" Wendet einen idealen Tiefpassfilter an. """# FFT F = np.fft.fft(signal) freqs = np.fft.fftfreq(len(signal), 1/sample_rate)# Filter anwenden F_filtered = F.copy() F_filtered[np.abs(freqs) > cutoff_freq] =0# Rücktransformation signal_filtered = np.fft.ifft(F_filtered).realreturn signal_filtered
Diese Funktion nimmt ein Signal, eine Grenzfrequenz und die Abtastrate entgegen und liefert das gefilterte Signal zurück. Der Filter arbeitet durch einfaches Nullsetzen der unerwünschten Frequenzkomponenten. In praktischen Anwendungen verwendet man häufig sanftere Filter, die einen allmählichen Übergang zwischen Durchlass- und Sperrbereich aufweisen, um unerwünschte Artefakte zu vermeiden.
Diese Beispiele illustrieren die praktische Anwendung der Fourier-Methoden in der Signalverarbeitung. Die FFT bildet die Grundlage für zahlreiche Algorithmen in der digitalen Signalverarbeitung, der Bildverarbeitung und der Datenanalyse. Die Fähigkeit, Signale effizient zwischen Zeit- und Frequenzbereich zu transformieren, eröffnet vielfältige Möglichkeiten zur Analyse und Manipulation von Daten.