Modelos Continuos · Tema 30

Método de Euler

El integrador más simple: congelar la pendiente, saltar y repetir.

01 · Punto de partida

Congelar y saltar

En t = 2 la tasa del tanque es +1,4 por minuto: Euler supone que seguirá igual todo el paso y salta a N + 1,4·dt. Ahí reevalúa y vuelve a saltar. Un paso, una evaluación, ninguna magia: x ← x + f(x, t)·dt.

Es el integrador mínimo que todo programador debe saber escribir dormido: si Euler no funciona, nada funciona; si funciona, los demás afinan.

  • ¿Qué pendiente congelo en este nodo?
  • ¿Cuánto salto (dt) antes de reevaluar?
  • ¿Me paso (overshoot) o me quedo corto?
  • ¿El error se parte a la mitad con dt/2?

02 · Definición

¿Qué es el método de Euler?

La tangente llevada todo el paso:

→

Pendiente congelada

Usa f del inicio para todo el intervalo: entre nodos supone tasa fija.

dt

Salto dt

Avanza h = min(dt, T − t): el último se recorta al horizonte.

1

Orden 1

Partir dt a la mitad parte el error a la mitad. Predecible y costoso.

Con tasa constante es exacto en los nodos; con f(x) se pasa donde la curva se dobla: arriba en subidas que se frenan, abajo donde aceleran.

Euler en exponencial r = 0,3, P₀ = 10, T = 10: error final.
dtPasosError
25≈ 60 (se escapa).
110≈ 26 (visible).
0,520≈ 12 (mitad).
0,2540≈ 6 (orden 1).

03 · Anatomía

Overshoot, costo y estabilidad

Euler en tres miradas:

Overshoot
Se pasa donde f cambia: en exponencial exagera (pendiente vieja, curva nueva). Con dt grande, el error explota.
Costo
1 f por paso: T/dt evaluaciones. Barato por paso, caro por precisión.
Estabilidad
Con decaimiento −λ exige dt < 2/λ: más allá oscila y diverge (Tema 34).
Semi-implícito
En sistemas (x, v): primero v, luego x. Misma firma, mucha más estabilidad.

Euler explícito

Usa lo viejo

x con f(xₙ): simple y general. En oscilaciones inyecta energía con dt grande.

Euler semi-implícito

Usa lo recién calculado

v nueva para x nueva: en resorte y órbitas conserva mejor con el mismo dt.

04 · Euler en el curso

El integrador de todos los laboratorios

Cada canvas hasta aquí integró con Euler (fino o visible):

f(x, t)→x + f·h→Historia
  1. 1
    Tanque y SIR.

    Euler fino dt = 0,05–0,5: la curva parece exacta.

  2. 2
    Duelo (Tema 28).

    Euler visible dt = 1: se pasa y enseña.

  3. 3
    Resorte (Tema 9).

    Semi-implícito: v antes que x para no inyectar energía.

  4. 4
    Sistemas (Temas 10, 20).

    Todas las tasas primero, todos los estados después.

  5. 5
    RK (Tema 31).

    Euler es RK1: el primer peldaño de la escalera.

05 · Representación en Python

Euler genérico en seis líneas

En Python, Euler es un bucle sobre f con recorte al horizonte. La misma función sirve para tanques, SIR y resortes.

Python en tu navegador. Estos bloques se ejecutan localmente con Pyodide, sin instalar nada. Duplicá dt y observá que el error casi se duplica.

import math


def euler(f, x0, t_final, dt):
    x, t = x0, 0.0
    while t < t_final - 1e-9:
        h = min(dt, t_final - t)
        x = x + f(x, t) * h
        t += h
    return x


f_exp = lambda p, t: 0.3 * p
exacta = 10 * math.exp(0.3 * 10)
for dt in [2, 1, 0.5, 0.25]:
    print(dt, round(euler(f_exp, 10, 10, dt), 1))

261 → 227 → 213 → 207 frente a exacta 200,9: gatea hacia ella partiendo el error.

Error que confirma el orden 1

Partir dt parte el error:

for dt in [2, 1, 0.5, 0.25]:
    e = abs(exacta - euler(f_exp, 10, 10, dt))
    print(dt, round(e, 1))

06 · Exploración

Laboratorio: la tangente que se pasa

Exponencial dP/dt = r·P desde P₀ = 10 hasta T = 10 con tu dt y tu r. Dorada: exacta. Teal con nodos: Euler, siempre por arriba (la pendiente vieja exagera). Achicá dt y observá que gatea hacia la exacta partiendo el error.

EXPERIMENTO 30

Overshoot visible

dP/dt = r·P · Euler(dt) vs exacta

Los resultados numéricos aparecen debajo.
Exacta en T=10200,86
Euler en T=10227,34
Error (sobre)26,48
Pasos10

Con dt 1 Euler se pasa en 26,48 (13 %): la tangente exagera.

Cada tramo teal arranca tangente a la dorada y se despega por arriba: el overshoot se acumula paso a paso.

Preguntas para explorar

  1. Con dt = 2, ¿el error se duplica respecto a dt = 1? ¿Qué orden confirma?
  2. Con r = 0,6, ¿el overshoot crece? ¿Por qué castiga más la curvatura?
  3. Si r fuera −0,3 (decaimiento), ¿Euler quedaría por arriba o por debajo?
Ver respuestas sugeridas
  1. Sí (≈ 60 vs 26): orden 1, error ∝ dt. Partir el paso parte el error.
  2. Sí: más curvatura, más mentira la tangente entre nodos.
  3. Por debajo en magnitud (cae de más): la tangente exagera hacia ambos lados.

07 · Comprensión

Confusiones frecuentes

«Euler es exacto si dt es chico»

Es preciso, no exacto: el error tiende a 0 con dt pero nunca es 0. Solo tasa constante lo clava.

«El error se ve solo al final»

Se acumula en cada paso: mirar la banda completa distingue overshoot de cancelación afortunada.

«dt/2 siempre alcanza»

Parte el error, no lo elimina: de 26 a 13, no a 0,1. Para eso están los RK.

«Explícito y semi-implícito dan igual»

En f(x) simple casi; en (x, v) oscilante el semi-implícito conserva energía mucho mejor.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: un paso a mano

Desde P = 10 con r = 0,3 y dt = 1, ¿a dónde salta Euler? ¿Y la exacta en t = 1?

import math


print("euler:", 10 + 0.3 * 10 * 1)
print("exacta:", round(10 * math.exp(0.3), 2))
Ver solución

Euler 13,0 frente a exacta 13,5: en un paso ya se nota. En diez se acumula a 26.

Ejercicio 2: orden 1 en números

Calculá el error final con dt = 1 y dt = 0,5 en la exponencial (r = 0,3, T = 10). ¿Se parte?

import math


def euler(r, p0, t_final, dt):
    p, t = p0, 0.0
    while t < t_final - 1e-9:
        p += r * p * min(dt, t_final - t)
        t += min(dt, t_final - t)
    return p


ex = 10 * math.exp(3)
for dt in [1, 0.5]:
    print(dt, round(abs(ex - euler(0.3, 10, 10, dt)), 1))
Ver solución

26,5 y 12,5: se parte a la mitad. Orden 1 firmado con números.

Ejercicio 3: Euler genérico con historia

Escribí euler_historia(f, x0, T, dt) que devuelva pares (t, x). Probalo en el tanque q = 3, k = 0,2.

Ver una posible respuesta
def euler_historia(f, x0, t_final, dt):
    x, t, hist = x0, 0.0, [(0.0, x0)]
    while t < t_final - 1e-9:
        h = min(dt, t_final - t)
        x = x + f(x, t) * h
        t += h
        hist.append((round(t, 2), round(x, 2)))
    return hist


f = lambda x, t: 3 - 0.2 * x
print(euler_historia(f, 2, 4, 2.0))

Historia con 3 puntos hasta (4, ·): la misma firma sirve para todo el curso.

09 · Síntesis

Ideas para recordar

  • Euler: x + f·h con h = min(dt, T − t); una f por paso, orden 1.
  • Se pasa donde f cambia: overshoot que se acumula; partir dt parte el error.
  • En sistemas: semi-implícito (v antes que x); tasas todas antes que estados.
  • En Python: euler(f, x0, T, dt) genérico + historia de pares.
  • dt debe resolver la física (1/k, período): si no, es otro sistema.

En el próximo tema promediaremos pendientes: Runge-Kutta.