/// <summary>Inverses the given matrix.</summary> /// <exception cref="SingularMatrixException">Thrown when a Singular Matrix error condition occurs.</exception> /// <param name="mat">Matrix.</param> /// <returns>A Matrix.</returns> private static Matrix Inverse(Matrix mat) { // working space Matrix matrix = new Matrix(mat.Rows, 2 * mat.Cols); // copy over colums for (int i = 0; i < mat.Cols; i++) { matrix[i, VectorType.Col] = mat[i, VectorType.Col]; } // fill in identity for (int i = mat.Cols; i < 2 * mat.Cols; i++) { matrix[i - mat.Cols, i] = 1; } int maxrow; double c; for (int y = 0; y < matrix.Rows; y++) { maxrow = y; for (int y2 = y + 1; y2 < matrix.Rows; y2++) { if (System.Math.Abs(matrix[y2, y]) > System.Math.Abs(matrix[maxrow, y])) { maxrow = y2; } } // swap rows matrix.SwapRow(maxrow, y); // uh oh if (System.Math.Abs(matrix[y][y]) <= 0.00000000001) { throw new SingularMatrixException("Matrix is becoming unstable!"); } for (int y2 = y + 1; y2 < matrix.Rows; y2++) { c = matrix[y2, y] / matrix[y, y]; for (int x = y; x < matrix.Cols; x++) { matrix[y2, x] -= matrix[y, x] * c; } } } // back substitute for (int y = matrix.Rows - 1; y >= 0; y--) { c = matrix[y][y]; for (int y2 = 0; y2 < y; y2++) { for (int x = matrix.Cols - 1; x > y - 1; x--) { matrix[y2, x] -= matrix[y, x] * matrix[y2, y] / c; } } matrix[y, y] /= c; for (int x = matrix.Rows; x < matrix.Cols; x++) { matrix[y, x] /= c; } } // generate result Matrix result = new Matrix(mat.Rows); for (int i = mat.Cols; i < 2 * mat.Cols; i++) { result[i - mat.Cols, VectorType.Col] = matrix[i, VectorType.Col]; } return(result); }
private static Matrix Inverse(Matrix mat) { // working space Matrix matrix = new Matrix(mat.Rows, 2 * mat.Cols); // copy over colums for (int i = 0; i < mat.Cols; i++) matrix[i, VectorType.Col] = mat[i, VectorType.Col]; // fill in identity for (int i = mat.Cols; i < 2 * mat.Cols; i++) matrix[i - mat.Cols, i] = 1; int maxrow; double c; for (int y = 0; y < matrix.Rows; y++) { maxrow = y; for (int y2 = y + 1; y2 < matrix.Rows; y2++) if (System.Math.Abs(matrix[y2, y]) > System.Math.Abs(matrix[maxrow, y])) maxrow = y2; // swap rows matrix.SwapRow(maxrow, y); // uh oh if (System.Math.Abs(matrix[y][y]) <= 0.00000000001) throw new SingularMatrixException("Matrix is becoming unstable!"); for (int y2 = y + 1; y2 < matrix.Rows; y2++) { c = matrix[y2, y] / matrix[y, y]; for (int x = y; x < matrix.Cols; x++) matrix[y2, x] -= matrix[y, x] * c; } } // back substitute for (int y = matrix.Rows - 1; y >= 0; y--) { c = matrix[y][y]; for (int y2 = 0; y2 < y; y2++) for (int x = matrix.Cols - 1; x > y - 1; x--) matrix[y2, x] -= matrix[y, x] * matrix[y2, y] / c; matrix[y, y] /= c; for (int x = matrix.Rows; x < matrix.Cols; x++) matrix[y, x] /= c; } // generate result Matrix result = new Matrix(mat.Rows); for (int i = mat.Cols; i < 2 * mat.Cols; i++) result[i - mat.Cols, VectorType.Col] = matrix[i, VectorType.Col]; return result; }
/// <summary> /// Matrix inverse using pivoted Gauss-Jordan elimination with partial pivoting /// See:http://www.cse.illinois.edu/iem/linear_equations/gauss_jordan/ /// for python implementaion /// </summary> /// <param name="mat">Matrix</param> /// <param name="n">-1</param> /// <returns>Inverse (or exception if matrix is singular)</returns> public static Matrix operator ^(Matrix mat, int n) { if (n != -1) throw new InvalidOperationException("This is a hack for the inverse, please use it as such!"); if (mat.Rows != mat.Cols) throw new InvalidOperationException("Can only find inverse of square matrix!"); // working space Matrix matrix = new Matrix(mat.Rows, 2 * mat.Cols); // copy over colums for (int i = 0; i < mat.Cols; i++) matrix[i, VectorType.Col] = mat[i, VectorType.Col]; // fill in identity for (int i = mat.Cols; i < 2 * mat.Cols; i++) matrix[i - mat.Cols, i] = 1; int maxrow; double c; for (int y = 0; y < matrix.Rows; y++) { maxrow = y; for (int y2 = y + 1; y2 < matrix.Rows; y2++) if (System.Math.Abs(matrix[y2, y]) > System.Math.Abs(matrix[maxrow, y])) maxrow = y2; // swap rows matrix.SwapRow(maxrow, y); // uh oh if (System.Math.Abs(matrix[y][y]) <= 0.00000000001) throw new SingularMatrixException("Matrix is becoming unstable!"); for (int y2 = y + 1; y2 < matrix.Rows; y2++) { c = matrix[y2, y] / matrix[y, y]; for (int x = y; x < matrix.Cols; x++) matrix[y2, x] -= matrix[y, x] * c; } } // back substitute for (int y = matrix.Rows - 1; y >= 0; y--) { c = matrix[y][y]; for (int y2 = 0; y2 < y; y2++) for (int x = matrix.Cols - 1; x > y - 1; x--) matrix[y2, x] -= matrix[y, x] * matrix[y2, y] / c; matrix[y, y] /= c; for (int x = matrix.Rows; x < matrix.Cols; x++) matrix[y, x] /= c; } // generate result Matrix result = new Matrix(mat.Rows); for (int i = mat.Cols; i < 2 * mat.Cols; i++) result[i - mat.Cols, VectorType.Col] = matrix[i, VectorType.Col]; return result; }