Fast Doubling method to find the Nth Fibonacci number

23 Jun, 2022
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++
Java
Python3
C#
Javascript
// 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 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 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 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# 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
<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>
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++
Python3
Javascript
// 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 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";}
# 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)
// 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)
F(13) = 233
Time Complexity: We are iterating over the binary string of number n which has length of log(n) and doing constant time arithmetic operations, so the time complexity is O(log n).
Auxiliary Space: We are storing two elements in f and binary string of n has length log(n), so space complexity is O(log n).
divyamohan123
rock_cool
Code_Mech
divyeshrabadiya07
pankajsharmagfg
2019029
anikakapoor
simmytarika5
gautamgoel962
Fibonacci
matrix-exponentiation
Algorithms
Articles
Competitive Programming
Divide and Conquer
Matrix
Divide and Conquer
Matrix
Fibonacci
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.