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:  

F(n+1) = F(n) + F(n-1)
F(2n) = F(n)[2F(n+1) – F(n)]
F(2n + 1) = F(n)2+F(n+1)2

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:

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


Article Tags :