The Wikipedia entry on inverting matrices lists 10 categories of techniques, and each category has dozens of variations. One of the simplest approaches is to use cofactors and the adjugate (aka adjoint). “Simplest” is relative — inverting a matrix is one of the most complex tasks in numerical programming.
Briefly, 1.) find all (n-1)x(n-1) submatrices, 2.) the minors are the determinants of the submatrices, 3.) the cofactors are the sign-adjusted (+1 or -1) values of the minors, 4.) the adjugate/adjoint is the cofactors matrix, where each term is divided by the determinant of the original matrix, 5.) the inverse is the transpose of the adjugate matrix.
A submatrix of an rxc size matrix m is a (r-1)x(c-1) size matrix where s omits one row and one column of m. For example, if
m =
1 2 3 4 0 5 1 6 7 9 0 8 3 7 2 1
Then submatrix(0, 3) removes row[0] and column [3] giving:
0 5 1 7 9 0 3 7 2
A matrix of “minors” of an rxc size matrix m is an rxc size matrix of the determinants of all possible submatrices.
A matrix of cofactors is the same as the matrix of minors except each term is multiplied by +1 (first, third, fifth, etc. term) or -1 (second, fourth, sixth, etc. term).
The adjugate matrix is the matrix of cofactors where each term is divided by the determinant of the original matrix.
As it turns out, the inverse of a matrix m is the transpose of the adjugate matrix. Whew!
All that said, this approach is probably the simplest way to find the inverse of a matrix but it’s inefficient compared to techniques that use a complicated approach called matrix decomposition. In general, the simple adjugate technique works reasonably well for matrices of size 10×10 or smaller. For larger matrices, the adjugate technique is too slow and a decomposition technique should be used.
Here’s a C# language implementation of the adjugate technique I created.
using System;
namespace MatrixInvAdjoint
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("\nBegin matrix inverse demo\n");
double[][] m = new double[4][];
m[0] = new double[] { 3, 7, 2, 5 };
m[1] = new double[] { 4, 0, 1, 1 };
m[2] = new double[] { 1, 6, 3, 0 };
m[3] = new double[] { 2, 8, 4, 3 };
Console.WriteLine("Original matrix m is ");
MatShow(m, 4, 8);
double d = MatDet(m);
Console.WriteLine("\nDet(m) = " + d.ToString("F4"));
Console.WriteLine("\nInverse using adjugate technique:");
double[][] altInv = MatInv(m);
MatShow(altInv, 4, 8);
Console.WriteLine("\nEnd demo");
Console.ReadLine();
} // Main
static double[][] MatInv(double[][] m)
{
// matrix inverse using adjugate matrix technique
//
// submatrix - eliminate one row & one column
// minor - determinant of a submatrix
// cofactor is +/- signed minor
// adjoint - cofactor matrix each term divided by orig det
// inverse - transpose of adjoint
int nr = m.Length;
int nc = m[0].Length;
double det = MatDet(m);
double[][] cm = Cofactors(m);
for (int i = 0; i less-than nr; ++i)
for (int j = 0; j less-than nc; ++j)
cm[i][j] /= det; // the "adjoint"
return MatTranspose(cm);
}
static double MatDet(double[][] m)
{
// recursive technique determinant
// works OK for 10x10 or smaller
double sum = 0.0;
int sign; // -1 or +1
if (m.Length == 1)
return m[0][0];
else if (m.Length == 2)
return (m[0][0] * m[1][1]) - (m[0][1] * m[1][0]);
for (int j = 0; j less-than m.Length; ++j) // each col of m
{
double[][] small = MatCreate(m.Length - 1, m.Length - 1);
for (int r = 1; r less-than m.Length; ++r)
{
for (int c = 0; c less-than m.Length; ++c)
{
if (c less-than j)
small[r - 1][c] = m[r][c];
else if (c greater-than j)
small[r - 1][c - 1] = m[r][c];
else // if (c == j)
;
} // c
} // r
if (j % 2 == 0)
sign = +1;
else
sign = -1;
sum += sign * m[0][j] * MatDet(small); // ouch!
} // j
return sum;
}
// --------------------------------------------------
static double[][] MatCreate(int rows, int cols)
{
double[][] result = new double[rows][];
for (int i = 0; i less-than rows; ++i)
result[i] = new double[cols];
return result;
}
static void MatShow(double[][] m, int dec, int wid)
{
for (int i = 0; i less-than m.Length; ++i)
{
for (int j = 0; j less-than m[0].Length; ++j)
{
double v = m[i][j];
if (Math.Abs(v) less-than 1.0e-5)
v = 0.0; // avoid "-0.00"
Console.Write(v.ToString("F" + dec).PadLeft(wid));
}
Console.WriteLine("");
}
}
static double[][] SubMatrix(double[][] m, int r, int c)
{
int nr = m.Length;
int nc = m[0].Length;
double[][] result = MatCreate(nr - 1, nc - 1);
// r, c row, col to eliminate
// i, j indices of source. ri, ci indices of result
int ri = 0; int ci = 0;
for (int i = 0; i less-than nr; ++i)
{
for (int j = 0; j less-than nc; ++j)
{
if (i == r || j == c) continue;
result[ri][ci] = m[i][j];
++ci;
if (ci == nc - 1) // end of column
{
++ri; // next row
ci = 0; // first column
}
}
}
return result;
}
static double[][] Cofactors(double[][] m)
{
// matrix of cofactors (signed minors)
int nr = m.Length;
int nc = m[0].Length;
double[][] result = MatCreate(nr, nc);
for (int i = 0; i less-than nr; ++i)
{
for (int j = 0; j less-than nc; ++j)
{
double[][] sub = SubMatrix(m, i, j);
double det = MatDet(sub);
if ((i + j) % 2 == 0)
result[i][j] = det;
else
result[i][j] = -det;
}
}
return result;
}
static double[][] MatTranspose(double[][] m)
{
int nr = m.Length;
int nc = m[0].Length;
double[][] result = MatCreate(nc, nr); // note
for (int i = 0; i less-than nr; ++i)
for (int j = 0; j less-than nc; ++j)
result[j][i] = m[i][j];
return result;
}
} // Program
} // ns

.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
2026 Visual Studio Live
2025 Summer MLADS Conference
2026 DevIntersection Conference
2025 Machine Learning Week
2025 Ai4 Conference
2026 G2E Conference
2026 iSC West Conference
You must be logged in to post a comment.