Given an integer N, the task is to find the N-th Fibonacci numbers.
Examples:
Input: N = 3
Output: 2
Explanation:
F(1) = 1, F(2) = 1
F(3) = F(1) + F(2) = 2
Input: N = 6
Output: 8
Approach:
-
The Matrix Exponentiation Method is already discussed before. The Doubling Method can be seen as an improvement to the matrix exponentiation method to find the N-th Fibonacci number although it doesn’t use matrix multiplication itself.
-
The Fibonacci recursive sequence is given by
F(n+1) = F(n) + F(n-1)
-
The Matrix Exponentiation method uses the following formula
-
The method involves costly matrix multiplication and moreover Fn is redundantly computed twice.
On the other hand, Fast Doubling Method is based on two basic formulas:
F(2n) = F(n)[2F(n+1) – F(n)]
F(2n + 1) = F(n)2+F(n+1)2
-
Here is a short explanation of the above results:
Start with:
F(n+1) = F(n) + F(n-1) &
F(n) = F(n)
It can be rewritten in the matrix form as:
For doubling, we just plug in “2n” into the formula:
Substituting F(n-1) = F(n+1)- F(n) and after simplification we get,
Below is the implementation of the above approach:
// C++ program to find the Nth Fibonacci // number using Fast Doubling Method #include <bits/stdc++.h> using namespace std;
int a, b, c, d;
#define MOD 1000000007 // Function calculate the N-th fibonacci // number using fast doubling method void FastDoubling( int n, int res[])
{ // Base Condition
if (n == 0) {
res[0] = 0;
res[1] = 1;
return ;
}
FastDoubling((n / 2), res);
// Here a = F(n)
a = res[0];
// Here b = F(n+1)
b = res[1];
c = 2 * b - a;
if (c < 0)
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0) {
res[0] = c;
res[1] = d;
}
else {
res[0] = d;
res[1] = c + d;
}
} // Driver code int main()
{ int N = 6;
int res[2] = { 0 };
FastDoubling(N, res);
cout << res[0] << "\n" ;
return 0;
} |
// Java program to find the Nth Fibonacci // number using Fast Doubling Method class GFG{
// Function calculate the N-th fibonacci // number using fast doubling method static void FastDoubling( int n, int []res)
{ int a, b, c, d;
int MOD = 1000000007 ;
// Base Condition
if (n == 0 )
{
res[ 0 ] = 0 ;
res[ 1 ] = 1 ;
return ;
}
FastDoubling((n / 2 ), res);
// Here a = F(n)
a = res[ 0 ];
// Here b = F(n+1)
b = res[ 1 ];
c = 2 * b - a;
if (c < 0 )
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0 )
{
res[ 0 ] = c;
res[ 1 ] = d;
}
else
{
res[ 0 ] = d;
res[ 1 ] = c + d;
}
} // Driver code public static void main(String []args)
{ int N = 6 ;
int res[] = new int [ 2 ];
FastDoubling(N, res);
System.out.print(res[ 0 ]);
} } // This code is contributed by rock_cool |
# Python3 program to find the Nth Fibonacci # number using Fast Doubling Method MOD = 1000000007
# Function calculate the N-th fibonacci # number using fast doubling method def FastDoubling(n, res):
# Base Condition
if (n = = 0 ):
res[ 0 ] = 0
res[ 1 ] = 1
return
FastDoubling((n / / 2 ), res)
# Here a = F(n)
a = res[ 0 ]
# Here b = F(n+1)
b = res[ 1 ]
c = 2 * b - a
if (c < 0 ):
c + = MOD
# As F(2n) = F(n)[2F(n+1) – F(n)]
# Here c = F(2n)
c = (a * c) % MOD
# As F(2n + 1) = F(n)^2 + F(n+1)^2
# Here d = F(2n + 1)
d = (a * a + b * b) % MOD
# Check if N is odd
# or even
if (n % 2 = = 0 ):
res[ 0 ] = c
res[ 1 ] = d
else :
res[ 0 ] = d
res[ 1 ] = c + d
# Driver code N = 6
res = [ 0 ] * 2
FastDoubling(N, res) print (res[ 0 ])
# This code is contributed by divyamohan123 |
// C# program to find the Nth Fibonacci // number using Fast Doubling Method using System;
class GFG{
// Function calculate the N-th fibonacci // number using fast doubling method static void FastDoubling( int n, int []res)
{ int a, b, c, d;
int MOD = 1000000007;
// Base Condition
if (n == 0)
{
res[0] = 0;
res[1] = 1;
return ;
}
FastDoubling((n / 2), res);
// Here a = F(n)
a = res[0];
// Here b = F(n+1)
b = res[1];
c = 2 * b - a;
if (c < 0)
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0)
{
res[0] = c;
res[1] = d;
}
else
{
res[0] = d;
res[1] = c + d;
}
} // Driver code public static void Main()
{ int N = 6;
int []res = new int [2];
FastDoubling(N, res);
Console.Write(res[0]);
} } // This code is contributed by Code_Mech |
<script> // Javascript program to find the Nth Fibonacci
// number using Fast Doubling Method
let a, b, c, d;
let MOD = 1000000007;
// Function calculate the N-th fibonacci
// number using fast doubling method
function FastDoubling(n, res)
{
// Base Condition
if (n == 0) {
res[0] = 0;
res[1] = 1;
return ;
}
FastDoubling(parseInt(n / 2, 10), res);
// Here a = F(n)
a = res[0];
// Here b = F(n+1)
b = res[1];
c = 2 * b - a;
if (c < 0)
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0) {
res[0] = c;
res[1] = d;
}
else {
res[0] = d;
res[1] = c + d;
}
}
let N = 6;
let res = new Array(2);
res.fill(0);
FastDoubling(N, res);
document.write(res[0]);
</script> |
Output
8
Time Complexity: Repeated squaring reduces time from linear to logarithmic . Hence, with constant time arithmetic, the time complexity is O(log n).
Auxiliary Space: O(n).
Iterative Version
We can implement iterative version of above method, by initializing array with two elements f = [F(0), F(1)] = [0, 1] and iteratively constructing F(n), on every step we will transform f into [F(2i), F(2i+1)] or [F(2i+1), F(2i+2)] , where i corresponds to the current value of i stored in f = [F(i), F(i+1)].
Approach:
- Create array with two elements f = [0, 1] , which represents [F(0), F(1)] .
- For finding F(n), iterate over binary representation of n from left to right, let kth bit from left be bk .
- Iteratively apply the below steps for all bits in n .
- Using bk we will decide whether to transform f = [F(i), F(i+1)] into [F(2i), F(2i+1)] or [F(2i+1), F(2i+2)] .
if bk == 0:
f = [F(2i), F(2i+1)] = [F(i){2F(i+1)-F(i)}, F(i+1)2+F(i)2]
if bk == 1:
f = [F(2i+1), F(2i+2)] = [F(i+1)2+F(i)2, F(i+1){2F(i)+F(i+1)}]
where,
F(i) and F(i+1) are current values stored in f.
- return f[0] .
Example:
for n = 13 = (1101)2
b = 1 1 0 1
[F(0), F(1)] -> [F(1), F(2)] -> [F(3), F(4)] -> [F(6), F(7)] -> [F(13), F(14)]
[0, 1] -> [1, 1] -> [2, 3] -> [8, 13] -> [233, 377]
Below is the implementation of the above approach:
// C++ program to find the Nth Fibonacci // number using Fast Doubling Method iteratively #include <bitset> #include <iostream> #include <string> using namespace std;
// helper function to get binary string string decimal_to_bin( int n)
{ // use bitset to get binary string
string bin = bitset< sizeof ( int ) * 8>(n).to_string();
auto loc = bin.find( '1' );
// remove leading zeros
if (loc != string::npos)
return bin.substr(loc);
return "0" ;
} // computes fib(n) iteratively using fast doubling method long long fastfib( int n)
{ string bin_of_n
= decimal_to_bin(n); // binary string of n
long long f[] = { 0, 1 }; // [F(i), F(i+1)] => i=0
for ( auto b : bin_of_n) {
long long f2i1
= f[1] * f[1] + f[0] * f[0]; // F(2i+1)
long long f2i = f[0] * (2 * f[1] - f[0]); // F(2i)
if (b == '0' ) {
f[0] = f2i; // F(2i)
f[1] = f2i1; // F(2i+1)
}
else {
f[0] = f2i1; // F(2i+1)
f[1] = f2i1 + f2i; // F(2i+2)
}
}
return f[0];
} int main()
{ int n = 13;
long long fib = fastfib(n);
cout << "F(" << n << ") = " << fib << "\n" ;
} |
// Java program to find the Nth Fibonacci // number using Fast Doubling Method iteratively import java.io.*;
class GFG {
// Helper function to convert decimal to binary.
static String convertToBinary( int x)
{
int bin = 0 ;
int rem, i = 1 , step = 1 ;
while (x != 0 ) {
rem = x % 2 ;
x = x / 2 ;
bin = bin + rem * i;
i = i * 10 ;
}
return Integer.toString(bin);
}
// helper function to get binary string
static String decimal_to_bin( int n)
{
// use bitset to get binary string
String bin = convertToBinary(n);
int loc = bin.indexOf( "1" );
// remove leading zeros
if (loc != - 1 ) {
return bin.substring(loc);
}
return "0" ;
}
// computes fib(n) iteratively using fast doubling
// method
static int fastfib( int n)
{
String bin_of_n
= decimal_to_bin(n); // binary string of n
int [] f = { 0 , 1 }; // [F(i), F(i+1)] => i=0
for ( int i = 0 ; i < bin_of_n.length(); i++) {
int b = bin_of_n.charAt(i);
int f2i1 = f[ 1 ] * f[ 1 ] + f[ 0 ] * f[ 0 ]; // F(2i+1)
int f2i = f[ 0 ] * ( 2 * f[ 1 ] - f[ 0 ]); // F(2i)
if (b == '0' ) {
f[ 0 ] = f2i; // F(2i)
f[ 1 ] = f2i1; // F(2i+1)
}
else {
f[ 0 ] = f2i1; // F(2i+1)
f[ 1 ] = f2i1 + f2i; // F(2i+2)
}
}
return f[ 0 ];
}
public static void main(String[] args)
{
int n = 13 ;
int fib = fastfib(n);
System.out.print( "F(" + n + ") = " + fib);
}
} // This code is contributed by lokeshmvs21. |
# Python3 program to find the Nth Fibonacci # number using Fast Doubling Method iteratively def fastfib(n):
"""computes fib(n) iteratively using fast doubling method"""
bin_of_n = bin (n)[ 2 :] # binary string of n
f = [ 0 , 1 ] # [F(i), F(i+1)] => i=0
for b in bin_of_n:
f2i1 = f[ 1 ] * * 2 + f[ 0 ] * * 2 # F(2i+1)
f2i = f[ 0 ] * ( 2 * f[ 1 ] - f[ 0 ]) # F(2i)
if b = = '0' :
f[ 0 ], f[ 1 ] = f2i, f2i1 # [F(2i), F(2i+1)]
else :
f[ 0 ], f[ 1 ] = f2i1, f2i1 + f2i # [F(2i+1), F(2i+2)]
return f[ 0 ]
n = 13
fib = fastfib(n)
print (f 'F({n}) =' , fib)
|
using System;
using System.Collections.Generic;
// C# program to find the Nth Fibonacci // number using Fast Doubling Method iteratively public class GFG {
// Helper function to convert decimal to binary.
public static string convertToBinary( int x)
{
int bin = 0;
int rem, i = 1, step = 1;
while (x != 0) {
rem = x % 2;
x = x / 2;
bin = bin + rem * i;
i = i * 10;
}
return bin.ToString();
}
// helper function to get binary string
public static string decimal_to_bin( int n)
{
// use bitset to get binary string
string bin = convertToBinary(n);
int loc = bin.IndexOf( '1' );
// remove leading zeros
if (loc != -1) {
return bin.Substring(loc);
}
return "0" ;
}
// computes fib(n) iteratively using fast doubling
// method
public static int fastfib( int n)
{
string bin_of_n
= decimal_to_bin(n); // binary string of n
int [] f = { 0, 1 }; // [F(i), F(i+1)] => i=0
for ( int i = 0; i < bin_of_n.Length; i++) {
int b = bin_of_n[i];
int f2i1 = f[1] * f[1] + f[0] * f[0]; // F(2i+1)
int f2i = f[0] * (2 * f[1] - f[0]); // F(2i)
if (b == '0' ) {
f[0] = f2i; // F(2i)
f[1] = f2i1; // F(2i+1)
}
else {
f[0] = f2i1; // F(2i+1)
f[1] = f2i1 + f2i; // F(2i+2)
}
}
return f[0];
}
static public void Main()
{
int n = 13;
int fib = fastfib(n);
Console.WriteLine( "F(" + n + ") = " + fib);
}
} // This code is contributed by akashish__ |
// JavaScript program to find the Nth Fibonacci // number using Fast Doubling Method iteratively // Helper function to convert decimal to binary. function convertToBinary(x) {
let bin = 0;
let rem, i = 1, step = 1;
while (x != 0) {
rem = x % 2;
x = parseInt(x / 2);
bin = bin + rem * i;
i = i * 10;
}
// let myArr = Array.from(String(bin).split(""));
return bin.toString();
} // helper function to get binary string function decimal_to_bin(n)
{ // use bitset to get binary string
let bin = convertToBinary(n);
let loc = bin.indexOf( '1' );
// remove leading zeros
if (loc != -1)
return bin.substring(loc);
return "0" ;
} // computes fib(n) iteratively using fast doubling method function fastfib(n)
{ let bin_of_n = decimal_to_bin(n); // binary string of n
let f = [0, 1]; // [F(i), F(i+1)] => i=0
for (let i = 0; i < bin_of_n.length; i++){
let b = bin_of_n[i];
let f2i1 = f[1] * f[1] + f[0] * f[0]; // F(2i+1)
let f2i = f[0] * (2 * f[1] - f[0]); // F(2i)
if (b == '0' ) {
f[0] = f2i; // F(2i)
f[1] = f2i1; // F(2i+1)
}
else {
f[0] = f2i1; // F(2i+1)
f[1] = f2i1 + f2i; // F(2i+2)
}
}
return f[0];
} let n = 13; let fib = fastfib(n); console.log( "F(" ,n, ") =" , fib);
// The code is contributed by Gautam goel (gautamgoel962) |
Output
F(13) = 233
Time Complexity: We are iterating over a binary string of length n and doing constant time arithmetic operations for each digit, so the time complexity is O(n).
Auxiliary Space: We are storing two elements in f (which is a constant cost), and the binary representation of the number (which has a cost of O(n)) so space complexity is O(n). We could reduce this down to O(1) if we didn’t convert the number to a string, but instead used the bits of the number to iterate through .