The Fibonacci sequence is described by the recurrence relation
with initial conditions
This sequence can be motivated by the following scenario:
A newly born breeding pair of rabbits are put in a field; each breeding pair mates at the age of one month, and at the end of their second month they always produce another pair of rabbits; and rabbits never die, but continue breeding forever.
Close-Form Solution
Main: Binet’s Formula
The close form solution of the Fibonacci numbers is given by the Binet’s Formula:
where
Info
Since
, Fibonacci numbers converges to for large and the ratio of consecutive Fibonacci numbers converges to the golden ratio .
In Programming
Recursive Approach
A recursive implementation of the Fibonacci numbers directly translates from the recurrence relation is highly inefficient.
def fib(n):
if n < 2:
return n
else:
return fib(n - 1) + fib(n - 2)
While this approach is highly ineffective (exponential time), it is still often used as a benchmark for programming languages performing computationally intensive tasks or as a demonstration of parallel algorithms.
Iterative Approach
While we can make the above implementation more efficient with memoization, a iterative approach also exists:
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a+b
return a
Exponentiating By Squaring
By recognizing the above computation as a linear transformation, we can rewrite it to a matrix multiplication:
As matrix multiplication is associative, we can use the exponentiating by squaring method to get the result in
def matrix_mult(A, B):
return [
[A[0][0] * B[0][0] + A[0][1] * B[1][0],
A[0][0] * B[0][1] + A[0][1] * B[1][1]],
[A[1][0] * B[0][0] + A[1][1] * B[1][0],
A[1][0] * B[0][1] + A[1][1] * B[1][1]]]
def matrix_pow(A, n):
result = [[1, 0], [0, 1]]
while n > 0:
if n % 2 == 1:
result = matrix_mult(result, A)
A = matrix_mult(A, A)
n //= 2
return result
def fib(n):
A = [[1, 1], [1, 0]]
result = matrix_pow(A, n)
return result[1][0]
See power of monoid for a generic solution using monoid.
Binet’s Formula
We can also use the Binet’s Formula to calculate the Fibonacci sequence. Do note that this method subjects to the floating-point precision limits.
def fib(n):
phi = (1 + sqrt(5)) / 2
psi = (1 - sqrt(5)) / 2
return round((phi**n - psi**n) / sqrt(5))