循环中添加矩阵的次数不能超过20次

时间:2019-01-29 19:18:05

标签: python numpy matrix factorial

我正在尝试在for循环中创建2x2矩阵的总和,但是当我将总和循环超过21次(当我的n> 20时,如下所示)时,它会显示以下错误消息:

  

TypeError:根据转换规则“ same_kind”,无法将ufunc'add'输出(类型代码'O')强制为提供的输出参数(类型代码'd')

这是我的代码:

k = 2
n = 21

A2 = np.matrix('0.5 -0.5; 0.5 0.5')
SumA2 = np.zeros((k,k))

for i in range(0, n+1):
    SumA2 += np.linalg.matrix_power(A2, i)/np.math.factorial(i)

print(A2)
print("\n", SumA2)

我怀疑这与阶乘过大有关,但这真的是一个问题吗?在Matlab中,我可以循环1000次而不会出现问题。

1 个答案:

答案 0 :(得分:1)

在21点,它将数组类型切换为对象:

In [776]: np.linalg.matrix_power(A2,20)/np.math.factorial(20)
Out[776]: 
matrix([[-4.01398205e-22,  0.00000000e+00],
        [ 0.00000000e+00, -4.01398205e-22]])
In [777]: np.linalg.matrix_power(A2,21)/np.math.factorial(21)
Out[777]: 
matrix([[-9.557100128609015e-24, 9.557100128609015e-24],
        [-9.557100128609015e-24, -9.557100128609015e-24]], dtype=object)

更具体地说,是切换的factorial

In [778]: np.array(np.math.factorial(20))
Out[778]: array(2432902008176640000)
In [779]: np.array(np.math.factorial(21))
Out[779]: array(51090942171709440000, dtype=object)

Python3对factorial使用整数。这些可以是任何长度。但是此时,该值变得太大而无法用np.int64表示。因此,它切换为使用包含长Python整数的对象dtype数组。该开关将传播到power计算中。

当尝试将此数组转换为与SumA2兼容的dtype时,会出现错误。

In [782]: SumA2 = np.zeros((k,k))
In [783]: SumA2 += Out[777]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-783-53cbd27f9514> in <module>()
----> 1 SumA2 += Out[777]

TypeError: ufunc 'add' output (typecode 'O') could not be coerced to provided output parameter (typecode 'd') according to the casting rule ''same_kind''
In [784]: SumA2 = np.zeros((k,k), object)
In [785]: SumA2 += Out[777]
In [786]: SumA2
Out[786]: 
array([[-9.557100128609015e-24, 9.557100128609015e-24],
       [-9.557100128609015e-24, -9.557100128609015e-24]], dtype=object)

在170,它开始遇到将整数转换为浮点数的问题

先执行1/factorial(...)似乎有帮助。将A2的dtype更改为更高精度的float可能会有所帮助:

In [812]: np.linalg.matrix_power(A2.astype('float128'),171)*(1/np.math.factorial(171))
Out[812]: 
matrix([[-1.04145922e-335, -1.04145922e-335],
        [ 1.04145922e-335, -1.04145922e-335]], dtype=float128)

对于2x2矩阵,实际上并没有特别使用numpy。使用列表和“原始” Python数字几乎可以很容易地计算出重复功效。但是,即使那些不是为无限精度数学而设计的。整数可能很长,但我认为Python浮点数没有那么灵活。