Find Nth term (A matrix exponentiation example)

We are given a recursive function that describes Nth terms in form of other terms. In this article we have taken specific example.
 $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 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 next one and so on. But time complexity of this problem is of order O(n).

Optimized Approach
All such problem where a term is a function of other terms in linear fashion. Then these can be solved using Matrix (Please refer : Matrix Exponentiation ). First we make transformation matrix and then just use matrix exponentiation to find Nth term.
Step by Step method includes:
Step 1. Determine k the number of terms on which T(i) depends.
In 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 relation. In this step, we have to make matrix of dimension k*k.
Such that
T(i)=TM*(initial value vector)
Here initial value vector is vector that contains intial 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 C++ program to implement above approach

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Output:

13

Time Complexity : O(Log n)

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



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.