2016-05-19 5 views
0

Ich schreibe ein paar Funktionen, um eine Fibonacci-Zahlen zu berechnen. Ich entdeckte, dass einige Werte der fib2 und fib3 nicht mit anderen übereinstimmen.numpy Matrix Multiplikation und Leistung ist nicht korrekt

dem folgenden zu reproduzieren:

import numpy as np 

def fib1(n): 
    if n == 0: return 0 
    a, b = 0, 1 
    for i in range(2, n + 1): 
     a, b = b, a + b 
    return b 

# numpy matrix power 
def fib2(n): 
    m = np.matrix([[1, 1], [1, 0]]) ** n 
    return m.flat[1] 

# numpy matrix multiplication 
def fib3(n): 
    r = m = np.array([[1, 1], [1, 0]]) 
    for _ in range(n - 1): 
     r = r.dot(m) 
    return r.flat[1] 

# manual matrix multiplication 
def fib4(n): 
    def matmult(X, Y): 
     return [[sum(el_x * el_y for el_x, el_y in zip(row_x, col_y)) 
       for col_y in zip(*Y)] for row_x in X] 
    r = m = [[1, 1], [1, 0]] 
    for _ in range(n - 1): 
     r = matmult(r, m) 
    return r[0][1] 

# print results 
print("{0:>5}{1:>25}{2:>25}{3:>25}{4:>25}".format("N", "fib1", "fib2", "fib3", "fib4")) 
for i in range(90, 101): 
    print("{0:>5}".format(i), 
      "{0:>25}".format(fib1(i)), 
      "{0:>25}".format(fib2(i)), 
      "{0:>25}".format(fib3(i)), 
      "{0:>25}".format(fib4(i))) 

Ausgang:

N fib1 fib2 fib3 fib4 
90  2880067194370816120  2880067194370816120  2880067194370816120  2880067194370816120 
91  4660046610375530309  4660046610375530309  4660046610375530309  4660046610375530309 
92  7540113804746346429  7540113804746346429  7540113804746346429  7540113804746346429 
93  12200160415121876738  -6246583658587674878  -6246583658587674878  12200160415121876738 
94  19740274219868223167  1293530146158671551  1293530146158671551  19740274219868223167 
95  31940434634990099905  -4953053512429003327  -4953053512429003327  31940434634990099905 
96  51680708854858323072  -3659523366270331776  -3659523366270331776  51680708854858323072 
97  83621143489848422977  -8612576878699335103  -8612576878699335103  83621143489848422977 
98  135301852344706746049  6174643828739884737  6174643828739884737  135301852344706746049 
99  218922995834555169026  -2437933049959450366  -2437933049959450366  218922995834555169026 
100 354224848179261915075  3736710778780434371  3736710778780434371  354224848179261915075 

Wie Sie sehen fib1 und fib4 Arbeiten korrekt ist. Irgendwelche Ideen?

Versionen:

  • Python 3.5.1
  • numpy 1.11.0
+4

Ihre NumPy-Routinen verwenden 32-Bit-Ganzzahlen, während pure-Python beliebig große Ganzzahlen verarbeiten kann. Sie haben Integer-Überlauf. –

+1

@ajcr Das sind eigentlich 64-Bit-Ganzzahlen. – kennytm

+0

@kennytm: Ja, danke, mein Fehler. –

Antwort

0

scheint dtype=object param für die numpy.matrix das Problem lösen:

def fib2(n): 
    m = np.matrix([[1, 1], [1, 0]], dtype=object) ** n 
    return m.flat[1] 
fib2(93) # 12200160415121876738