public static MMatrix EchelonForm(MMatrix matrix) { try { MMatrix EchelonMatrix = new MMatrix(matrix); for (int i = 0; i < matrix.row; ++i) { /*Overcome round-off error to approximate values for (int j = 0; j < EchelonMatrix.row; ++j) for (int k = 0 ; k < EchelonMatrix.col; ++k) if (Math.Abs(EchelonMatrix[j, k]) <= ZERO) EchelonMatrix[j, k] = 0; */ if (i < EchelonMatrix.col) { if (EchelonMatrix[i, i] == 0) // if diagonal entry is zero, for (int j = i + 1; j < EchelonMatrix.row; ++j) if (EchelonMatrix[j, i] != 0) //check if some below entry is non-zero EchelonMatrix.InterchangeRow(i, j); // then interchange the two rows if (EchelonMatrix[i, i] == 0) // if not found any non-zero diagonal entry continue; // increment i; if (EchelonMatrix[i, i] != 1) // if diagonal entry is not 1 , for (int j = i + 1; j < EchelonMatrix.row; ++j) if (EchelonMatrix[j, i] == 1) //check if some below entry is 1 EchelonMatrix.InterchangeRow(i, j); // then interchange the two rows EchelonMatrix.MultiplyRow(i, 1 / (EchelonMatrix[i, i])); for (int j = i + 1; j < EchelonMatrix.row; ++j) EchelonMatrix.AddRow(j, i, -EchelonMatrix[j, i]); } } return EchelonMatrix; } catch (Exception) { throw new MMatrixException("MMatrix can not be reduced to Echelon form"); } }
public static MMatrix ReducedEchelonForm(MMatrix matrix) { try { MMatrix ReducedEchelonMatrix = new MMatrix(matrix); for (int i = 0; i < matrix.row; ++i) { if (i < ReducedEchelonMatrix.col) { if (ReducedEchelonMatrix[i, i] == 0) // if diagonal entry is zero, for (int j = i + 1; j < ReducedEchelonMatrix.row; ++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.row; ++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, 1 / (ReducedEchelonMatrix[i, i])); for (int j = i + 1; j < ReducedEchelonMatrix.row; ++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 MMatrixException("MMatrix can not be reduced to Echelon form"); } }
//Solve A*x = b //After solving the system, Argument Matrix will contain the reduced system public static Vector SolveSystemOfEquations(MMatrix CoefficientMatrix, Vector b,ref MMatrix ArgumentMatrix, ref bool InfiniteSolution) { if (CoefficientMatrix.row != b.Elements.Length) throw new MMatrixException("The coefficient matrix A and vector b are different size."); Vector x = new Vector(CoefficientMatrix.col); Vector xSetFlag = new Vector(CoefficientMatrix.col); double sum; InfiniteSolution = false; ArgumentMatrix = CalculateArgumentMatrix(CoefficientMatrix,b); try { //Gaussian elimination for (int i = 0; i < CoefficientMatrix.row; ++i) { if (i < ArgumentMatrix.col - 1) { if (ArgumentMatrix[i, i] == 0) // if diagonal entry is zero, for (int j = i + 1; j < ArgumentMatrix.row; ++j) if (ArgumentMatrix[j, i] != 0) //check if some below entry is non-zero ArgumentMatrix.InterchangeRow(i, j); // then interchange the two rows if (ArgumentMatrix[i, i] == 0) // if not found any non-zero diagonal entry continue; // increment i; if (ArgumentMatrix[i, i] != 1) // if diagonal entry is not 1 , for (int j = i + 1; j < ArgumentMatrix.row; ++j) if (ArgumentMatrix[j, i] == 1) //check if some below entry is 1 ArgumentMatrix.InterchangeRow(i, j); // then interchange the two rows ArgumentMatrix.MultiplyRow(i, 1 / (ArgumentMatrix[i, i])); for (int j = i + 1; j < ArgumentMatrix.row; ++j) ArgumentMatrix.AddRow(j, i, -ArgumentMatrix[j, i]); } } //Finding solution based on the reduced system == Argument matrix //More equations than unknown varriables x[i] if (CoefficientMatrix.row > CoefficientMatrix.col) for (int i = CoefficientMatrix.col; i < CoefficientMatrix.row; ++i) { if (ArgumentMatrix[i, CoefficientMatrix.col - 1] == 0) if (ArgumentMatrix[i, ArgumentMatrix.col - 1] != 0) //b[i] == 0 return null; } for (int i = Math.Min(CoefficientMatrix.row, CoefficientMatrix.col) - 1; i >= 0; i--) { //The system has more than one solutions. Get one. if (ArgumentMatrix[i, i] == 0) { //More unknowns than equations int j; for (j = i+1; j < CoefficientMatrix.col; ++j) { if (ArgumentMatrix[i, j] != 0) { sum = 0; for (int k = j + 1; k < CoefficientMatrix.col; ++k) { sum += ArgumentMatrix[i, k] * x[k]; } if (xSetFlag[j] == 0) { //this is the 1st time setting the solution x[j] = (ArgumentMatrix[i, ArgumentMatrix.col - 1] - sum) / ArgumentMatrix[i, j]; xSetFlag[j] = 1; } //this is not the 1st time setting the solution else if (x[j] != (ArgumentMatrix[i, ArgumentMatrix.col - 1] - sum) / CoefficientMatrix[i, j]) { return null; } else InfiniteSolution = true; break; } } //All coefficient == 0 & b[i] == 0 -> The system has infinitely many solutions if ((j == CoefficientMatrix.col) && (ArgumentMatrix[i, ArgumentMatrix.col - 1] == 0)) { x[i] = 0; //xSetFlag[i] = 1;-> since we may use other equations to update this x[i] later, so don't set flag for case 0 = 0. InfiniteSolution = true; } else if ((j == CoefficientMatrix.col) && (ArgumentMatrix[i, ArgumentMatrix.col - 1] != 0)) return null; //All coefficient == 0 & b[i] != 0 -> The system has no solutions } else { sum = 0; for (int j = i + 1; j < CoefficientMatrix.col; ++j) { sum += ArgumentMatrix[i, j] * x[j]; } x[i] = (ArgumentMatrix[i, ArgumentMatrix.col - 1] - sum) / ArgumentMatrix[i, i]; xSetFlag[i] = 1; } } return x; } catch (Exception exp) { throw new MMatrixException("The system of equation cannot be solved:" + exp.Message); } }