lunes, 3 de junio de 2024

Método de Euler Explicito e Implícito en Python 3

Métodos numéricos: Euler Explicito e Implícito

El método de Euler es una técnica numérica utilizada para resolver ecuaciones diferenciales ordinarias (ODEs). Hay dos versiones principales del método de Euler: explícito e implícito. A continuación, se presenta una tabla comparativa que destaca las diferencias clave entre estos métodos:

Característica Método de Euler Explícito Método de Euler Implícito
Fórmula
Estabilidad Condicionalmente estable, puede requerir pasos pequeños Más estable, puede manejar pasos más grandes
Simplicidad Más sencillo de implementar Más complejo, puede requerir resolver ecuaciones algebraicas
Cálculo en cada paso Directo, no requiere resolver sistemas de ecuaciones Implica resolver una ecuación no lineal en cada paso
Aplicabilidad Adecuado para problemas donde la estabilidad no es crítica Adecuado para problemas donde la estabilidad es crítica
Velocidad Más rápido en cada paso Más lento en cada paso debido a la necesidad de resolver ecuaciones
Convergencia Menor precisión, puede necesitar pasos más pequeños Mayor precisión con pasos más grandes

Por ejemplo, el siguiente código en Python que implemente ambos métodos de Euler para resolver la ecuación diferencial $$\frac{dy}{dx} + 3y = 13\sin(2t)$$ y calcular el error comparando con la solución analítica:

import numpy as np
import matplotlib.pyplot as plt

# Definición de la ecuación diferencial
def f(t, y):
    return 13 * np.sin(2 * t) - 3 * y

# Solución analítica para la comparación
def y_exact(t):
  
    return 8 * np.exp(-3*t)-2*np.cos(2*t) + 3*np.sin(2*t)

# Método de Euler Explícito
def euler_explicito(f, t0, y0, h, n):
    t = np.zeros(n+1)
    y = np.zeros(n+1)
    t[0], y[0] = t0, y0
    for i in range(n):
        y[i+1] = y[i] + h * f(t[i], y[i])
        t[i+1] = t[i] + h
    return t, y

# Método de Euler Implícito
def euler_implicito(f, t0, y0, h, n):
    t = np.zeros(n+1)
    y = np.zeros(n+1)
    t[0], y[0] = t0, y0
    for i in range(n):
        t[i+1] = t[i] + h
        y_guess = y[i]  # Guess inicial
        # Iteración de punto fijo para resolver y[i+1]
        for _ in range(10):  # 10 iteraciones
            y_guess = y[i] + h * f(t[i+1], y_guess)
        y[i+1] = y_guess
    return t, y

# Parámetros de la solución
t0, y0 = 0, 0  # Condiciones iniciales
h = 0.01  # Paso de tiempo
t_final = 5 # Tiempo final
n = int((t_final - t0) / h)  # Número de pasos

# Resolviendo la ODE con ambos métodos
t_exp, y_exp = euler_explicito(f, t0, y0, h, n)
t_imp, y_imp = euler_implicito(f, t0, y0, h, n)

# Solución exacta
y_exacta = y_exact(t_exp)

# Calculando el error
error_exp = np.abs(y_exacta - y_exp)
error_imp = np.abs(y_exacta - y_imp)

# Graficando las soluciones y los errores
plt.figure(figsize=(8, 6))

# Soluciones
plt.subplot(2, 1, 1)
plt.plot(t_exp, y_exacta, label='Solución Exacta', color='black', linestyle='dashed')
plt.plot(t_exp, y_exp, label='Euler Explícito', color='blue')
plt.plot(t_imp, y_imp, label='Euler Implícito', color='red')
plt.legend()
plt.xlabel('t')
plt.ylabel('y')
plt.title('Soluciones de la ODE')
plt.grid()

# Errores
plt.subplot(2, 1, 2)
plt.plot(t_exp, error_exp, label='Error Euler Explícito', color='blue')
plt.plot(t_imp, error_imp, label='Error Euler Implícito', color='red')
plt.legend()
plt.xlabel('t')
plt.ylabel('Error')
plt.title('Error de las soluciones')
plt.grid()
plt.tight_layout()
plt.show()

La solución de la ecuación diferencial se muestra a continuación:

Solucion_ODE

Solución analítica

Utilizando el método de la transformada de Laplace se resolverá la ecuación diferencial siguiente:

  \frac{dy}{dx}+3y = 13Sin 2t \:\: \forall \:\: y\left ( 0 \right )=5

Aplicando la transformada de Laplace a la Ecuación diferencial anterior se obtiene la solución para Y(S).

  Y\left (S \right )=\frac{6s^{2}+50}{\left ( s+3 \right )\left ( s^{2}+4 \right )} 

La solución en el dominio del tiempo se obtiene con la transformada inversa.

  y\left ( t \right )=8e^{-3t}-2Cos2t+3Sin2t