python - symbolic - sympy: el objeto ''Transpose'' no tiene ningún atributo tolist
sympy multiple symbols (1)
Yo diría que esto es un error en Sympy:
En Python, puede sobrecargar el operador de multiplicación desde ambos lados . A*B
puede manejarse internamente llamando a A.__mul__(B)
o B.__rmul__(A)
. Python primero llama a A.__mul__
, y si este método no existe o devuelve NotImplemented
, entonces Python prueba B.__rmul__
automáticamente. SymPy en su lugar usa un decorador llamado call_highest_priority para decidir cuál de las dos implementaciones usar. Busca la _op_priority
de las clases involucradas y llama a la función de la implementación con mayor prioridad. Las prioridades en su caso son 11 para v
e I
y 10.01 para I_
, por lo I
se prefiere. Además, la implementación base de __mul__
, que I
uso, carece del decorador.
Para abreviar, I*v
termina siempre llamando a I.__mul__
, y __mul__
no puede manejar MatrixSymbol
pero tampoco devuelve NotImplemented
. v.__rmul__(I)
funciona como se esperaba.
La solución correcta sería capturar AttributeError
en matrices.py
y devolver NotImplemented
, es decir,
try:
blst = B.T.tolist()
except AttributeError:
return NotImplemented
Python se volvería automáticamente a __rmul__
. La solución de hack''ish sería ajustar _op_priority
. De cualquier manera, debe presentar un informe de error: si el error fue por diseño (es decir, si accidentalmente probó algo que no debería funcionar), entonces el mensaje de error lo diría.
Estoy tratando de hacer algunos cálculos de matriz simbólica con Sympy. Mi objetivo es obtener una representación simbólica del resultado de algunos cálculos matriciales. Me he encontrado con algunos problemas que he reducido a este simple ejemplo, en el que trato de evaluar el resultado de un exponencial de una matriz específica y multiplicarla por un vector arbitrario.
>>> import sympy
>>> v = sympy.MatrixSymbol(''v'', 2, 1)
>>> Z = sympy.zeros(2, 2) # create 2x2 zero matrix
>>> I = sympy.exp(Z) # exponentiate zero matrix to get identity matrix
>>> I * v
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "sympy/matrices/matrices.py", line 507, in __mul__
blst = B.T.tolist()
AttributeError: ''Transpose'' object has no attribute ''tolist''
Por el contrario, si creo directamente la matriz de identidad y luego la multiplico por v, entonces no hay problema:
>>> I_ = sympy.eye(2) # directly create the identity matrix
>>> I_ == I # check the two matrices are equal
True
>>> I_ * v
v
Una cosa que he notado es que las dos matrices de identidad son de diferentes clases:
>>> I.__class__
sympy.matrices.immutable.ImmutableMatrix
>>> I_.__class__
sympy.matrices.dense.MutableDenseMatrix
También encontré que llamar al método as_mutable()
proporcionaba una as_mutable()
.
>>> I.as_mutable() * v
v
¿Siempre es necesario poner llamadas as_mutable()
a lo largo de los cálculos de álgebra lineal de uno? Supongo que no, y que en su lugar estos errores sugieren que estoy usando la estrategia incorrecta para resolver mi problema, pero no puedo entender cuál sería la estrategia correcta. ¿Alguien tiene alguna indicación?
He leído la página de documentación sobre Matrices inmutables, pero aún podría utilizar algo de ayuda para entender cómo sus diferencias con las matrices mutables estándar son importantes aquí, y por qué algunas operaciones (por ejemplo, sympy.exp) se convierten entre estas diferentes clases.