private static double[][] MatrixDecompose(double[][] matrix, out int[] perm, out int toggle) { // Doolittle LUP decomposition with partial pivoting. // rerturns: result is L (with 1s on diagonal) and U; // perm holds row permutations; toggle is +1 or -1 (even or odd) int rows = matrix.Length; int cols = matrix[0].Length; // assume square if (rows != cols) { throw new Exception("Attempt to decompose a non-square m"); } int n = rows; // convenience double[][] result = MatrixHelper.MatrixDuplicate(matrix); perm = new int[n]; // set up row permutation result for (int i = 0; i < n; ++i) { perm[i] = i; } toggle = 1; // toggle tracks row swaps. // +1 -greater-than even, -1 -greater-than odd. used by MatrixDeterminant CalculateEachColumn(result, n, perm, toggle); return(result); }
private static double[][] MatrixInverse(double[][] matrix) { int n = matrix.Length; double[][] result = MatrixHelper.MatrixDuplicate(matrix); int[] perm; int toggle; double[][] lum = MatrixDecompose(matrix, out perm, out toggle); if (lum == null) { throw new Exception("Unable to compute inverse"); } double[] b = new double[n]; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i == perm[j]) { b[j] = 1.0; } else { b[j] = 0.0; } } double[] x = HelperSolve(lum, b); for (int j = 0; j < n; ++j) { result[j][i] = x[j]; } } return(result); }
private static double[][] MatrixDecompose(double[][] matrix, out int[] perm, out int toggle) { // Doolittle LUP decomposition with partial pivoting. // rerturns: result is L (with 1s on diagonal) and U; // perm holds row permutations; toggle is +1 or -1 (even or odd) int rows = matrix.Length; int cols = matrix[0].Length; // assume square if (rows != cols) { throw new Exception("Attempt to decompose a non-square m"); } int n = rows; // convenience double[][] result = MatrixHelper.MatrixDuplicate(matrix); perm = new int[n]; // set up row permutation result for (int i = 0; i < n; ++i) { perm[i] = i; } toggle = 1; // toggle tracks row swaps. // +1 -greater-than even, -1 -greater-than odd. used by MatrixDeterminant for (int j = 0; j < n - 1; ++j) // each column { double colMax = Math.Abs(result[j][j]); // find largest val in col int pRow = j; // reader Matt V needed this: for (int i = j + 1; i < n; ++i) { if (Math.Abs(result[i][j]) > colMax) { colMax = Math.Abs(result[i][j]); pRow = i; } } // Not sure if this approach is needed always, or not. if (pRow != j) // if largest value not on pivot, swap rows { double[] rowPtr = result[pRow]; result[pRow] = result[j]; result[j] = rowPtr; int tmp = perm[pRow]; // and swap perm info perm[pRow] = perm[j]; perm[j] = tmp; toggle = -toggle; // adjust the row-swap toggle } if (result[j][j] == 0.0) { // find a good row to swap int goodRow = -1; for (int row = j + 1; row < n; ++row) { if (result[row][j] != 0.0) { goodRow = row; } } if (goodRow == -1) { throw new Exception("Cannot use Doolittle's method"); } // swap rows so 0.0 no longer on diagonal double[] rowPtr = result[goodRow]; result[goodRow] = result[j]; result[j] = rowPtr; int tmp = perm[goodRow]; // and swap perm info perm[goodRow] = perm[j]; perm[j] = tmp; toggle = -toggle; // adjust the row-swap toggle } for (int i = j + 1; i < n; ++i) { result[i][j] /= result[j][j]; for (int k = j + 1; k < n; ++k) { result[i][k] -= result[i][j] * result[j][k]; } } } return(result); }