public MatrixClass(int[,] elements) { m_iRows = elements.GetLength(0); m_iCols = elements.GetLength(1); ; m_iElement = new Fraction[m_iRows, m_iCols]; for (int i = 0; i < elements.GetLength(0); i++) { for (int j = 0; j < elements.GetLength(1); j++) { this[i, j] = new Fraction(elements[i, j]); } } }
/// <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 function for negation /// </summary> private static Fraction Negate(Fraction frac1) { long iNumerator = -frac1.Numerator; long iDenominator = frac1.Denominator; return (new Fraction(iNumerator, iDenominator)); }
/// <summary> /// Constructors /// </summary> public MatrixClass(Fraction[,] elements) { m_iElement = elements; m_iRows = elements.GetLength(0); m_iCols = elements.GetLength(1); }
/// <summary> /// The function replicates current Fraction object /// </summary> public Fraction Duplicate() { Fraction frac = new Fraction(); frac.Numerator = Numerator; frac.Denominator = Denominator; return frac; }
private static Fraction Multiply(Fraction frac1, Fraction frac2) { try { checked { long iNumerator = frac1.Numerator * frac2.Numerator; long iDenominator = frac1.Denominator * frac2.Denominator; return (new Fraction(iNumerator, iDenominator)); } } catch (OverflowException) { throw new FractionException("Overflow occurred while performing arithemetic operation"); } catch (Exception) { throw new FractionException("An error occurred while performing arithemetic operation"); } }
/// <summary> /// The function takes a Fraction object and returns its value as double /// </summary> public static double ToDouble(Fraction frac) { return ((double)frac.Numerator / frac.Denominator); }
/// <summary> /// The function multiplies the given row of the current MatrixClass object by a Fraction /// </summary> public void MultiplyRow(int iRow, Fraction frac) { for (int j = 0; j < this.Cols; j++) { this[iRow, j] *= frac; Fraction.ReduceFraction(this[iRow, j]); } }
/// <summary> /// The function returns the inverse of a Fraction object /// </summary> public static Fraction Inverse(Fraction frac1) { if (frac1.Numerator == 0) throw new FractionException("Operation not possible (Denominator cannot be assigned a ZERO Value)"); long iNumerator = frac1.Denominator; long iDenominator = frac1.Numerator; return (new Fraction(iNumerator, iDenominator)); }
/// <summary> /// The function reduces(simplifies) a Fraction object by dividing both its numerator /// and denominator by their GCD /// </summary> public static void ReduceFraction(Fraction frac) { try { if (frac.Numerator == 0) { frac.Denominator = 1; return; } long iGCD = GCD(frac.Numerator, frac.Denominator); frac.Numerator /= iGCD; frac.Denominator /= iGCD; if (frac.Denominator < 0) // if -ve sign in denominator { //pass -ve sign to numerator frac.Numerator *= -1; frac.Denominator *= -1; } } // end try catch (Exception exp) { throw new FractionException("Cannot reduce Fraction: " + exp.Message); } }
private void SetElement(int iRow, int iCol, Fraction value) { if (iRow < 0 || iRow > Rows - 1 || iCol < 0 || iCol > Cols - 1) throw new MatrixClassException("Invalid index specified"); m_iElement[iRow, iCol] = value.Duplicate(); }
/// <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; }
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 returns a Unit MatrixClass of dimension ( Row x Col ) /// </summary> public static MatrixClass UnitMatrixClass(int iRows, int iCols) { Fraction temp = new Fraction(1); 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 takes a floating point number as an argument /// and returns its corresponding reduced fraction /// </summary> public static Fraction ToFraction(double dValue) { try { checked { Fraction frac; if (dValue % 1 == 0) // if whole number { frac = new Fraction((long)dValue); } else { double dTemp = dValue; long iMultiple = 1; string strTemp = dValue.ToString(); while (strTemp.IndexOf("E") > 0) // if in the form like 12E-9 { dTemp *= 10; iMultiple *= 10; strTemp = dTemp.ToString(); } int i = 0; while (strTemp[i] != '.') i++; int iDigitsAfterDecimal = strTemp.Length - i - 1; while (iDigitsAfterDecimal > 0) { dTemp *= 10; iMultiple *= 10; iDigitsAfterDecimal--; } frac = new Fraction((int)Math.Round(dTemp), iMultiple); } return frac; } } catch (OverflowException) { throw new FractionException("Conversion not possible due to overflow"); } catch (Exception) { throw new FractionException("Conversion not possible"); } }
/// <summary> /// The function adds two rows for current MatrixClass object /// It performs the following calculation: /// iTargetRow = iTargetRow + iMultiple*iSecondRow /// </summary> public void AddRow(int iTargetRow, int iSecondRow, Fraction iMultiple) { for (int j = 0; j < this.Cols; j++) this[iTargetRow, j] += (this[iSecondRow, j] * iMultiple); }
/// <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"); } }