/// <summary> /// The function returns the reduced echelon form of the current SimpleMatrix /// </summary> public SimpleMatrix ReducedEchelonForm() { try { SimpleMatrix ReducedEchelonSimpleMatrix = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonSimpleMatrix[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { if (ReducedEchelonSimpleMatrix[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonSimpleMatrix.InterchangeRow(i, j); // then interchange the two rows } } } if (ReducedEchelonSimpleMatrix[i, i] == 0) // if not found any non-zero diagonal entry { continue; // increment i; } if (ReducedEchelonSimpleMatrix[i, i] != 1) // if diagonal entry is not 1 , { for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { if (ReducedEchelonSimpleMatrix[j, i] == 1) //check if some below entry is 1 { ReducedEchelonSimpleMatrix.InterchangeRow(i, j); // then interchange the two rows } } } ReducedEchelonSimpleMatrix.MultiplyRow(i, (double)(1.0 / (ReducedEchelonSimpleMatrix[i, i]))); for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { ReducedEchelonSimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); } for (int j = i - 1; j >= 0; j--) { ReducedEchelonSimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); } } return(ReducedEchelonSimpleMatrix); } catch (Exception) { throw new SimpleMatrixException("SimpleMatrix can not be reduced to Echelon form"); } }
/// <summary> /// The function returns the inverse of the current SimpleMatrix 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 SimpleMatrix InverseFast() { if (this.DeterminentFast() == 0) { throw new SimpleMatrixException("Inverse of a singular SimpleMatrix is not possible"); } try { SimpleMatrix IdentitySimpleMatrix = SimpleMatrix.IdentitySimpleMatrix(this.Rows, this.Cols); SimpleMatrix ReducedEchelonSimpleMatrix = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonSimpleMatrix[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { if (ReducedEchelonSimpleMatrix[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonSimpleMatrix.InterchangeRow(i, j); // then interchange the two rows IdentitySimpleMatrix.InterchangeRow(i, j); // then interchange the two rows } } } IdentitySimpleMatrix.MultiplyRow(i, (double)(1.0 / (ReducedEchelonSimpleMatrix[i, i]))); ReducedEchelonSimpleMatrix.MultiplyRow(i, (double)(1.0 / (ReducedEchelonSimpleMatrix[i, i]))); for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { IdentitySimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); ReducedEchelonSimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); } for (int j = i - 1; j >= 0; j--) { IdentitySimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); ReducedEchelonSimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); } } return(IdentitySimpleMatrix); } catch (Exception) { throw new SimpleMatrixException("Inverse of the given SimpleMatrix could not be calculated"); } }
/// <summary> /// The function returns the determinent of the current SimpleMatrix object as double /// It computes the determinent by reducing the SimpleMatrix 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 double DeterminentFast() { if (this.Rows != this.Cols) { throw new SimpleMatrixException("Determinent of a non-square SimpleMatrix doesn't exist"); } double det = 1; try { SimpleMatrix ReducedEchelonSimpleMatrix = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonSimpleMatrix[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { if (ReducedEchelonSimpleMatrix[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonSimpleMatrix.InterchangeRow(i, j); // then interchange the two rows det *= -1; //interchanging two rows negates the determinent } } } det *= ReducedEchelonSimpleMatrix[i, i]; ReducedEchelonSimpleMatrix.MultiplyRow(i, (double)(1.0 / (ReducedEchelonSimpleMatrix[i, i]))); for (int j = i + 1; j < ReducedEchelonSimpleMatrix.Rows; j++) { ReducedEchelonSimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); } for (int j = i - 1; j >= 0; j--) { ReducedEchelonSimpleMatrix.AddRow(j, i, -ReducedEchelonSimpleMatrix[j, i]); } } return(det); } catch (Exception) { throw new SimpleMatrixException("Determinent of the given SimpleMatrix could not be calculated"); } }