2017-01-27 3 views
4

Je travaille sur une implémentation de la séquence de Fibonacci dans Numpy en utilisant le Q-Matrix method. Les résultats sont bons jusqu'à n = 47. À ce stade, la fonction matrix_power renvoie incorrect results. Toute explication sur la raison pour laquelle cela se produit?La fonction matrix_power de Numpy donne de mauvais résultats pour les grands exposants

import numpy 
def fibonacci(n): 
    qmatrix = numpy.matrix([[1, 1], [1, 0]]) 
    (a,b,c,d) = numpy.linalg.matrix_power(qmatrix,n).flatten().tolist()[0] 
    return b 
print fibonacci(47) # Outputs -1323752223 
+1

Etes-vous sûr? Je reçois '2971215073'. S'il s'agit d'un problème de plate-forme, essayez de convertir la matrice en un autre type, comme 'numpy.linalg.matrix_power (qmatrix, n) .astype (numpy.uint64) .flatten(). Tolist() [0]' – alexpeits

+0

Merci, en effet Cela semble être un problème de plateforme. Pour 'n = 47', la conversion en' numpy.uint32' corrige le résultat, mais il se trompe à nouveau pour les plus grandes valeurs. Je n'ai pas eu à faire de casting avant, quelle est la meilleure approche pour que ça marche? –

+0

Vous pouvez lire sur [this] (https://docs.scipy.org/doc/numpy/user/basics.types.html). Fondamentalement, un petit entier, disons 4 bits, ne peut pas contenir une très grande valeur, et il fait des choses bizarres quand vous demandez de l'afficher, donc vous lancez le tableau afin de surpasser ce problème. D'après ce que je vois, 'uint64' est le plus grand que vous puissiez obtenir, mais je ne suis pas un expert. – alexpeits

Répondre

4

Si vous allez jouer avec les nombres de Fibonacci, il est probablement justifié de sacrifier un peu de vitesse et d'utiliser des entiers arbitrairement grands Python. Vous pouvez le faire en définissant dtype de votre matrice à object.

Vous n'avez pas vraiment besoin d'utiliser l'objet np.matrix, il est presque toujours préférable de s'en tenir à des réseaux normaux. Et vous pouvez extraire l'élément pertinent sans convertir votre tableau en une liste:

def fibonacci(n): 
    qmatrix = numpy.array([[1, 1], [1, 0]], dtype=object) 
    return numpy.linalg.matrix_power(qmatrix, n)[0, 1] 
+0

Génial, cela fonctionne parfaitement. Une modification nécessaire dans votre code est le retour doit être à l'index [0,1], selon le théorème de la matrice Q. SO ne me laissera pas éditer parce que c'est juste un caractère: \ –

+1

Ah, vous avez raison! Le fixe déjà. – Jaime

+0

'cumprod' peut être utilisé pour obtenir toute une gamme de ces puissances' qmatrix' (en utilisant la version 'np.matrix') https://stackoverflow.com/a/47444215/901925 – hpaulj