Series de Fourier MAM

De MateWiki
Saltar a: navegación, buscar
Trabajo realizado por estudiantes
Título Series de Fourier. Grupo MAM
Asignatura EDP
Curso 2025-26
Autores Mario Alonso Rodríguez

Adrián Nieto Moreno

Matías Martínez Mancebo

Este artículo ha sido escrito por estudiantes como parte de su evaluación en la asignatura


POSTER FOURIER MAM.png Archivo:PosterFourierMAM.pdf


Abajo se puede ver el código que se ha utilizado para conseguir las gráficas:

import numpy as np
import matplotlib.pyplot as plt

# -----------------------------
# Funciones objetivo
# -----------------------------
def signo(x):
    return np.sign(x)

def integral_signo(x):
    return np.abs(x)

def derivada_signo(x):
    # Derivada clásica: 0 para x != 0 (en x=0 no existe; ignoramos el delta)
    return np.zeros_like(x)


# -----------------------------
# Serie de Fourier de signo(x)
# signo(x) ~ (4/pi) * sum_{k=1..n} sin((2k-1)x)/(2k-1)
# -----------------------------
def serie_fourier_signo(x, n):
    k = np.arange(1, n + 1)
    m = 2 * k - 1  # impares
    # sum over m: sin(m x)/m
    return (4 / np.pi) * np.sum(np.sin(np.outer(m, x)) / m[:, None], axis=0)


# -----------------------------
# Integral de la serie (aprox de |x|)
# |x| = pi/2 - (4/pi) * sum_{k=1..∞} cos((2k-1)x)/(2k-1)^2
# -----------------------------
def integral_serie_fourier_signo(x, n):
    k = np.arange(1, n + 1)
    m = 2 * k - 1
    return (np.pi / 2) - (4 / np.pi) * np.sum(np.cos(np.outer(m, x)) / (m[:, None] ** 2), axis=0)


# -----------------------------
# Derivada de la serie (ojo: no converge a la derivada clásica en x=0)
# d/dx [serie] = (4/pi) * sum_{k=1..n} cos((2k-1)x)
# -----------------------------
def derivada_serie_fourier_signo(x, n):
    k = np.arange(1, n + 1)
    m = 2 * k - 1
    return (4 / np.pi) * np.sum(np.cos(np.outer(m, x)), axis=0)


# -----------------------------
# Norma L2: ||f-g||_2 = sqrt( ∫ |f-g|^2 dx )
# (integral numérica con trapecios)
# -----------------------------
def l2_error(x, f, g):
    return np.sqrt(np.trapz((f - g) ** 2, x))


# -----------------------------
# Plantilla: figura (aprox) + (error L2 vs n)
# -----------------------------
def figura_aprox_y_error(
    x,
    f_true_func,
    f_aprox_func,
    titulo_izq,
    titulo_der,
    n_list_plot=(5, 10, 30),
    n_max_error=200,
    ylims_izq=None
):
    f_true = f_true_func(x)

    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

    # --- Izquierda: curvas ---
    ax1.plot(x, f_true, linewidth=3, label="Función objetivo", color="black")
    for n in n_list_plot:
        ax1.plot(x, f_aprox_func(x, n), linewidth=2, label=f"Fourier (n={n})")

    ax1.set_title(titulo_izq)
    ax1.set_xlabel("x")
    ax1.set_ylabel("y")
    ax1.grid(True, alpha=0.3)
    ax1.legend()
    if ylims_izq is not None:
        ax1.set_ylim(ylims_izq)

    # --- Derecha: error L2 vs n ---
    ns = np.arange(1, n_max_error + 1)
    errs = np.array([l2_error(x, f_true, f_aprox_func(x, n)) for n in ns])

    ax2.plot(ns, errs, linewidth=2, label=r"Error $L^2$: $||f - S_n||_2$")

    # marcar los n usados en la izquierda
    for n in n_list_plot:
        ax2.scatter([n], [errs[n - 1]], s=60)

    ax2.set_title(titulo_der)
    ax2.set_xlabel("n")
    ax2.set_ylabel(r"$||f - S_n||_2$")
    ax2.grid(True, alpha=0.3)
    ax2.legend()

    plt.tight_layout()
    plt.show()


# -----------------------------
# Dominio (más puntos => integral numérica más estable)
# -----------------------------
x = np.linspace(-np.pi, np.pi, 4000)

# Elige los n que quieres dibujar en la izquierda
n_list = (5, 10, 30)

# 1) signo(x)
figura_aprox_y_error(
    x,
    f_true_func=signo,
    f_aprox_func=serie_fourier_signo,
    titulo_izq="Aproximación por series de Fourier de la función signo",
    titulo_der=r"Error $L^2$ vs $n$",
    n_list_plot=n_list,
    n_max_error=200,
    ylims_izq=(-1.5, 1.5)
)

# 2) Integral -> |x|
figura_aprox_y_error(
    x,
    f_true_func=integral_signo,
    f_aprox_func=integral_serie_fourier_signo,
    titulo_izq="Integral: aproximación de |x| mediante Fourier",
    titulo_der=r"Error $L^2$ vs $n$ (integral)",
    n_list_plot=(1, 3, 5),  # menos n porque converge más rápido
    n_max_error=200,
    ylims_izq=(0, np.pi)
)

# 3) Derivada (comparada con 0)
# Nota: este “error” no tenderá a 0, porque la derivada real incluye una singularidad en 0.
figura_aprox_y_error(
    x,
    f_true_func=derivada_signo,
    f_aprox_func=derivada_serie_fourier_signo,
    titulo_izq="Derivada de la serie de Fourier (comparada con 0)",
    titulo_der=r"Error $L^2$ vs $n$ (derivada)",
    n_list_plot=n_list,
    n_max_error=200,
    ylims_izq=(-10, 10)
)