numpy矩阵求幂给出负值 [英] Numpy matrix exponentiation gives negative value

查看:208
本文介绍了numpy矩阵求幂给出负值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在斐波那契问题中使用NumPy,因为它在矩阵乘法中非常有效.您知道有一种使用矩阵[[1, 1], [1, 0]]来查找斐波那契数的方法.

I wanted to use NumPy in a Fibonacci question because of its efficiency in matrix multiplication. You know that there is a method for finding Fibonacci numbers with the matrix [[1, 1], [1, 0]].

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

I wrote some very simple code but after increasing n, the matrix is starting to give negative numbers.

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编码的?如果是这样,我该如何解决?

Note2: I tried numbers from 0 to 100. It starts to give negative values after 47. Is it a large integer issue because NumPy is coded in C ? If so, how could I solve this ?

编辑:将常规python list矩阵与linalg.matrix_power一起使用也会产生负面结果.此外,我还要补充一点,并非所有结果在47之后都是负数,而是随机发生的.

Using regular python list matrix with linalg.matrix_power also gave negative results. Also let me add that not all results are negative after 47, it occurs randomly.

Edit2 :我尝试使用建议的@ AlbertoGarcia-Raboso方法.它解决了负数问题,但是又出现了另一个问题.在我需要-51680708854858323072L的地方,答案为-5.168070885485832e+19.因此,我尝试使用int(),将其转换为L,但是现在看来,由于精度降低,答案是不正确的.

I tried using the method @AlbertoGarcia-Raboso suggested. It resolved the negative number problem, however another issues occured. It gives the answer as -5.168070885485832e+19 where I need -51680708854858323072L. So I tried using int(), it converted it to L, but now it seems the answer is incorrect because of a loss in precision.

推荐答案

看到负值的原因是因为NumPy默认将np.int32 dtype用于矩阵.

The reason you see negative values appearing is because NumPy has defaulted to using the np.int32 dtype for your matrix.

此dtype可以表示的最大正整数是2 31 -1,即2147483647.不幸的是,这比第47个斐波纳契数2971215073少.结果溢出导致出现负数:

The maximum positive integer this dtype can represent is 231-1 which is 2147483647. Unfortunately, this is less the 47th Fibonacci number, 2971215073. The resulting overflow is causing the negative number to appear:

>>> np.int32(2971215073)
-1323752223

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

Using a bigger integer type (like np.int64) would fix this, but only temporarily: you'd still run into problems if you kept on asking for larger and larger Fibonacci numbers.

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

The only sure fix is to use an unlimited-size integer type, such as Python's int type. To do this, modify your matrix to be of np.object type:

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

np.object类型允许矩阵或数组容纳本机Python类型的任何混合.本质上,矩阵现在不再像保存机器类型那样运行,就像Python列表一样,仅由指向内存中整数对象的指针组成.现在,将使用Python整数来计算斐波那契数,而溢出不是问题.

The np.object type allows a matrix or array to hold any mix of native Python types. Essentially, instead of holding machine types, the matrix is now behaving like a Python list and simply consists of pointers to integer objects in memory. Python integers will be used in the calculation of the Fibonacci numbers now and overflow is not an issue.

>>> fib_2(300)
222232244629420445529739893461909967206666939096499764990979600

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

This flexibility comes at the cost of decreased performance: NumPy's speed originates from direct storage of integer/float types which can be manipulated by your hardware.

这篇关于numpy矩阵求幂给出负值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆