Diferencia entre revisiones de «Series de Fourier (MAMBD)»
(→Cambio de intervalo de aproximación) |
(→Cambio de intervalo de aproximación) |
||
| Línea 183: | Línea 183: | ||
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 distintos valores de <math>n</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 distintos valores de <math>n</math>. | ||
| + | |||
| + | <syntaxhighlight lang="python"> | ||
| + | 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() | ||
| + | </syntaxhighlight> | ||
[[Categoría:EDP]] | [[Categoría:EDP]] | ||
[[Categoría:EDP24/25]] | [[Categoría:EDP24/25]] | ||
Revisión del 00:16 13 feb 2025
| 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]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 \cos \left( \frac{n\pi x}{T} \right) + \sum_{n=1}^{\infty} c_n \cdot \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, \cos \left( \frac{n\pi x}{T} \right) \rangle = \int_{-T}^{T} f(x) \cdot \cos \left( \frac{n\pi x}{T} \right) \,dx \\ &\bullet \quad c_n = \langle f, \sin \left( \frac{n\pi x}{T} \right) \rangle = \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 efectivamente una función 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}{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, es decir [math](\left\{\frac{1}{2}\right\}[/math] y [math]\{\cos(n\pi x)\})[/math], resultan ser impares. 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
Una vez hecho el análisis anterior, nos disponemos a ver gráficamente como a medida que aumentamos la cantidad de términos de la serie esta se aproxima mejor a la función original [math]f[/math]. Para ello, hemos usado el lenguaje de programación de Python con el que hemos conseguido representar los siguientes gráficos, en ellos vemos como efectivamente, al aumentar la [math]n[/math], los primeros términos de la serie de Fourier se acercan más y más a nuestra función original. Así mismo, por motivo de esta mejora en la aproximación, en la segunda gráfica podemos apreciar como el error disminuye conforme aumenta [math]n[/math]. Insetar fotos (no se hacerlo)
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()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]) \). Luego, daremos su desarrollo en serie de Fourier y finalmente aproximaremos [math]f(x)[/math] con los primeros 5, 10 y 20 términos de la serie obtenida.
Como ya sabemos, en el espacio [math]L^2[-\pi, \pi][/math] la base trigonométrica asociada es:
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
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:
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. De esta manera, [math]g(x) \in [-\pi, \pi][/math], lo que permite trasladar la base ortonormal del espacio [math]L^2(-\pi, \pi)[/math] al nuevo intervalo [math][a, b][/math].
Ahora, pasemos de lo general a nuestro caso concreto, el intervalo [math][-2, 3][/math]. Obtenemos que:
Definición: El espacio [math]L^2(-T, T)[/math] se define 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]
Definición: 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:
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 la función [math]f(x)[/math] son:
[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 distintos valores de [math]n[/math].
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()