Open in App
Not now

# Fast Doubling method to find the Nth Fibonacci number

• Difficulty Level : Hard
• Last Updated : 14 Feb, 2023

Given an integer N, the task is to find the N-th Fibonacci numbers.
Examples:

Input: N = 3
Output:
Explanation:
F(1) = 1, F(2) = 1
F(3) = F(1) + F(2) = 2
Input: N = 6
Output:

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:

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++

 // C++ program to find the Nth Fibonacci // number using Fast Doubling Method #include  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

 // 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

 # 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#

 // 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

## Javascript

 

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++

 // C++ program to find the Nth Fibonacci // number using Fast Doubling Method iteratively   #include  #include  #include    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

 // 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

 # 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)

## C#

 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

 // 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 .

My Personal Notes arrow_drop_up
Related Articles