Series de Fourier (MAMBD)

De MateWiki
Saltar a: navegación, buscar
Trabajo realizado por estudiantes
Título Series de Fourier. Grupo MAMBD
Asignatura EDP
Curso 2024-25
Autores Matilde Rubio Arranz, Antonio Lozano Fernández, Marcos Gil García, Bárbara Jiménez Pérez y Daniel Marcos Viña
Este artículo ha sido escrito por estudiantes como parte de su evaluación en la asignatura


1 Introducción

El interés de las series de Fourier radica en su capacidad para aproximar, a partir de una base de funciones trigonométricas, aplicaciones periódicas ampliando así el alcance de los desarrollos de Taylor. Sea [math]f[/math] una función integrable y periódica en [math][-T,T][/math], dada la base


[math]\mathcal{B}=\left\{ \frac{1}{\sqrt{2T}} \right\} \cup \left\{ \frac{1}{\sqrt{T}} \cdot \cos \left( \frac{n\pi x}{T} \right) \right\}_{n \in \mathbb{N}} \cup \left\{ \frac{1}{\sqrt{T}} \cdot \sin \left( \frac{n\pi x}{T} \right) \right\}_{n \in \mathbb{N}},[/math]


su serie de Fourier viene dada por la expresión:


[math]\begin{equation*} f(x) \sim \frac{d_0}{\sqrt{2T}} + \sum_{n=1}^{\infty} d_n \cdot\frac{1}{\sqrt{T}} \cos \left( \frac{n\pi x}{T} \right) + \sum_{n=1}^{\infty} c_n \cdot \frac{1}{\sqrt{T}}\sin \left( \frac{n\pi x}{T} \right) \end{equation*}[/math]


cuyos coeficientes son:


[math] \begin{aligned} &\bullet \quad d_0 = \langle f, \frac{1}{\sqrt{2T}} \rangle = \int_{-T}^{T} f(x) \cdot \frac{1}{\sqrt{2T}} \,dx \\ &\bullet \quad d_n = \langle f, \frac{1}{\sqrt{T}}\cos \left( \frac{n\pi x}{T} \right) \rangle = \frac{1}{\sqrt{T}}\int_{-T}^{T} f(x) \cdot \cos \left( \frac{n\pi x}{T} \right) \,dx \\ &\bullet \quad c_n = \langle f, \frac{1}{\sqrt{T}}\sin \left( \frac{n\pi x}{T} \right) \rangle = \frac{1}{\sqrt{T}}\int_{-T}^{T} f(x) \cdot \sin \left( \frac{n\pi x}{T} \right) \,dx. \end{aligned} [/math]

2 Aproximación de una función continua

Para ilustrar la aproximación por series trigonométricas, consideramos la función [math]f(x)=1-2\left|\frac{1}{2}-x\right|[/math] en el intervalo [math][0,1][/math]. Buscamos extenderla de forma impar obteniendo una función

[math]g(x)=\left\{\begin{array}{cc} f(x), & x\in[0,1] \\ -f(-x), & x\in[-1,0) \end{array}\right..[/math]

La extensión impar que buscamos viene dada por [math]g(x)=\left\{\begin{array}{cc} -2-2x, & -1\leq x\lt-\frac{1}{2} \\ 2x, & -\frac{1}{2}\leq x\lt\frac{1}{2} \\ 2-2x, & \frac{1}{2}\leq x\leq1 \end{array}\right.,[/math] que es continua en [math][-1,1][/math].

Ahora, por ser [math]f\in L^2([-1,1])[/math], utilizamos para la aproximación la base trigonométrica correspondiente [math]\left\{\frac{1}{\sqrt{2}}, \cos(n\pi x), \sin(n\pi x)\right\}_{n\in\mathbb{N}}[/math]. Sin embargo, al haber extendido la función de forma impar, el producto escalar de [math]f[/math] con las funciones pares de la base resulta ser impar. Con esto deducimos que integrar dicho producto en un intervalo simétrico da como resultado cero, pues las áreas positivas y negativas se anulan entre sí debido a la simetría de la función con respecto al origen. Entonces podemos definir [math]f_n(x)[/math] como la suma de los primeros [math]n[/math] términos de la serie de Fourier

[math]f_n(x)=\sum_{k=1}^n c_k \sin(k\pi x), \hspace{0.5cm} c_k=2\int_0^1 f(x)\sin(k\pi x).[/math]

Tras el análisis anterior, veamos gráficamente como, según aumentamos la cantidad de términos de la serie, esta se aproxima mejor a la función original [math]f[/math]. En los siguientes gráficos observamos como, efectivamente, al aumentar la [math]n[/math], los primeros términos de la serie de Fourier se van acercando a nuestra función original. Así mismo, gracias a esta mejora en la aproximación, en la segunda gráfica podemos apreciar como el error disminuye conforme aumenta [math]n[/math]. Destacamos que el error de aproximación desciende del orden [math]10^{-2}[/math], que es una cifra más que aceptable teniendo en cuenta que solamente hemos tomado 20 términos de una serie infinita.

Comparación de la extensión impar con la aproximación de Fourier
Errores [math]L^2[/math] y uniforme en función de n
import numpy as np
import matplotlib.pyplot as plt

#Primero, hemos definido la función del enunciado y su extensión impar. A continuación de eso, hemos creado dos funciones, las cuales crean los coeficientes de Fourier y la serie de Fourier, respectivamente. Además, se ha creado una última función para los errores. Usando matplotlib.pyplot, deja las siguientes gráficas:

# Definimos la función del enunciado con la que trabajar
def f(x):
    return 1 - 2 * np.abs(1/2 - x)

# Extensión impar de la propia función para poder aproximarla con la serie de Fourier
def odd_extension(x):
    return np.where(x < 0, -f(-x), f(x))

# Cálculo de los coeficientes de la serie con integración numérica por medio del método del trapecio
def compute_coefficients(n_max, dx=1e-3):
    x = np.arange(0, 1, dx)
    a_k = []
    for k in range(1, n_max + 1):
        integrand = f(x) * np.sin(k * np.pi * x)
        a_k.append(2 * np.trapz(integrand, x))  # Integral numérica por trapecios
    return a_k

# Construcción de la serie de Fourier
def fourier_approximation(x, a_k):
    f_n = np.zeros_like(x)
    for k, ak in enumerate(a_k, start=1):
        f_n += ak * np.sin(k * np.pi * x)
    return f_n

# Valores de n
n_values = [1, 5, 10]

# Discretización del intervalo
x = np.linspace(0, 1, 1000)
x_ext = np.linspace(-1, 1, 2000)

# Gráfica de la función original
plt.plot(x, f(x), label='f(x)', color='black', linewidth=2)

# Aproximaciones de Fourier con f extendida
for n in n_values:
    a_k = compute_coefficients(n)
    f_n = fourier_approximation(x_ext, a_k)
    plt.plot(x_ext, f_n, label=f'n={n}')

plt.legend()
plt.xlabel('x')
plt.ylabel('f(x) y f_n(x)')
plt.title('Comparación de la extensión impar con la Aproximación de Fourier')
plt.show()

# Calculamos el error de estimación entre la correspondiente f_n(x) y f(x)
def compute_errors(n_values, x, dx=1e-3):
    L2_errors = []
    uniform_errors = []
    f_exact = odd_extension(x)
    for n in n_values:
        a_k = compute_coefficients(n, dx)
        f_n = fourier_approximation(x, a_k)
        error = np.abs(f_exact - f_n)
        L2_error = np.sqrt(np.trapz(error**2, x))  # Norma L^2
        uniform_error = np.max(error)  # Norma uniforme
        L2_errors.append(L2_error)
        uniform_errors.append(uniform_error)
    return L2_errors, uniform_errors

# Valores de n
n_values2 = np.arange(1, 21)

# Discretización del intervalo
x_ext = np.linspace(-1, 1, 2000)

# Cálculo de errores
L2_errors, uniform_errors = compute_errors(n_values2, x_ext)

# Gráfica de errores
plt.figure(figsize=(8, 5))
plt.plot(n_values2, L2_errors, label='Error L2', marker='o')
plt.plot(n_values2, uniform_errors, label='Error Uniforme', marker='s')
plt.yscale('log')
plt.xlabel('Número de términos n')
plt.ylabel('Error')
plt.title('Errores en función de n')
plt.legend()
plt.grid()
plt.show()

3 Cambio de intervalo de aproximación

A continuación aproximaremos la función \( f(x) = x e^x \) en el intervalo \([-2, 3]\) mediante su serie de Fourier. En primer lugar, calcularemos la base trigonométrica asociada al espacio \( L^2([-2, 3]) \). Definimos el espacio [math]L^2(-T, T)[/math] como el conjunto de funciones medibles [math]f(x)[/math] en el intervalo [math][-T, T][/math] tales que:[math] \int_{-T}^{T} |f(x)|^2 \, dx \lt \infty [/math]. Como ya sabemos, en el espacio [math]L^2([-\pi, \pi])[/math] la base trigonométrica asociada es:


[math] \mathcal{B} = \left\{ \frac{1}{\sqrt{2\pi}}, \frac{1}{\sqrt{\pi}} \cos(nx), \frac{1}{\sqrt{\pi}} \sin(nx) \right\}_{n \in \mathbb{N}}. [/math]


En general, para [math]L^2([a,b])[/math], mediante el cambio de variable [math] g(x) = \frac{2\pi}{b - a} (x - a) - \pi, [/math] se tiene que la base trigonométrica asociada es


[math] \mathcal{F} = \left\{ \frac{1}{\sqrt{b - a}}, \left[ \sqrt{\frac{2}{b - a}} \cos\left( n \left(\frac{2\pi(x - a)}{b - a} - \pi\right) \right), \sqrt{\frac{2}{b - a}} \sin\left( n \left(\frac{2\pi(x - a)}{b - a} - \pi \right)\right) \right] \right\}_{n=1}^{\infty}, [/math]


que es una base ortonormal para [math]L^2([a,b])[/math]. Bajo este cambio de variable, una función [math]f(x)[/math] en [math]L^2([a,b])[/math] se puede expresar como:


[math] f(x) = \frac{d_0}{\sqrt{b - a}} + \sum_{n=1}^{\infty} d_n \cos\left(n g(x)\right) + \sum_{n=1}^{\infty} c_n \sin\left(n g(x)\right), [/math]


donde [math]g(x)[/math] es el cambio de variable aplicado, y [math]d_n[/math] y [math]c_n[/math] son los coeficientes correspondientes. Así, [math]g(x) \in [-\pi, \pi][/math], permitiendo trasladar la base ortonormal del espacio [math]L^2(-\pi, \pi)[/math] al nuevo intervalo [math][a, b][/math].

Ahora, analicemos nuestro caso concreto, el intervalo [math][-2, 3][/math]. Obtenemos que:


[math] f(x) \sim \frac{d_0}{\sqrt{5}} + \sum_{n=1}^{\infty} d_n \frac{\sqrt{2}}{\sqrt{5}}\cos\left(n \frac{2\pi x - \pi}{5}\right) + \sum_{n=1}^{\infty} c_n \frac{\sqrt{2}}{\sqrt{5}}\sin\left(n \frac{2\pi x - \pi}{5}\right), [/math]


  • Decimos que una función [math]f(x)[/math] satisface la condición de dirichlet si [math]f(x) \in L^2([-T,T])[/math] es continua salvo en un conjunto finito de puntos y podemos dividir [math][-T,T][/math] en un conjunto de subintervalos en los que [math]f[/math] es monótona.


  • Teorema: Sea [math]f \in L^2([-2, 3])[/math] una función continua y que satisface la condición de Dirichlet, entonces su serie de Fourier converge puntualmente a [math]f(x)[/math] si [math]x[/math] es un punto de continuidad en [math][-2,3][/math].


Claramente, [math]f(x)[/math] es continua y satisface la condición de dirichlet. Además, se verifica que [math]f(x) \in L^2([-2, 3])[/math], pues:


[math] \int_{-2}^{3} (x e^{-x})^2 \, dx = \frac{5}{4 e^6} \left( e^{10} - 5 \right) \lt \infty. [/math]


Concluimos con que su desarrollo en serie de Fourier converge en los puntos de continuidad a [math]f(x)[/math]. Finalmente, calculemos los coeficientes de Fourier. Para la base ortonormal asociada al espacio [math]L^2([-2, 3])[/math], los coeficientes de Fourier de [math]f(x)[/math] son:


[math] d_0 = \frac{1}{\sqrt{5}} \int_{-2}^{3} x e^x \, dx = \frac{-4 + e^5}{\sqrt{5} e^3} [/math]

[math] d_n = \frac{\sqrt{2}}{\sqrt{5}c} \int_{-2}^{3} x e^x \cos\left( n \frac{2\pi x - \pi}{5} \right) \, dx \quad \text{para} \quad n \geq 1 [/math]

[math] c_n = \frac{\sqrt{2}}{\sqrt{5}} \int_{-2}^{3} x e^x \sin\left( n \frac{2\pi x - \pi}{5} \right) \, dx \quad \text{para} \quad n \geq 1. [/math]


Calcularemos los coeficientes [math]d_n[/math] y [math]c_n[/math] mediante métodos numéricos en Python, obteniendo así la serie de Fourier de [math]f(x)[/math] en [math][-2,3][/math] y, por tanto, la gráfica de la función y de la serie para sus primeros [math]5, 10[/math] y [math]20[/math] términos.

Aproximación de Fourier con distintos n
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad

# Definimos la función f(x)
def f(x):
    return x * np.exp(-x)

# Intervalo de definición
a= -2
b = 3

# Funciones base ortonormales en L^2([-2,3])
def phi0(x):
    return 1/np.sqrt(5)

def phi(n, x):
    return np.sqrt(2/5) * np.cos(n * (2*np.pi*x - np.pi) / 5)

def psi(n, x):
    return np.sqrt(2/5) * np.sin(n * (2*np.pi*x - np.pi) / 5)

# Cálculo de los coeficientes de Fourier
d0, _ = quad(lambda x: f(x) * phi0(x), a, b)

# Se calcularán los coeficientes para n=1,...,N_max
N_max = 20
d_coeffs = []  # para los coeficientes asociados a los cosenos
c_coeffs = []  # para los coeficientes asociados a los senos

for n in range(1, N_max+1):
    d_n, _ = quad(lambda x: f(x) * phi(n, x), a, b)
    c_n, _ = quad(lambda x: f(x) * psi(n, x), a, b)
    d_coeffs.append(d_n)
    c_coeffs.append(c_n)

# Función que reconstruye la serie de Fourier truncada a N términos
def fourier_series(x, N):
    s = d0 * phi0(x)
    for n in range(1, N+1):
        s += d_coeffs[n-1] * phi(n, x) + c_coeffs[n-1] * psi(n, x)
    return s

x_vals = np.linspace(a, b, 400)
f_vals = f(x_vals)

# Lista de números de términos para la aproximación
n_list = [5, 10, 20]

# Se generan tres gráficos, uno para cada valor de n
plt.figure(figsize=(15, 4))
for i, n in enumerate(n_list, 1):
    # Se evalúa la serie de Fourier para cada x
    s_vals = np.array([fourier_series(x, n) for x in x_vals])
    
    plt.subplot(1, 3, i)
    plt.plot(x_vals, f_vals, label=r'$f(x)= x e^-x$', color='blue', linestyle='--')
    plt.plot(x_vals, s_vals, label=f'Aproximación (n={n})', color='red')
    plt.title(f'Aproximación de Fourier con n = {n} términos')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.legend()
    plt.grid(True)

plt.tight_layout()
plt.show()