In linear algebra, an n-by-n square matrix A is called Invertible, if there exists an n-by-n square matrix B such that
where ‘In‘ denotes the n-by-n identity matrix. The matrix B is called the inverse matrix of A.
A square matrix is Invertible if and only if its determinant is non-zero.
Examples:
Input : {{1, 2, 3} {4, 5, 6} {7, 8, 9}} Output : No The given matrix is NOT Invertible The value of Determinant is: 0
We find determinant of the matrix. Then we check if the determinant value is 0 or not. If the value is 0, then we output, not invertible.
Implementation:
// C++ program to find Determinant of a matrix #include <bits/stdc++.h> using namespace std;
// Dimension of input square matrix #define N 4 // Function to get cofactor of mat[p][q] in temp[][]. n is current // dimension of mat[][] void getCofactor( int mat[N][N], int temp[N][N], int p, int q, int n)
{ int i = 0, j = 0;
// Looping for each element of the matrix
for ( int row = 0; row < n; row++) {
for ( int col = 0; col < n; col++) {
// Copying into temporary matrix only those element
// which are not in given row and column
if (row != p && col != q) {
temp[i][j++] = mat[row][col];
// Row is filled, so increase row index and
// reset col index
if (j == n - 1) {
j = 0;
i++;
}
}
}
}
} /* Recursive function for finding determinant of matrix. n is current dimension of mat[][]. */ int determinantOfMatrix( int mat[N][N], int n)
{ int D = 0; // Initialize result
// Base case : if matrix contains single element
if (n == 1)
return mat[0][0];
int temp[N][N]; // To store cofactors
int sign = 1; // To store sign multiplier
// Iterate for each element of first row
for ( int f = 0; f < n; f++) {
// Getting Cofactor of mat[0][f]
getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1);
// terms are to be added with alternate sign
sign = -sign;
}
return D;
} bool isInvertible( int mat[N][N], int n)
{ if (determinantOfMatrix(mat, N) != 0)
return true ;
else
return false ;
} // Driver program to test above functions int main()
{ /* int mat[N][N] = {{6, 1, 1},
{4, -2, 5},
{2, 8, 7}}; */
int mat[N][N] = { { 1, 0, 2, -1 },
{ 3, 0, 0, 5 },
{ 2, 1, 4, -3 },
{ 1, 0, 5, 0 } };
if (isInvertible(mat, N))
cout << "Yes" ;
else
cout << "No" ;
return 0;
} |
// Java program to find // Determinant of a matrix class GFG
{ // Dimension of input square matrix
static int N = 4 ;
// Function to get cofactor
// of mat[p][q] in temp[][].
// n is current dimension
// of mat[][]
static void getCofactor( int [][]mat, int [][]temp,
int p, int q, int n)
{
int i = 0 , j = 0 ;
// Looping for each
// element of the matrix
for ( int row = 0 ; row < n; row++)
{
for ( int col = 0 ; col < n; col++)
{
// Copying into temporary matrix
// only those element which are
// not in given row and column
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// Row is filled, so increase
// row index and reset col index
if (j == n - 1 )
{
j = 0 ;
i++;
}
}
}
}
}
/* Recursive function for finding
determinant of matrix. n is current
dimension of mat[][]. */
static int determinantOfMatrix( int [][]mat,
int n)
{
int D = 0 ; // Initialize result
// Base case : if matrix
// contains single element
if (n == 1 )
return mat[ 0 ][ 0 ];
// To store cofactors
int [][]temp = new int [N][N];
// To store sign multiplier
int sign = 1 ;
// Iterate for each
// element of first row
for ( int f = 0 ; f < n; f++)
{
// Getting Cofactor of mat[0][f]
getCofactor(mat, temp, 0 , f, n);
D += sign * mat[ 0 ][f] *
determinantOfMatrix(temp, n - 1 );
// terms are to be added
// with alternate sign
sign = -sign;
}
return D;
}
static boolean isInvertible( int [][]mat, int n)
{
if (determinantOfMatrix(mat, N) != 0 )
return true ;
else
return false ;
}
// Driver Code
public static void main(String []args)
{
int [][]mat = {{ 1 , 0 , 2 , - 1 },
{ 3 , 0 , 0 , 5 },
{ 2 , 1 , 4 , - 3 },
{ 1 , 0 , 5 , 0 }};
if (isInvertible(mat, N))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
} // This code is contributed // by ChitraNayal |
# Function to get cofactor of # mat[p][q] in temp[][]. n is # current dimension of mat[][] def getCofactor(mat, temp, p, q, n):
i = 0
j = 0
# Looping for each element
# of the matrix
for row in range (n):
for col in range (n):
# Copying into temporary matrix
# only those element which are
# not in given row and column
if (row ! = p and col ! = q) :
temp[i][j] = mat[row][col]
j + = 1
# Row is filled, so increase
# row index and reset col index
if (j = = n - 1 ):
j = 0
i + = 1
# Recursive function for # finding determinant of matrix. # n is current dimension of mat[][]. def determinantOfMatrix(mat, n):
D = 0 # Initialize result
# Base case : if matrix
# contains single element
if (n = = 1 ):
return mat[ 0 ][ 0 ]
# To store cofactors
temp = [[ 0 for x in range (N)]
for y in range (N)]
sign = 1 # To store sign multiplier
# Iterate for each
# element of first row
for f in range (n):
# Getting Cofactor of mat[0][f]
getCofactor(mat, temp, 0 , f, n)
D + = (sign * mat[ 0 ][f] *
determinantOfMatrix(temp, n - 1 ))
# terms are to be added
# with alternate sign
sign = - sign
return D
def isInvertible(mat, n):
if (determinantOfMatrix(mat, N) ! = 0 ):
return True
else :
return False
# Driver Code mat = [[ 1 , 0 , 2 , - 1 ],
[ 3 , 0 , 0 , 5 ],
[ 2 , 1 , 4 , - 3 ],
[ 1 , 0 , 5 , 0 ]];
N = 4
if (isInvertible(mat, N)):
print ( "Yes" )
else :
print ( "No" )
# This code is contributed # by ChitraNayal |
// C# program to find // Determinant of a matrix using System;
class GFG
{ // Dimension of input // square matrix static int N = 4;
// Function to get cofactor of // mat[p,q] in temp[,]. n is // current dimension of mat[,] static void getCofactor( int [,] mat, int [,] temp,
int p, int q, int n)
{ int i = 0, j = 0;
// Looping for each element // of the matrix for ( int row = 0; row < n; row++)
{ for ( int col = 0; col < n; col++)
{
// Copying into temporary matrix
// only those element which are
// not in given row and column
if (row != p && col != q)
{
temp[i, j++] = mat[row, col];
// Row is filled, so
// increase row index and
// reset col index
if (j == n - 1)
{
j = 0;
i++;
}
}
}
} } /* Recursive function for finding determinant of matrix. n is current dimension of mat[,]. */ static int determinantOfMatrix( int [,]
mat, int n)
{ int D = 0; // Initialize result
// Base case : if matrix // contains single element if (n == 1)
return mat[0, 0];
// To store cofactors int [,] temp = new int [N, N];
int sign = 1; // To store sign multiplier
// Iterate for each // element of first row for ( int f = 0; f < n; f++)
{ // Getting Cofactor of mat[0,f]
getCofactor(mat, temp, 0, f, n);
D += sign * mat[0, f] *
determinantOfMatrix(temp, n - 1);
// terms are to be added
// with alternate sign
sign = -sign;
} return D;
} static bool isInvertible( int [,] mat, int n)
{ if (determinantOfMatrix(mat, N) != 0)
return true ;
else
return false ;
} // Driver Code public static void Main()
{ int [,] mat = {{ 1, 0, 2, -1 },
{ 3, 0, 0, 5 },
{ 2, 1, 4, -3 },
{ 1, 0, 5, 0 }};
if (isInvertible(mat, N))
Console.Write( "Yes" );
else
Console.Write( "No" );
} } // This code is contributed // by ChitraNayal |
<?php // PHP program to find Determinant // of a matrix // Dimension of input // square matrix $N = 4;
// Function to get cofactor of // $mat[$p][$q] in $temp[][]. // $n is current dimension of $mat[][] function getCofactor(& $mat , & $temp ,
$p , $q , $n )
{ $i = 0;
$j = 0;
// Looping for each element
// of the matrix
for ( $row = 0; $row < $n ; $row ++)
{
for ( $col = 0; $col < $n ; $col ++)
{
// Copying into temporary matrix
// only those element which are
// not in given row and column
if ( $row != $p && $col != $q )
{
$temp [ $i ][ $j ++] = $mat [ $row ][ $col ];
// Row is filled, so
// increase row index and
// reset col index
if ( $j == $n - 1)
{
$j = 0;
$i ++;
}
}
}
}
} /* Recursive function for finding determinant of matrix. n is current dimension of $mat[][]. */ function determinantOfMatrix(& $mat , $n )
{ $D = 0; // Initialize result
// Base case : if matrix
// contains single element
if ( $n == 1)
return $mat [0][0];
$temp = array ( array ()); // To store cofactors
$sign = 1; // To store sign multiplier
// Iterate for each
// element of first row
for ( $f = 0; $f < $n ; $f ++)
{
// Getting Cofactor of $mat[0][$f]
getCofactor( $mat , $temp , 0, $f , $n );
$D += $sign * $mat [0][ $f ] *
determinantOfMatrix( $temp , $n - 1);
// terms are to be added
// with alternate sign
$sign = - $sign ;
}
return $D ;
} function isInvertible(& $mat , $n )
{ global $N ;
if (determinantOfMatrix( $mat , $N ) != 0)
return true;
else
return false;
} // Driver Code $mat = array ( array (1, 0, 2, -1 ),
array (3, 0, 0, 5 ),
array (2, 1, 4, -3 ),
array (1, 0, 5, 0 ));
if (isInvertible( $mat , $N ))
echo "Yes" ;
else echo "No" ;
// This code is contributed // by ChitraNayal ?> |
<script> // Javascript program to find // Determinant of a matrix // Function to get cofactor // of mat[p][q] in temp[][].
// n is current dimension
// of mat[][]
function getCofactor(mat,temp,p,q,n)
{ let i = 0, j = 0;
// Looping for each
// element of the matrix
for (let row = 0; row < n; row++)
{
for (let col = 0; col < n; col++)
{
// Copying into temporary matrix
// only those element which are
// not in given row and column
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// Row is filled, so increase
// row index and reset col index
if (j == n - 1)
{
j = 0;
i++;
}
}
}
}
} /* Recursive function for finding determinant of matrix. n is current
dimension of mat[][]. */
function determinantOfMatrix(mat,n)
{ let D = 0; // Initialize result
// Base case : if matrix
// contains single element
if (n == 1)
return mat[0][0];
// To store cofactors
let temp = new Array(N);
for (let i=0;i<N;i++)
{
temp[i]= new Array(N);
for (let j=0;j<N;j++)
{
temp[i][j]=0;
}
}
// To store sign multiplier
let sign = 1;
// Iterate for each
// element of first row
for (let f = 0; f < n; f++)
{
// Getting Cofactor of mat[0][f]
getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] *
determinantOfMatrix(temp, n - 1);
// terms are to be added
// with alternate sign
sign = -sign;
}
return D;
} function isInvertible(mat,n)
{ if (determinantOfMatrix(mat, N) != 0)
return true ;
else
return false ;
} // Driver Code let mat = [[ 1, 0, 2, -1 ], [ 3, 0, 0, 5 ],
[ 2, 1, 4, -3 ],
[ 1, 0, 5, 0 ]];
let N = 4 if (isInvertible(mat, N))
document.write( "Yes" )
else document.write( "No" )
// This code is contributed by rag2127 </script> |
Output
Yes
Time Complexity: O(n3)
Auxiliary Space: O(n2)
Optimizing the Approach
If we extend the concept of calculating invertibility using a determinant from n =3 to some greater value, calculating the determinant would be quite cumbersome. Whether we do it using a pen and paper or use a calculator/computer.
So we’ll make use of the Reduced Row Echelon Form Concept. This makes use of computational operations which is quite efficient compared to the above-mentioned approach.
Here we’ll elaborate on the concept using a 4 X 4 matrix, which can be further generalized to an n X n matrix. The matrix will be processed by our function, replacing each row in turn and converting it to echelon form. We will return the value False if it ever fails because we can’t fit a 1 onto the leading diagonal; else, we will return True.
Approach:
Here is an implementation on Google Colab Notebook for the same.
import numpy as np #installing the numpy
The following steps need to be followed for a 4 X 4 matrix and can be generalized further for an N X N matrix.
- All we need for Row Zero is that the first element is equal to one.
- The row will be divided by the value of A[0, 0]. We’ll first check to see if A[0, 0] = 0, and if it does, we’ll add one of the lower rows to the first one before the division to avoid the problem.
- Until we can perform the division, we will repeat the test while moving down each lower row.
- The sub-diagonal elements will first be set to zero, or A[1,0].
- The diagonal component should then equal one. We’ll divide the row by A[1, 1]’s value.
- We must check one more to see if this is zero.
- If so, we will repeat the process of setting the sub-diagonal elements to zero and add a lower row.
- The same procedure continues further for the second and third row respectively.
Converting to Row Echelon Form
def isInvertible(X): # Make Y as a copy of X, since we're going to alter it's values. Y = np.array(X, dtype=np.float_) try: fix_r0(X) fix_r1(X) fix_r2(X) fix_r3(X) except MatrixIsSingular: return False return True # The following line specifies our error flag. # For if the matrix is singular and anything goes wrong. class MatrixIsSingular(Exception): pass def fix_r0(A): if A[0, 0] == 0: A[0] = A[0] + A[1] if A[0, 0] == 0: A[0] = A[0] + A[2] if A[0, 0] == 0: A[0] = A[0] + A[3] if A[0, 0] == 0: raise MatrixIsSingular() A[0] = A[0] / A[0, 0] return A def fix_r1(A): A[1] = A[1] - A[1, 0] * A[0] if A[1, 1] == 0: A[1] = A[1] + A[2] A[1] = A[1] - A[1, 0] * A[0] if A[1, 1] == 0: A[1] = A[1] + A[3] A[1] = A[1] - A[1, 0] * A[0] if A[1, 1] == 0: raise MatrixIsSingular() A[1] = A[1] / A[1, 1] return A def fix_r2(A): # Set the sub-diagonal elements of row two to zero. A[2] = A[2] - A[2, 0] * A[0] A[2] = A[2] - A[2, 1] * A[1] # Next we'll test that the diagonal element is not zero. if A[2, 2] == 0: A[2] = A[2] + A[3] A[2] = A[2] - A[2, 0] * A[0] A[2] = A[2] - A[2, 1] * A[1] if A[2, 2] == 0: raise MatrixIsSingular() A[2] = A[2]/A[2, 2] return A def fix_r3(A): # Set the sub-diagonal elements of row three to zero. A[3] = A[3] - A[3, 0] * A[0] A[3] = A[3] - A[3, 1] * A[1] A[3] = A[3] - A[3, 2] * A[2] if A[3, 3] == 0: raise MatrixIsSingular() # Transform the row to set the diagonal element to one. A[3] = A[3]/A[3, 3] return A # Contributed by Pranav Gupta
Step-by-Step Demonstration:
P.S. Performing this conversion on pen and paper might seem cumbersome but these approaches are made from the perspective of a machine and not a human. This is quite evident after watching the terms of the matrix after this step.
Finally, we arrived at our Reduced Row Echelon Form. As we can see We were able to reduce it to the desired form. Hence it is invertible. The code would have thrown the MatrixIsSingular exception and returned false if we had failed at any step. The memory required for the above approach would be O(1) as we are modifying just the copy of the original matrix in contrast to the naive approach which required additional O(n2) space for storing the co-factors. If the matrix is passed by the value we can perform the steps directly on the passed matrix.