【问题标题】:Numpy matrix exponentiation gives negative valueNumpy矩阵求幂给出负值
【发布时间】:2016-09-20 19:32:29
【问题描述】:

我想在斐波那契问题中使用NumPy,因为它在矩阵乘法中的效率很高。你知道有一种方法可以用矩阵[[1, 1], [1, 0]]求斐波那契数。

我写了一些非常简单的代码,但是在增加n 之后,矩阵开始给出负数。

import numpy
def fib(n):
    return (numpy.matrix("1 1; 1 0")**n).item(1)

print fib(90)
# Gives -1581614984

这可能是什么原因?

注意:linalg.matrix_power 也给出负值。

注意2:我尝试了从0到100的数字。它在47之后开始给出负值。这是一个大整数问题,因为NumPy是用C编码的吗?如果是这样,我该如何解决?

编辑: 使用带有 linalg.matrix_power 的常规 python list 矩阵也给出了负面结果。另外让我补充一点,并不是所有的结果在 47 之后都是阴性的,它是随机发生的。

Edit2:我尝试使用@AlbertoGarcia-Raboso 建议的方法。它解决了负数问题,但出现了另一个问题。它给出了-5.168070885485832e+19 的答案,我需要-51680708854858323072L。所以我尝试使用int(),将其转换为L,但现在由于精度损失,答案似乎不正确。

【问题讨论】:

  • @mgilson 我用了numpy.__version__,它给了1.11.1
  • 听起来你有一个 32 位版本的 NumPy。 fib(47) 应该是 2971215073,这对于带符号的 32 位整数来说有点太大了。
  • @ajcr 我用这个stackoverflow.com/questions/33553549/… 来检查我的NumPy。它说 64 位。
  • @Rockybilly:你当然可以用 NumPy 来做,只是如果你计算大值,你必须使用 Python 的内置整数类型来计算矩阵(这种类型比机器慢-宽度整数)。只需使用(np.matrix("1 1; 1 0", dtype=np.object)**n).item(1)(即声明矩阵应使用“对象”类型)。
  • @ajcr 您能否将其添加为您解释np.object 的答案?

标签: python numpy matrix fibonacci exponentiation


【解决方案1】:

您看到出现负值的原因是因为 NumPy 已默认为您的矩阵使用 np.int32 dtype。

这个 dtype 可以表示的最大正整数是 231-1,即 2147483647。不幸的是,这小于第 47 个斐波那契数 2971215073。由此产生的溢出导致负数出现:

>>> np.int32(2971215073)
-1323752223

使用更大的整数类型(如np.int64)可以解决这个问题,但只是暂时的:如果你继续要求越来越大的斐波那契数,你仍然会遇到问题。

唯一确定的解决方法是使用无限大小的整数类型,例如 Python 的 int 类型。为此,请将您的矩阵修改为 np.object 类型:

def fib_2(n):
    return (np.matrix("1 1; 1 0", dtype=np.object)**n).item(1)

np.object 类型允许矩阵或数组保存任何原生 Python 类型的组合。本质上,矩阵不再保存机器类型,而是表现得像一个 Python 列表,并且只包含指向内存中整数对象的指针。 Python 整数现在将用于计算斐波那契数,溢出不是问题。

>>> fib_2(300)
222232244629420445529739893461909967206666939096499764990979600

这种灵活性是以降低性能为代价的:NumPy 的速度源于直接存储可以由硬件操作的整数/浮点类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 2013-01-24
    • 2016-05-30
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多