|
|
| (No se muestran 6 ediciones intermedias de 2 usuarios) |
| Línea 5: |
Línea 5: |
| | Javier Martín Pérez }} | | Javier Martín Pérez }} |
| | | | |
| | + | [[Archivo:Series de fourier RAJ.jpeg||800px]] |
| | + | [[Archivo:Poster_Gibbs_RAJ.pdf]] |
| | | | |
| − | <source lang="python" line>
| |
| | | | |
| − | import numpy as np
| + | Se adjunta a continuación el código utilizado para la visualización de las gráficas expuestas durante la presentación. |
| − | import matplotlib.pyplot as plt
| + | |
| − | import scipy.integrate
| + | |
| − | | + | |
| − | def f_discontinua(x):
| + | |
| − | """
| + | |
| − | Define la función característica del intervalo [0, 1/4].
| + | |
| − | Retorna 1 si 0 <= x <= 0.25, y 0 en otro caso.
| + | |
| − | """
| + | |
| − | # Usamos np.where para vectorizar la operación sobre arrays de numpy
| + | |
| − | return np.where((x >= 0) & (x <= 0.25), 1.0, 0.0)
| + | |
| − | | + | |
| − | def construir_coeficientes_par(funcion, n_terminos, dx=1e-3):
| + | |
| − | """
| + | |
| − | Construye los coeficientes de Fourier para una extensión PAR de la función dada.
| + | |
| − | | + | |
| − | Parámetros:
| + | |
| − | -----------
| + | |
| − | funcion : callable
| + | |
| − | Función f(x) definida en [0, 1].
| + | |
| − | n_terminos : int
| + | |
| − | Número de coeficientes a calcular (incluyendo a0).
| + | |
| − | dx : float
| + | |
| − | Tamaño de la malla para la integración numérica (Sugerencia: 10^-3).
| + | |
| − | | + | |
| − | Retorna:
| + | |
| − | --------
| + | |
| − | coeficientes : list
| + | |
| − | Lista [a0, a1, ..., a_n-1] calculada mediante la regla del trapecio.
| + | |
| − | """
| + | |
| − | | + | |
| − | # 1. Definir la malla de integración [0, 1]
| + | |
| − | # Se usa arange hasta 1 + dx/2 para asegurar que incluye el punto final 1.0
| + | |
| − | x = np.arange(0, 1 + dx/2, dx)
| + | |
| − | | + | |
| − | # 2. Evaluar la función en la malla
| + | |
| − | y = funcion(x)
| + | |
| − | | + | |
| − | coeficientes = []
| + | |
| − | | + | |
| − | # 3. Calcular los coeficientes a_k
| + | |
| − | for k in range(n_terminos):
| + | |
| − | # Base trigonométrica par: cos(k * pi * x)
| + | |
| − | termino_base = np.cos(k * np.pi * x)
| + | |
| − | | + | |
| − | # Integrando: 2 * f(x) * cos(k*pi*x)
| + | |
| − | # El factor '2' proviene de la simetría par en [-1, 1]
| + | |
| − | integrando = 2 * y * termino_base
| + | |
| − | | + | |
| − | # Aproximación de la integral usando la regla del trapecio
| + | |
| − | # Tal como se sugiere en el punto 2 del texto
| + | |
| − | a_k = scipy.integrate.trapezoid(integrando, dx=dx)
| + | |
| − | | + | |
| − | coeficientes.append(a_k)
| + | |
| − | | + | |
| − | return coeficientes
| + | |
| − | | + | |
| − | # ---------------------------------------------------------
| + | |
| − | # 1. Función de Reconstrucción (Solicitada al inicio)
| + | |
| − | # ---------------------------------------------------------
| + | |
| − | def reconstruir_serie_par(coeficientes, x_eval):
| + | |
| − | """
| + | |
| − | Reconstruye la serie de Fourier de cosenos.
| + | |
| − | S_N(x) = a0/2 + sum(a_k * cos(k*pi*x))
| + | |
| − | | + | |
| − | Parámetros:
| + | |
| − | -----------
| + | |
| − | coeficientes : list
| + | |
| − | Coeficientes [a0, a1, ..., aN] calculados.
| + | |
| − | x_eval : array
| + | |
| − | Puntos donde evaluar la serie (puede ser [-1, 1]).
| + | |
| − | """
| + | |
| − | # 1. Término constante (siempre es a0 / 2)
| + | |
| − | a0 = coeficientes[0]
| + | |
| − | y_approx = (a0 / 2) * np.ones_like(x_eval)
| + | |
| − | | + | |
| − | # 2. Sumar términos cosenos
| + | |
| − | # La paridad (simetría) en [-1, 1] es automática con cos(k*pi*x)
| + | |
| − | for k in range(1, len(coeficientes)):
| + | |
| − | a_k = coeficientes[k]
| + | |
| − | y_approx += a_k * np.cos(k * np.pi * x_eval)
| + | |
| − | | + | |
| − | return y_approx
| + | |
| − | | + | |
| − | # ---------------------------------------------------------
| + | |
| − | # 2. Funciones Auxiliares (Coeficientes y Error)
| + | |
| − | # ---------------------------------------------------------
| + | |
| − | def f_par_extendida(x):
| + | |
| − | """
| + | |
| − | Define la función par en todo el eje real.
| + | |
| − | f(x) = 1 si |x| <= 0.25, 0 en otro caso.
| + | |
| − | """
| + | |
| − | return np.where(np.abs(x) <= 0.25, 1.0, 0.0)
| + | |
| − | | + | |
| − | def construir_coeficientes(n_terminos, dx):
| + | |
| − | """
| + | |
| − | Calcula a_k integrando solo en [0, 1] (suficiente por simetría).
| + | |
| − | Usa 'dx' para crear la malla con np.arange (sin linspace).
| + | |
| − | """
| + | |
| − | # Malla positiva [0, 1] para la integral
| + | |
| − | x = np.arange(0, 1 + dx/10, dx)
| + | |
| − | y = f_par_extendida(x)
| + | |
| − | | + | |
| − | coefs = []
| + | |
| − | for k in range(n_terminos):
| + | |
| − | base = np.cos(k * np.pi * x)
| + | |
| − | integrando = 2 * y * base
| + | |
| − | # Integral numérica
| + | |
| − | a_k = scipy.integrate.trapezoid(integrando, dx=dx)
| + | |
| − | coefs.append(a_k)
| + | |
| − | return coefs
| + | |
| − | | + | |
| − | def calcular_errores_completo(y_real, y_aprox, dx):
| + | |
| − | """Calcula errores L2 y Uniforme en el dominio dado."""
| + | |
| − | diff = np.abs(y_real - y_aprox)
| + | |
| − | # L2 = sqrt( integral(diff^2) )
| + | |
| − | err_l2 = np.sqrt(scipy.integrate.trapezoid(diff**2, dx=dx))
| + | |
| − | # Uniforme = max(diff)
| + | |
| − | err_unif = np.max(diff)
| + | |
| − | return err_l2, err_unif
| + | |
| − | | + | |
| − | def reconstruir_cesaro_par(coeficientes, x_eval):
| + | |
| − | """
| + | |
| − | Reconstruye la Suma de Cesàro (promedio de sumas parciales).
| + | |
| − | Matemáticamente equivale a multiplicar los coeficientes a_k
| + | |
| − | por el peso triangular: (N - k + 1) / (N + 1).
| + | |
| − | | + | |
| − | Parámetros:
| + | |
| − | -----------
| + | |
| − | coeficientes : list
| + | |
| − | [a0, a1, ..., aN] calculados previamente.
| + | |
| − | x_eval : array
| + | |
| − | Puntos de evaluación.
| + | |
| − | """
| + | |
| − | N = len(coeficientes) - 1 # El índice máximo es N
| + | |
| − | y_approx = np.zeros_like(x_eval)
| + | |
| − | | + | |
| − | # El denominador común del peso es N + 1
| + | |
| − | denominador = N + 1
| + | |
| − | | + | |
| − | # 1. Término constante a0/2
| + | |
| − | # El peso de Cesàro para k=0 es (N - 0 + 1)/(N+1) = 1.
| + | |
| − | # Pero recordamos que en la serie el término es a0/2.
| + | |
| − | a0 = coeficientes[0]
| + | |
| − | y_approx += (a0 / 2) * np.ones_like(x_eval)
| + | |
| − | | + | |
| − | # 2. Términos cosenos con pesos de Fejér
| + | |
| − | for k in range(1, len(coeficientes)):
| + | |
| − | a_k = coeficientes[k]
| + | |
| − | | + | |
| − | # Peso triangular que define la suma de Cesàro
| + | |
| − | peso = (N - k + 1) / denominador
| + | |
| − | | + | |
| − | y_approx += peso * a_k * np.cos(k * np.pi * x_eval)
| + | |
| − | | + | |
| − | return y_approx
| + | |
| − | | + | |
| − | # --- Función para Método de Lanczos (Factores Sigma) ---
| + | |
| − | def reconstruir_lanczos_par(coeficientes, x_eval):
| + | |
| − | """
| + | |
| − | Reconstruye usando factores Sigma (sinc).
| + | |
| − | Suaviza Gibbs manteniendo buena pendiente.
| + | |
| − | """
| + | |
| − | N = len(coeficientes) - 1
| + | |
| − | y_approx = np.zeros_like(x_eval)
| + | |
| − | | + | |
| − | # Término a0/2
| + | |
| − | y_approx += (coeficientes[0] / 2)
| + | |
| − | | + | |
| − | # Términos cosenos multiplicados por sigma = sinc(k/N)
| + | |
| − | for k in range(1, len(coeficientes)):
| + | |
| − | # np.sinc(x) calcula sin(pi*x)/(pi*x)
| + | |
| − | sigma = np.sinc(k / N)
| + | |
| − | y_approx += sigma * coeficientes[k] * np.cos(k * np.pi * x_eval)
| + | |
| − | | + | |
| − | return y_approx
| + | |
| − | | + | |
| − | # --- Función para Método de Abel (Poisson) ---
| + | |
| − | def reconstruir_abel_r_variable(coeficientes, x_eval, r):
| + | |
| − | """
| + | |
| − | Reconstruye la serie usando Abel con un r fijo dado por el usuario.
| + | |
| − | """
| + | |
| − | y_approx = np.zeros_like(x_eval)
| + | |
| − | | + | |
| − | # Término a0/2 (r^0 = 1)
| + | |
| − | y_approx += (coeficientes[0] / 2)
| + | |
| − | | + | |
| − | # Términos cosenos multiplicados por r^k
| + | |
| − | for k in range(1, len(coeficientes)):
| + | |
| − | peso = r**k
| + | |
| − | y_approx += peso * coeficientes[k] * np.cos(k * np.pi * x_eval)
| + | |
| − | | + | |
| − | return y_approx
| + | |
| − | | + | |
| − | # ---------------------------------------------------------
| + | |
| − | # 3. Ejecución y Gráficas (Extensión Par Completa [-1, 1])
| + | |
| − | # ---------------------------------------------------------
| + | |
| − | | + | |
| − | # A. Parámetros Basados en Malla (Sin número fijo de puntos)
| + | |
| − | dx_malla = 1e-4 # Tamaño del paso (resolución)
| + | |
| − | N_max_calculo = 500 # Máximo N para el análisis de error
| + | |
| − | lista_N_dibujar = [1, 5, 20, 50, 100, 500]
| + | |
| − | | + | |
| − | # B. Construcción del Dominio Completo [-1, 1]
| + | |
| − | # Usamos arange: start=-1, stop=1 (con margen), step=dx
| + | |
| − | x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
| + | |
| − | y_real = f_par_extendida(x_completo)
| + | |
| − | | + | |
| − | # C. Cálculo de Coeficientes (una sola vez hasta N_max)
| + | |
| − | coefs_totales = construir_coeficientes(N_max_calculo + 1, dx_malla)
| + | |
| − | | + | |
| − | # --- GRÁFICA 1: Función y Aproximaciones ---
| + | |
| − | plt.figure(figsize=(12, 6))
| + | |
| − | | + | |
| − | # Dibujar la función original (Exacta)
| + | |
| − | plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Función Original (Par)', alpha=0.3)
| + | |
| − | | + | |
| − | # Dibujar las aproximaciones para distintos N
| + | |
| − | colores = plt.cm.magma(np.linspace(0, 0.85, len(lista_N_dibujar)))
| + | |
| − | for i, n in enumerate(lista_N_dibujar):
| + | |
| − | coefs_n = coefs_totales[:n+1]
| + | |
| − | y_aprox = reconstruir_serie_par(coefs_n, x_completo)
| + | |
| − | | + | |
| − | plt.plot(x_completo, y_aprox, label=f'N={n}', color=colores[i], linewidth=1.5)
| + | |
| − | | + | |
| − | plt.title(f'Extensión Par Completa en [-1, 1] (dx={dx_malla})')
| + | |
| − | plt.xlabel('x')
| + | |
| − | plt.ylabel('f(x)')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | # --- GRÁFICA 2: Evolución de Errores (L2 y Uniforme) ---
| + | |
| − | errores_l2 = []
| + | |
| − | errores_inf = []
| + | |
| − | rango_n = np.arange(1, N_max_calculo + 1)
| + | |
| − | | + | |
| − | for n in rango_n:
| + | |
| − | coefs_n = coefs_totales[:n+1]
| + | |
| − | y_aprox = reconstruir_serie_par(coefs_n, x_completo)
| + | |
| − | | + | |
| − | # Calcular error sobre todo el intervalo [-1, 1]
| + | |
| − | l2, unif = calcular_errores_completo(y_real, y_aprox, dx_malla)
| + | |
| − | errores_l2.append(l2)
| + | |
| − | errores_inf.append(unif)
| + | |
| − | | + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | plt.loglog(rango_n, errores_l2, 'b-o', label='Error L2 [-1, 1]', markersize=4)
| + | |
| − | plt.loglog(rango_n, errores_inf, 'r-s', label='Error Uniforme (Max)', markersize=4)
| + | |
| − | | + | |
| − | plt.title('Evolución del Error vs Número de Términos')
| + | |
| − | plt.xlabel('N (log)')
| + | |
| − | plt.ylabel('Error (log)')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, which="both", alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | | + | |
| − | # Parámetros globales
| + | |
| − | dx_malla = 1e-4
| + | |
| − | N_max_calculo = 500
| + | |
| − | lista_N_dibujar = [1, 5, 20, 50, 100, 500]
| + | |
| − | | + | |
| − | # Dominio completo [-1, 1] usando arange y dx
| + | |
| − | x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
| + | |
| − | y_real = f_par_extendida(x_completo)
| + | |
| − | | + | |
| − | # Calcular coeficientes "crudos" una sola vez
| + | |
| − | coefs_totales = construir_coeficientes_par(f_par_extendida, N_max_calculo + 1, dx_malla)
| + | |
| − | | + | |
| − | # --- GRÁFICA 1: Aproximación de Cesàro ---
| + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | | + | |
| − | # Función original
| + | |
| − | plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Original f(x)', alpha=0.6)
| + | |
| − | | + | |
| − | colores = plt.cm.magma(np.linspace(0, 0.85, len(lista_N_dibujar)))
| + | |
| − | | + | |
| − | for i, n in enumerate(lista_N_dibujar):
| + | |
| − | # Para Cesàro de orden N, necesitamos coeficientes hasta N
| + | |
| − | coefs_n = coefs_totales[:n+1]
| + | |
| − | | + | |
| − | # Reconstrucción usando la función de Cesàro
| + | |
| − | y_cesaro = reconstruir_cesaro_par(coefs_n, x_completo)
| + | |
| − | | + | |
| − | plt.plot(x_completo, y_cesaro, label=f'Cesàro N={n}', color=colores[i], linewidth=2)
| + | |
| − | | + | |
| − | plt.title(f'Sumas de Cesàro (Mitigación de Gibbs) en [-1, 1]')
| + | |
| − | plt.xlabel('x')
| + | |
| − | plt.ylabel('S_N(x) [Cesàro]')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | # --- GRÁFICA 2: Evolución de Errores (Cesàro) ---
| + | |
| − | errores_l2 = []
| + | |
| − | errores_inf = []
| + | |
| − | rango_n = np.arange(1, N_max_calculo + 1)
| + | |
| − | | + | |
| − | for n in rango_n:
| + | |
| − | coefs_n = coefs_totales[:n+1]
| + | |
| − | y_cesaro = reconstruir_cesaro_par(coefs_n, x_completo)
| + | |
| − | | + | |
| − | l2, unif = calcular_errores_completo(y_real, y_cesaro, dx_malla)
| + | |
| − | errores_l2.append(l2)
| + | |
| − | errores_inf.append(unif)
| + | |
| − | | + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | plt.loglog(rango_n, errores_l2, 'b-o', label='Error L2 (Cesàro)', markersize=4)
| + | |
| − | plt.loglog(rango_n, errores_inf, 'r-s', label='Error Uniforme (Cesàro)', markersize=4)
| + | |
| − | | + | |
| − | plt.title('Evolución del Error en Sumas de Cesàro vs N')
| + | |
| − | plt.xlabel('N (log)')
| + | |
| − | plt.ylabel('Error (log)')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, which="both", alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | | + | |
| − | | + | |
| − | # --- Configuración (Tomamos los valores del caso anterior) ---
| + | |
| − | dx_malla = 1e-4
| + | |
| − | N_max_calculo = 500
| + | |
| − | lista_N_dibujar = [5, 20, 50, 100, 500]
| + | |
| − | | + | |
| − | # Dominio
| + | |
| − | x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
| + | |
| − | y_real = f_par_extendida(x_completo)
| + | |
| − | | + | |
| − | # Calculamos coeficientes (si no existen ya en memoria)
| + | |
| − | # Nota: Aquí SÍ usamos dx_malla
| + | |
| − | coefs_totales = construir_coeficientes(N_max_calculo + 1, dx_malla)
| + | |
| − | | + | |
| − | # ---------------------------------------------------------
| + | |
| − | # GRÁFICAS LANCZOS
| + | |
| − | # ---------------------------------------------------------
| + | |
| − | | + | |
| − | # 1. Aproximación Visual
| + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Original', alpha=0.5)
| + | |
| − | | + | |
| − | colores = plt.cm.viridis(np.linspace(0, 0.9, len(lista_N_dibujar)))
| + | |
| − | | + | |
| − | for i, n in enumerate(lista_N_dibujar):
| + | |
| − | coefs_n = coefs_totales[:n+1]
| + | |
| − | # Aquí NO hace falta dx, solo coeficientes y x
| + | |
| − | y_lanczos = reconstruir_lanczos_par(coefs_n, x_completo)
| + | |
| − | | + | |
| − | plt.plot(x_completo, y_lanczos, label=f'Lanczos N={n}', color=colores[i])
| + | |
| − | | + | |
| − | plt.title('Método de Lanczos (Factores Sigma)')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | # 2. Evolución del Error
| + | |
| − | errores_l2 = []
| + | |
| − | errores_inf = []
| + | |
| − | rango_n = np.arange(1, N_max_calculo + 1)
| + | |
| − | | + | |
| − | for n in rango_n:
| + | |
| − | coefs_n = coefs_totales[:n+1]
| + | |
| − | y_lanczos = reconstruir_lanczos_par(coefs_n, x_completo)
| + | |
| − | | + | |
| − | # Aquí usamos dx SOLO para calcular la integral del error L2
| + | |
| − | l2, unif = calcular_errores_completo(y_real, y_lanczos, dx_malla)
| + | |
| − | errores_l2.append(l2)
| + | |
| − | errores_inf.append(unif)
| + | |
| − | | + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | plt.loglog(rango_n, errores_l2, 'b-o', label='Error L2', markersize=4)
| + | |
| − | plt.loglog(rango_n, errores_inf, 'r-s', label='Error Uniforme', markersize=4)
| + | |
| − | plt.title('Error en Lanczos vs N')
| + | |
| − | plt.xlabel('N (log)')
| + | |
| − | plt.ylabel('Error (log)')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, which="both", alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | | + | |
| − | dx_malla = 1e-4
| + | |
| − | N_FIJO = 300 # Fijamos un N alto para tener "espacio" de frecuencias
| + | |
| − | lista_r_dibujar = [0.6, 0.8, 0.9, 0.95, 0.99, 0.999] # Variamos r
| + | |
| − | | + | |
| − | # Dominio
| + | |
| − | x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
| + | |
| − | y_real = f_par_extendida(x_completo)
| + | |
| − | | + | |
| − | # Calculamos coeficientes HASTA N_FIJO
| + | |
| − | coefs_fijos = construir_coeficientes(N_FIJO + 1, dx_malla)
| + | |
| − | | + | |
| − | # ---------------------------------------------------------
| + | |
| − | # GRÁFICA 1: Aproximación Visual (N fijo, r variable)
| + | |
| − | # ---------------------------------------------------------
| + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Original', alpha=0.3)
| + | |
| − | | + | |
| − | # Usamos un mapa de colores secuencial (Blues) para ver la progresión de r
| + | |
| − | colores = plt.cm.Blues(np.linspace(0.4, 1.0, len(lista_r_dibujar)))
| + | |
| − | | + | |
| − | for i, r_val in enumerate(lista_r_dibujar):
| + | |
| − | y_abel = reconstruir_abel_r_variable(coefs_fijos, x_completo, r_val)
| + | |
| − | | + | |
| − | plt.plot(x_completo, y_abel, label=f'r={r_val}', color=colores[i], linewidth=1.5)
| + | |
| − | | + | |
| − | plt.title(f'Método de Abel variando r (N fijo = {N_FIJO})')
| + | |
| − | plt.xlabel('x')
| + | |
| − | plt.ylabel('A_r(x)')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | # ---------------------------------------------------------
| + | |
| − | # GRÁFICA 2: Evolución del Error vs r
| + | |
| − | # ---------------------------------------------------------
| + | |
| − | # Generamos muchos valores de r entre 0.5 y 0.999
| + | |
| − | r_range = np.linspace(0.5, 0.999, 100)
| + | |
| − | | + | |
| − | errores_l2 = []
| + | |
| − | errores_inf = []
| + | |
| − | | + | |
| − | for r_val in r_range:
| + | |
| − | y_abel = reconstruir_abel_r_variable(coefs_fijos, x_completo, r_val)
| + | |
| − | | + | |
| − | l2, unif = calcular_errores_completo(y_real, y_abel, dx_malla)
| + | |
| − | errores_l2.append(l2)
| + | |
| − | errores_inf.append(unif)
| + | |
| − | | + | |
| − | plt.figure(figsize=(10, 6))
| + | |
| − | plt.loglog(r_range, errores_l2, 'b-o', label='Error L2', markersize=4)
| + | |
| − | plt.loglog(r_range, errores_inf, 'r-s', label='Error Uniforme', markersize=4)
| + | |
| − | plt.title(f'Evolución del Error al aumentar r (N={N_FIJO})')
| + | |
| − | plt.xlabel('Valor de r')
| + | |
| − | plt.ylabel('Error')
| + | |
| − | plt.legend()
| + | |
| − | plt.grid(True, which="both", alpha=0.3)
| + | |
| − | plt.show()
| + | |
| − | | + | |
| − | # Invertimos el eje X si quieres ver el efecto de acercarse a 1,
| + | |
| − | # o simplemente observamos que al acercarse a 1 el error L2 baja pero el Uniforme sube (Gibbs).
| + | |
| − | plt.show()
| + | |
| | | | |
| | + | <source lang="python" line> |
| | | | |
| | import numpy as np | | import numpy as np |
| Línea 751: |
Línea 313: |
| | | | |
| | plt.show() | | plt.show() |
| − |
| |
| | | | |
| | | | |
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate
def construir_coeficientes_par(funcion, n_terminos, dx=1e-3):
x = np.arange(0, 1 + dx/2, dx)
y = funcion(x)
coeficientes = []
for k in range(n_terminos):
termino_base = np.cos(k * np.pi * x)
integrando = 2 * y * termino_base
a_k = scipy.integrate.trapezoid(integrando, dx=dx)
coeficientes.append(a_k)
return coeficientes
def reconstruir_serie_par(coeficientes, x_eval):
a0 = coeficientes[0]
y_approx = (a0 / 2) * np.ones_like(x_eval)
for k in range(1, len(coeficientes)):
a_k = coeficientes[k]
y_approx += a_k * np.cos(k * np.pi * x_eval)
return y_approx
def f_par_extendida(x):
return np.where(np.abs(x) <= 0.25, 1.0, 0.0)
def calcular_errores_completo(y_real, y_aprox, dx):
diff = np.abs(y_real - y_aprox)
err_l2 = np.sqrt(scipy.integrate.trapezoid(diff**2, dx=dx))
err_unif = np.max(diff)
return err_l2, err_unif
def reconstruir_cesaro_par(coeficientes, x_eval):
N = len(coeficientes) - 1
y_approx = np.zeros_like(x_eval)
denominador = N + 1
a0 = coeficientes[0]
y_approx += (a0 / 2) * np.ones_like(x_eval)
for k in range(1, len(coeficientes)):
a_k = coeficientes[k]
peso = (N - k + 1) / denominador
y_approx += peso * a_k * np.cos(k * np.pi * x_eval)
return y_approx
def reconstruir_lanczos_par(coeficientes, x_eval):
N = len(coeficientes) - 1
y_approx = np.zeros_like(x_eval)
y_approx += (coeficientes[0] / 2)
for k in range(1, len(coeficientes)):
sigma = np.sinc(k / N)
y_approx += sigma * coeficientes[k] * np.cos(k * np.pi * x_eval)
return y_approx
def reconstruir_abel_r_variable(coeficientes, x_eval, r):
y_approx = np.zeros_like(x_eval)
y_approx += (coeficientes[0] / 2)
for k in range(1, len(coeficientes)):
peso = r**k
y_approx += peso * coeficientes[k] * np.cos(k * np.pi * x_eval)
return y_approx
# Gráficas de Fourier
dx_malla = 1e-4
N_max_calculo = 500
lista_N_dibujar = [1, 5, 20, 50, 100, 300]
x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
y_real = f_par_extendida(x_completo)
coefs_totales = construir_coeficientes_par(f_par_extendida, N_max_calculo + 1, dx_malla)
plt.figure(figsize=(12, 6))
plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Función Original', alpha=0.3)
colores = plt.cm.magma(np.linspace(0, 0.85, len(lista_N_dibujar)))
for i, n in enumerate(lista_N_dibujar):
coefs_n = coefs_totales[:n+1]
y_aprox = reconstruir_serie_par(coefs_n, x_completo)
plt.plot(x_completo, y_aprox, label=f'N={n}', color=colores[i], linewidth=1.5)
plt.title(f'Gráfica de Fourier en [-1, 1]')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
errores_l2 = []
errores_inf = []
rango_n = np.arange(1, N_max_calculo + 1)
for n in rango_n:
coefs_n = coefs_totales[:n+1]
y_aprox = reconstruir_serie_par(coefs_n, x_completo)
l2, unif = calcular_errores_completo(y_real, y_aprox, dx_malla)
errores_l2.append(l2)
errores_inf.append(unif)
plt.figure(figsize=(10, 6))
plt.loglog(rango_n, errores_l2, 'b-o', label='Error L2', markersize=4)
plt.loglog(rango_n, errores_inf, 'r-s', label='Error Uniforme', markersize=4)
plt.title(f'Errores de Fourier en [-1, 1]')
plt.xlabel('N (log)')
plt.ylabel('Error (log)')
plt.legend()
plt.grid(True, which="both", alpha=0.3)
plt.show()
# Gráficas de Cesaro
dx_malla = 1e-4
N_max_calculo = 500
lista_N_dibujar = [1, 5, 20, 50, 100, 300]
x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
y_real = f_par_extendida(x_completo)
coefs_totales = construir_coeficientes_par(f_par_extendida, N_max_calculo + 1, dx_malla)
plt.figure(figsize=(10, 6))
plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Función Original', alpha=0.6)
colores = plt.cm.magma(np.linspace(0, 0.85, len(lista_N_dibujar)))
for i, n in enumerate(lista_N_dibujar):
coefs_n = coefs_totales[:n+1]
y_cesaro = reconstruir_cesaro_par(coefs_n, x_completo)
plt.plot(x_completo, y_cesaro, label=f'N={n}', color=colores[i], linewidth=2)
plt.title(f'Gráfica de Cesàro en [-1, 1]')
plt.xlabel('x')
plt.ylabel('S_N(x)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
errores_l2 = []
errores_inf = []
rango_n = np.arange(1, N_max_calculo + 1)
for n in rango_n:
coefs_n = coefs_totales[:n+1]
y_cesaro = reconstruir_cesaro_par(coefs_n, x_completo)
l2, unif = calcular_errores_completo(y_real, y_cesaro, dx_malla)
errores_l2.append(l2)
errores_inf.append(unif)
plt.figure(figsize=(10, 6))
plt.loglog(rango_n, errores_l2, 'b-o', label='Error L2', markersize=4)
plt.loglog(rango_n, errores_inf, 'r-s', label='Error Uniforme', markersize=4)
plt.title(f'Errores de Cesàro en [-1, 1]')
plt.xlabel('N (log)')
plt.ylabel('Error (log)')
plt.legend()
plt.grid(True, which="both", alpha=0.3)
plt.show()
# Gráficas de Lanczos
dx_malla = 1e-4
N_max_calculo = 500
lista_N_dibujar = [1, 5, 20, 50, 100, 300]
x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
y_real = f_par_extendida(x_completo)
coefs_totales = construir_coeficientes_par(f_par_extendida, N_max_calculo + 1, dx_malla)
plt.figure(figsize=(10, 6))
plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Función Original', alpha=0.5)
colores = plt.cm.viridis(np.linspace(0, 0.9, len(lista_N_dibujar)))
for i, n in enumerate(lista_N_dibujar):
coefs_n = coefs_totales[:n+1]
y_lanczos = reconstruir_lanczos_par(coefs_n, x_completo)
plt.plot(x_completo, y_lanczos, label=f'N={n}', color=colores[i])
plt.title(f'Gráfica de Lanczos en [-1, 1]')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
errores_l2 = []
errores_inf = []
rango_n = np.arange(1, N_max_calculo + 1)
for n in rango_n:
coefs_n = coefs_totales[:n+1]
y_lanczos = reconstruir_lanczos_par(coefs_n, x_completo)
l2, unif = calcular_errores_completo(y_real, y_lanczos, dx_malla)
errores_l2.append(l2)
errores_inf.append(unif)
plt.figure(figsize=(10, 6))
plt.loglog(rango_n, errores_l2, 'b-o', label='Error L2', markersize=4)
plt.loglog(rango_n, errores_inf, 'r-s', label='Error Uniforme', markersize=4)
plt.title(f'Errores de Lanczos en [-1, 1]')
plt.xlabel('N (log)')
plt.ylabel('Error (log)')
plt.legend()
plt.grid(True, which="both", alpha=0.3)
plt.show()
#Gráficas de Abel
dx_malla = 1e-4
N_FIJO = 300
lista_r_dibujar = [0.6, 0.8, 0.9, 0.95, 0.99, 0.999]
x_completo = np.arange(-1, 1 + dx_malla/10, dx_malla)
y_real = f_par_extendida(x_completo)
coefs_fijos = construir_coeficientes_par(f_par_extendida, N_FIJO + 1, dx_malla)
plt.figure(figsize=(10, 6))
plt.plot(x_completo, y_real, 'k-', linewidth=2, label='Función Original', alpha=0.3)
colores = plt.cm.Blues(np.linspace(0.4, 1.0, len(lista_r_dibujar)))
for i, r_val in enumerate(lista_r_dibujar):
y_abel = reconstruir_abel_r_variable(coefs_fijos, x_completo, r_val)
plt.plot(x_completo, y_abel, label=f'r={r_val}', color=colores[i], linewidth=1.5)
plt.title(f'Gráfica de Abel en [-1, 1]')
plt.xlabel('x')
plt.ylabel('A_r(x)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
r_range = np.linspace(0.5, 0.999, 100)
errores_l2 = []
errores_inf = []
for r_val in r_range:
y_abel = reconstruir_abel_r_variable(coefs_fijos, x_completo, r_val)
l2, unif = calcular_errores_completo(y_real, y_abel, dx_malla)
errores_l2.append(l2)
errores_inf.append(unif)
plt.figure(figsize=(10, 6))
plt.loglog(r_range, errores_l2, 'b-o', label='Error L2', markersize=4)
plt.loglog(r_range, errores_inf, 'r-s', label='Error Uniforme', markersize=4)
plt.title(f'Errores de Abel en [-1, 1]')
plt.xlabel('r (log)')
plt.ylabel('Error (log)')
plt.legend()
plt.grid(True, which="both", alpha=0.3)
plt.show()
plt.show()