Open In App

Find Nth term (A matrix exponentiation example)

Improve
Improve
Like Article
Like
Save
Share
Report

We are given a recursive function that describes Nth terms in the form of other terms. In this article, we have taken specific examples. 
T_{n} = 2*T_{n-1}+3*T{n-2} \\ Given, T_0=1 T_1=1

Now you are given n, and you have to find out nth term using the above formula.

Examples: 

Input : n = 2
Output : 5

Input : n = 3
Output :13 

Prerequisite : 

Basic Approach: This problem can be solved by simply just iterating over the n terms. Every time you find a term, using this term find the next one, and so on. But the time complexity of this problem is of order O(n).

Optimized Approach:
All such problems where a term is a function of other terms in a linear fashion. Then these can be solved using the Matrix (Please refer: Matrix Exponentiation ). First, we make a transformation matrix and then just use matrix exponentiation to find the Nth term. 

Step by Step method includes: 

  • Step 1. Determine k the number of terms on which T(i) depends. 
    For our example, T(i) depends on two terms. So, k = 2
  • Step 2. Determine initial values 
    As in this article T0=1, T1=1 are given.
  • Step 3. Determine TM, the transformation matrix. 
    This is the most important step in solving recurrence relations. In this step, we have to make the matrix of dimension k*k. 
    Such that 
    T(i)=TM*(initial value vector)

Here initial value vector is the vector that contains an initial value. We name this vector as initial
$ So, Initial Vector=\left[ \begin{array}{c} T_1 & T_0\\ \end{array} \right] $ Now find Transformation matrix. $TM=\left[ \begin{array}{cc} 2 & 3\\ 1 & 0 \\ \end{array} \right]$ Now, First row of T2 give us 2nd term. $T_2=\left[ \begin{array}{cc} 2 & 3\\ 1 & 0 \\ \end{array} \right]*\left[ \begin{array}{c} T_1 & T_0\\ \end{array} \right]$ So, general term will be, First row of Tn. $T_n=\left[ \begin{array}{cc} 2 & 3\\ 1 & 0 \\ \end{array} \right]^{n-1}*\left[ \begin{array}{c} T_1 & T_0\\ \end{array} \right]$ So, finally we have Tn=$TM^{n-1}*Intial Vector$ And this power of matrix can be calculated using matrix exponenciation in O(logn).

Below is the program to implement the above approach. 

C++

// CPP program to find n-th term of a recursive
// function using matrix exponentiation.
#include <bits/stdc++.h>
using namespace std;
#define MOD 1000000009
 
#define ll long long int
 
ll power(ll n)
{
    if (n <= 1)
        return 1;
 
    // This power function returns first row of
    // {Transformation Matrix}^n-1*Initial Vector
    n--;
 
    // This is an identity matrix.
    ll res[2][2] = { 1, 0, 0, 1 };
 
    // this is Transformation matrix.
    ll tMat[2][2] = { 2, 3, 1, 0 };
 
    // Matrix exponentiation to calculate power of {tMat}^n-1
    // store res in "res" matrix.
    while (n) {
 
        if (n & 1) {
            ll tmp[2][2];
            tmp[0][0] = (res[0][0] * tMat[0][0] + res[0][1] * tMat[1][0]) % MOD;
            tmp[0][1] = (res[0][0] * tMat[0][1] + res[0][1] * tMat[1][1]) % MOD;
            tmp[1][0] = (res[1][0] * tMat[0][0] + res[1][1] * tMat[1][0]) % MOD;
            tmp[1][1] = (res[1][0] * tMat[0][1] + res[1][1] * tMat[1][1]) % MOD;
            res[0][0] = tmp[0][0];
            res[0][1] = tmp[0][1];
            res[1][0] = tmp[1][0];
            res[1][1] = tmp[1][1];
        }
        n = n / 2;
        ll tmp[2][2];
        tmp[0][0] = (tMat[0][0] * tMat[0][0] + tMat[0][1] * tMat[1][0]) % MOD;
        tmp[0][1] = (tMat[0][0] * tMat[0][1] + tMat[0][1] * tMat[1][1]) % MOD;
        tmp[1][0] = (tMat[1][0] * tMat[0][0] + tMat[1][1] * tMat[1][0]) % MOD;
        tmp[1][1] = (tMat[1][0] * tMat[0][1] + tMat[1][1] * tMat[1][1]) % MOD;
        tMat[0][0] = tmp[0][0];
        tMat[0][1] = tmp[0][1];
        tMat[1][0] = tmp[1][0];
        tMat[1][1] = tmp[1][1];
    }
 
    // res store {Transformation matrix}^n-1
    // hence will be first row of res*Initial Vector.
    return (res[0][0] * 1 + res[0][1] * 1) % MOD;
}
 
// Driver code
int main()
{
    ll n = 3;
    cout << power(n);
    return 0;
}

                    

Java

// Java program to find n-th term of a recursive
// function using matrix exponentiation.
class GfG {
 
    static int MAX = 100;
    static int MOD = 1000000009;
    static int power(int n)
    {
        if (n <= 1) {
            return 1;
        }
 
        // This power function returns first row of
        // {Transformation Matrix}^n-1*Initial Vector
        n--;
 
        // This is an identity matrix.
        int res[][] = { { 1, 0 }, { 0, 1 } };
 
        // this is Transformation matrix.
        int tMat[][] = { { 2, 3 }, { 1, 0 } };
 
        // Matrix exponentiation to calculate power of {tMat}^n-1
        // store res in "res" matrix.
        while (n > 0) {
 
            if (n % 2 == 1) {
                int tmp[][] = new int[2][2];
                tmp[0][0] = (res[0][0] * tMat[0][0]
                             + res[0][1] * tMat[1][0])
                            % MOD;
                tmp[0][1] = (res[0][0] * tMat[0][1]
                             + res[0][1] * tMat[1][1])
                            % MOD;
                tmp[1][0] = (res[1][0] * tMat[0][0]
                             + res[1][1] * tMat[1][0])
                            % MOD;
                tmp[1][1] = (res[1][0] * tMat[0][1]
                             + res[1][1] * tMat[1][1])
                            % MOD;
                res[0][0] = tmp[0][0];
                res[0][1] = tmp[0][1];
                res[1][0] = tmp[1][0];
                res[1][1] = tmp[1][1];
            }
 
            n = n / 2;
            int tmp[][] = new int[2][2];
            tmp[0][0] = (tMat[0][0] * tMat[0][0]
                         + tMat[0][1] * tMat[1][0])
                        % MOD;
            tmp[0][1] = (tMat[0][0] * tMat[0][1]
                         + tMat[0][1] * tMat[1][1])
                        % MOD;
            tmp[1][0] = (tMat[1][0] * tMat[0][0]
                         + tMat[1][1] * tMat[1][0])
                        % MOD;
            tmp[1][1] = (tMat[1][0] * tMat[0][1]
                         + tMat[1][1] * tMat[1][1])
                        % MOD;
            tMat[0][0] = tmp[0][0];
            tMat[0][1] = tmp[0][1];
            tMat[1][0] = tmp[1][0];
            tMat[1][1] = tmp[1][1];
        }
 
        // res store {Transformation matrix}^n-1
        // hence wiint be first row of res*Initial Vector.
        return (res[0][0] * 1 + res[0][1] * 1) % MOD;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 3;
        System.out.println(power(n));
    }
}
 
// This code contributed by Rajput-Ji

                    

Python3

# Python3 program to find n-th term of a recursive
# function using matrix exponentiation.
MOD = 1000000009;
 
def power(n):
    if (n <= 1):
        return 1;
 
    # This power function returns first row of
    # {Transformation Matrix}^n-1 * Initial Vector
    n-= 1;
 
    # This is an identity matrix.
    res = [[1, 0], [0, 1]];
 
    # this is Transformation matrix.
    tMat = [[2, 3], [1, 0]];
 
    # Matrix exponentiation to calculate
    # power of {tMat}^n-1 store res in "res" matrix.
    while (n):
        if (n & 1):
            tmp = [[0 for x in range(2)] for y in range(2)];
            tmp[0][0] = (res[0][0] * tMat[0][0] +
                        res[0][1] * tMat[1][0]) % MOD;
            tmp[0][1] = (res[0][0] * tMat[0][1] +
                        res[0][1] * tMat[1][1]) % MOD;
            tmp[1][0] = (res[1][0] * tMat[0][0] +
                        res[1][1] * tMat[1][0]) % MOD;
            tmp[1][1] = (res[1][0] * tMat[0][1] +
                        res[1][1] * tMat[1][1]) % MOD;
            res[0][0] = tmp[0][0];
            res[0][1] = tmp[0][1];
            res[1][0] = tmp[1][0];
            res[1][1] = tmp[1][1];
     
        n = n // 2;
        tmp = [[0 for x in range(2)] for y in range(2)];
        tmp[0][0] = (tMat[0][0] * tMat[0][0] +
                    tMat[0][1] * tMat[1][0]) % MOD;
        tmp[0][1] = (tMat[0][0] * tMat[0][1] +
                    tMat[0][1] * tMat[1][1]) % MOD;
        tmp[1][0] = (tMat[1][0] * tMat[0][0] +
                    tMat[1][1] * tMat[1][0]) % MOD;
        tmp[1][1] = (tMat[1][0] * tMat[0][1] +
                    tMat[1][1] * tMat[1][1]) % MOD;
        tMat[0][0] = tmp[0][0];
        tMat[0][1] = tmp[0][1];
        tMat[1][0] = tmp[1][0];
        tMat[1][1] = tmp[1][1];
 
    # res store {Transformation matrix}^n-1
    # hence will be first row of res * Initial Vector.
    return (res[0][0] * 1 + res[0][1] * 1) % MOD;
 
# Driver code
n = 3;
print(power(n));
     
# This code is contributed by mits

                    

C#

// C# program to find n-th term of a recursive
// function using matrix exponentiation.
using System;
 
class GfG {
 
    // static int MAX = 100;
    static int MOD = 1000000009;
    static int power(int n)
    {
        if (n <= 1) {
            return 1;
        }
 
        // This power function returns first row of
        // {Transformation Matrix}^n-1*Initial Vector
        n--;
 
        // This is an identity matrix.
        int[, ] res = { { 1, 0 }, { 0, 1 } };
 
        // this is Transformation matrix.
        int[, ] tMat = { { 2, 3 }, { 1, 0 } };
 
        // Matrix exponentiation to calculate power of {tMat}^n-1
        // store res in "res" matrix.
        while (n > 0) {
 
            if (n % 2 == 1) {
                int[, ] tmp = new int[2, 2];
                tmp[0, 0] = (res[0, 0] * tMat[0, 0]
                             + res[0, 1] * tMat[1, 0])
                            % MOD;
                tmp[0, 1] = (res[0, 0] * tMat[0, 1]
                             + res[0, 1] * tMat[1, 1])
                            % MOD;
                tmp[1, 0] = (res[1, 0] * tMat[0, 0]
                             + res[1, 1] * tMat[1, 0])
                            % MOD;
                tmp[1, 1] = (res[1, 0] * tMat[0, 1]
                             + res[1, 1] * tMat[1, 1])
                            % MOD;
                res[0, 0] = tmp[0, 0];
                res[0, 1] = tmp[0, 1];
                res[1, 0] = tmp[1, 0];
                res[1, 1] = tmp[1, 1];
            }
 
            n = n / 2;
            int[, ] tmp1 = new int[2, 2];
            tmp1[0, 0] = (tMat[0, 0] * tMat[0, 0]
                          + tMat[0, 1] * tMat[1, 0])
                         % MOD;
            tmp1[0, 1] = (tMat[0, 0] * tMat[0, 1]
                          + tMat[0, 1] * tMat[1, 1])
                         % MOD;
            tmp1[1, 0] = (tMat[1, 0] * tMat[0, 0]
                          + tMat[1, 1] * tMat[1, 0])
                         % MOD;
            tmp1[1, 1] = (tMat[1, 0] * tMat[0, 1]
                          + tMat[1, 1] * tMat[1, 1])
                         % MOD;
            tMat[0, 0] = tmp1[0, 0];
            tMat[0, 1] = tmp1[0, 1];
            tMat[1, 0] = tmp1[1, 0];
            tMat[1, 1] = tmp1[1, 1];
        }
 
        // res store {Transformation matrix}^n-1
        // hence wiint be first row of res*Initial Vector.
        return (res[0, 0] * 1 + res[0, 1] * 1) % MOD;
    }
 
    // Driver code
    public static void Main()
    {
        int n = 3;
        Console.WriteLine(power(n));
    }
}
 
// This code contributed by mits

                    

PHP

<?php
// PHP program to find n-th term of a recursive
// function using matrix exponentiation.
$MOD = 1000000009;
 
function power($n)
{
    global $MOD;
    if ($n <= 1)
        return 1;
 
    // This power function returns first row of
    // {Transformation Matrix}^n-1*Initial Vector
    $n--;
 
    // This is an identity matrix.
    $res = array(array(1, 0), array(0, 1));
 
    // this is Transformation matrix.
    $tMat= array(array(2, 3), array(1, 0));
 
    // Matrix exponentiation to calculate
    // power of {tMat}^n-1 store res in "res" matrix.
    while ($n)
    {
        if ($n & 1)
        {
            $tmp = array_fill(0, 2, array_fill(0, 2, 0));
            $tmp[0][0] = ($res[0][0] * $tMat[0][0] +
                          $res[0][1] * $tMat[1][0]) % $MOD;
            $tmp[0][1] = ($res[0][0] * $tMat[0][1] +
                          $res[0][1] * $tMat[1][1]) % $MOD;
            $tmp[1][0] = ($res[1][0] * $tMat[0][0] +
                          $res[1][1] * $tMat[1][0]) % $MOD;
            $tmp[1][1] = ($res[1][0] * $tMat[0][1] +
                          $res[1][1] * $tMat[1][1]) % $MOD;
            $res[0][0] = $tmp[0][0];
            $res[0][1] = $tmp[0][1];
            $res[1][0] = $tmp[1][0];
            $res[1][1] = $tmp[1][1];
        }
        $n = (int)($n / 2);
        $tmp = array_fill(0, 2, array_fill(0, 2, 0));
        $tmp[0][0] = ($tMat[0][0] * $tMat[0][0] +
                      $tMat[0][1] * $tMat[1][0]) % $MOD;
        $tmp[0][1] = ($tMat[0][0] * $tMat[0][1] +
                      $tMat[0][1] * $tMat[1][1]) % $MOD;
        $tmp[1][0] = ($tMat[1][0] * $tMat[0][0] +
                      $tMat[1][1] * $tMat[1][0]) % $MOD;
        $tmp[1][1] = ($tMat[1][0] * $tMat[0][1] +
                      $tMat[1][1] * $tMat[1][1]) % $MOD;
        $tMat[0][0] = $tmp[0][0];
        $tMat[0][1] = $tmp[0][1];
        $tMat[1][0] = $tmp[1][0];
        $tMat[1][1] = $tmp[1][1];
    }
 
    // res store {Transformation matrix}^n-1
    // hence will be first row of res*Initial Vector.
    return ($res[0][0] * 1 + $res[0][1] * 1) % $MOD;
}
 
// Driver code
$n = 3;
echo power($n);
     
// This code is contributed by mits
?>

                    

Javascript

<script>
 
// Javascript program to find n-th term of a recursive
// function using matrix exponentiation.
var MOD = 1000000009;
 
function power(n)
{
    if (n <= 1)
        return 1;
 
    // This power function returns first row of
    // {Transformation Matrix}^n-1*Initial Vector
    n--;
 
    // This is an identity matrix.
    var res = [[1, 0,], [0, 1]];
 
    // this is Transformation matrix.
    var tMat = [[2, 3],[1, 0]];
 
    // Matrix exponentiation to calculate power of {tMat}^n-1
    // store res in "res" matrix.
    while (n) {
 
        if (n & 1) {
            var tmp = Array.from(Array(2), ()=> Array(2));
            tmp[0][0] = (res[0][0] * tMat[0][0] + res[0][1] * tMat[1][0]) % MOD;
            tmp[0][1] = (res[0][0] * tMat[0][1] + res[0][1] * tMat[1][1]) % MOD;
            tmp[1][0] = (res[1][0] * tMat[0][0] + res[1][1] * tMat[1][0]) % MOD;
            tmp[1][1] = (res[1][0] * tMat[0][1] + res[1][1] * tMat[1][1]) % MOD;
            res[0][0] = tmp[0][0];
            res[0][1] = tmp[0][1];
            res[1][0] = tmp[1][0];
            res[1][1] = tmp[1][1];
        }
        n = parseInt(n / 2);
        var tmp = Array.from(Array(2), ()=> Array(2));
        tmp[0][0] = (tMat[0][0] * tMat[0][0] + tMat[0][1] * tMat[1][0]) % MOD;
        tmp[0][1] = (tMat[0][0] * tMat[0][1] + tMat[0][1] * tMat[1][1]) % MOD;
        tmp[1][0] = (tMat[1][0] * tMat[0][0] + tMat[1][1] * tMat[1][0]) % MOD;
        tmp[1][1] = (tMat[1][0] * tMat[0][1] + tMat[1][1] * tMat[1][1]) % MOD;
        tMat[0][0] = tmp[0][0];
        tMat[0][1] = tmp[0][1];
        tMat[1][0] = tmp[1][0];
        tMat[1][1] = tmp[1][1];
    }
 
    // res store {Transformation matrix}^n-1
    // hence will be first row of res*Initial Vector.
    return (res[0][0] * 1 + res[0][1] * 1) % MOD;
}
 
// Driver code
var n = 3;
document.write( power(n));
 
</script>

                    

Output
13

Time Complexity : O(Log n)
Auxiliary Space: O(m2), where m is the order of the transformation matrix. Here, m is 2.

The same idea is used to find n-th Fibonacci number in O(Log n)



Last Updated : 07 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads