(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)))