I want to calculate the Fibonacci of very large value of N ie. 10^6 with a complexity of O(logN). Here is my code but it gives the result for 10^6 in 30 seconds which is ver
I get a more reasonable - although still very slow - time of real 0m2.335s
using your code.
The algorithm to compute the Fibonacci numbers is okay (there are some tweaks that could speed it up somewhat, but nothing very dramatic), so the problem is that operations on large BigInteger
s are slow, and F(10^6)
has nearly 700,000 bits.
Since you want to compute the remainder modulo mod = 10^9 + 7
, and (mod-1)^2
fits in a long
, you can get a much faster implementation using long
s instead of BigInteger
s, computing the remainder in each step. The direct transcription
public class FiboL {
static final long mod = 1000000007L;
static long fibo(long n){
long F[][] = {{1,1},{1,0}};
if(n == 0)
return 0;
power(F, n-1);
return F[0][0]; //.mod(mod);
}
static void power(long F[][], long n){
if( n == 0 || n == 1)
return;
long M[][] = {{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if( n%2 != 0 )
multiply(F, M);
}
static void multiply(long F[][], long M[][]){
long x = (F[0][0] * M[0][0]) % mod + (F[0][1] * M[1][0]) % mod;
long y = (F[0][0] * M[0][1]) % mod + (F[0][1] * M[1][1]) % mod;
long z = (F[1][0] * M[0][0]) % mod + (F[1][1] * M[1][0]) % mod;
long w = (F[1][0] * M[0][1]) % mod + (F[1][1] * M[1][1]) % mod;
F[0][0] = x % mod;
F[0][1] = y % mod;
F[1][0] = z % mod;
F[1][1] = w % mod;
}
public static void main(String[] args) {
System.out.println(fibo(1000000));
}
}
runs in real 0m0.083s
.