Open In App

# Fast Doubling method to find the Nth Fibonacci number

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 methodvoid 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 codeint 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 Methodclass GFG{ // Function calculate the N-th fibonacci// number using fast doubling methodstatic 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 codepublic 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 MethodMOD = 1000000007 # Function calculate the N-th fibonacci# number using fast doubling methoddef 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 codeN = 6res = [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 Methodusing System;class GFG{ // Function calculate the N-th fibonacci// number using fast doubling methodstatic 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 codepublic 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 stringstring 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 methodlong 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 iterativelyimport 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 = 13fib = 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 iterativelypublic 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 stringfunction 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 methodfunction 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 .