Fibonacci Numbers¶
The Fibonacci sequence is defined as follows:
The first elements of the sequence (OEIS A000045) are:
Properties¶
Fibonacci numbers possess a lot of interesting properties. Here are a few of them:
- Cassini's identity:
This can be proved by induction. A one-line proof by Knuth comes from taking the determinant of the 2x2 matrix form below.
- The "addition" rule:
- Applying the previous identity to the case
-
From this we can prove by induction that for any positive integer
-
The inverse is also true: if
-
GCD identity:
- Fibonacci numbers are the worst possible inputs for Euclidean algorithm (see Lame's theorem in Euclidean algorithm)
Fibonacci Coding¶
We can use the sequence to encode positive integers into binary code words. According to Zeckendorf's theorem, any natural number
such that
It follows that any number can be uniquely encoded in the Fibonacci coding.
And we can describe this representation with binary codes
The encoding of an integer
-
Iterate through the Fibonacci numbers from the largest to the smallest until you find one less than or equal to
-
Suppose this number was
-
Repeat until there is no remainder.
-
Add a final
To decode a code word, first remove the final
Formulas for the Fibonacci number¶
Closed-form expression¶
There is a formula known as "Binet's formula", even though it was already known by Moivre:
This formula is easy to prove by induction, but it can be deduced with the help of the concept of generating functions or by solving a functional equation.
You can immediately notice that the second term's absolute value is always less than
where the square brackets denote rounding to the nearest integer.
As these two formulas would require very high accuracy when working with fractional numbers, they are of little use in practical calculations.
Fibonacci in linear time¶
The
We can start from an iterative approach, to take advantage of the use of the formula
int fib(int n) {
int a = 0;
int b = 1;
for (int i = 0; i < n; i++) {
int tmp = a + b;
a = b;
b = tmp;
}
return a;
}
In this way, we obtain a linear solution,
Matrix form¶
To go from
This lets us treat iterating the recurrence as repeated matrix multiplication, which has nice properties. In particular,
where
we can use the matrix directly:
Thus, in order to find
struct matrix {
long long mat[2][2];
matrix friend operator *(const matrix &a, const matrix &b){
matrix c;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c.mat[i][j] = 0;
for (int k = 0; k < 2; k++) {
c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
}
}
}
return c;
}
};
matrix matpow(matrix base, long long n) {
matrix ans{ {
{1, 0},
{0, 1}
} };
while (n) {
if(n&1)
ans = ans*base;
base = base*base;
n >>= 1;
}
return ans;
}
long long fib(int n) {
matrix base{ {
{1, 1},
{1, 0}
} };
return matpow(base, n).mat[0][1];
}
Fast Doubling Method¶
By expanding the above matrix expression for
we can find these simpler equations:
Thus using above two equations Fibonacci numbers can be calculated easily by the following code:
pair<int, int> fib (int n) {
if (n == 0)
return {0, 1};
auto p = fib(n >> 1);
int c = p.first * (2 * p.second - p.first);
int d = p.first * p.first + p.second * p.second;
if (n & 1)
return {d, c + d};
else
return {c, d};
}
Periodicity modulo p¶
Consider the Fibonacci sequence modulo
Let us prove this by contradiction. Consider the first
There can only be
We now choose two pairs of identical remainders with the smallest indices in the sequence. Let the pairs be
Practice Problems¶
- SPOJ - Euclid Algorithm Revisited
- SPOJ - Fibonacci Sum
- HackerRank - Is Fibo
- Project Euler - Even Fibonacci numbers
- DMOJ - Fibonacci Sequence
- DMOJ - Fibonacci Sequence (Harder)
- DMOJ UCLV - Numbered sequence of pencils
- DMOJ UCLV - Fibonacci 2D
- DMOJ UCLV - fibonacci calculation
- LightOJ - Number Sequence
- Codeforces - C. Fibonacci
- Codeforces - A. Hexadecimal's theorem
- Codeforces - B. Blackboard Fibonacci
- Codeforces - E. Fibonacci Number