Encontrando Soluções#

O Sympy tem diversas ferramentas para encontrar a soluções de equações, sistemas, EDO, etc de forma simbólica.

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/

Equações#

O solveset é uma função do SymPy utilizada para encontrar soluções de equações etc de forma simbólica.

Antigamente, a função utilizada era solve(), mas ela foi substituída (veja mais em http://docs.sympy.org/latest/modules/solvers/solveset.html).

A sintaxe é

solveset(equação, variável)

No exemplo abaixo tentamos buscar o conjunto solução da equação \(x^2-x=4\), que para denota-lá usamos Eq(x**2 - x,4)

solveset(Eq(x**2 - x,4), x)
\[\displaystyle \left\{\frac{1}{2} - \frac{\sqrt{17}}{2}, \frac{1}{2} + \frac{\sqrt{17}}{2}\right\}\]

Se Eq() não for utilizado, assume-se que a equação é igual a 0.

solveset(x**2 - x, x)
\[\displaystyle \left\{0, 1\right\}\]

A função solveset no SymPy permite restringir as soluções de uma equação a um determinado domínio. Os principais domínios de restrição são:

  1. S.Reals:

    • Restringe as soluções aos números reais.

    • Exemplo: Encontrar soluções reais para uma equação.

  2. S.Integers:

    • Restringe as soluções aos números inteiros.

    • Exemplo: Encontrar soluções inteiras para uma equação.

  3. S.Complexes:

    • Restringe as soluções aos números complexos.

    • Este é o comportamento padrão se nenhum domínio for especificado.

    • Exemplo: Encontrar soluções complexas para uma equação.

  4. Interval:

    • Restringe as soluções a um intervalo específico.

    • Você pode definir um intervalo com a função sp.Interval(inicio, fim), onde inicio e fim são os limites do intervalo.

    • Exemplo: Encontrar soluções de uma equação dentro do intervalo [0, 3].

solveset(sin(x) - 1, x, domain=S.Reals)
\[\displaystyle \left\{2 n \pi + \frac{\pi}{2}\; \middle|\; n \in \mathbb{Z}\right\}\]

em que o conjunto Z representa os inteiros.

O root é um método do SymPy que permite encontrar a raiz de uma equação ou expressão simbólica. Ele é mais usaddo para encontrar raízes diretas de polinômios simples, enqual o solveset para equações gerais com maior flexibilidade e controle sobre o domínio.

solveset(x**3 - 6*x**2 + 9*x, x)
\[\displaystyle \left\{0, 3\right\}\]
roots(x**3 - 6*x**2 + 9*x, x)
\[\displaystyle \left\{ 0 : 1, \ 3 : 2\right\}\]

O número 0 representa uma raiz única, enquanto o número 3 indica duas raízes que coincidem.

Sistemas Lineares#

O linsolve() é uma função do SymPy utilizada para encontrar soluções de sistemas de equações lineares de forma simbólica.

Sua sintaxe é:

linsolve([expr1, expr2], [variavel1, variavel2])

linsolve([x - y + 2, x + y - 3], [x, y])
\[\displaystyle \left\{\left( \frac{1}{2}, \ \frac{5}{2}\right)\right\}\]
linsolve([x + y + z - 1, x + y + 2*z - 3 ], (x, y, z))
\[\displaystyle \left\{\left( - y - 1, \ y, \ 2\right)\right\}\]

Equações Diferenciais#

É necessário ter uma função indefinida (f e g já estão definidas como indefinidas por meio da nossa init_session() mencionada acima, mas é provável que já tenhamos reiniciado essas funções).

f, g = symbols('f g', cls=Function)

Assim

f(x)
\[\displaystyle f{\left(x \right)}\]

Para termos a derivida de \(f\) fazemos

f(x).diff(x)
\[\displaystyle \frac{d}{d x} f{\left(x \right)}\]

Consequentemos podemos escrever uma equação usando derivadas

diffeq = Eq(f(x).diff(x, 2) - 2*f(x).diff(x) + f(x), sin(x))
diffeq
\[\displaystyle f{\left(x \right)} - 2 \frac{d}{d x} f{\left(x \right)} + \frac{d^{2}}{d x^{2}} f{\left(x \right)} = \sin{\left(x \right)}\]

Tais equações envolvendo derivadas ordinárias são chamadas de EDO (equações diferencias ordinárias) e para resolve-las o Sympy tem a função dsolve

dsolve(diffeq, f(x))
\[\displaystyle f{\left(x \right)} = \left(C_{1} + C_{2} x\right) e^{x} + \frac{\cos{\left(x \right)}}{2}\]

Matrizes#

Considere uma matriz qualquer

\[\begin{split} A = \left ( \begin{array}{ccc} u & p & 0 \\ 0 & u & 1/p\\ 0 & c^2 p & u \end{array} \right ) \end{split}\]

Vamos trabalhar com a matriz de Vandermonde para exemplificar

Para definir a mariz usamos o comando Matrix, mas antes precisamos especificar os simbolos que vamos utilizar usando symbols

p, u, c = symbols('p u c')
A = Matrix([[u, p, 0], [0, u, p**-1], [0, c**2 * p, u]])
A
\[\begin{split}\displaystyle \left[\begin{matrix}u & p & 0\\0 & u & \frac{1}{p}\\0 & c^{2} p & u\end{matrix}\right]\end{split}\]

Caso quisessemos letras gregas precisariamos importar ela diretamente de sympy.ab, utilizando o comando:

from sympy.abc import + letra

from sympy.abc import rho, alpha
p, u, c = symbols('rho alpha c')
A = Matrix([[u, p, 0], [0, u, p**-1], [0, c**2 * p, u]])
A
\[\begin{split}\displaystyle \left[\begin{matrix}\alpha & \rho & 0\\0 & \alpha & \frac{1}{\rho}\\0 & c^{2} \rho & \alpha\end{matrix}\right]\end{split}\]
A.row(0)
\[\displaystyle \left[\begin{matrix}\alpha & \rho & 0\end{matrix}\right]\]

The eigenvalues of the system are the speeds at which information propagates

A.eigenvals()
\[\displaystyle \left\{ \alpha : 1, \ \alpha - c : 1, \ \alpha + c : 1\right\}\]

A diagonalização (ou decomposição espectral) de uma matriz quadrada \(A\) é dada por: $\( A = PDP^{-1}\)\( onde \)P\( é a matriz dos autovetores e \)D$ a matriz dos autovalores.

Podemos obter tais matrizes utilizando .diagonalize

P, D = A.diagonalize()

Assim, \(D\) irá fornecer uma matriz diagonal cujos elementos são os autovalores de \(A\).

D
\[\begin{split}\displaystyle \left[\begin{matrix}\alpha & 0 & 0\\0 & \alpha - c & 0\\0 & 0 & \alpha + c\end{matrix}\right]\end{split}\]

Enquanto \(P\) a matriz cujas colunas são os autovetores de \(A\).

P
\[\begin{split}\displaystyle \left[\begin{matrix}1 & \frac{1}{c^{2}} & \frac{1}{c^{2}}\\0 & - \frac{1}{c \rho} & \frac{1}{c \rho}\\0 & 1 & 1\end{matrix}\right]\end{split}\]

Além disso, podemos calcula a inversa de \(A\) utilizando **-1

A**-1
\[\begin{split}\displaystyle \left[\begin{matrix}\frac{1}{\alpha} & \frac{\rho}{- \alpha^{2} + c^{2}} & - \frac{1}{- \alpha^{3} + \alpha c^{2}}\\0 & - \frac{\alpha}{- \alpha^{2} + c^{2}} & \frac{1}{- \alpha^{2} \rho + c^{2} \rho}\\0 & \frac{c^{2} \rho}{- \alpha^{2} + c^{2}} & - \frac{\alpha}{- \alpha^{2} + c^{2}}\end{matrix}\right]\end{split}\]

ou usando o comando .inv()

A.inv()
\[\begin{split}\displaystyle \left[\begin{matrix}\frac{1}{\alpha} & \frac{\rho}{- \alpha^{2} + c^{2}} & - \frac{1}{- \alpha^{3} + \alpha c^{2}}\\0 & - \frac{\alpha}{- \alpha^{2} + c^{2}} & \frac{1}{- \alpha^{2} \rho + c^{2} \rho}\\0 & \frac{c^{2} \rho}{- \alpha^{2} + c^{2}} & - \frac{\alpha}{- \alpha^{2} + c^{2}}\end{matrix}\right]\end{split}\]

Além disso ele faz operações de multiplicação apenas utilizando o comando *

C = A**-1
A * C
\[\begin{split}\displaystyle \left[\begin{matrix}1 & 0 & - \frac{\alpha}{- \alpha^{3} + \alpha c^{2}} + \frac{\rho}{- \alpha^{2} \rho + c^{2} \rho}\\0 & - \frac{\alpha^{2}}{- \alpha^{2} + c^{2}} + \frac{c^{2}}{- \alpha^{2} + c^{2}} & \frac{\alpha}{- \alpha^{2} \rho + c^{2} \rho} - \frac{\alpha}{\rho \left(- \alpha^{2} + c^{2}\right)}\\0 & 0 & - \frac{\alpha^{2}}{- \alpha^{2} + c^{2}} + \frac{c^{2} \rho}{- \alpha^{2} \rho + c^{2} \rho}\end{matrix}\right]\end{split}\]

Usando o simplify, obtemos a matriz A

simplify(A*C)
\[\begin{split}\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]\end{split}\]