#!/usr/bin/env python # coding: utf-8 # # Ecuaciones Diferenciales con Python # *Esta notebook fue creada originalmente como un blog post por [Raúl E. López Briega](http://relopezbriega.com.ar/) en [Matemáticas, análisis de datos y python](http://relopezbriega.github.io). El contenido esta bajo la licencia BSD.* # # ## Introducción # # Vivimos en un mundo en constante cambio. La posición de la Tierra cambia con el tiempo; la velocidad de un objeto en caída libre cambia con la distancia; el área de un círculo cambia según el tamaño de su *radio*; la trayectoria de un proyectil cambia según la velocidad y el ángulo de disparo. # Al intentar modelar matemáticamente cualquiera de estos fenómenos, veremos que generalmente adoptan la forma de una o más [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial). # # **_Nota_**: Antes de continuar leyendo, si no tienen frescos sus conocimientos básicos de [Cálculo integral](https://es.wikipedia.org/wiki/Integraci%C3%B3n) y [Cálculo diferencial](https://es.wikipedia.org/wiki/C%C3%A1lculo_diferencial); les recomiendo que visiten mi anterior artículo de [Introducción al Cálculo](http://relopezbriega.github.io/blog/2015/12/02/introduccion-al-calculo-con-python/). # # ## ¿Qué es una ecuación diferencial? # # Una [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) es una ecuación que involucra una variable dependiente y sus [derivadas](https://es.wikipedia.org/wiki/Derivada) con respecto a una o más variables independientes. Muchas de las leyes de la naturaleza, en [Física](https://es.wikipedia.org/wiki/F%C3%ADsica), [Química](https://es.wikipedia.org/wiki/Qu%C3%ADmica), [Biología](https://es.wikipedia.org/wiki/Biolog%C3%ADa), y [Astronomía](https://es.wikipedia.org/wiki/Astronom%C3%ADa); encuentran la forma más natural de ser expresadas en el lenguaje de las [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial). Estas ecuaciones no sólo tienen aplicaciones en la ciencias físicas, sino que también abundan sus aplicaciones en las ciencias aplicadas como ser [Ingeniería](https://es.wikipedia.org/wiki/Ingenier%C3%ADa), [Finanzas](https://es.wikipedia.org/wiki/Finanzas) y [Economía](https://es.wikipedia.org/wiki/Econom%C3%ADa). # # Es fácil entender la razón detrás de esta amplia utilidad de las [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial). Si recordamos que $y = f(x)$ es una [función](https://es.wikipedia.org/wiki/Funci%C3%B3n_matem%C3%A1tica), entonces su [derivada](https://es.wikipedia.org/wiki/Derivada) $dy / dx$ puede ser interpretada como el *ritmo de cambio* de $y$ con respecto a $x$. En muchos procesos naturales, las variables involucradas y su *ritmo de cambio* están conectados entre sí por medio de los principios científicos básicos que rigen el proceso. Cuando esta conexión es expresada matemáticamente, el resultado generalmente es una [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial). # # Para ilustrar el caso, veamos un ejemplo. Según la [segunda ley de la dinámica de Newton](https://es.wikipedia.org/wiki/Leyes_de_Newton#Segunda_Ley_de_Newton_o_Ley_Fundamental_de_la_din.C3.A1mica), la [aceleración](https://es.wikipedia.org/wiki/Aceleraci%C3%B3n) $a$ de un cuerpo de [masa](https://es.wikipedia.org/wiki/Masa) $m$ es proporcional a la [fuerza](https://es.wikipedia.org/wiki/Fuerza) total $F$ que actúa sobre él. Si expresamos esto matemáticamente en la forma de una ecuación, entonces tememos que: # # $$F = ma$$ # # A primera vista, esta ecuación no parece ser una [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial), pero supongamos que un objeto de [masa](https://es.wikipedia.org/wiki/Masa) $m$ esta en caída libre bajo la influencia de la [fuerza](https://es.wikipedia.org/wiki/Fuerza) de [gravedad](https://es.wikipedia.org/wiki/Gravedad). En este caso, la única [fuerza](https://es.wikipedia.org/wiki/Fuerza) actuando sobre el objeto es $mg$, donde $g$ es la [aceleración](https://es.wikipedia.org/wiki/Aceleraci%C3%B3n) debido a la [gravedad](https://es.wikipedia.org/wiki/Gravedad). Si consideramos a $u$, como la posición del objeto desde una altura determinada; entonces la [velocidad](https://es.wikipedia.org/wiki/Velocidad) de caída del objeto va a ser igual al *ritmo de cambio* de la posición $u$ con respecto al tiempo $t$; es decir que la [velocidad](https://es.wikipedia.org/wiki/Velocidad) es igual a $v = du / dt$, o sea, la [derivada](https://es.wikipedia.org/wiki/Derivada) de la posición del objeto con respecto al tiempo; y como la [aceleración](https://es.wikipedia.org/wiki/Aceleraci%C3%B3n) no es otra cosa que el *ritmo de cambio* de la [velocidad](https://es.wikipedia.org/wiki/Velocidad), entonces podemos definir a la [aceleración](https://es.wikipedia.org/wiki/Aceleraci%C3%B3n) como una segunda [derivada](https://es.wikipedia.org/wiki/Derivada) de la posición del objeto con respecto al tiempo, lo que es igual a decir que $g = d^2u / dt^2$. De esta forma, podemos reescribir la ecuación inicial de la [segunda ley de la dinámica de Newton](https://es.wikipedia.org/wiki/Leyes_de_Newton#Segunda_Ley_de_Newton_o_Ley_Fundamental_de_la_din.C3.A1mica) como la siguiente [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial). # # $$F = m\frac{d^2u}{dt^2}$$ # # De esta manera, estamos expresando a la [segunda ley de la dinámica de Newton](https://es.wikipedia.org/wiki/Leyes_de_Newton#Segunda_Ley_de_Newton_o_Ley_Fundamental_de_la_din.C3.A1mica) en función de la posición del objeto. # # ### Ecuaciones diferenciales ordinarias y parciales # # El caso precedente, es el caso típico de una [Ecuación diferencial ordinaria](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria), ya que todas las [derivadas](https://es.wikipedia.org/wiki/Derivada) involucradas son tomadas con respecto a una única y misma variable independiente. Por otro lado, si en la ecuación tenemos [derivadas](https://es.wikipedia.org/wiki/Derivada) de más de una variable independiente, debemos hablar de [Ecuaciones difenciales parciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_en_derivadas_parciales). Por ejemplo, si $w = f(x, y, z, t)$ es una función de tiempo y 3 coordenadas de un punto en el espacio, entonces las siguientes son sus [Ecuaciones diferenciales parciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_en_derivadas_parciales): # # $$\frac{\partial^2 w}{\partial x^2} + \frac{\partial^2 w}{\partial y^2} + \frac{\partial^2 w}{\partial z^2} = 0; # \\ # \\ # a^2\left(\frac{\partial^2 w}{\partial x^2} + \frac{\partial^2 w}{\partial y^2} + \frac{\partial^2 w}{\partial z^2}\right) = \frac{\partial w}{\partial t}; # \\ # \\ # a^2\left(\frac{\partial^2 w}{\partial x^2} + \frac{\partial^2 w}{\partial y^2} + \frac{\partial^2 w}{\partial z^2}\right) = \frac{\partial^2 w}{\partial t^2}. # $$ # # En esta caso, el símbolo $\partial$, es la notación matemática para expresar que estamos derivando parcialmente, así por ejemplo, si queremos expresar que vamos a derivar z con respecto a x, escribimos $\partial z / \partial x$. # # Estos ejemplos, tienen una gran aplicación en [Física](https://es.wikipedia.org/wiki/F%C3%ADsica) y se conocen como la [ecuación de Laplace](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_de_Laplace), la [ecuación del calor](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_del_calor) y la [ecuación de onda](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_de_onda) respectivamente. En general, las [Ecuaciones diferenciales parciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_en_derivadas_parciales) surgen en problemas de [campos eléctricos](https://es.wikipedia.org/wiki/Campo_el%C3%A9ctrico), [mecánica de fluidos](https://es.wikipedia.org/wiki/Mec%C3%A1nica_de_fluidos), difusión y movimientos de [ondas](https://es.wikipedia.org/wiki/Onda). La teoría de estas ecuaciones es bastante diferente con respecto a las [ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) y suelen ser también más complicadas de resolver. En este artículo me voy a enfocar principalmente en las [ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria), o [EDOs](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) para abreviar. # # ### Orden de las Ecuaciones diferenciales # # El *orden* de una [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) va a ser igual al *orden* de la mayor [derivada](https://es.wikipedia.org/wiki/Derivada) presente. Así, en nuestro primer ejemplo, la [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) de la [segunda ley de la dinámica de Newton](https://es.wikipedia.org/wiki/Leyes_de_Newton#Segunda_Ley_de_Newton_o_Ley_Fundamental_de_la_din.C3.A1mica) es de segundo orden, ya que nos encontramos ante la segunda derivada de la posición del objeto con respecto al tiempo. # La ecuación general de las [ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) de grado $n$ es la siguiente: # # $$F\left(x, y, \frac{dy}{dx}, \frac{d^2y}{dx^2}, \dots , \frac{d^ny}{dx^n}\right) = 0 $$ # # o utilizando la notación prima para las [derivadas](https://es.wikipedia.org/wiki/Derivada), # # $$F(x, y, y', y'', \dots, y^{(n)}) = 0$$ # # La más simple de todas las [ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) es la siguiente ecuación de primer orden: # # $$ \frac{dy}{dx} = f(x)$$ # # y para resolverla simplemente debemos calcular su [integral indefinida](https://es.wikipedia.org/wiki/Integraci%C3%B3n_indefinida): # # $$y = \int f(x) dx + c$$. # # ### Ecuaciones diferenciales separables # # Una *ecuación separable* es una [ecuación diferencial de primer orden](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria_de_primer_orden) en la que la expresión para # $dx / dy$ se puede factorizar como una función de x multiplicada por una función de y. En otras palabras, puede ser # escrita en la forma: # # $$\frac{dy}{dx} = f(x)g(y)$$ # # El nombre *separable* viene del hecho de que la expresión en el lado derecho se puede "separar" en una función de $x$ y una función de $y$. # # Para resolver este tipo de ecuaciones, podemos reescribirlas en la forma diferencial: # # $$\frac{dy}{g(y)} = f(x)dx$$ # # y luego podemos resolver la ecuación original integrando: # # $$\int \frac{dy}{g(y)} = \int f(x) dx + c$$ # # Éstas suelen ser las [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) más fáciles de resolver, ya que el problema de resolverlas puede ser reducido a un problema de [integración](https://es.wikipedia.org/wiki/Integraci%C3%B3n); a pesar de que igualmente muchas veces estas integrales pueden ser difíciles de calcular. # # ### Ecuaciones diferenciales lineales # # Uno de los tipos más importantes de [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) son las [Ecuaciones diferenciales lineales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_lineal). Este tipo de ecuaciones son muy comunes en varias ciencias y tienen la ventaja de que pueden llegar a ser resueltas en forma analítica ya que su [ecuación diferencial de primer orden](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria_de_primer_orden) adopta la forma: # # $$\frac{dy}{dx} + P(x)y = Q(x) $$ # # donde, $P$ y $Q$ son funciones continuas de $x$ en un determinado intervalo. Para resolver este tipo de ecuaciones de la forma $ y' + P(x)y = Q(x)$, debemos multiplicar los dos lados de la ecuación por el *factor de integración* $e^{\int P(x) dx}$ y luego [integrar](https://es.wikipedia.org/wiki/Integraci%C3%B3n) ambos lados. Así, si por ejemplo quisiéramos resolver la siguiente [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial): # # $$\frac{dy}{dx} + 3x^2y = 6x^2$$ # # Primero calculamos el *factor de integración*, $I(x) = e^{\int 3x^2 \ dx}$, lo que es igual a $e^{x^3}$. # # Luego multiplicamos ambos lados de la ecuación por el recién calculado *factor de integración*. # # $$e^{x^3}\frac{dy}{dx} + 3x^2e^{x^3}y = 6x^2e^{x^3}$$ # # simplificando, obtenemos: # # $$\frac{d}{dx}(e^{x^3}y) = 6x^2e^{x^3}$$ # # Por último, integramos ambos lados de la ecuación: # # $$e^{x^3}y = \int 6x^2e^{x^3} \ dx = 2e^{x^3} + C$$ # # y podemos obtener la solución final: # # $$y = Ce^{-x^3} +2 $$ # # ### Condición inicial # # Cuando utilizamos [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial), generalmente no estamos interesados en encontrar una familia de soluciones (la solución general), como la que hayamos en el caso precedente, sino que vamos a estar más interesados en una solución que satisface un requerimiento particular.En muchos problemas físicos debemos de encontrar una solución particular que satisface una condición de la forma $y(t_o) = y_0$. Esto se conoce como la **condición inicial**, y el problema de encontrar una solución de la [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) que satisface la *condición inicial* se conoce como el **problema de valor inicial**. # # ## Series de potencias # # Cuando comenzamos a lidiar con las [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial), veremos que existen un gran número de ellas que no pueden ser resueltas en forma analítica utilizando los principios del [Cálculo integral](https://es.wikipedia.org/wiki/Integraci%C3%B3n) y el [Cálculo diferencial](https://es.wikipedia.org/wiki/C%C3%A1lculo_diferencial); pero sin embargo, tal vez podamos encontrar soluciones aproximadas para este tipo de ecuaciones en términos de [Series de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias). # # ### ¿Qué es una serie de potencias? # # Una [Serie de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias) es una [serie](https://es.wikipedia.org/wiki/Serie_matem%C3%A1tica), generalmente infinita, que posee la siguiente forma: # # $$\sum_{n=0}^{\infty} C_nX^n = C_0 + C_1X + C_2X^2 + C_3X^3 + \dots $$ # # En dónde $X$ es una variable y las $C_n$ son *constantes* o los *coeficientes* de la serie. Una [Serie de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias) puede [converger](https://es.wikipedia.org/wiki/Serie_convergente) para algunos valores de $X$ y [divergir](https://es.wikipedia.org/wiki/Serie_divergente) para otros valores de $X$. La suma de la [serie](https://es.wikipedia.org/wiki/Serie_matem%C3%A1tica) es una [función](https://es.wikipedia.org/wiki/Funci%C3%B3n_matem%C3%A1tica). # # $$f(x) = C_0 + C_1X + C_2X^2 + C_3X^3 + \dots + C_nX^n + \dots$$ # # El *dominio* de esta [función](https://es.wikipedia.org/wiki/Funci%C3%B3n_matem%C3%A1tica) va a estar dado por el conjunto de todos los $X$ para los que la [serie](https://es.wikipedia.org/wiki/Serie_matem%C3%A1tica) [converge](https://es.wikipedia.org/wiki/Serie_convergente). # # ### Series de Taylor # # Las [Series de Taylor](https://es.wikipedia.org/wiki/Serie_de_Taylor) son un caso especial de [Serie de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias) cuyos términos adoptan la forma $(x - a)^n$. Las [Series de Taylor](https://es.wikipedia.org/wiki/Serie_de_Taylor) nos van a permitir aproximar [funciones continuas](https://es.wikipedia.org/wiki/Funci%C3%B3n_continua) que no pueden resolverse en forma analítica y se van a calcular a partir de las [derivadas](https://es.wikipedia.org/wiki/Derivada) de estas [funciones](https://es.wikipedia.org/wiki/Funci%C3%B3n_matem%C3%A1tica). Su definición matemática es la siguiente: # # $$f(x) = \sum_{n=0}^{\infty}\frac{f^{(n)}(a)}{n!}(x - a)^n$$ # # Lo que es equivalente a decir: # # $$f(x) = f(a) + \frac{f'(a)}{1!}(x -a) + \frac{f''(a)}{2!}(x -a)^2 + \frac{f'''(a)}{3!}(x -a)^3 + \dots$$ # # Una de las razones de que las [Series de Taylor](https://es.wikipedia.org/wiki/Serie_de_Taylor) sean importantes es que nos permiten [integrar](https://es.wikipedia.org/wiki/Integraci%C3%B3n) funciones que de otra forma no podíamos manejar. De hecho, a menudo [Newton](https://es.wikipedia.org/wiki/Isaac_Newton) [integraba](https://es.wikipedia.org/wiki/Integraci%C3%B3n) funciones por medio de, en primer lugar, expresarlas como [Series de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias) y luego [integrando](https://es.wikipedia.org/wiki/Integraci%C3%B3n) la serie término a término. Por ejemplo, la función $f(x) = e^{-x^2}$, no puede ser integrada por los métodos normales del [Cálculo integral](https://es.wikipedia.org/wiki/Integraci%C3%B3n), por lo que debemos recurrir a las [Series de Taylor](https://es.wikipedia.org/wiki/Serie_de_Taylor) para aproximar la solución de su [integral](https://es.wikipedia.org/wiki/Integraci%C3%B3n). Podríamos construir la [Serie de Taylor](https://es.wikipedia.org/wiki/Serie_de_Taylor) de esta función, del siguiente modo: # # $$e^{-x^2} = \sum_{n=0}^{\infty}\frac{(-x^2)^n}{n!} = \sum_{n=0}^{\infty}(-1)^n\frac{x^{2n}}{n!} = # 1 - \frac{x^2}{1!} + \frac{x^4}{2!} -\frac{x^6}{3!} + \dots$$ # ## Resolviendo Ecuaciones diferenciales con Python # # Mientras que algunos problemas de [Ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) se pueden resolver con métodos analíticos, como hemos mencionado anteriormente, son mucho más comunes los problemas que no se pueden resolver analíticamente. Por lo tanto, en estos casos debemos recurrir a los métodos numéricos. Es aquí, dónde el poder de las computadoras y en especial, de los paquetes científicos de [Python](https://www.python.org/) como [NumPy](http://www.numpy.org/), [Matplotlib](http://matplotlib.org/), [SymPy](http://www.sympy.org/es/) y [SciPy](http://www.scipy.org/), se vuelven sumamente útiles. Veamos como podemos utilizar la fuerza computacional para resolver [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial). # # ### Soluciones analíticas con Python # # [SymPy](http://www.sympy.org/es/) nos proporciona un solucionador genérico de [Ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria), `sympy.dsolve`, el cual es capaz de encontrar soluciones analíticas a muchas [EDOs](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) elementales. Mientras `sympy.dsolve` se puede utilizar para resolver muchas [EDOs](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) sencillas simbólicamente, como veremos a continuación, debemos tener en cuenta que la mayoría de las [EDOs](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) no se pueden resolver analíticamente. Por ejemplo, retomando el ejemplo que resolvimos analíticamente más arriba, veamos si llegamos al mismo resultado utilizando [SymPy](http://www.sympy.org/es/) para solucionar la siguiente [Ecuación diferencial ordinaria](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria): # # $$\frac{dy}{dx} = -3x^2y + 6x^2$$ # In[1]: # # importando modulos necesarios get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib.pyplot as plt import numpy as np import sympy from scipy import integrate # imprimir con notación matemática. sympy.init_printing(use_latex='mathjax') # In[2]: # Resolviendo ecuación diferencial # defino las incognitas x = sympy.Symbol('x') y = sympy.Function('y') # expreso la ecuacion f = 6*x**2 - 3*x**2*(y(x)) sympy.Eq(y(x).diff(x), f) # Aquí primero definimos la incógnitas $x$ utilizando el objeto `Symbol` e $y$, que al ser una función, la definimos con el objeto `Function`, luego expresamos en [Python](https://www.python.org/) la ecuación que define a la función. Ahora solo nos restaría aplicar la función `dsolve` para resolver nuestra [EDO](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria). # In[3]: # Resolviendo la ecuación sympy.dsolve(y(x).diff(x) - f) # Como podemos ver, arribamos exactamente al mismo resultado. Siguiendo el mismo procedimiento, podemos resolver otras [EDOs](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria), por ejemplo si quisiéramos resolver la siguiente [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial): # # $$\frac{dy}{dx} = \frac{1}{2}(y^2 -1) $$ # # que cumpla con la condición inicial $y(0) = 2$, debemos realizar el siguiente procedimiento: # In[4]: # definiendo la ecuación eq = 1.0/2 * (y(x)**2 - 1) # Condición inicial ics = {y(0): 2} # Resolviendo la ecuación edo_sol = sympy.dsolve(y(x).diff(x) - eq) edo_sol # Aquí encontramos la solución general de nuestra [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial), ahora reemplazamos los valores de la condición inicial en nuestra ecuación. # In[5]: C_eq = sympy.Eq(edo_sol.lhs.subs(x, 0).subs(ics), edo_sol.rhs.subs(x, 0)) C_eq # y por último despejamos el valor de la [constante de integración](https://es.wikipedia.org/wiki/Constante_de_integraci%C3%B3n) resolviendo la ecuación. # In[6]: sympy.solve(C_eq) # Como vemos, el valor de la [constante de integración](https://es.wikipedia.org/wiki/Constante_de_integraci%C3%B3n) es 3, por lo tanto nuestra solución para el **problema del valore inicial** es: # # $$y{\left (x \right )} = \frac{3 + e^{x}}{3 - e^{x}}$$ # # Para los casos en que no exista una solución analítica, pero sí una solución aproximada por una [Serie de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias), `sympy.dsolve` nos va a devolver la serie como solución. Veamos el caso de la siguiente [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial): # # $$\frac{dy}{dx} = x^2 + y^2 -1$$ # In[7]: # Solución con serie de potencias f = y(x)**2 + x**2 -1 sympy.dsolve(y(x).diff(x) - f) # ### Campos de direcciones # # Los [Campos de direcciones](https://es.wikipedia.org/wiki/Campo_de_direcciones) es una técnica sencilla pero útil para visualizar posibles soluciones a las [ecuaciones diferenciales de primer orden](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria_de_primer_orden). Se compone de líneas cortas que muestran la pendiente de la función incógnita en el plano x-y. Este gráfico se puede producir fácilmente debido a que la pendiente de $y(x)$ en los puntos arbitrarios del plano x-y está dada por la definición misma de la [Ecuación diferencial ordinaria](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria): # # $$\frac{dy}{dx} = f(x, y(x))$$ # # Es decir, que sólo tenemos que iterar sobre los valores $x$ e $y$ en la grilla de coordenadas de interés y evaluar $f(x, y(x))$ para saber la pendiente de $y(x)$ en ese punto. Cuantos más segmentos de líneas trazamos en un [Campo de dirección](https://es.wikipedia.org/wiki/Campo_de_direcciones), más clara será la imagen. La razón por la cual el gráfico de [Campos de direcciones](https://es.wikipedia.org/wiki/Campo_de_direcciones) es útil, es que las curvas suaves y continuos que son tangentes a las líneas de pendiente en cada punto del gráfico, son las posibles soluciones a la [Ecuación diferencial ordinaria](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria). # # Por supuesto que calcular las pendientes y dibujar los segmentos de línea para un gran número de puntos a mano sería algo realmente tedioso, pero para eso existen las computadoras y [Python](https://www.python.org/)!. Veamos un ejemplo, supongamos que tenemos la siguiente [Ecuación diferencial ordinaria](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria), la cual según lo que vimos más arriba, sabemos que no tiene una solución analítica: # # $$\frac{dy}{dx} = x^2 + y^2 -1$$ # # entonces, con la ayuda de [Python](https://www.python.org/), podemos graficar su [Campo de dirección](https://es.wikipedia.org/wiki/Campo_de_direcciones) del siguiente modo: # In[8]: # def plot_direction_field(x, y_x, f_xy, x_lim=(-5, 5), y_lim=(-5, 5), ax=None): """Esta función dibuja el campo de dirección de una EDO""" f_np = sympy.lambdify((x, y_x), f_xy, modules='numpy') x_vec = np.linspace(x_lim[0], x_lim[1], 20) y_vec = np.linspace(y_lim[0], y_lim[1], 20) if ax is None: _, ax = plt.subplots(figsize=(4, 4)) dx = x_vec[1] - x_vec[0] dy = y_vec[1] - y_vec[0] for m, xx in enumerate(x_vec): for n, yy in enumerate(y_vec): Dy = f_np(xx, yy) * dx Dx = 0.8 * dx**2 / np.sqrt(dx**2 + Dy**2) Dy = 0.8 * Dy*dy / np.sqrt(dx**2 + Dy**2) ax.plot([xx - Dx/2, xx + Dx/2], [yy - Dy/2, yy + Dy/2], 'b', lw=0.5) ax.axis('tight') ax.set_title(r"$%s$" % (sympy.latex(sympy.Eq(y(x).diff(x), f_xy))), fontsize=18) return ax # In[9]: # Defino incognitas x = sympy.symbols('x') y = sympy.Function('y') # Defino la función f = y(x)**2 + x**2 -1 # grafico de campo de dirección fig, axes = plt.subplots(1, 1, figsize=(8, 6)) campo_dir = plot_direction_field(x, y(x), f, ax=axes) # Las líneas de dirección en el gráfico de arriba sugieren cómo las curvas que son soluciones a la [Ecuación diferencial ordinaria](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) se van a comportar. Por lo tanto, los [Campos de direcciones](https://es.wikipedia.org/wiki/Campo_de_direcciones) son una herramienta muy útil para visualizar posibles soluciones para [Ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) que no se pueden resolver analíticamente. Este gráfico, también nos puede ayudar a determinar el rango de validez de la solución aproximada por la [Serie de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias). Por ejemplo si resolvemos nuestra [EDO](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) para la condición inicial $y(0) = 0$, veamos a que conclusiones arribamos. # In[10]: # Condición inicial ics = {y(0): 0} # Resolviendo la ecuación diferencial edo_sol = sympy.dsolve(y(x).diff(x) - f, ics=ics) edo_sol # In[11]: fig, axes = plt.subplots(1, 2, figsize=(10, 5)) # panel izquierdo - solución aproximada por Serie de potencias plot_direction_field(x, y(x), f, ax=axes[0]) x_vec = np.linspace(-3, 3, 100) axes[0].plot(x_vec, sympy.lambdify(x, edo_sol.rhs.removeO())(x_vec), 'b', lw=2) # panel derecho - Solución por método iterativo plot_direction_field(x, y(x), f, ax=axes[1]) x_vec = np.linspace(-1, 1, 100) axes[1].plot(x_vec, sympy.lambdify(x, edo_sol.rhs.removeO())(x_vec), 'b', lw=2) # Resolviendo la EDO en forma iterativa edo_sol_m = edo_sol_p = edo_sol dx = 0.125 # x positivos for x0 in np.arange(1, 2., dx): x_vec = np.linspace(x0, x0 + dx, 100) ics = {y(x0): edo_sol_p.rhs.removeO().subs(x, x0)} edo_sol_p = sympy.dsolve(y(x).diff(x) - f, ics=ics, n=6) axes[1].plot(x_vec, sympy.lambdify(x, edo_sol_p.rhs.removeO())(x_vec), 'r', lw=2) # x negativos for x0 in np.arange(1, 5, dx): x_vec = np.linspace(-x0-dx, -x0, 100) ics = {y(-x0): edo_sol_m.rhs.removeO().subs(x, -x0)} edo_sol_m = sympy.dsolve(y(x).diff(x) - f, ics=ics, n=6) axes[1].plot(x_vec, sympy.lambdify(x, edo_sol_m.rhs.removeO())(x_vec), 'r', lw=2) # En el panel de la izquierda podemos ver el gráfico de la solución aproximada por la [Serie de potencias](https://es.wikipedia.org/wiki/Serie_de_potencias); en el panel de la derecha vemos el gráfico al que podemos arribar resolviendo la [EDO](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) para valores incrementales de $x$ para la condición inicial en forma iterativa. Como podemos ver, las solución aproximada se alinea bien con el [campo de direcciones](https://es.wikipedia.org/wiki/Campo_de_direcciones) para los valores de $x$ entre $-1.5$ y $1.5$, luego comienza a desviarse, lo que nos indica que la solución aproximada ya no sería válida. En el panel de la derecha podemos ver una solución que se adapta mucho mejor con el [campo de direcciones](https://es.wikipedia.org/wiki/Campo_de_direcciones). # ### Transformada de Laplace # # Un método alternativo que podemos utilizar para resolver en forma analítica [Ecuaciones diferenciales ordinarias](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial_ordinaria) complejas, es utilizar la [Transformada de Laplace](https://es.wikipedia.org/wiki/Transformada_de_Laplace), que es un tipo particular de [transformada integral](https://es.wikipedia.org/wiki/Transformada_integral). La idea es que podemos utilizar esta técnica para transformar nuestra [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) en algo más simple, resolver esta ecuación más simple y, a continuación, invertir la transformación para recuperar la solución a la [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) original. # # #### ¿Qué es una Transformada de Laplace? # # Para poder comprender la [Transformada de Laplace](https://es.wikipedia.org/wiki/Transformada_de_Laplace), primero debemos revisar la definición general de la [transformada integral](https://es.wikipedia.org/wiki/Transformada_integral), la cuál adapta la siguiente forma: # # $$T(f(t)) = \int_{\alpha}^{\beta} K (s, t) \ f(t) \ dt = F(s) $$ # # En este caso, $f(t)$ es la función que queremos transformar, y $F(s)$ es la función transformada. Los límites de la integración, $\alpha$ y $\beta$, pueden ser cualquier valor entre $-\infty$ y $+\infty$ y $K(s, t)$ es lo que se conoce como el *núcleo* o *kernel* de la transformada, y podemos elegir el *kernel* que nos plazca. La idea es poder elegir un *kernel* que nos dé la oportunidad de simplificar la [Ecuación diferencial](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) con mayor facilidad. # # Si nos restringimos a [Ecuaciones diferenciales](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_diferencial) con *coeficientes* constantes, entonces un *kernel* que resulta realmente útil es $e^{-st}$, ya que al [diferenciar](https://es.wikipedia.org/wiki/C%C3%A1lculo_diferencial) este *kernel* con respecto de $t$, terminamos obteniendo potencias de $s$, que podemos equiparar a los *coeficientes* constantes. De esta forma, podemos arribar a la definición de la [Transformada de Laplace](https://es.wikipedia.org/wiki/Transformada_de_Laplace): # # $$\mathcal{L}\{f(t)\}=\int_0^{\infty} e^{-st} \ f(t) \ dt$$ # # Tengan en cuenta, que además de usar el *kernel* $e^{-st}$, los límites de la integración van desde $0$ a $\infty$, ya que valores negativos de $t$ harían [divergir](https://es.wikipedia.org/wiki/Serie_divergente) la [integral](https://es.wikipedia.org/wiki/Integraci%C3%B3n). # # #### Tabla de transformadas de Laplace # # Calcular la [Transformada de Laplace](https://es.wikipedia.org/wiki/Transformada_de_Laplace) a veces puede resultar en una tarea complicada. Por suerte, podemos recurrir a la siguiente tabla para resolver la [Transformada de Laplace](https://es.wikipedia.org/wiki/Transformada_de_Laplace) para las funciones más comunes: # #
Función original | #Transformada de Laplace | #Restricciones | #
---|---|---|
$1$ | #$\frac{1}{s}$ | #$s>0$ | #
$e^{at}$ | #$\frac{1}{s -a}$ | #$s>a$ | #
$t^n$ | #$\frac{n!}{s^{n+1}}$ | #$s>0$, $n$ un entero $> 0$ | #
$\cos at$ | #$\frac{s}{s^2 + a^2}$ | #$s>0$ | #
$\sin at$ | #$\frac{a}{s^2 + a^2}$ | #$s>0$ | #
$\cosh at$ | #$\frac{s}{s^2 - a^2}$ | #$s>|a|$ | #
$\sinh at$ | #$\frac{a}{s^2 - a^2}$ | #$s>|a|$ | #
$e^{at}\cos bt$ | #$\frac{s- a}{(s^2 - a^2) + b^2}$ | #$s>a$ | #
$e^{at}\sin bt$ | #$\frac{b}{(s^2 - a^2) + b^2}$ | #$s>a$ | #
$t^n e^{at}$ | #$\frac{n!}{(s-a)^{n+1}}$ | #$s>a$, $n$ un entero $> 0$ | #
$f(ct)$ | #$\frac{1}{c}\mathcal{L}\{f(s/c)\}$ | #$c>0$ | #