python用sypy和numpy得到一个倒置的浮点矩阵

2024-09-25 00:25:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在python上实现一些算法。为了记录和清楚地理解流程细节,我使用sympy。结果它在计算一个反向的浮点矩阵时失败了。在

所以我得到了

TypeError                                 Traceback (most recent call last)
<ipython-input-20-c2193b2ae217> in <module>()
     10 np.linalg.inv(xx)
     11 symInv = lambdify(X0,X0Inv)
---> 12 symInv(xx)

/opt/anaconda3/lib/python3.6/site-packages/numpy/__init__.py in <lambda>(X0)

TypeError: ufunc 'bitwise_xor' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

如果矩阵为整数,则工作正常:

^{pr2}$

Link to a live version of the code

如果有人知道任何解决办法,如果你能分享的话,那就太好了。提前谢谢。在

更新。正如@hpaulj和@tel指出的,问题是lambdify如何将**转换为矩阵符号的numpy代码:出于某种原因,它尝试异或元素。我会设法找到一个简单的方法来改变这种行为。如有任何帮助/提示,我们将不胜感激。在


Tags: thetoinnumpy算法inputnot矩阵
1条回答
网友
1楼 · 发布于 2024-09-25 00:25:31

正如hpaulj所指出的,这个错误似乎源于**到{}的转换,这种转换发生在{}中。在

您可以通过使用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')

输出:

^{pr2}$

但是,正如您设置的那样,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%肯定你遇到的是sypy代码中的一个bug。似乎X0^-1在某个时候是Sympy Matrix对象的有效语法,但现在不再有效。然而,似乎有人忘了告诉维护lambdify代码的人,因为它仍然将每个矩阵求幂转换成carrot^语法。在

所以你应该提交一个关于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]]

基本上,在将所有数组传递到symInv之前,必须将所有数组强制转换为瘦包装器类型XormulArray。由于很多原因,这种方法并不是最佳实践(包括它显然打破了您对(2,2)的形状限制),但在Sympy代码库修复之前,它可能是您能做的最好的方法。在

相关问题 更多 >