/// <summary> /// Solves a linear equation system. /// </summary> /// <param name="decomposition">The LU decomposition.</param> /// <param name="b">The vector.</param> /// <returns>The vector containing the unknown variables of the equation.</returns> private static Vector SolveEquation(LUDecomposition decomposition, Vector b) { // P*b Vector pb = decomposition.P * b; // L*y = P*b with forward substitution Vector y = new Vector(pb.Size); for (Int32 rowIndex = 0; rowIndex < decomposition.L.NumberOfRows; ++rowIndex) { y[rowIndex] = pb[rowIndex]; for (Int32 columnIndex = 0; columnIndex < rowIndex; ++columnIndex) { y[rowIndex] -= decomposition.L[rowIndex, columnIndex] * y[columnIndex]; } y[rowIndex] /= decomposition.L[rowIndex, rowIndex] == 0 ? 1 : decomposition.L[rowIndex, rowIndex]; } // U*x = y with back substitution Vector x = new Vector(y.Size); for (Int32 rowIndex = x.Size - 1; rowIndex >= 0; --rowIndex) { x[rowIndex] = y[rowIndex]; for (Int32 columnIndex = rowIndex + 1; columnIndex < decomposition.U.NumberOfRows; ++columnIndex) { x[rowIndex] -= decomposition.U[rowIndex, columnIndex] * x[columnIndex]; } x[rowIndex] /= decomposition.U[rowIndex, rowIndex] == 0 ? 1 : decomposition.U[rowIndex, rowIndex]; } return(x); }
/// <summary> /// Computes the determinant of the matrix. /// </summary> /// <param name="matrix">The matrix.</param> /// <returns>The determinant of the matrix.</returns> /// <exception cref="System.ArgumentNullException">The matrix is null.</exception> /// <exception cref="System.ArgumentException">The matrix is not square.</exception> public static Double Determinant(this Matrix matrix) { if (matrix == null) { throw new ArgumentNullException(nameof(matrix)); } if (matrix.NumberOfRows != matrix.NumberOfColumns) { throw new ArgumentException(NumericsMessages.MatrixIsNotSquare, nameof(matrix)); } if (matrix.NumberOfRows == 0) { return(0); } if (matrix.NumberOfRows == 1) { return(matrix[0, 0]); } if (matrix.NumberOfRows == 2) { return(matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0]); } return(LUDecomposition.ComputeDeterminant(matrix)); }
/// <summary> /// Computes the determinant of the specified matrix. /// </summary> /// <param name="matrix">The matrix.</param> /// <returns>The determinant of the specified matrix.</returns> /// <exception cref="System.ArgumentNullException">The matrix is null.</exception> /// <exception cref="System.ArgumentException">The matrix is not square.</exception> public static Double ComputeDeterminant(Matrix matrix) { LUDecomposition decomposition = new LUDecomposition(matrix); decomposition.Compute(); return(decomposition.Determinant); }
/// <summary> /// Decomposes the specified matrix. /// </summary> /// <param name="matrix">The matrix.</param> /// <returns>The decomposed (LU) matrix.</returns> /// <exception cref="System.ArgumentNullException">The matrix is null.</exception> /// <exception cref="System.ArgumentException">The matrix is not square.</exception> public static Matrix Decompose(Matrix matrix) { LUDecomposition decomposition = new LUDecomposition(matrix); decomposition.Compute(); return(decomposition.LU); }
/// <summary> /// Decomposes the specified matrix. /// </summary> /// <param name="matrix">The matrix to decompose.</param> /// <param name="l">The L (lower triangular) matrix.</param> /// <param name="u">The U (upper triangular) matrix.</param> /// <exception cref="System.ArgumentNullException">The matrix is null.</exception> /// <exception cref="System.ArgumentException">The matrix is not square.</exception> public static void Decompose(Matrix matrix, out Matrix l, out Matrix u) { LUDecomposition decomposition = new LUDecomposition(matrix); decomposition.Compute(); l = decomposition.L; u = decomposition.U; }
/// <summary> /// Solves a linear equation system. /// </summary> /// <param name="a">The left side of the equation represented by a matrix.</param> /// <param name="b">The right side of the equation represented by a vector.</param> /// <returns>The vector containing the unknown variables of the equation.</returns> /// <exception cref="System.ArgumentNullException"> /// The matrix is null. /// or /// The vector is null. /// </exception> /// <exception cref="System.ArgumentException"> /// The matrix is not square. /// or /// The size of the matrix does not match the size of the vector. /// </exception> public static Vector SolveEquation(Matrix a, Vector b) { if (a == null) { throw new ArgumentNullException(nameof(a)); } if (b == null) { throw new ArgumentNullException(nameof(b)); } if (!a.IsSquare) { throw new ArgumentException(NumericsMessages.MatrixIsNotSquare, nameof(a)); } if (a.NumberOfRows != b.Size) { throw new ArgumentException(NumericsMessages.MatrixSizeDoesNotMatchVector, nameof(b)); } LUDecomposition decomposition = new LUDecomposition(a); decomposition.Compute(); return(SolveEquation(decomposition, b)); }
/// <summary> /// Inverts the specified matrix. /// </summary> /// <param name="matrix">The matrix.</param> /// <returns>The inverted matrix.</returns> /// <exception cref="System.ArgumentNullException">The matrix is null.</exception> /// <exception cref="System.ArgumentException">The matrix is not invertible.</exception> public static Matrix Invert(Matrix matrix) { if (matrix == null) { throw new ArgumentNullException(nameof(matrix)); } if (matrix.All(value => value == 0)) { throw new ArgumentException(NumericsMessages.MatrixIsNotInvertible, nameof(matrix)); } LUDecomposition decomposition = new LUDecomposition(matrix); decomposition.Compute(); if (decomposition.Determinant == 0) { throw new ArgumentException(NumericsMessages.MatrixIsNotInvertible, nameof(matrix)); } Matrix inverse = new Matrix(matrix.NumberOfRows, matrix.NumberOfColumns); for (Int32 columnIndex = 0; columnIndex < matrix.NumberOfColumns; columnIndex++) { Vector b = VectorFactory.CreateUnitVector(matrix.NumberOfRows, columnIndex); Vector y = SolveEquation(decomposition, b); for (Int32 rowIndex = 0; rowIndex < inverse.NumberOfRows; ++rowIndex) { inverse[rowIndex, columnIndex] = y[rowIndex]; } } return(inverse); }
/// <summary> /// Inverts the specified matrix. /// </summary> /// <param name="matrix">The matrix.</param> /// <returns>The inverse matrix.</returns> /// <exception cref="System.ArgumentNullException">The matrix is null.</exception> /// <exception cref="System.ArgumentException">The matrix is not invertible.</exception> public static Matrix Invert(this Matrix matrix) { return(LUDecomposition.Invert(matrix)); }