【问题标题】:Cannot add matrices more than 20 times in loop循环添加矩阵不能超过 20 次
【发布时间】:2019-01-30 17:17:23
【问题描述】:

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

TypeError: ufunc 'add' output (typecode 'O') 无法根据转换规则 ''same_kind'' 强制转换为提供的输出参数 (typecode '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 次。

【问题讨论】:

    标签: python numpy matrix factorial


    【解决方案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 更改为更高精度的浮点数可能会有所帮助:

    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 浮点数没有那么灵活。

    【讨论】:

    • SumA2 的初始数据类型更改为对象似乎可以解决问题。
    • 谢谢!这将其修复为 n = 170。我会看看如何从那里获得更大的数字。
    • 是的,您开始遇到整数到浮点转换问题。 numpy 和 Python 不是为无限精度数学而设计的。
    猜你喜欢
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多