01 · Punto de partida
Una ecuación sola no alcanza
El agua que sale del primer tanque alimenta al segundo. Los susceptibles que se contagian alimentan a los infectados. La posición alimenta a la velocidad y viceversa. En cada caso, la tasa de un estado depende de otro estado: hace falta un sistema de ecuaciones.
El sistema se integra como un todo: no se puede resolver A sin B ni B sin A. El vector evoluciona junto o no evoluciona.
- ¿Qué estados comparten tasas?
- ¿Quién alimenta a quién?
- ¿Qué se conserva entre todos (masa, población, energía)?
- ¿Dónde está el equilibrio conjunto?
02 · Definición
¿Qué es un sistema de ecuaciones diferenciales?
n estados, n tasas, n arranques:
Vector x
El paquete: [A, B], [S, I, R], [x, v]. Cada uno tiene su curva, todas comparten el tiempo.
Acoplamiento
Una tasa usa otro estado: dB/dt = k₁·A − k₂·B. Ahí vive la interacción.
Equilibrio conjunto
Todas las tasas en cero a la vez: f(x*) = 0. Un estado quieto no basta.
Si las tasas no se cruzan, no hay sistema: son dos EDOs sueltas que casualmente viven en la misma página.
| Sistema | Ecuaciones | Acoplamiento |
|---|---|---|
| Tanques en cascada | dA/dt = q − k₁A, dB/dt = k₁A − k₂B | A alimenta a B en una dirección. |
| SIR | dS, dI, dR con contagio βSI/N | S → I → R en cadena cerrada. |
| Resorte (x, v) | dx/dt = v, dv/dt = −kx − cv | Ida y vuelta entre posición y velocidad. |
| Depredador-presa | Dos tasas con encuentro xy | Mutuo: cada uno mueve al otro. |
03 · Anatomía
Cascada, ciclo y conservación
Los acoplamientos tienen formas típicas:
- Cascada
- A alimenta a B sin retorno: tanques en serie. B retrasa y suaviza lo que A ya hizo.
- Ciclo
- A mueve a B y B mueve a A: resorte, SIR, depredador-presa. Pueden oscilar.
- Conservación
- Lo que sale de uno entra a otro: S + I + R constante. La suma de tasas es cero.
- Equilibrio del sistema
- Resolver f₁ = 0 y f₂ = 0 juntas: A* = q/k₁, B* = q/k₂ en la cascada lineal.
Sin acoplamiento
Dos relojes sueltos
dA/dt = −k₁A, dB/dt = −k₂B: cada uno decae por su cuenta. Juntarlos no crea sistema.
Con acoplamiento
Una historia compartida
dB/dt = k₁A − k₂B: B sube cuando A está alto aunque B parta de cero. B hereda el pasado de A.
04 · Sistemas en el curso
El mismo vector, cinco contenidos
Todo sistema del curso es un vector con su f:
- 1Cascada de tanques.
[A, B]: el primero alimenta al segundo. Retardo y suavizado.
- 2SIR.
[S, I, R]: cadena con conservación total. Joroba de I.
- 3Resorte.
[x, v]: ciclo posición-velocidad. Oscilación.
- 4Expuestos (SEIR).
[S, E, I, R]: latencia que retrasa el pico.
- 5Dos temperaturas.
[T₁, T₂]: dos cuerpos que se intercambian calor y convergen.
05 · Representación en Python
El estado es un dict, f devuelve un dict
En Python, el sistema es una función f(estado, t) que recibe el vector y devuelve el vector de derivadas. Euler avanza todo el dict junto con el mismo dt.
Python en tu navegador. Estos bloques se ejecutan localmente con Pyodide, sin instalar nada. Cambiá k1 y observá que B responde aunque sus parámetros no cambien.
def f_cascada(estado, q, k1, k2):
a, b = estado["A"], estado["B"]
return {"dA": q - k1 * a, "dB": k1 * a - k2 * b}
print(f_cascada({"A": 0.0, "B": 0.0}, 3, 0.3, 0.2))
Con ambos vacíos, A sube a +3 pero B quieto en 0: B necesita que A tenga algo para arrancar.
Un paso del sistema completo
El paso actualiza A y B con las tasas del mismo instante:
def paso(estado, q, k1, k2, dt):
d = f_cascada(estado, q, k1, k2)
return {"A": estado["A"] + d["dA"] * dt, "B": estado["B"] + d["dB"] * dt}
x = {"A": 0.0, "B": 0.0}
for _ in range(3):
x = paso(x, 3, 0.3, 0.2, dt=1.0)
print({k: round(v, 2) for k, v in x.items()})
06 · Exploración
Laboratorio: el segundo tanque hereda el pasado
Cascada dA/dt = q − k₁A, dB/dt = k₁A − k₂B desde vacíos. A (dorada) sube primero; B (teal) la sigue con retardo y punteadas en A* y B*. Tocá k₁ y mirá cómo el primero manda sobre el segundo.
Dos niveles, una historia
A → B · q = 3, vacíos al inicio
Con q 3, A* = 10 y B* = 15: B tarda más en llegar.
B arranca plana (su tasa inicial es cero con A vacío) y despega cuando A le entrega caudal: el retardo es la firma de la cascada.
Preguntas para explorar
- ¿Cuál es la tasa inicial de B? ¿Por qué su curva arranca horizontal?
- Subí k₁ con q y k₂ fijos. ¿A* y B* se mueven igual?
- Si k₂ es mucho mayor que k₁, ¿B sigue de cerca a A o se despega?
Ver respuestas sugeridas
- Cero: dB/dt = k₁·0 − k₂·0. B espera a que A tenga nivel: arranque plano = cascada.
- A* = q/k₁ baja, B* = q/k₂ no se mueve: el equilibrio de B lo mandan q y k₂, no k₁.
- La sigue de cerca: B drena rápido y copia a A con poco retardo. El lento manda la forma.
07 · Comprensión
Confusiones frecuentes
«Integro A y después B»
No: el acoplamiento exige avanzar juntos. Integrar en serie usa valores de A de tiempos que B aún no vivió.
«Equilibrio de A ya es equilibrio»
El sistema reposa cuando todas las tasas son cero. A quieto con B moviéndose es transitorio, no régimen.
«Más estados, mejor modelo»
Cada estado pide condición inicial, tasas y datos. Un estado sin datos es una curva inventada con ecuaciones.
«El orden de actualización no importa»
Sí importa: actualizá con las tasas del mismo instante (todas primero, después todos los estados).
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: equilibrio conjunto
Con q = 4, k₁ = 0,4 y k₂ = 0,2, ¿cuánto valen A* y B*? Comprobalo anulando ambas tasas.
def equilibrios(q, k1, k2):
return q / k1, q / k2
print(equilibrios(4, 0.4, 0.2))
Ver solución
(10,0, 20,0): A* lo fija k₁ y B* lo fija k₂; q escala a ambos por igual.
Ejercicio 2: arranque de B
Si A = 0 y B = 0, ¿cuánto valen dA y dB con q = 3, k₁ = 0,3, k₂ = 0,2? ¿Y con A = 10, B = 0?
def f_cascada(estado, q, k1, k2):
return (q - k1 * estado["A"], k1 * estado["A"] - k2 * estado["B"])
print(f_cascada({"A": 0.0, "B": 0.0}, 3, 0.3, 0.2))
print(f_cascada({"A": 10.0, "B": 0.0}, 3, 0.3, 0.2))
Ver solución
(3,0, 0,0) y (0,0, 3,0): B solo despega cuando A le entrega. La cascada se lee en las tasas.
Ejercicio 3: simular el sistema junto
Integrá ambos tanques juntos con Euler (dt = 0,5) hasta T = 40 desde vacíos. ¿A qué valores llegan?
Ver una posible respuesta
def simular(q, k1, k2, t_final, dt=0.5):
a, b, t = 0.0, 0.0, 0.0
while t < t_final - 1e-9:
da = q - k1 * a
db = k1 * a - k2 * b
a, b = a + da * dt, b + db * dt
t += dt
return round(a, 2), round(b, 2)
print(simular(3, 0.3, 0.2, 40))
Llegan a ≈ (10,0, 15,0): A* y B* con B retardada. Todo junto, todo con el mismo dt.
09 · Síntesis
Ideas para recordar
- Sistema = vector dx/dt = f(x, t) con tasas que cruzan estados; se integra junto.
- Cascada (A → B), ciclo (A ⇄ B) y conservación (suma de tasas cero) son las formas típicas.
- El equilibrio anula todas las tasas a la vez: A* = q/k₁, B* = q/k₂.
- En Python: f devuelve dict de derivadas; el paso calcula todo y después actualiza todo.
- B arranca plana y sigue a A con retardo: la firma visual de la cascada.
En el próximo tema fijaremos los arranques: las condiciones iniciales que eligen la curva.