Sympy: Trabalhando com Símbolos Matemáticos#

SymPy oferece recursos para cálculos matemáticos simbólicos no Python, de maneira semelhante ao que é possível com programas como Mathematica ou Maple. A principal diferença é que o SymPy funciona como qualquer outro módulo Python, permitindo que você combine a matemática simbólica com as funcionalidades do Python em seus projetos. Além disso, enquanto o Python é uma plataforma de código aberto, o Mathematica é uma ferramenta proprietária, embora, na minha opinião, o Mathematica ainda se mantenha mais robusto em termos de capacidade.

Para começar a usar, a seguinte importação, juntamente com a função init_session(), configura um ambiente conveniente, ideal para trabalhar com o SymPy dentro do Jupyter.

from sympy import init_session
init_session(use_latex="mathjax")
IPython console for SymPy 1.14.0 (Python 3.11.12-64-bit) (ground types: python)

These commands were executed:
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)
>>> init_printing()

Documentation can be found at https://docs.sympy.org/1.14.0/
import math

Tipos do SymPy e manipulação simbólica básica#

O SymPy utiliza tipos próprios para representar seus objetos matemáticos. Embora seja possível converter esses tipos para os tipos nativos do Python, essa prática não é recomendada na maioria das vezes, pois pode resultar em uma perda de precisão.

print(sqrt(2))
sqrt(2)
print(sqrt(8))
2*sqrt(2)
print(2**0.5)
1.4142135623730951
#help(sqrt(8))

No SymPy, não estamos limitados a cálculos com números. Podemos definir expressões simbólicas, informando ao SymPy quais elementos devem ser tratados como símbolos, por meio da função symbols().

from sympy import symbols
x, y, z = symbols("x y z")
expr = x + 2*y
expr
\[\displaystyle x + 2 y\]
expr - 1
\[\displaystyle x + 2 y - 1\]
expr - y
\[\displaystyle x + y\]
f = x*expr
f
\[\displaystyle x \left(x + 2 y\right)\]
g = expand(f)
g
\[\displaystyle x^{2} + 2 x y\]
factor(g)
\[\displaystyle x \left(x + 2 y\right)\]

Substituição#

Com o SymPy, é possível substituir valores por símbolos em expressões simbólicas. Contudo, o seguinte provavelmente não irá gerar o comportamento esperado:

w = symbols("w")
expr = sin(w*2*pi)
w = 0
expr
\[\displaystyle \sin{\left(2 \pi w \right)}\]

Agora, redefinimos z para ser um tipo do Python

type(w)
int

A substituição é feita utilizando o método subs() (equivalente ao comando ./ no Mathematica).

expr = sin(x*2*pi)
expr
\[\displaystyle \sin{\left(2 \pi x \right)}\]
a = expr.subs(x, 0.125)
a
\[\displaystyle \frac{\sqrt{2}}{2}\]

Observe que o valor ainda não é um número de ponto flutuante — ele continua sendo um objeto do SymPy. Para convertê-lo para ponto flutuante, podemos utilizar o método evalf().

b = a.evalf()
print(b, type(b))
0.707106781186548 <class 'sympy.core.numbers.Float'>

Ainda estamos lidando com um objeto do SymPy, uma vez que o SymPy permite cálculos com precisão arbitrária.

a.evalf(50)
\[\displaystyle 0.70710678118654752440084436210484903928483593768847\]

Está buscando pelos tipos padrão do Python?

c = float(b)
print(c, type(c))
0.7071067811865476 <class 'float'>

Python e sympy#

x, y, z, t = symbols('x y z t')

Os símbolos do Sympy são apenas objetos, e quando você realiza operações com dois objetos do Sympy, o resultado é também um objeto do Sympy.

Quando você combina um objeto do Sympy com um objeto do Python, o resultado também será um objeto do Sympy.

No entanto, devemos ter cuidado ao trabalhar com frações. Por exemplo, ao fazer x + 1/3, primeiro o Python calculará 1/3 (resultando em 0.333...) e depois adicionará isso ao símbolo x do Sympy. A função Rational() faz com que tudo isso aconteça dentro do Sympy.

f = expr + Rational(1,3)
f
\[\displaystyle \sin{\left(2 \pi x \right)} + \frac{1}{3}\]
expr + 1/3
\[\displaystyle \sin{\left(2 \pi x \right)} + 0.333333333333333\]

Igualdade#

O operador = continua sendo o operador de atribuição em Python (não representando igualdade simbólica), enquanto == verifica a igualdade lógica (ou seja, a comparação exata de estruturas). Para definir igualdade simbólica, usamos o objeto Eq().

Além disso, quando se trata de verificar a igualdade algébrica, o operador == não é adequado, pois ele verifica a igualdade estrutural, não levando em consideração a equivalência algébrica.

x + 1 == 4
False
Eq(x + 1, 4)
\[\displaystyle x + 1 = 4\]
a = (x + 1)**2
b = x**2 + 2*x + 1    # these are algebraically equal
a == b
False
Eq(a,b) # That's not enough...
\[\displaystyle \left(x + 1\right)^{2} = x^{2} + 2 x + 1\]

A função simplify() pode ser utilizada para verificar a igualdade algébrica.

simplify(a - b)
\[\displaystyle 0\]
a = cos(x) + I*sin(x)
a
\[\displaystyle i \sin{\left(x \right)} + \cos{\left(x \right)}\]
simplify(a)
\[\displaystyle e^{i x}\]

Substituições adicionais#

É importante notar que a substituição gera uma nova expressão, pois as expressões no Sympy são imutáveis.

expr = cos(x)
expr.subs(x, 0)
\[\displaystyle 1\]
expr
\[\displaystyle \cos{\left(x \right)}\]
x
\[\displaystyle x\]

Se precisar realizar várias substituições, basta passar uma lista de tuplas.

expr = x**3 + 4*x*y - z
expr
\[\displaystyle x^{3} + 4 x y - z\]
expr.subs([(x, 2), (y, 4), (z, 0)])
\[\displaystyle 40\]