/// <summary> /// The function concatenates the two given matrices column-wise /// it can be helpful in a equation solver class where the augmented MatrixClass is obtained by concatenation /// </summary> public static MatrixClass Concatenate(MatrixClass MatrixClass1, MatrixClass MatrixClass2) { if (MatrixClass1.Rows != MatrixClass2.Rows) { throw new MatrixClassException("Concatenation not possible"); } MatrixClass MatrixClass = new MatrixClass(MatrixClass1.Rows, MatrixClass1.Cols + MatrixClass2.Cols); for (int i = 0; i < MatrixClass.Rows; i++) { for (int j = 0; j < MatrixClass.Cols; j++) { if (j < MatrixClass1.Cols) { MatrixClass[i, j] = MatrixClass1[i, j]; } else { MatrixClass[i, j] = MatrixClass2[i, j - MatrixClass1.Cols]; } } } return(MatrixClass); }
/// <summary> /// The function return the Minor of element[Row,Col] of a MatrixClass object /// </summary> public static MatrixClass Minor(MatrixClass MatrixClass, int iRow, int iCol) { MatrixClass minor = new MatrixClass(MatrixClass.Rows - 1, MatrixClass.Cols - 1); int m = 0, n = 0; for (int i = 0; i < MatrixClass.Rows; i++) { if (i == iRow) { continue; } n = 0; for (int j = 0; j < MatrixClass.Cols; j++) { if (j == iCol) { continue; } minor[m, n] = MatrixClass[i, j]; n++; } m++; } return(minor); }
private static MatrixClass Multiply(MatrixClass MatrixClass, Fraction frac) { MatrixClass result = new MatrixClass(MatrixClass.Rows, MatrixClass.Cols); for (int i = 0; i < MatrixClass.Rows; i++) { for (int j = 0; j < MatrixClass.Cols; j++) { result[i, j] = MatrixClass[i, j] * frac; } } return(result); }
/// <summary> /// The function duplicates the current MatrixClass object /// </summary> public MatrixClass Duplicate() { MatrixClass MatrixClass = new MatrixClass(Rows, Cols); for (int i = 0; i < Rows; i++) { for (int j = 0; j < Cols; j++) { MatrixClass[i, j] = this[i, j]; } } return(MatrixClass); }
/// <summary> /// The function returns the transpose of the current MatrixClass /// </summary> public MatrixClass Transpose() { MatrixClass TransposeMatrixClass = new MatrixClass(this.Cols, this.Rows); for (int i = 0; i < TransposeMatrixClass.Rows; i++) { for (int j = 0; j < TransposeMatrixClass.Cols; j++) { TransposeMatrixClass[i, j] = this[j, i]; } } return(TransposeMatrixClass); }
/// <summary> /// The function returns a Null MatrixClass of dimension ( Row x Col ) /// </summary> public static MatrixClass NullMatrixClass(int iRows, int iCols) { Fraction temp = new Fraction(0); MatrixClass MatrixClass = new MatrixClass(iRows, iCols); for (int i = 0; i < iRows; i++) { for (int j = 0; j < iCols; j++) { MatrixClass[i, j] = temp; } } return(MatrixClass); }
/// <summary> /// The function returns the adjoint of the current MatrixClass /// </summary> public MatrixClass Adjoint(int b) { if (this.Rows != this.Cols) { throw new MatrixClassException("Adjoint of a non-square MatrixClass does not exists"); } MatrixClass AdjointMatrixClass = new MatrixClass(this.Rows, this.Cols); for (int i = 0; i < this.Rows; i++) { for (int j = 0; j < this.Cols; j++) { AdjointMatrixClass[i, j] = b * Math.Pow(-1, i + j) * (Minor(this, j, i).Determinent()); } } return(AdjointMatrixClass); }
/// <summary> /// The function returns the reduced echelon form of the current MatrixClass /// </summary> public MatrixClass ReducedEchelonForm() { try { MatrixClass ReducedEchelonMatrixClass = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonMatrixClass[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { if (ReducedEchelonMatrixClass[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonMatrixClass.InterchangeRow(i, j); // then interchange the two rows } } } if (ReducedEchelonMatrixClass[i, i] == 0) // if not found any non-zero diagonal entry { continue; // increment i; } if (ReducedEchelonMatrixClass[i, i] != 1) // if diagonal entry is not 1 , { for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { if (ReducedEchelonMatrixClass[j, i] == 1) //check if some below entry is 1 { ReducedEchelonMatrixClass.InterchangeRow(i, j); // then interchange the two rows } } } ReducedEchelonMatrixClass.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrixClass[i, i])); for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { ReducedEchelonMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); } for (int j = i - 1; j >= 0; j--) { ReducedEchelonMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); } } return(ReducedEchelonMatrixClass); } catch (Exception) { throw new MatrixClassException("MatrixClass can not be reduced to Echelon form"); } }
private static MatrixClass Add(MatrixClass MatrixClass1, MatrixClass MatrixClass2) { if (MatrixClass1.Rows != MatrixClass2.Rows || MatrixClass1.Cols != MatrixClass2.Cols) { throw new MatrixClassException("Operation not possible"); } MatrixClass result = new MatrixClass(MatrixClass1.Rows, MatrixClass1.Cols); for (int i = 0; i < result.Rows; i++) { for (int j = 0; j < result.Cols; j++) { result[i, j] = MatrixClass1[i, j] + MatrixClass2[i, j]; } } return(result); }
/// <summary> /// The helper function for the above Determinent() method /// it calls itself recursively and computes determinent using minors /// </summary> private Fraction Determinent(MatrixClass MatrixClass) { Fraction det = new Fraction(0); if (MatrixClass.Rows != MatrixClass.Cols) { throw new MatrixClassException("Determinent of a non-square MatrixClass doesn't exist"); } if (MatrixClass.Rows == 1) { return(MatrixClass[0, 0]); } for (int j = 0; j < MatrixClass.Cols; j++) { det += (MatrixClass[0, j] * Determinent(MatrixClass.Minor(MatrixClass, 0, j)) * (int)System.Math.Pow(-1, 0 + j)); } return(det); }
/// <summary> /// The function returns the inverse of the current MatrixClass 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 MatrixClass InverseFast() { if (this.DeterminentFast() == 0) { throw new MatrixClassException("Inverse of a singular MatrixClass is not possible"); } try { MatrixClass IdentityMatrixClass = MatrixClass.IdentityMatrixClass(this.Rows, this.Cols); MatrixClass ReducedEchelonMatrixClass = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonMatrixClass[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { if (ReducedEchelonMatrixClass[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonMatrixClass.InterchangeRow(i, j); // then interchange the two rows IdentityMatrixClass.InterchangeRow(i, j); // then interchange the two rows } } } IdentityMatrixClass.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrixClass[i, i])); ReducedEchelonMatrixClass.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrixClass[i, i])); for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { IdentityMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); ReducedEchelonMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); } for (int j = i - 1; j >= 0; j--) { IdentityMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); ReducedEchelonMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); } } return(IdentityMatrixClass); } catch (Exception) { throw new MatrixClassException("Inverse of the given MatrixClass could not be calculated"); } }
/// <summary> /// The function returns the determinent of the current MatrixClass object as Fraction /// It computes the determinent by reducing the MatrixClass 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 MatrixClassException("Determinent of a non-square MatrixClass doesn't exist"); } Fraction det = new Fraction(1); try { MatrixClass ReducedEchelonMatrixClass = this.Duplicate(); for (int i = 0; i < this.Rows; i++) { if (ReducedEchelonMatrixClass[i, i] == 0) // if diagonal entry is zero, { for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { if (ReducedEchelonMatrixClass[j, i] != 0) //check if some below entry is non-zero { ReducedEchelonMatrixClass.InterchangeRow(i, j); // then interchange the two rows det *= -1; //interchanging two rows negates the determinent } } } det *= ReducedEchelonMatrixClass[i, i]; ReducedEchelonMatrixClass.MultiplyRow(i, Fraction.Inverse(ReducedEchelonMatrixClass[i, i])); for (int j = i + 1; j < ReducedEchelonMatrixClass.Rows; j++) { ReducedEchelonMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); } for (int j = i - 1; j >= 0; j--) { ReducedEchelonMatrixClass.AddRow(j, i, -ReducedEchelonMatrixClass[j, i]); } } return(det); } catch (Exception) { throw new MatrixClassException("Determinent of the given MatrixClass could not be calculated"); } }
private static MatrixClass Multiply(MatrixClass MatrixClass1, MatrixClass MatrixClass2) { if (MatrixClass1.Cols != MatrixClass2.Rows) { throw new MatrixClassException("Operation not possible"); } MatrixClass result = MatrixClass.NullMatrixClass(MatrixClass1.Rows, MatrixClass2.Cols); for (int i = 0; i < result.Rows; i++) { for (int j = 0; j < result.Cols; j++) { for (int k = 0; k < MatrixClass1.Cols; k++) { result[i, j] += MatrixClass1[i, k] * MatrixClass2[k, j]; } } } return(result); }
/// <summary> /// The function returns a Scalar MatrixClass of dimension ( Row x Col ) and scalar K /// </summary> public static MatrixClass ScalarMatrixClass(int iRows, int iCols, int K) { Fraction zero = new Fraction(0); Fraction scalar = new Fraction(K); MatrixClass MatrixClass = new MatrixClass(iRows, iCols); for (int i = 0; i < iRows; i++) { for (int j = 0; j < iCols; j++) { if (i == j) { MatrixClass[i, j] = scalar; } else { MatrixClass[i, j] = zero; } } } return(MatrixClass); }
/// <summary> /// Internal Fucntions for the above operators /// </summary> private static MatrixClass Negate(MatrixClass MatrixClass) { return(MatrixClass.Multiply(MatrixClass, -1)); }
public static MatrixClass operator /(MatrixClass MatrixClass1, Fraction frac) { return(MatrixClass.Multiply(MatrixClass1, Fraction.Inverse(frac))); }
public static MatrixClass operator /(MatrixClass MatrixClass1, double dbl) { return(MatrixClass.Multiply(MatrixClass1, Fraction.Inverse(Fraction.ToFraction(dbl)))); }
public static MatrixClass operator /(MatrixClass MatrixClass1, int iNo) { return(MatrixClass.Multiply(MatrixClass1, Fraction.Inverse(new Fraction(iNo)))); }
public static MatrixClass operator *(Fraction frac, MatrixClass MatrixClass1) { return(MatrixClass.Multiply(MatrixClass1, frac)); }
public static MatrixClass operator *(double dbl, MatrixClass MatrixClass1) { return(MatrixClass.Multiply(MatrixClass1, Fraction.ToFraction(dbl))); }
public static MatrixClass operator *(int iNo, MatrixClass MatrixClass1) { return(MatrixClass.Multiply(MatrixClass1, iNo)); }
/// <summary> /// Operators for the MatrixClass object /// includes -(unary), and binary opertors such as +,-,*,/ /// </summary> public static MatrixClass operator -(MatrixClass MatrixClass) { return(MatrixClass.Negate(MatrixClass)); }
public static MatrixClass operator -(MatrixClass MatrixClass1, MatrixClass MatrixClass2) { return(MatrixClass.Add(MatrixClass1, -MatrixClass2)); }
public static MatrixClass operator *(MatrixClass MatrixClass1, MatrixClass MatrixClass2) { return(MatrixClass.Multiply(MatrixClass1, MatrixClass2)); }