2016-09-20 153 views
4

我想在斐波那契問題中使用NumPy,因爲它在矩陣乘法中的效率很高。你知道有一種方法找到矩陣[[1, 1], [1, 0]]的斐波納契數字。Numpy矩陣求冪給出負值

Fibo

我寫了一些非常簡單的代碼,但增加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之後並不是所有的結果都是負數,它是隨機發生的。

編輯2:我嘗試使用@ AlbertoGarcia-Raboso建議的方法。它解決了負數問題,但是另一個問題發生了。它給出了答案-5.168070885485832e+19我需要-51680708854858323072L。所以我嘗試使用int(),它將它轉換爲L,但現在看起來答案是錯誤的,因爲精度的損失。

+0

您的代碼對我而言(numpy1.10.4)產生'2880067194370816120'。你有什麼numpy版本? – mgilson

+0

嘗試在'1'和'0'之後添加點來創建浮點矩陣:'numpy.matrix(「1.1; 1.0。」)''。 –

+1

@mgilson我用'numpy .__ version__'給了'1.11.1' – Rockybilly

回答

7

您看到負值出現的原因是因爲NumPy默認爲您的矩陣使用np.int32 dtype。

最大正整數此D型細胞可以表示爲2 -1這是2147483647。不幸的是,這是不太第47 Fibonacci數,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的速度從可以通過硬件進行操作整數/浮點類型的直接存儲起源。