# SymPy
    
    

[SymPy](https://es.wikipedia.org/wiki/SymPy) es una biblioteca de Python que permite realizar cálculos simbólicos.
Nos ofrece las capacidades de álgebra computacional, y se puede usar en línea a través de [SymPy Live](http://live.sympy.org/) o [SymPy Gamma](http://www.sympygamma.com/), este último es similar a
[Wolfram Alpha](https://www.wolframalpha.com/).

Si usas Anaconda este paquete ya viene instalado por defecto pero si se usa miniconda o pip debe instalarse.

````python
conda install sympy # Usando el gestor conda de Anaconda/Miniconda
pip install sympy # Usando el gestor pip (puede requerir instalar más paquetes)
````


Lo primero que debemos hacer, antes de usarlo, es importar el módulo, como con cualquier
otra biblioteca de Python.

Si deseamos usar SymPy de forma interactiva usamos

```python
from sympy import *
init_printing()
```

Para scripting es mejor importar la biblioteca de la siguiente manera

```python
import sympy as sym
```

Y llamar las funciones de la siguiente manera

```python
x = sym.Symbols("x")
expr = sym.cos(x)**2 + 3*x
deriv = expr.diff(x)
```

en donde calculamos la derivada de  $\cos^2(x) + 3x$,
que debe ser $-2\sin(x)\cos(x) + 3$.


```python
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
from sympy import *
```


```python
init_printing()
```

Definamos la variable $x$ como un símbolo matemático. Esto nos permite hacer uso de
esta variable en SymPy.


```python
x = symbols("x")
```

Empecemos con cálculos simples. Abajo, tenemos una _celda de código_ con una suma.
Ubica el cursor en ella y presiona SHIFT + ENTER para evaluarla.



```python
1 + 3
```

Realicemos algunos cálculos.


```python
factorial(5)
```


```python
1 // 3
```


```python
1 / 3
```


```python
S(1) / 3
```

Podemos evaluar esta expresión a su versión en punto flotante


```python
sqrt(2*pi)
```


```python
float(sqrt(2*pi))
```

También podemos almacenar expresiones como variables, como cualquier variable de Python.



```python
radius = 10
height = 100
area = pi * radius**2
volume = area * height
```


```python
volume
```


```python
float(volume)
```

Hasta ahora, hemos usado SymPy como una calculadora. Intentemos
algunos cálculos más avanzados. Por ejemplo, algunas integrales.



```python
integrate(sin(x), x)
```


```python
integrate(sin(x), (x, 0, pi))
```

Podemos definir una función, e integrarla


```python
f = lambda x: x**2 + 5
```


```python
f(5)
```


```python
integrate(f(x), x)
```


```python
y = symbols("y")
integrate(1/(x**2 + y), x)
```

Si asumimos que el denominador es positivo, esta expresión se puede simplificar aún más


```python
a = symbols("a", positive=True)
integrate(1/(x**2 + a), x)
```

Hasta ahora, aprendimos lo más básico. Intentemos algunos ejemplos
más complicados ahora.

**Nota:** Si quieres saber más sobre una función específica se puede usar
la función ``help()`` o el comándo _mágico_ de IPython ``??``


```python
help(integrate)
```

    Help on function integrate in module sympy.integrals.integrals:
    
    integrate(*args, **kwargs)
        integrate(f, var, ...)
        
        Compute definite or indefinite integral of one or more variables
        using Risch-Norman algorithm and table lookup. This procedure is
        able to handle elementary algebraic and transcendental functions
        and also a huge class of special functions, including Airy,
        Bessel, Whittaker and Lambert.
        
        var can be:
        
        - a symbol                   -- indefinite integration
        - a tuple (symbol, a)        -- indefinite integration with result
                                        given with `a` replacing `symbol`
        - a tuple (symbol, a, b)     -- definite integration
        
        Several variables can be specified, in which case the result is
        multiple integration. (If var is omitted and the integrand is
        univariate, the indefinite integral in that variable will be performed.)
        
        Indefinite integrals are returned without terms that are independent
        of the integration variables. (see examples)
        
        Definite improper integrals often entail delicate convergence
        conditions. Pass conds='piecewise', 'separate' or 'none' to have
        these returned, respectively, as a Piecewise function, as a separate
        result (i.e. result will be a tuple), or not at all (default is
        'piecewise').
        
        **Strategy**
        
        SymPy uses various approaches to definite integration. One method is to
        find an antiderivative for the integrand, and then use the fundamental
        theorem of calculus. Various functions are implemented to integrate
        polynomial, rational and trigonometric functions, and integrands
        containing DiracDelta terms.
        
        SymPy also implements the part of the Risch algorithm, which is a decision
        procedure for integrating elementary functions, i.e., the algorithm can
        either find an elementary antiderivative, or prove that one does not
        exist.  There is also a (very successful, albeit somewhat slow) general
        implementation of the heuristic Risch algorithm.  This algorithm will
        eventually be phased out as more of the full Risch algorithm is
        implemented. See the docstring of Integral._eval_integral() for more
        details on computing the antiderivative using algebraic methods.
        
        The option risch=True can be used to use only the (full) Risch algorithm.
        This is useful if you want to know if an elementary function has an
        elementary antiderivative.  If the indefinite Integral returned by this
        function is an instance of NonElementaryIntegral, that means that the
        Risch algorithm has proven that integral to be non-elementary.  Note that
        by default, additional methods (such as the Meijer G method outlined
        below) are tried on these integrals, as they may be expressible in terms
        of special functions, so if you only care about elementary answers, use
        risch=True.  Also note that an unevaluated Integral returned by this
        function is not necessarily a NonElementaryIntegral, even with risch=True,
        as it may just be an indication that the particular part of the Risch
        algorithm needed to integrate that function is not yet implemented.
        
        Another family of strategies comes from re-writing the integrand in
        terms of so-called Meijer G-functions. Indefinite integrals of a
        single G-function can always be computed, and the definite integral
        of a product of two G-functions can be computed from zero to
        infinity. Various strategies are implemented to rewrite integrands
        as G-functions, and use this information to compute integrals (see
        the ``meijerint`` module).
        
        The option manual=True can be used to use only an algorithm that tries
        to mimic integration by hand. This algorithm does not handle as many
        integrands as the other algorithms implemented but may return results in
        a more familiar form. The ``manualintegrate`` module has functions that
        return the steps used (see the module docstring for more information).
        
        In general, the algebraic methods work best for computing
        antiderivatives of (possibly complicated) combinations of elementary
        functions. The G-function methods work best for computing definite
        integrals from zero to infinity of moderately complicated
        combinations of special functions, or indefinite integrals of very
        simple combinations of special functions.
        
        The strategy employed by the integration code is as follows:
        
        - If computing a definite integral, and both limits are real,
          and at least one limit is +- oo, try the G-function method of
          definite integration first.
        
        - Try to find an antiderivative, using all available methods, ordered
          by performance (that is try fastest method first, slowest last; in
          particular polynomial integration is tried first, Meijer
          G-functions second to last, and heuristic Risch last).
        
        - If still not successful, try G-functions irrespective of the
          limits.
        
        The option meijerg=True, False, None can be used to, respectively:
        always use G-function methods and no others, never use G-function
        methods, or use all available methods (in order as described above).
        It defaults to None.
        
        Examples
        ========
        
        >>> from sympy import integrate, log, exp, oo
        >>> from sympy.abc import a, x, y
        
        >>> integrate(x*y, x)
        x**2*y/2
        
        >>> integrate(log(x), x)
        x*log(x) - x
        
        >>> integrate(log(x), (x, 1, a))
        a*log(a) - a + 1
        
        >>> integrate(x)
        x**2/2
        
        Terms that are independent of x are dropped by indefinite integration:
        
        >>> from sympy import sqrt
        >>> integrate(sqrt(1 + x), (x, 0, x))
        2*(x + 1)**(3/2)/3 - 2/3
        >>> integrate(sqrt(1 + x), x)
        2*(x + 1)**(3/2)/3
        
        >>> integrate(x*y)
        Traceback (most recent call last):
        ...
        ValueError: specify integration variables to integrate x*y
        
        Note that ``integrate(x)`` syntax is meant only for convenience
        in interactive sessions and should be avoided in library code.
        
        >>> integrate(x**a*exp(-x), (x, 0, oo)) # same as conds='piecewise'
        Piecewise((gamma(a + 1), -re(a) < 1),
            (Integral(x**a*exp(-x), (x, 0, oo)), True))
        
        >>> integrate(x**a*exp(-x), (x, 0, oo), conds='none')
        gamma(a + 1)
        
        >>> integrate(x**a*exp(-x), (x, 0, oo), conds='separate')
        (gamma(a + 1), -re(a) < 1)
        
        See Also
        ========
        
        Integral, Integral.doit
    



```python
integrate??
```

## Ejemplos

### Solución de ecuaciones algebraicas

Para resolver sistemas de ecuaciones algebraicos podemos usar: 
[``solveset`` and ``solve``](http://docs.sympy.org/latest/tutorial/solvers.html).
El método preferido es ``solveset``, sin embargo, hay sistemas que
se pueden resolver usando ``solve`` y no ``solveset``.

Para resolver sistemas usando ``solveset``:


```python
a, b, c = symbols("a b c")
solveset(a*x**2 + b*x + c, x)
```

Debemos ingresar la expresión igualada a 0, o como una ecuación


```python
solveset(Eq(a*x**2 + b*x, -c), x)
```

``solveset`` no permite resolver sistemas de ecuaciones no lineales, por ejemplo



```python
solve([x*y - 1, x - 2], x, y)
```

### Álgebra lineal

Usamos ``Matrix`` para crear matrices. Las matrices pueden contener variables y expresiones matemáticas.

Usamos el método ``.inv()`` para calcular la inversa, y ``*`` para multiplicar matrices.


```python
A = Matrix([
        [1, -1],
        [1, sin(c)]
    ])
display(A)
```


$$\left[\begin{matrix}1 & -1\\1 & \sin{\left (c \right )}\end{matrix}\right]$$



```python
B = A.inv()
display(B)
```


$$\left[\begin{matrix}\frac{\sin{\left (c \right )}}{\sin{\left (c \right )} + 1} & \frac{1}{\sin{\left (c \right )} + 1}\\- \frac{1}{\sin{\left (c \right )} + 1} & \frac{1}{\sin{\left (c \right )} + 1}\end{matrix}\right]$$



```python
A * B
```




$$\left[\begin{matrix}\frac{\sin{\left (c \right )}}{\sin{\left (c \right )} + 1} + \frac{1}{\sin{\left (c \right )} + 1} & 0\\0 & \frac{\sin{\left (c \right )}}{\sin{\left (c \right )} + 1} + \frac{1}{\sin{\left (c \right )} + 1}\end{matrix}\right]$$



Esta expresión debería ser la matriz identidad, simplifiquemos la expresión.
Existen varias formas de simplificar expresiones, y ``simplify`` es la más general.


```python
simplify(A * B)
```




$$\left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]$$



### Graficación

SymPy permite realizar gráficos 2D y 3D


```python
from sympy.plotting import plot3d
```


```python
plot(sin(x), (x, -pi, pi));
```


    <IPython.core.display.Javascript object>







```python
monkey_saddle = x**3 - 3*x*y**2
p = plot3d(monkey_saddle, (x, -2, 2), (y, -2, 2))
```


    <IPython.core.display.Javascript object>






### Derivadas y ecuaciones diferenciales

Podemos usar la función ``diff`` o el método ``.diff()`` para calcular derivadas.


```python
f = lambda x: x**2
```


```python
diff(f(x), x)
```


```python
f(x).diff(x)
```


```python
g = lambda x: sin(x)
```


```python
diff(g(f(x)), x)
```

Y sí, ¡SymPy sabe sobre la regla de la cadena!

Para terminar, resolvamos una ecuación diferencial de segundo orden

$$ u''(t) + \omega^2 u(t) = 0$$


```python
t = symbols("t")
u = symbols("u", cls=Function)
omega = symbols("omega", positive=True)
```


```python
ode = u(t).diff(t, 2) + omega**2 * u(t)
dsolve(ode, u(t))
```

## Convertir expresiones de SymPy en funciones de NumPy

``lambdify`` permite convertir expresiones de sympy en funciones para hacer cálculos usando NumPy.

Veamos cómo.


```python
f = lambdify(x, x**2, "numpy")
f(3)
```




    9




```python
f(np.array([1, 2, 3]))
```




    array([1, 4, 9])



Intentemos un ejemplo más complejo


```python
fun = diff(sin(x)*cos(x**3) - sin(x)/x, x)
fun
```


```python
fun_numpy = lambdify(x, fun, "numpy")
```

y evalúemoslo en algún intervalo, por ejemplo, $[0, 5]$.


```python
pts = np.linspace(0, 5, 1000)
fun_pts = fun_numpy(pts + 1e-6) # Para evitar división por 0
```


```python
plt.figure()
plt.plot(pts, fun_pts)
```


    <IPython.core.display.Javascript object>









    [<matplotlib.lines.Line2D at 0x7fab6c5644e0>]



## Ejercicios

1. Calcule el límite

  $$ \lim_{x \rightarrow 0} \frac{\sin(x)}{x}\, .$$

2. Resuelva la ecuación diferencial de Bernoulli

  $$x \frac{\mathrm{d} u(x)}{\mathrm{d}x}  + u(x) - u(x)^2 = 0\, .$$


## Recursos adicionales

- Equipo de desarrollo de SymPy. [SymPy Tutorial](http://docs.sympy.org/latest/tutorial/index.html), (2018). Consultado: Julio 23, 2018
- Ivan Savov. [Taming math and physics using SymPy](https://minireference.com/static/tutorials/sympy_tutorial.pdf), (2017). Consultado: Julio 23, 2018


```python

```

de9d11ca63b0890a98479ee118fbaa100690d2fe
ipynb
Jupyter Notebook
notebooks/herramientas/sympy_basico.ipynb
AppliedMechanics-EAFIT/Mod_Temporal
6a0506d906ed42b143b773777e8dc0da5af763eb
MIT
2019-02-20T18:14:01.000Z
2020-07-19T22:44:44.000Z
notebooks/herramientas/sympy_basico.ipynb
AppliedMechanics-EAFIT/Mod_Temporal
6a0506d906ed42b143b773777e8dc0da5af763eb
MIT
2020-04-15T00:22:58.000Z
2020-07-04T17:03:54.000Z
notebooks/herramientas/sympy_basico.ipynb
AppliedMechanics-EAFIT/Mod_Temporal
6a0506d906ed42b143b773777e8dc0da5af763eb
MIT
2020-05-14T18:17:09.000Z
2020-10-27T06:37:05.000Z
Qwen/Qwen-72B
1. YES
2. YES