package org.jgrasstools.gears.utils.math.matrixes;
/**
* From: Java Number Cruncher
* The Java Programmer's Guide to Numerical Computation
* by Ronald Mak
*
* A matrix that can be inverted. Also, compute its determinant,
* norm, and condition number.
*/
public class InvertibleMatrix extends LinearSystem
{
/**
* Constructor.
* @param n the number of rows = the number of columns
*/
public InvertibleMatrix(int n) { super(n); }
/**
* Constructor.
* @param values the array of values
*/
public InvertibleMatrix(double values[][]) { super(values); }
/**
* Compute the inverse of this matrix.
* @return the inverse matrix
* @throws matrix.MatrixException if an error occurred
*/
public InvertibleMatrix inverse() throws MatrixException
{
InvertibleMatrix inverse = new InvertibleMatrix(nRows);
IdentityMatrix identity = new IdentityMatrix(nRows);
// Compute each column of the inverse matrix
// using columns of the identity matrix.
for (int c = 0; c < nCols; ++c) {
ColumnVector col = solve(identity.getColumn(c), true);
inverse.setColumn(col, c);
}
return inverse;
}
/**
* Compute the determinant.
* @return the determinant
* @throws matrix.MatrixException if an error occurred
*/
public double determinant() throws MatrixException
{
decompose();
// Each row exchange during forward elimination flips the sign
// of the determinant, so check for an odd number of exchanges.
double determinant = ((exchangeCount & 1) == 0) ? 1 : -1;
// Form the product of the diagonal elements of matrix U.
for (int i = 0; i < nRows; ++i) {
int pi = permutation[i]; // permuted index
determinant *= LU.at(pi, i);
}
return determinant;
}
/**
* Compute the Euclidean norm of this matrix.
* @return the norm
*/
public double norm()
{
double sum = 0;
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
double v = values[r][c];
sum += v*v;
}
}
return (double) Math.sqrt(sum);
}
/**
* Compute the condition number based on the Euclidean norm.
* @return the condition number
*/
public double condition() throws MatrixException
{
return norm() * inverse().norm();
}
}