Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Fast Doubling method to find the Nth Fibonacci number

  • Difficulty Level : Expert
  • Last Updated : 25 Nov, 2021

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

        \[ \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^n = \begin{bmatrix} F_{n+1} & F_n \\ F_n & F_{n-1} \end{bmatrix} \]

     

  • 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: 

    \[ \begin{bmatrix} F(n+1) \\ F(n) \end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} \begin{bmatrix} F(n) \\ F(n-1) \end{bmatrix} \] \[\quad\enspace= \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^2 \begin{bmatrix} F(n-1) \\ F(n-2) \end{bmatrix} \] \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\enspace\enspace\thinspace......\\ \[= \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^n \begin{bmatrix} F(1) \\ F(0) \end{bmatrix} \]

For doubling, we just plug in “2n” into the formula:

    \[ \begin{bmatrix} F(2n+1) \\ F(2n) \end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{2n} \begin{bmatrix} F(1) \\ F(0) \end{bmatrix} \] \[\quad\enspace= \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^n \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^n \begin{bmatrix} F(1) \\ F(0) \end{bmatrix} \] \[\quad\enspace= \begin{bmatrix} F(n+1) & F(n) \\ F(n) & F(n-1) \end{bmatrix} \begin{bmatrix} F(n+1) & F(n) \\ F(n) & F(n-1) \end{bmatrix} \begin{bmatrix} F(1) \\ F(0) \end{bmatrix} \] \[\quad\enspace= \begin{bmatrix} F(n+1)^2 + F(n)^2 \\ F(n)F(n+1) + F(n)F(n-1) \end{bmatrix} \]

Substituting F(n-1) = F(n+1)- F(n) and after simplification we get, 

    \[ \begin{bmatrix} F(2n+1) \\ F(2n) \end{bmatrix} = \begin{bmatrix} F(n+1)^2 + F(n)^2 \\ 2F(n+1)F(n) - F(n)^2 \end{bmatrix} \]

 



Below is the implementation of the above approach:
 

C++




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




<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 fibanacci
    // 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 wether 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 <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";
}

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)
Output
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).




My Personal Notes arrow_drop_up
Recommended Articles
Page :