fast fibonacci Algorithm
The Fast Fibonacci Algorithm, also known as the Matrix Exponentiation method, is an efficient technique used to compute the nth Fibonacci number in logarithmic time complexity. This algorithm is based on the principle of matrix exponentiation, which leverages the properties of matrix multiplication and exponentiation to quickly compute large Fibonacci numbers. Compared to the traditional recursive or iterative methods, which have linear or exponential time complexity, the Fast Fibonacci Algorithm significantly reduces the time required to calculate large Fibonacci numbers, thus making it highly suitable for applications requiring swift computation of large Fibonacci sequences.
The core concept of the Fast Fibonacci Algorithm involves expressing the Fibonacci sequence as a matrix equation and then raising the matrix to the power of n-1. This is achieved by utilizing the properties of matrix multiplication and the observation that the Fibonacci sequence can be transformed into a matrix equation. The algorithm begins with the initial matrix [[1, 1], [1, 0]], which, when multiplied with any Fibonacci vector [Fn, Fn-1], results in the next Fibonacci vector [Fn+1, Fn]. By repeatedly multiplying this matrix by itself, we can quickly reach the nth Fibonacci number. The exponentiation process is further optimized by employing the divide-and-conquer technique, which allows the matrix to be raised to the power of n-1 in logarithmic time complexity. This results in the Fast Fibonacci Algorithm being significantly more efficient than traditional Fibonacci computation methods for large n values.
#!/usr/bin/env python3
"""
This program calculates the nth Fibonacci number in O(log(n)).
It's possible to calculate F(1_000_000) in less than a second.
"""
import sys
from typing import Tuple
def fibonacci(n: int) -> int:
"""
return F(n)
>>> [fibonacci(i) for i in range(13)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
"""
if n < 0:
raise ValueError("Negative arguments are not supported")
return _fib(n)[0]
# returns (F(n), F(n-1))
def _fib(n: int) -> Tuple[int, int]:
if n == 0: # (F(0), F(1))
return (0, 1)
# F(2n) = F(n)[2F(n+1) − F(n)]
# F(2n+1) = F(n+1)^2+F(n)^2
a, b = _fib(n // 2)
c = a * (b * 2 - a)
d = a * a + b * b
return (d, c + d) if n % 2 else (c, d)
if __name__ == "__main__":
n = int(sys.argv[1])
print(f"fibonacci({n}) is {fibonacci(n)}")