Ir al contenido principal

Problemas en Sympy de Python

 Fuente: https://docs.sympy.org/latest/tutorials/intro-tutorial/gotchas.html

Problemas

Para empezar, debemos dejar claro algo sobre SymPy. SymPy no es nada más que una biblioteca de Python, como NumPy, Django, o incluso módulos en el Biblioteca estándar de Python syso re. Lo que esto significa es que SymPy no No agregar nada al lenguaje Python. Limitaciones inherentes a la El lenguaje Python también es inherente a SymPy. También significa que SymPy intenta Utilice modismos de Python siempre que sea posible, lo que facilita la programación con SymPy. aquellos que ya están familiarizados con la programación con Python. Como ejemplo sencillo, SymPy usa la sintaxis de Python para crear expresiones. Multiplicación implícita (como 3xo 3 x) no está permitido en Python y, por lo tanto, no está permitido en SymPy. Multiplicar 3y x, debes escribir 3*xcon el *.

Símbolos

Una consecuencia de este hecho es que SymPy se puede utilizar en cualquier entorno. donde Python está disponible. Simplemente lo importamos, como lo haríamos con cualquier otro. biblioteca:

from sympy import *

Esto importa todas las funciones y clases de SymPy a nuestro interactivo Sesión de Python. Ahora supongamos que comenzamos a hacer un cálculo.

x + 1
Traceback (most recent call last):
...
NameError: name 'x' is not defined

¡Ups! ¿Que pasó aquí? Intentamos usar la variable. x, pero nos dice eso xno está definido. En Python, las variables no tienen significado hasta que están definidos. SymPy no es diferente. A diferencia de muchas manipulaciones simbólicas sistemas que haya utilizado, en SymPy, las variables no se definen automáticamente. Para definir variables debemos utilizar symbols.

x = symbols('x')
x + 1
x + 1

symbolstoma una cadena de nombres de variables separados por espacios o comas, y crea símbolos a partir de ellos. Luego podemos asignarlos a nombres de variables. Más adelante, investigaremos algunas formas convenientes en las que podemos solucionar este problema. Por ahora, definamos simplemente los nombres de variables más comunes, x, y, y z, para uso durante el resto de esta sección

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

Como nota final, observamos que el nombre de un Símbolo y el nombre del La variable a la que está asignada no necesita tener nada que ver entre sí.

a, b = symbols('b a')
a
b
b
a

Aquí hemos hecho lo muy confuso de asignar un símbolo con el nombre aa la variable by un símbolo del nombre ba la variable a. Ahora la variable de Python llamada aapunta al símbolo SymPy llamado b, y viceversa. Qué confuso. También podríamos haber hecho algo como

crazy = symbols('unrelated')
crazy + 1
unrelated + 1

Esto también muestra que los símbolos pueden tener nombres de más de un carácter si desear.

Por lo general, la mejor práctica es asignar símbolos a las variables de Python del mismo nombre, aunque hay excepciones: Los nombres de los símbolos pueden contener caracteres que no están permitidos en los nombres de variables de Python, o que simplemente quieran evitar escribir nombres largos asignando símbolos con nombres largos a una sola letra Python variables.

Para evitar confusiones, a lo largo de este tutorial, los nombres de los símbolos y las variables de Python Los nombres siempre coincidirán. Además, la palabra “Símbolo” se referirá a un El símbolo SymPy y la palabra "variable" se referirán a una variable de Python.

Finalmente, asegurémonos de comprender la diferencia entre símbolos SymPy y Variables de Python. Considera lo siguiente:

x = symbols('x')
expr = x + 1
x = 2
print(expr)

¿Cuál crees que será el resultado de este código? si pensaras 3, te equivocas. veamos que pasa realmente

x = symbols('x')
expr = x + 1
x = 2
print(expr)
x + 1

Cambiando xa 2no tuvo ningún efecto sobre expr. Esto es porque x = 2 cambia la variable de Python xa 2, pero no tiene ningún efecto en SymPy Símbolo x, que fue lo que usamos para crear expr. cuando creamos expr, la variable de Python xera un símbolo. Después de que lo creamos, nosotros cambió la variable de Python xa 2. Pero exprsigue siendo el mismo. Este El comportamiento no es exclusivo de SymPy. Todos los programas Python funcionan de esta manera: si un se cambia la variable, las expresiones que ya fueron creadas con esa variable no cambie automáticamente. Por ejemplo

x = 'abc'
expr = x + 'def'
expr
'abcdef'
x = 'ABC'
expr
'abcdef'

Para cambiar el valor de un símbolo en una expresión, use subs

x = symbols('x')
expr = x + 1
expr.subs(x, 2)
3

En este ejemplo, si queremos saber qué expres con el nuevo valor de x, necesitamos reevaluar el código que creó expr, a saber, expr = x + 1. Esto puede resultar complicado si se crean varias líneas. expr. Uno La ventaja de utilizar un sistema de cálculo simbólico como SymPy es que podemos construir una representación simbólica para expry luego sustituir xcon valores. La forma correcta de hacer esto en SymPy es usar subs, Cuál podría ser discutido con más detalle más adelante.

x = symbols('x')
expr = x + 1
expr.subs(x, 2)
3

Signos iguales

Otra consecuencia muy importante del hecho de que SymPy no se extiende La sintaxis de Python es esa =no representa igualdad en SymPy. Más bien es la asignación de variables de Python. Esto está codificado en el lenguaje Python, y SymPy no intenta cambiar eso.

Puedes pensar, sin embargo, que ==, que se utiliza para pruebas de igualdad en Python, se usa para SymPy como igualdad. Esto tampoco es del todo correcto. Dejar veamos qué pasa cuando usamos ==.

x + 1 == 4
False
en lugar de tratar x + 1 == 4simbólicamente, acabamos de llegar False. En simpy, ==representa una prueba exacta de igualdad estructural. Esto significa que a == bsignifica que estamos preguntando si

. Siempre recibimos un boolcomo el resultado de ==. Hay un objeto separado, llamado Eq, que puede ser utilizado para crear igualdades simbólicas

Eq(x + 1, 4)
Eq(x + 1, 4)
Hay una advertencia adicional sobre ==también. Supongamos que queremos saber si

. Podríamos intentar algo como esto:

(x + 1)**2 == x**2 + 2*x + 1
False
Tenemos Falsede nuevo. Sin embargo, es igual

. Qué esta pasando aqui? ¿Encontramos un error en SymPy o simplemente no es potente? ¿Suficiente para reconocer este hecho algebraico básico?

Recuerda desde arriba que ==representa exacta de igualdad estructural. "Exacta" aquí significa que dos expresiones se compararán igual ==sólo si son exactamente iguales estructuralmente. Aquí,

y

son No es lo mismo estructuralmente. Uno es la potencia de la suma de dos términos, y el otro es la suma de tres términos.

Resulta que al usar SymPy como biblioteca, tener ==prueba de exactitud La igualdad estructural es mucho más útil que representar valores simbólicos. igualdad, o hacer que pruebe la igualdad matemática. Sin embargo, como nuevo usuario, probablemente le interesarán más los dos últimos. ya hemos visto una alternativa a la representación simbólica de las igualdades, Eq. para probar si dos cosas son iguales, es mejor recordar el hecho básico de que si

, entonces . Por lo tanto, la mejor manera de comprobar si es tomar

aprenderemos Más adelante que la función para hacer esto se llama simplify. Este El método no es infalible; de ​​hecho, se puede demostrar teóricamente que es imposible. determinar si dos expresiones simbólicas son idénticamente iguales en general, pero para la mayoría de las expresiones comunes, funciona bastante bien.

a = (x + 1)**2
b = x**2 + 2*x + 1
simplify(a - b)
0
c = x**2 - 2*x + 1
simplify(a - c)
4*x

También existe un método llamado equalsque prueba si dos expresiones son iguales evaluándolos numéricamente en puntos aleatorios.

a = cos(x)**2 - sin(x)**2
b = cos(2*x)
a.equals(b)
True

Dos notas finales: ^y /

Quizás hayas notado que hemos estado usando **para la exponenciación en su lugar de la norma ^. Esto se debe a que SymPy sigue las convenciones de Python. En Pitón, ^representa lógica exclusiva o. SymPy sigue esta convención:

True ^ False
True
True ^ True
False
Xor(x, y)
x ^ y

Finalmente, conviene realizar una pequeña discusión técnica sobre cómo funciona SymPy. Cuando escribes algo como x + 1, el símbolo SymPy xse agrega a la Python entero 1. Las reglas del operador de Python permiten que SymPy le diga a Python que los objetos SymPy saben cómo agregarse a las entradas de Python, y así 1es convertido automáticamente al objeto SymPy Integer.

Este tipo de magia del operador ocurre automáticamente detrás de escena, y usted Rara vez necesitamos siquiera saber lo que está sucediendo. Sin embargo, hay uno excepción. Siempre que combine un objeto SymPy y un objeto SymPy, o un SymPy objeto y un objeto Python, obtienes un objeto SymPy, pero siempre que combinas dos objetos Python, SymPy nunca entra en juego, por lo que obtienes un Python objeto.

type(Integer(1) + 1)
<class 'sympy.core.numbers.Integer'>
type(1 + 1)
<... 'int'>

Por lo general, esto no es gran cosa. Las entradas de Python funcionan de manera muy similar a SymPy Números enteros, pero hay una excepción importante: la división. En SymPy, el La división de dos Enteros da un Racional:

Integer(1)/Integer(3)
1/3
type(Integer(1)/Integer(3))
<class 'sympy.core.numbers.Rational'>

Pero en Python /representa división entera o punto flotante división, dependiendo de si estás en Python 2 o Python 3, y dependiendo sobre si has corrido o no from __future__ import divisionen pitón 2 que ya no es compatible con versiones superiores a SymPy 1.5.1:

from __future__ import division
1/2
0.5

Para evitar esto, podemos construir el objeto racional explícitamente.

Rational(1, 2)
1/2

Este problema también surge cada vez que tenemos una expresión simbólica más grande con int/inten eso. Por ejemplo:

x + 1/2
x + 0.5

Esto sucede porque Python primero evalúa 1/2en 0.5, y luego que se convierte en un tipo SymPy cuando se agrega a x. Nuevamente podemos obtener alrededor de esto creando explícitamente un Racional:

x + Rational(1, 2)
x + 1/2

Hay varios consejos para evitar esta situación en los errores y trampas. documento.

Otras lecturas

Comentarios

Entradas más populares de este blog

TEST DE VARIABLES EN PYTHON

PySDR: una guía para SDR y DSP usando Python by Dr. Marc Lichtman. Introducciòn.

LEER Y CONVERTIR AUDIOS CON PYTHON EN GOOGLE COLAB