(a) Since this method of calculating the Fibonacci sequence is rather round-about anyway, we can tolerate the inefficiency of the most obvious implementation:
import numpy as np
F = np.matrix('1 1; 1 0')
for n in range(10):
print((F**n)[0,0], end=' ')
print()
(b) The necessary matrix eigenvalue, eigenvector and inverse operations are provided by numpy.linalg
. Note that the value for $F_n$ obtained will be approximate for all but the smallest values of $n$ because of the finite floating point precision of the calculations.
import numpy as np
F = np.matrix('1 1; 1 0')
(lam1, lam2), C = np.linalg.eig(F)
Ci = np.linalg.inv(C)
def fib(n):
D = np.matrix( [[lam1**n, 0], [0, lam2**n]] )
M = C * D * Ci
return int(M[0,0])
n = 1100
print('F({:d}) = {:d}'.format(n, fib(n-1)))
The output is:
F(1100) = 3442859285241154346892196225573457671992103442062265067036882365866370
86258589521820944507296037626279970501040816716437642709859166330016558491460760
02833721609607394223286654158912580200000298063796245829929013387821468870508544