/// <summary> /// The function returns the reduced echelon form of the current matrix /// </summary> public Matrix ReducedEchelonForm() { try { Matrix ReducedEchelonMatrix = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonMatrix[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { if (ReducedEchelonMatrix[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonMatrix.InterchangeRow(i, j); // then interchange the two rows } } } if (ReducedEchelonMatrix[i, i] == 0) // if not found any non-zero diagonal entry { continue; // increment i; } if (ReducedEchelonMatrix[i, i] != 1) // if diagonal entry is not 1 , { for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { if (ReducedEchelonMatrix[j, i] == 1) //check if some below entry is 1 { ReducedEchelonMatrix.InterchangeRow(i, j); // then interchange the two rows } } } ReducedEchelonMatrix.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrix[i, i])); for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); } for (int j = i - 1; j >= 0; j--) { ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); } } return(ReducedEchelonMatrix); } catch (Exception) { throw new MatrixException("Matrix can not be reduced to Echelon form"); } }
/// <summary> /// The function returns the inverse of the current matrix using Reduced Echelon Form method /// The function is very fast and efficient but may raise overflow exceptions in some cases. /// In such cases use the Inverse() method which computes inverse in the traditional way(using adjoint). /// </summary> public Matrix InverseFast() { if (this.DeterminentFast() == 0) { throw new MatrixException("Inverse of a singular matrix is not possible"); } try { Matrix IdentityMatrix = Matrix.IdentityMatrix(this.Rows, this.Cols); Matrix ReducedEchelonMatrix = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonMatrix[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { if (ReducedEchelonMatrix[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonMatrix.InterchangeRow(i, j); // then interchange the two rows IdentityMatrix.InterchangeRow(i, j); // then interchange the two rows } } } IdentityMatrix.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrix[i, i])); ReducedEchelonMatrix.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrix[i, i])); for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { IdentityMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); } for (int j = i - 1; j >= 0; j--) { IdentityMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); } } return(IdentityMatrix); } catch (Exception) { throw new MatrixException("Inverse of the given matrix could not be calculated"); } }
/// <summary> /// The function returns the determinent of the current Matrix object as Fraction /// It computes the determinent by reducing the matrix to reduced echelon form using row operations /// The function is very fast and efficient but may raise overflow exceptions in some cases. /// In such cases use the Determinent() function which computes determinent in the traditional /// manner(by using minors) /// </summary> public Fraction DeterminentFast() { if (this.Rows != this.Cols) { throw new MatrixException("Determinent of a non-square matrix doesn't exist"); } Fraction det = new Fraction(1); try { Matrix ReducedEchelonMatrix = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonMatrix[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { if (ReducedEchelonMatrix[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonMatrix.InterchangeRow(i, j); // then interchange the two rows det *= -1; //interchanging two rows negates the determinent } } } det *= ReducedEchelonMatrix[i, i]; ReducedEchelonMatrix.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrix[i, i])); for (int j = i + 1; j < ReducedEchelonMatrix.Rows; j++) { ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); } for (int j = i - 1; j >= 0; j--) { ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]); } } return(det); } catch (Exception) { throw new MatrixException("Determinent of the given matrix could not be calculated"); } }
/// <summary> /// Creates an inverted Fraction /// </summary> /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> public static Fraction Inverted(double value) { Fraction frac = new Fraction(value); return frac.Inverse(); }
public static Matrix operator /(Matrix matrix1, Fraction frac) { return(Matrix.Multiply(matrix1, Fraction.Inverse(frac))); }
public static Matrix operator /(Matrix matrix1, double dbl) { return(Matrix.Multiply(matrix1, Fraction.Inverse(Fraction.ToFraction(dbl)))); }
public static Matrix operator /(Matrix matrix1, int iNo) { return(Matrix.Multiply(matrix1, Fraction.Inverse(new Fraction(iNo)))); }
public static Fraction operator /(Fraction frac1, double dbl) { return(Multiply(frac1, Fraction.Inverse(Fraction.ToFraction(dbl)))); }