Is there any algorithm to compute the nth fibonacci number in sub linear time?
Wikipedia has a closed form solution http://en.wikipedia.org/wiki/Fibonacci_number
Or in c#:
public static int Fibonacci(int N)
{
double sqrt5 = Math.Sqrt(5);
double phi = (1 + sqrt5) / 2.0;
double fn = (Math.Pow(phi, N) - Math.Pow(1 - phi, N)) / sqrt5;
return (int)fn;
}
The n
th Fibonacci number is given by
f(n) = Floor(phi^n / sqrt(5) + 1/2)
where
phi = (1 + sqrt(5)) / 2
Assuming that the primitive mathematical operations (+
, -
, *
and /
) are O(1)
you can use this result to compute the n
th Fibonacci number in O(log n)
time (O(log n)
because of the exponentiation in the formula).
In C#:
static double inverseSqrt5 = 1 / Math.Sqrt(5);
static double phi = (1 + Math.Sqrt(5)) / 2;
/* should use
const double inverseSqrt5 = 0.44721359549995793928183473374626
const double phi = 1.6180339887498948482045868343656
*/
static int Fibonacci(int n) {
return (int)Math.Floor(Math.Pow(phi, n) * inverseSqrt5 + 0.5);
}
You can do it by exponentiating a matrix of integers as well. If you have the matrix
/ 1 1 \
M = | |
\ 1 0 /
then (M^n)[1, 2]
is going to be equal to the n
th Fibonacci number, if []
is a matrix subscript and ^
is matrix exponentiation. For a fixed-size matrix, exponentiation to an positive integral power can be done in O(log n) time in the same way as with real numbers.
EDIT: Of course, depending on the type of answer you want, you may be able to get away with a constant-time algorithm. Like the other formulas show, the n
th Fibonacci number grows exponentially with n
. Even with 64-bit unsigned integers, you'll only need a 94-entry lookup table in order to cover the entire range.
SECOND EDIT: Doing the matrix exponential with an eigendecomposition first is exactly equivalent to JDunkerly's solution below. The eigenvalues of this matrix are the (1 + sqrt(5))/2
and (1 - sqrt(5))/2
.
One of the exercises in SICP is about this, which has the answer described here.
In the imperative style, the program would look something like
Function Fib(count) a ← 1 b ← 0 p ← 0 q ← 1 While count > 0 Do If Even(count) Then p ← p² + q² q ← 2pq + q² count ← count ÷ 2 Else a ← bq + aq + ap b ← bp + aq count ← count - 1 End If End While Return b End Function
Just giving a pointer to a reddit discussion about the topic. It has some nice comments.
It's impossible!
As stated above, the formula for fibonacci numbers is:
fib n = floor (phin/√5 + 1/2)
fib n ~= phin/√5
How many digits is fib n
?
numDigits (fib n) = log (fib n) = log (phin/√5) = log phin - log √5 = n * log phi - log √5
numDigits (fib n) = n * const + const
it's O(n)
Since the requested result is of O(n), it can't be calculated in less than O(n) time.
If you only want the lower digits of the answer, then it is possible to calculate in sub-linear time using the matrix exponentiation method.