Created
March 12, 2013 02:50
-
-
Save wanooknox/5139902 to your computer and use it in GitHub Desktop.
Recursive matrix determinants by cofactor expansion. Contains Minor, Cofactor, CofactorMatrix, Transpose, Adjoint, and Inverse methods. The corresponding IMatrix, AMatrix, and full Matrix class structure is not mine to post. Structure assumes matrix indexing is 1 based, not 0 based.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public double Minor(int row, int col) | |
{ | |
//can only calculate a Minor value if the matrix is square | |
if (this.Rows != this.Cols) | |
{ | |
throw new ApplicationException("Number of rows does not match number of columns"); | |
} | |
//the sub matrix | |
Matrix subMatrix = (Matrix)this.NewMatrix(this.Rows - 1, this.Cols - 1); | |
//submatrix counters | |
int subRows = 1; | |
int subCols = 1; | |
for (int i = 1; i <= this.Rows; i++) | |
{ | |
//if we are not on the passed in row | |
if (i != row) | |
{ | |
for (int j = 1; j <= this.Cols; j++) | |
{ | |
//if we are not on the passed in col | |
if (j != col) | |
{ | |
//add this element to the sub matrix | |
subMatrix.SetElement(subRows, subCols, this.GetElement(i, j)); | |
//increment cols | |
subCols++; | |
} | |
} | |
//increment rows, restart columns | |
subRows++; | |
subCols = 1; | |
} | |
} | |
//minor equals the determinant of the subMatrix | |
return subMatrix.Determinant(); | |
} | |
public double Cofactor(int row, int col) | |
{ | |
//a cofactor is (-1)^(i+j) * Minor(i,j) | |
return Math.Pow(-1, row + col) * this.Minor(row, col); | |
} | |
public double Determinant() | |
{ | |
double result = 0; | |
//BASE CASE: if one of our dimesions is too small. | |
if (this.Rows <= 1 || this.Cols <= 1) | |
{ | |
throw new ApplicationException("Row/Col less than 2"); | |
} | |
//BASE CASE: if this is a 2x2 matrix | |
else if (this.Rows == 2 && this.Cols == 2) | |
{ | |
//det(2x2) = ad-bc | |
result = (this.GetElement(1, 1) * this.GetElement(2, 2)) - (this.GetElement(1, 2) * this.GetElement(2, 1)); | |
} | |
else //anything bigger than a 2x2 | |
{ | |
//for now, always use the first column to perform cofactor expansion. | |
//this could be done more efficiently if there is a row/col with multiple 0 elements | |
for (int i = 1; i <= this.Rows; i++) | |
{ | |
result += this.GetElement(i, 1) * this.Cofactor(i, 1); | |
} | |
} | |
return result; | |
} | |
public Matrix CofactorMatrix() | |
{ | |
//get a new mtrix to opperate on | |
Matrix coMatrix = (Matrix)this.NewMatrix(this.Rows, this.Cols); | |
//for every element | |
for (int i = 1; i <= this.Rows; i++) | |
{ | |
for (int j = 1; j <= this.Cols; j++) | |
{ | |
//insert the respective cofactor | |
coMatrix.SetElement(i, j, this.Cofactor(i, j)); | |
} | |
} | |
return coMatrix; | |
} | |
public Matrix Adjoint() | |
{ | |
//adjoint is the traspose of the cofactor matrix | |
return this.CofactorMatrix().Transpose(); | |
} | |
public Matrix Transpose() | |
{ | |
//get a matrix to opperate on | |
Matrix matrixT = (Matrix)this.NewMatrix(this.Rows, this.Cols); | |
//for every element | |
for (int i = 1; i <= this.Rows; i++) | |
{ | |
for (int j = 1; j <= this.Cols; j++) | |
{ | |
//transpose it's location | |
matrixT.SetElement(i, j, this.GetElement(j,i)); | |
} | |
} | |
return matrixT; | |
} | |
public Matrix Inverse() | |
{ | |
//get the determinant of the matrix | |
double det = this.Determinant(); | |
//if it's not zero | |
if (det == 0) | |
{ | |
throw new ApplicationException("Matrix is not invertible, determinant of 0"); | |
} | |
//inverse is 1/det * adj() | |
// the * has been overloaded for scalar multiplication. | |
return (1 / det) * this.Adjoint(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment