Files
INF6B/fib/fib.py

42 lines
1.2 KiB
Python

# tiny class to hold a 2x2 matrix
class Matrix2x2:
def __init__(self, m00, m01, m10, m11):
self.m00 = m00
self.m01 = m01
self.m10 = m10
self.m11 = m11
# multiply two 2x2 matrices
def multiply(a, b):
return Matrix2x2(
a.m00 * b.m00 + a.m01 * b.m10, # top-left
a.m00 * b.m01 + a.m01 * b.m11, # top-right
a.m10 * b.m00 + a.m11 * b.m10, # bottom-left
a.m10 * b.m01 + a.m11 * b.m11 # bottom-right
)
# raise a matrix to the power n using binary exponentiation
def matrix_pow(base, n):
result = Matrix2x2(1, 0, 0, 1) # start with identity matrix
while n > 0:
if n % 2 == 1: # if n is odd, multiply once
result = multiply(result, base)
base = multiply(base, base) # square the base
n //= 2 # integer division
return result
# get nth fibonacci number using matrix exponentiation
def fibonacci_matrix(n):
if n == 0:
return 0 # edge case
base = Matrix2x2(1, 1, 1, 0) # Fibonacci Q-matrix
result = matrix_pow(base, n - 1)
return result.m00 # top-left is F(n)
# print first n fibonacci numbers
if __name__ == "__main__":
n = 50
for i in range(n):
print(fibonacci_matrix(i), end=" ")
print()