Skip to content

Fibonacci Numbers

There are various problems that play with the Fibonacci numbers, so we need to look into these as well. They form a series and are defined like this:

Definition: Fibonacci Numbers

The Fibonacci numbers for them infinite natural number sequence (Fi)i which is defined as

F1:=1F2:=1,Fn:=Fn2+Fn1.

Efficient computation

Although the definition is recursive, one shouldn't compute them in a recursive way. Otherwise one will have to recompute terms that one had computed before and end up with an O(2n) complexity to compute the Fn.

Example: Let's compute F4. Then we have the following recursive expansion:

  • F4
  • F2+F3
  • (F0+F1)+(F1+F2)
  • (F0+F1)+(F1+(F0+F1))

You can see that we need to compute F2 twice and look up F0 twice, F1 three times. When we would compute F5 in this way, we would have to compute F3 and F4 again.

Iterative generation

It is much better to use an iterative algorithm:

  • Set a:=0, b:=1.
  • Iterate …
    • Yield b.
    • Set c:=a+b.
    • Set a:=b.
    • Set b:=c.

This will yield 1, 1, 2, 3, 5, … as we want.

It never recomputes any number. Therefore the complexity here is O(n) for a specific Fn, and O(1) per number in the sequence. If one needs to iterate through the Fibonacci numbers, this is the algorithm of choice.

Computation in O(log n)

If we want to compute Fn in isolation, we would have to iterate up to the desired n. Computing a specific Fn can be made more efficient:

Theorem: n-th Fibonacci Number by Exponentiation

Fn and Fn+1 can be computed in O(logn) by using

(FnFn+1)=(0111)n(01)

together with exponentiation by squaring.

Proof

The above iterative algorithm can also be expressed in matrix form:

(ab):=(0111)(ab)

We can apply this matrix over and over in order to advance in the algorithm. Hence we can write a closed-form expression:

(FnFn+1)=(0111)n(01)

The exponentiation of the matrix would be O(n) naively, but with exponentiation by squaring, one can do this in O(logn) steps.

Eigenvalue trick for O(1)

There is an eigenvalue trick that one can use to directly compute any Fibonacci number in closed form:

Theorem: n-th Fibonacci Number via Eigenvalues

The n-th Fibonacci number is

Fn=β5(αn+1+βn+1),whereα:=1+52,β:=152.

Proof

We start with the closed-form expression from the other theorem:

(FnFn+1)=(0111)n(01)

We will do an eigensystem decomposition of the matrix in order efficiently compute its exponentiation. Let's call the matrix in the middle M. We can find its eigenvalues

λ1=1+52,λ2=152.

The associated eigenvectors are

v1=(5121),v2=(5+121).

We collect these into an eigenvalue matrix Λ and an eigenvector matrix V:

Λ=(1+5200152),V=(5125+1211).

Hence we can write the matrix M using the eigensystem as

M=VΛV1.

The inverse of V is

V1=15(15+121512).

Putting all of that together gives us

(FnFn+1)=(VΛV1)n(01).

The real simplification comes from writing out (VΛV1)n and realizing that V1V=1. Then we can simplify

(VΛV1)n=VΛnV1.

Because Λ is a diagonal matrix, applying the power to the matrix is the same as applying the power to the elements on the diagonal.

We can then plug in all the expressions and we arrive at

(FnFn+1)=15(5125+1211)((1+52)n00(152)n)(15+121512)(01).

As we're only interested in Fn and not Fn+1, it is sufficient to use the first row of V. Then we can introduce the shorthands α and β. After executing the matrix multiplications, we arrive at the claimed formula.

This expression doesn't work well numerically as one has to project high powers of an irrational number (the 5) back onto an integer. Eventually, even 64-bit floating point will be insufficient as they lack both the precision to faithfully represent the whole number. They will return inf results.

Numerical approximation

We can work with the logarithm to make it more tractable.

Theorem

The n-th Fibonacci number approximately is

log(Fn)log(β5)+(n+1)log(α).,whereα:=1+52,β:=152.

Proof

We have |α|>1 and |β|<1. For large n, βn+10 and we can neglect this. Then we apply the logarithm to both sides and get the desired result.