Numpy 矩阵求幂给出负值
Numpy matrix exponentiation gives negative value
我想在斐波那契问题中使用 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编码的吗?如果是这样,我该如何解决?
编辑: 使用常规 python list
矩阵和 linalg.matrix_power
也给出了负面结果。另外让我补充一点,并不是所有的结果在 47 之后都是负面的,它是随机出现的。
Edit2: 我尝试使用@AlbertoGarcia-Raboso 建议的方法。它解决了负数问题,但是出现了另一个问题。它在我需要 -51680708854858323072L
的地方给出了 -5.168070885485832e+19
的答案。所以我尝试使用 int()
,它把它转换成 L
,但现在看起来答案不正确,因为精度损失。
您看到负值出现的原因是因为 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 的速度源于直接存储 integer/float 类型,可以由您的硬件操作。
我想在斐波那契问题中使用 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编码的吗?如果是这样,我该如何解决?
编辑: 使用常规 python list
矩阵和 linalg.matrix_power
也给出了负面结果。另外让我补充一点,并不是所有的结果在 47 之后都是负面的,它是随机出现的。
Edit2: 我尝试使用@AlbertoGarcia-Raboso 建议的方法。它解决了负数问题,但是出现了另一个问题。它在我需要 -51680708854858323072L
的地方给出了 -5.168070885485832e+19
的答案。所以我尝试使用 int()
,它把它转换成 L
,但现在看起来答案不正确,因为精度损失。
您看到负值出现的原因是因为 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 的速度源于直接存储 integer/float 类型,可以由您的硬件操作。