#!/usr/bin/env python # coding: utf-8 # AeroPython # # Clase 5: SymPy # ![](http://sympy.org/static/images/logo.png) # # _ __SymPy es una biblioteca de Python para matemática simbólica__. Apunta a convertirse en un sistema de algebra computacional (__CAS__) con todas sus prestaciones manteniendo el código tan simple como sea posible para manterlo comprensible y fácilmente extensible. SymPy está __escrito totalmente en Python y no requiere bibliotecas adicionales__. _Este proyecto comenzó en 2005, fue lanzado al público en 2007 y a él han contribuido durante estos años cientos de personas._ # # _ Otros CAS conocidos son Mathematica y Maple, sin embargo ambos son software privativo y de pago. [Aquí](https://github.com/sympy/sympy/wiki/SymPy-vs.-Maple) puedes encontrar una comparativa de SymPy con Maple. _ # # Hoy veremos cómo: # # * Crear símbolos y expresiones. # * Manipular expresiones (simplificación, expansión...) # * Calcular derivadas e integrales. # * Límites y desarrollos en serie. # * Resolución de ecuaciones. # * Resolción de EDOs. # * Matrices # # Sin embargo, SymPy no acaba aquí ni mucho menos... # ## Documentación & SymPy Live Shell # In[1]: from IPython.display import HTML HTML('') # ## SymPy Gamma # In[2]: HTML('') # ## Creación de símbolos # Lo primero, como siempre, es importar aquello que vayamos a necesitar: # In[3]: # Importación from sympy import init_session # In[4]: init_session(use_latex=True) # Lo primero que vemos es que el comando `init_session` ha llevado a cabo algunas acciones por nostros: # # * Gracias a `use_latex=True` obtenemos la salida en $\LaTeX$. # * __Ha creado una serie de variables__ para que podamos ponernos a trabajar en el momento. #
Nota: # En Python, no se declaran las variables, sin embargo, no puedes usar una hasta que no le hayas asignado un valor. Si ahora intentamos crear una variable `a` que sea `a = 2 * b`, veamos qué ocurre: #
# In[5]: # Intentamos usar un símbolo que no hemos creado a = 2 * b # Como en `b` no había sido creada, Python no sabe qué es `b`. # # Esto mismo nos ocurre con los símbolos de SymPy. __Antes de usar una variable, debo decir que es un símbolo y asignárselo:__ # In[6]: # Creamos el símbolo a a = symbols('a') a # In[7]: # Número pi (a + pi) ** 2 # In[8]: # Unidad imaginaria a + 2 * I # In[9]: # Número e E # In[10]: # Vemos qué tipo de variable es a type(a) # Ahora ya podría crear `b = 2 * a`: # In[11]: b = 2 * a b # In[12]: type(b) # ¿Qué está ocurriendo? Python detecta que a es una variable de tipo `Symbol` y al multiplicarla por `2` devuelve una variable de Sympy. # # Como Python permite que el tipo de una variable cambie, __si ahora le asigno a `a` un valor float deja de ser un símbolo.__ # In[13]: a = 2.26492 a # In[14]: type(a) # --- # __Las conclusiones son:__ # # * __Si quiero usar una variable como símbolo debo crearla previamente.__ # * Las operaciones con símbolos devuelven símbolos. # * Si una varibale que almacenaba un símbolo recibe otra asignación, cambia de tipo. # # --- # __Las variables de tipo `Symbol` actúan como contenedores en los que no sabemos qué hay (un real, un complejo, una lista...)__. Hay que tener en cuenta que: __una cosa es el nombre de la variable y otra el símbolo con el que se representa__. # In[15]: #creación de símbolos coef_traccion = symbols('c_T') coef_traccion # Incluso puedo hacer cosas raras como: # In[16]: # Diferencia entre variable y símbolo a = symbols('b') a # Además, se pueden crear varos símbolos a la vez: # In[17]: x, y, z, t = symbols('x y z t') # y símbolos griegos: # In[18]: w = symbols('omega') W = symbols('Omega') w, W # ![](../static/simplification_sympy.png) # _Fuente: Documentación oficial de SymPy_ # __Por defecto, SymPy entiende que los símbolos son números complejos__. Esto puede producir resultados inesperados ante determinadas operaciones como, por ejemplo, lo logaritmos. __Podemos indicar que la variable es real, entera... en el momento de la creación__: # In[19]: # Creamos símbolos reales x, y, z, t = symbols('x y z t', real=True) # In[20]: # Podemos ver las asunciones de un símbolo x.assumptions0 # ## Expresiones # Comencemos por crear una expresión como: $\cos(x)^2+\sin(x)^2$ # In[21]: expr = cos(x)**2 + sin(x)**2 expr # ### `simplify()` # Podemos pedirle que simplifique la expresión anterior: # In[22]: simplify(expr) # En este caso parece estar claro lo que quiere decir más simple, pero como en cualquier _CAS_ el comando `simplify` puede no devolvernos la expresión que nosotros queremos. Cuando esto ocurra necesitaremos usar otras instrucciones. # ### `.subs()` # En algunas ocasiones necesitaremos sustituir una variable por otra, por otra expresión o por un valor. # In[23]: expr # In[24]: # Sustituimos x por y ** 2 expr.subs(x, y**2) # In[25]: # ¡Pero la expresión no cambia! expr # In[26]: # Para que cambie expr = expr.subs(x, y**2) expr # Cambia el `sin(x)` por `exp(x)` # In[27]: expr.subs(sin(x), exp(x)) # Particulariza la expresión $sin(x) + 3 x $ en $x = \pi$ # In[28]: (sin(x) + 3 * x).subs(x, pi) # __Aunque si lo que queremos es obtener el valor numérico lo mejor es `.evalf()`__ # In[29]: (sin(x) + 3 * x).subs(x, pi).evalf(25) # In[30]: #ver pi con 25 decimales pi.evalf(25) # In[31]: #el mismo resultado se obtiene ocn la función N() N(pi,25) # # Simplificación # SymPy ofrece numerosas funciones para __simplificar y manipular expresiones__. Entre otras, destacan: # # * `expand()` # * `factor()` # * `collect()` # * `apart()` # * `cancel()` # # Puedes consultar en la documentación de SymPy lo que hace cada una y algunos ejemplos. __Existen también funciones específicas de simplificación para funciones trigonométricas, potencias y logaritmos.__ Abre [esta documentación](http://docs.sympy.org/latest/tutorial/simplification.html) si lo necesitas. # ##### ¡Te toca! # Pasaremos rápidamente por esta parte, para hacer cosas "más interesantes". Te proponemos algunos ejemplos para que te familiarices con el manejor de expresiones: # __Crea las expresiones de la izquierda y averigua qué función te hace obtener la de la derecha:__ # # expresión 1| expresión 2 # :------:|:------: # $\left(x^{3} + 3 y + 2\right)^{2}$ | $x^{6} + 6 x^{3} y + 4 x^{3} + 9 y^{2} + 12 y + 4$ # $\frac{\left(3 x^{2} - 2 x + 1\right)}{\left(x - 1\right)^{2}} $ | $3 + \frac{4}{x - 1} + \frac{2}{\left(x - 1\right)^{2}}$ # $x^{3} + 9 x^{2} + 27 x + 27$ | $\left(x + 3\right)^{3}$ # $\sin(x+2y)$ | $\left(2 \cos^{2}{\left (y \right )} - 1\right) \sin{\left (x \right )} + 2 \sin{\left (y \right )} \cos{\left (x \right )} \cos{\left (y \right )}$ # # In[32]: #1 expr1 = (x ** 3 + 3 * y + 2) ** 2 expr1 # In[33]: expr1_exp = expr1.expand() expr1_exp # In[34]: #2 expr2 = (3 * x ** 2 - 2 * x + 1) / (x - 1) ** 2 expr2 # In[35]: expr2.apart() # In[36]: #3 expr3 = x ** 3 + 9 * x ** 2 + 27 * x + 27 expr3 # In[37]: expr3.factor() # In[38]: #4 expr4 = sin(x + 2 * y) expr4 # In[39]: expand(expr4) # In[40]: expand_trig(expr4) # In[41]: expand(expr4, trig=True) # # Derivadas e integrales # Puedes derivar una expresion usando el método `.diff()` y la función `dif()` # In[42]: #creamos una expresión expr = cos(x) #obtenemos la derivada primera con funcion diff(expr, x) # In[43]: #utilizando método expr.diff(x) # __¿derivada tercera?__ # In[44]: expr.diff(x, x, x) # In[45]: expr.diff(x, 3) # __¿varias variables?__ # In[46]: expr_xy = y ** 3 * sin(x) ** 2 + x ** 2 * cos(y) expr_xy # In[47]: diff(expr_xy, x, 2, y, 2) # __Queremos que la deje indicada__, usamos `Derivative()` # In[48]: Derivative(expr_xy, x, 2, y) # __¿Será capaz SymPy de aplicar la regla de la cadena?__ # In[49]: # Creamos una función F F = Function('F') F(x) # In[50]: # Creamos una función G G = Function('G') G(x) # $$\frac{d}{d x} F{\left (G(x) \right )} $$ # In[51]: # Derivamos la función compuesta F(G(x)) F(G(x)).diff(x) # En un caso en el que conocemos las funciones: # In[52]: # definimos una f f = 2 * y * exp(x) f # In[53]: # definimos una g(f) g = f **2 * cos(x) + f g # In[54]: #la derivamos diff(g,x) # ##### Te toca integrar # __Si te digo que se integra usando el método `.integrate()` o la función `integrate()`__. ¿Te atreves a integrar estas casi inmediatas...?: # # $$\int{\cos(x)^2}dx$$ # $$\int{\frac{dx}{\sin(x)}}$$ # $$\int{\frac{dx}{(x^2+a^2)^2}}$$ # # # In[55]: int1 = cos(x) ** 2 integrate(int1) # In[56]: int2 = 1 / sin(x) integrate(int2) # In[57]: x, a = symbols('x a', real=True) int3 = 1 / (x**2 + a**2)**2 integrate(int3, x) # # Límites # Calculemos este límite sacado del libro _Cálculo: definiciones, teoremas y resultados_, de Juan de Burgos: # # $$\lim_{x \to 0} \left(\frac{x}{\tan{\left (x \right )}}\right)^{\frac{1}{x^{2}}}$$ # # Primero creamos la expresión: # In[58]: x = symbols('x', real=True) expr = (x / tan(x)) ** (1 / x**2) expr # Obtenemos el límite con la función `limit()` y si queremos dejarlo indicado, podemos usar `Limit()`: # In[59]: limit(expr, x, 0) # # Series # Los desarrollos en serie se pueden llevar a cabo con el método `.series()` o la función `series()` # In[60]: #creamos la expresión expr = exp(x) expr # In[61]: #la desarrollamos en serie series(expr) # Se puede especificar el número de términos pasándole un argumento `n=...`. El número que le pasemos será el primer término que desprecie. # In[62]: # Indicando el número de términos series(expr, n=10) # Si nos molesta el $\mathcal{O}(x^{10})$ lo podemos quitar con `removeO()`: # In[63]: series(expr, n=10).removeO() # In[64]: series(sin(x), n=8, x0=pi/3).removeO().subs(x, x-pi/3) # --- # ## Resolución de ecuaciones # Como se ha mencionado anteriormente las ecuaciones no se pueden crear con el `=` # In[65]: #creamos la ecuación ecuacion = Eq(x ** 2 - x, 3) ecuacion # In[66]: # También la podemos crear como Eq(x ** 2 - x -3) # In[67]: #la resolvemos solve(ecuacion) # Pero la gracia es resolver con símbolos, ¿no? # $$a e^{\frac{x}{t}} = C$$ # In[68]: # Creamos los símbolos y la ecuación a, x, t, C = symbols('a, x, t, C', real=True) ecuacion = Eq(a * exp(x/t), C) ecuacion # In[69]: # La resolvemos solve(ecuacion ,x) # Si consultamos la ayuda, vemos que las posibilidades y el número de parámetros son muchos, no vamos a entrar ahora en ellos, pero ¿se ve la potencia? # ## Ecuaciones diferenciales # Tratemos de resolver, por ejemplo: # # $$y{\left (x \right )} + \frac{d}{d x} y{\left (x \right )} + \frac{d^{2}}{d x^{2}} y{\left (x \right )} = \cos{\left (x \right )}$$ # In[70]: x = symbols('x') f = Function('y') ecuacion_dif = Eq(y(x).diff(x,2) + y(x).diff(x) + y(x), cos(x)) ecuacion_dif # In[71]: #resolvemos dsolve(ecuacion_dif, f(x)) # # Matrices # In[72]: #creamos una matriz llena de símbolos a, b, c, d = symbols('a b c d') A = Matrix([ [a, b], [c, d] ]) A # In[73]: #sacamos autovalores A.eigenvals() # In[74]: #inversa A.inv() # In[75]: #elevamos al cuadrado la matriz A ** 2 # --- # # _ Esto ha sido un rápido recorrido por algunas de las posibilidades que ofrece SymPy . El cálculo simbólico es un terreno díficil y este joven paquete avanza a pasos agigantados gracias a un grupo de desarrolladores siempre dispuestos a mejorar y escuchar sugerencias. Sus posibilidades no acaban aquí. En la siguiente clase presentaremos el paquete `mechanics`, pero además cuenta con herramientas para geometría, mecánica cuántica, teoría de números, combinatoria... Puedes echar un ojo [aquí](http://docs.sympy.org/latest/modules/index.html). _ # --- # # Clase en vídeo, parte del [Curso de Python para científicos e ingenieros](http://cacheme.org/curso-online-python-cientifico-ingenieros/) grabado en la Escuela Politécnica Superior de la Universidad de Alicante. # In[1]: from IPython.display import YouTubeVideo YouTubeVideo("OGQRcYVys1Q", width=560, height=315, list="PLGBbVX_WvN7as_DnOGcpkSsUyXB1G_wqb") # --- # Si te ha gustado esta clase: # # Tweet # # # --- # ####

¡Síguenos en Twitter! # ###### Follow @AeroPython # ##### Licencia Creative Commons
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional. # ##### # --- # _Las siguientes celdas contienen configuración del Notebook_ # # _Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_ # # File > Trusted Notebook # In[2]: get_ipython().run_cell_magic('html', '', 'Follow @AeroPython\n\n') # In[1]: # Esta celda da el estilo al notebook from IPython.core.display import HTML css_file = '../static/styles/style.css' HTML(open(css_file, "r").read())