Una vez finalizado el curso, por favor ayúdanos completando la siguiente **Encuesta de FINAL del curso**.

[](https://forms.office.com/Pages/ResponsePage.aspx?id=r4yvt9iDREaFrjF8VFIjwUHkKiCq1wxFstxAwkoFiilUOExRVkVMWlZERVcyWlpUU1EyTFg4T1Q3WC4u)

## 11. Ecuaciones Diferenciales

[Playlist de Ciencia de Datos en castellano](https://www.youtube.com/playlist?list=PLjyvn6Y1kpbEmRY4-ELeRA80ZywV7Xd67)
[](https://www.youtube.com/watch?v=HReAo38LoM4&list=PLLBUgWXdTBDg1Qgmwt4jKtVn9BWh5-zgy "Python Data Science")

Algunas ecuaciones con términos diferenciales surgen de relaciones fundamentales como conservación de masa, energía y momento. Por ejemplo, la aculumación de masa $\frac{dm}{dt}$ en un volumen de control es igual a la masa que entra $\dot m_{in}$ menos la masa que sale $\dot m_{out}$ de ese volumen.  

$\frac{dm}{dt} = \dot m_{in} - \dot m_{out}$

Se puede desarrollar un modelo dinámico mediante regresión de datos o con relaciones fundamentales sin necesidad de datos. Incluso las relaciones fundamentales pueden tener parámetros desconocidos o inciertos. Un enfoque para el modelado dinámico es combinar relaciones físicas fundamentales con Ciencia de Datos. Este enfoque usa lo mejor de ambos métodos porque crea un modelo que se alinea con los valores medidos y puede extrapolarse a regiones donde los datos son limitados o inexistentes.        



En este primer ejercicio para [resolver ecuaciones diferenciales](https://www.youtube.com/watch?v=v9fGOHQMeIA) vamos a utilizar `odeint`. Los mismos ejemplos también serán [resueltos con Gekko](https://apmonitor.com/pdc/index.php/Main/PythonDifferentialEquations). Ambos alcanzan resultados equivalentes de simulación. Sin embargo, Gekko está diseñado para usar ecuaciones diferenciales en optimización o combinarse con aprendizaje automático (machine learning). La función `odeint` tiene como propósito principal resolver ecuaciones diferenciales ordinarias (EDO), y requiere tres entradas (inputs).

    y = odeint(model, y0, t)

1. `model` Nombre de la Función que devuelve la derivada para un par de valores solicitados `y`, `t`, de la forma `dydt = model(y,t)`.
2. `y0` Condiciones iniciales.
3. `t` Puntos de tiempo donde se reporta la solución. 



### Resolver Ecuaciones  Diferenciales

Resolveremos la ecuación diferencial con la condición inicial $y(0) = 5$:

$ k \, \frac{dy}{dt} = -y$

Donde $k=10$. La solución para `y` se reporta desde un tiempo inicial `0` hasta un tiempo final `20`. También se grafica el resultado para $y(t)$ vs. $t$. Notemos cómo se establece la ecuación para obtener la derivada como `dydt = -(1.0/k) * y` a partir de la función.


```python
import numpy as np
from scipy.integrate import odeint

# función que devuelve dy/dt
def model(y,t):
    k = 10.0
    dydt = -(1.0/k) * y
    return dydt

y0 = 5                 # condición inicial
t = np.linspace(0,20)  # puntos de tiempo
y = odeint(model,y0,t) # resolución de la ODE

import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(t,y)
plt.xlabel('Tiempo'); plt.ylabel('y(t)')

plt.show()
```



### Resolver Ecuaciones Diferenciales con Gekko

[Python Gekko](https://gekko.readthedocs.io/en/latest/) resuelve la misma ecuación diferencial. Está diseñado para problemas a gran escala. El [tutorial de Gekko en inglés](https://apmonitor.com/wiki/index.php/Main/GekkoPythonOptimization) nos muestra cómo resolver otro tipo de problemas con ecuaciones y optimización.


```python
from gekko import GEKKO

m = GEKKO(remote=False)    # modelo GEKKO
m.time = np.linspace(0,20) # puntos de tiempo
y = m.Var(5.0); k = 10.0   # variables y constantes GEKKO
m.Equation(k*y.dt()+y==0)  # Ecuación GEKKO

m.options.IMODE = 4        # Simulación dinámica
m.solve(disp=False)        # Resolución

plt.plot(m.time,y)
plt.xlabel('Tiempo'); plt.ylabel('y(t)')
plt.show()
```



### Actividad sobre Ecuaciones Diferenciales

Resuelve la ecuación diferencial con condición inicial $y(0) = 10$:

$ k \, \frac{dy}{dt} = -y$

Compara las primeras cinco soluciones de `y` entre los tiempos `0` y `20` con `k=[1,2,5,10,20]`.


```python

```



### Solución Simbólica 

Los problemas con ecuaciones diferenciales que tienen solución analítica pueden expresarse simbólicamente. Una librería con símbolos matemáticos en Python es `sympy`. Sympy determina la solución analítica como $y(x)=C_1 \, \exp{\left(-\frac{x}{k}\right)}$. Con la condición inicial $y(0)=5$, y la constante $C_1$ igual a 5.


```python
from IPython.display import display
import sympy as sym
from sympy.abc import x, k
y = sym.Function('y')
ans = sym.dsolve(sym.Derivative(y(x), x) + y(x)/k, y(x))
display(ans)
```



### Resolver Ecuaciones Diferenciales con Entradas (Input) `u`

Las ecuaciones diferenciales también pueden tener una entrada (atributo) que cambie desde una fuente externa (entrada exógena). Por ejemplo, cambios interactivos debido a medidas de un sensor, a personas (manualmente) o seleccionados por un computador.



Calcula la respuesta `y(t)` cuando la entrada `u` cambia desde `0` a `2` en `t = 5`.

$2 \frac{dy(t)}{dt} + y(t) = u(t)$

La condición inicial es `y(0)=1` y la solución puede calcularse hasta `t=15`. **Ayuda**: La expresión `y(t)` no es equivalente a `y` multiplicado por `t`. Esta indica que `y` cambia con el tiempo y se escribe como una función del tiempo. Hay ejemplos adicionales para [odeint en inglés](https://apmonitor.com/pdc/index.php/Main/SolveDifferentialEquations) y [Gekko en inglés](https://apmonitor.com/pdc/index.php/Main/PythonDifferentialEquations) por si necesitas ayuda.


```python

```

### Actividad con el TCLab



### Recolección de Datos



Enciende el calentador 1 al 100% y guarda el valor de $T_1$ cada 5 segundos durante 3 minutos. Los datos deben incluir un total de 37 puntos para cada sensor de temperatura.


```python
import numpy as np
import pandas as pd
import tclab
import time
# Recolectar datos por 3 minutos, cada 5 segundos
n = 37
tm = np.linspace(0,180,n)
t1s = np.empty(n); t2s = np.empty(n)
with tclab.TCLab() as lab:
    lab.Q1(100); lab.Q2(0)
    print('Tiempo T1  T2')
    for i in range(n):
        t1s[i] = lab.T1; t2s[i] = lab.T2
        print(tm[i],t1s[i],t2s[i])
        time.sleep(5.0)
# Colocar en un Dataframe
data = pd.DataFrame(np.column_stack((tm,t1s,t2s)),\
                    columns=['Tiempo','T1','T2'])
data.to_csv('11-data.csv',index=False)
```



### Resolver Ecuaciones Diferenciales

Usa los parámetros `a`, `b` y `c` del módulo [10. Resolver Ecuaciones](https://github.com/APMonitor/data_science/blob/master/10.%20Solve_Equations.ipynb) o utiliza los siguientes valores:

| Parámetro | Valor |
|------|------|
| a    | 78.6 |
| b    | -50.3 |
| c    | -0.003677 |

Resuelve la ecuación diferencial ordinaria (ODE en inglés) con estos valores.

$\frac{dT_1}{dt} = c (T_1-a)$

La condición inicial para $T_1$ es $a + b$. Muestra la solución para la ODE en el intervalo de tiempo desde `0` hasta `180` segundos. Grafica el valor medido de $T_1$ en la misma figura que muestra la predicción de la temperatura por la ODE. Añade las etiquetas necesarias en el gráfico.


```python

```

77d00d711bf6153f8c937bd8622b39678a590629
ipynb
Jupyter Notebook
11. Ecuaciones_diferenciales.ipynb
APMonitor/ciencia_de_datos
4e989992a71bc59040799772af14784a83b94153
MIT
2021-08-21T15:32:07.000Z
2021-12-05T15:56:38.000Z
11. Ecuaciones_diferenciales.ipynb
APMonitor/ciencia_de_datos
4e989992a71bc59040799772af14784a83b94153
MIT
11. Ecuaciones_diferenciales.ipynb
APMonitor/ciencia_de_datos
4e989992a71bc59040799772af14784a83b94153
MIT
2021-05-27T06:08:57.000Z
2021-12-19T20:57:15.000Z
Qwen/Qwen-72B
1. YES
2. YES