Как указывает hpaulj, ошибка, по-видимому, связана с преобразованием **
в ^
, которое происходит по какой-то причине в lambdify
.
Вы можете исправить ошибку,получение с использованием np.power
вместо **
:
import numpy as np
from sympy import MatrixSymbol, lambdify
X0 = MatrixSymbol('X0',2,2)
xx = np.random.rand(4,4)
X0Inv = np.power(X0, -1)
symInv = lambdify(X0,X0Inv)
print('matrix xx')
print(xx, end='\n\n')
print('result of symInv(xx)')
print(symInv(xx), end='\n\n')
Вывод:
matrix xx
[[0.4514882 0.84588859 0.02431252 0.25468078]
[0.46767727 0.85748153 0.51207567 0.59636962]
[0.84557537 0.38459205 0.76814414 0.96624407]
[0.0933803 0.43467119 0.77823338 0.58770188]]
result of symInv(xx)
[[2.214897321138516, 1.1821887747951494], [2.1382266426713077, 1.1662058776397513]]
Однако при настройке symInv
матрица не инвертируется, но вместо этого только поэлементное возведение в степень каждого значения в xx
.Другими словами, symInv(xx)[i,j] == xx[i,j]**-1
.Этот код показывает разницу между поэлементным возведением в степень и истинным обратным.
print('result of xx**-1')
print(xx**-1, end='\n\n')
print('result of np.linalg.inv(xx)')
print(np.linalg.inv(xx))
Вывод:
result of xx**-1
[[ 2.21489732 1.18218877 41.13107402 3.92648394]
[ 2.13822664 1.16620588 1.95283638 1.67681243]
[ 1.18262669 2.60015778 1.301839 1.0349352 ]
[10.7088969 2.30058954 1.28496159 1.70154295]]
result of np.linalg.inv(xx)
[[-118.7558445 171.37619558 -20.37188041 -88.94733652]
[ -0.56274492 2.49107626 -1.00812489 -0.62648633]
[-160.35674704 230.3266324 -28.87548299 -116.75862026]
[ 231.62940572 -334.07044947 42.21936405 170.90926978]]
Редактировать: обходной путь
Я уверен на 95%То, с чем вы столкнулись, является ошибкой в коде Sympy.Кажется, что X0^-1
был допустимым синтаксисом для объектов Sympy Matrix
в некоторый момент, но больше не.Тем не менее, кажется, что кто-то забыл сказать, что тот, кто поддерживает код lambdify
, так как он по-прежнему переводит все возведения в матрицу в синтаксис морковного ^
.
Так что вы должны сделать, это отправить вопрос на Sympy Github .Просто опубликуйте свой код и ошибку, которую он вызывает, и спросите, является ли это предполагаемым поведением.А пока вот грязный хак, чтобы обойти эту проблему:
import numpy as np
from sympy import MatrixSymbol, lambdify
class XormulArray(np.ndarray):
def __new__(cls, input_array):
return np.asarray(input_array).view(cls)
def __xor__(self, other):
return np.linalg.matrix_power(self, other)
X0 = MatrixSymbol('X0',2,2)
xx = np.random.rand(4,4)
X0Inv = X0.inv()
symInv = lambdify(X0,X0Inv,'numpy')
print('result of symInv(XormulArray(xx))')
print(symInv(XormulArray(xx)), end='\n\n')
print('result of np.linalg.inv(xx)')
print(np.linalg.inv(xx))
Вывод:
result of symInv(XormulArray(xx))
[[ 3.50382881 -3.84573344 3.29173896 -2.01224981]
[-1.88719742 1.86688465 0.3277883 0.0319487 ]
[-3.77627792 4.30823019 -5.53247103 5.53412775]
[ 3.89620805 -3.30073088 4.27921307 -4.68944191]]
result of np.linalg.inv(xx)
[[ 3.50382881 -3.84573344 3.29173896 -2.01224981]
[-1.88719742 1.86688465 0.3277883 0.0319487 ]
[-3.77627792 4.30823019 -5.53247103 5.53412775]
[ 3.89620805 -3.30073088 4.27921307 -4.68944191]]
По сути, вам придется привести все ваши массивы к тонкой оболочкевведите XormulArray
прямо перед тем, как передать их в symInv
.Этот хак не является лучшей практикой по ряду причин (включая тот факт, что он, очевидно, нарушает ограничение формы (2,2)
, которое вы наложили на X0
), но, вероятно, будет лучшим, что вы можете сделать, пока не исправлена база кода Sympy..