예제 #1
0
 /// <summary>
 /// Kopierkonstruktor
 /// </summary>
 /// <param name="other">Original</param>
 internal MatrixEx(MatrixEx other)
 {
     this._components = new Fraction[other.Rows][];
     for (int i = 0; i < other.Rows; i++)
     {
         this._components[i] = new Fraction[other.Columns];
         for (int j = 0; j < other.Columns; j++)
         {
             this._components[i][j] = new Fraction(other._components[i][j]);
         }
     }
 }
예제 #2
0
        private static bool SolveFromPivot(ref MatrixEx matrix, uint row, uint col)
        {
            bool result = true;

            //int max = 0;
            //if rad_equation.Checked then max := edt_Dimension.Value else if rad_inverse.Checked then max := edt_Dimension.Value*2-1;

            //Pivotelement ist Null - tausche Pivotzeile mit anderer Zeile
            if (matrix[row, col].Numerator == 0)
            {
                bool valid = false;
                //gültige Zeile ohne Null suchen
                for (uint i = row + 1; i < matrix.Rows; i++)
                {
                    if (matrix[i, col].Numerator != 0)
                    {
                        valid = true;
                        //Zeilenelemente tauschen
                        for (uint j = 0; j < /*max*/ matrix.Columns; j++)
                        {
                            Fraction h = matrix[row, j];
                            matrix[row, j] = matrix[i, j];
                            matrix[i, j]   = h;
                        }
                        break;
                    }
                }
                result = valid;
            }
            // Erzeugen von Nullen unterhalb des Pivotelements
            if (result)
            {
                for (uint i = row + 1; i < matrix.Rows; i++)
                {
                    if (matrix[i, col].Numerator != 0)
                    {
                        // Zeilenmodifikator bestimmen
                        Fraction mul = matrix[i, col] / matrix[row, col] * -1;
                        for (uint j = col; j < /*col*/ matrix.Columns; j++)
                        {
                            matrix[i, j] = matrix[row, j] * mul + matrix[i, j];
                        }
                    }
                }
            }
            // Mit nächster Spalte weitermachen
            if (row + 1 < matrix.Rows - 1 && result)
            {
                result = SolveFromPivot(ref matrix, row + 1, col + 1);
            }
            return(result);
        }
예제 #3
0
        /// <summary>
        /// Transponierte Matrix
        /// </summary>
        /// <returns>Transponierte Matrix</returns>
        public MatrixEx Transpone()
        {
            MatrixEx trans = new MatrixEx(this.Columns, this.Rows);

            for (int i = 0; i < this.Rows; i++)
            {
                for (int j = 0; j < this.Columns; j++)
                {
                    trans._components[j][i] = this._components[i][j];
                }
            }
            return(trans);
        }
예제 #4
0
        /// <summary>
        /// Division durch Skalar
        /// </summary>
        /// <param name="v"></param>
        /// <param name="skalar"></param>
        /// <returns></returns>
        public static MatrixEx operator /(MatrixEx m, Fraction skalar)
        {
            MatrixEx matrix = new MatrixEx(m);

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    matrix._components[i][j] /= skalar;
                }
            }
            return(matrix);
        }
예제 #5
0
 private static Fraction CalcDeterminant(MatrixEx matrix)
 {
     if (matrix.Rows != matrix.Columns)
     {
         //Determinante nur für quadr. Matrizen
         throw new NotSupportedException("Determinant only applicable to quadratic matrices.");
     }
     if (matrix.Columns == 2)
     {
         return(matrix[0, 0] * matrix[1, 1] - matrix[1, 0] * matrix[0, 1]);
     }
     else
     {
         Fraction sum = new Fraction(0);
         //Laplace'scher Entwicklungssatz
         for (uint i = 0; i < matrix.Columns; i++)
         {
             //Matrix nach Spalte i entwickeln
             MatrixEx eMat = new MatrixEx(matrix.Rows - 1, matrix.Columns - 1);
             for (uint m = 1; m < matrix.Rows; m++)
             {
                 for (uint n = 0; n < matrix.Columns; n++)
                 {
                     if (n < i)
                     {
                         eMat[m - 1, n] = new Fraction(matrix[m, n]);
                     }
                     else if (n > i)
                     {
                         eMat[m - 1, n - 1] = new Fraction(matrix[m, n]);
                     }
                 }
             }
             //rekursiver Aufruf
             if (matrix[0, i].Numerator != 0)
             {
                 Fraction det = matrix[0, i] * CalcDeterminant(eMat);
                 // odd(i)
                 if (i % 2 != 0)
                 {
                     sum -= det;
                 }
                 else
                 {
                     sum += det;
                 }
             }
         }
         return(sum);
     }
 }
예제 #6
0
        private static bool ReverseSolveFromPivot(ref MatrixEx matrix, uint row, uint col)
        {
            bool result = true;

            //max := 0;
            //if rad_equation.Checked then max := edt_Dimension.Value else if rad_inverse.Checked then max := edt_Dimension.Value*2-1;

            //Pivotelement ist nicht Eins - gesamte Zeile dividieren
            if (matrix[row, col].Equals(1) == false)
            {
                Fraction h = new Fraction(matrix[row, col]);
                for (uint j = /*max*/ matrix.Columns - 1; j >= 0; j--)
                {
                    matrix[row, j] /= h;
                    if (j == 0)
                    {
                        break;
                    }
                }
            }
            // Erzeugen von Nullen überhalb des Pivotelements
            if (row > 0)
            {
                for (uint i = row - 1; ; i--)
                {
                    // Zeilenmodifikator bestimmen
                    //mul := Matrix.Element[i,Col]/Matrix.Element[Row,Col]*-1;
                    Fraction mul = new Fraction(matrix[i, col]) / matrix[row, col] * -1;
                    for (uint j = matrix.Columns - 1; ; j--)
                    {
                        //Matrix.Element[i,j] := mul*Matrix.Element[Row,j]+Matrix.Element[i,j];
                        Fraction h = new Fraction(matrix[row, j]) * mul + matrix[i, j];
                        matrix[i, j] = h;
                        if (j == 0)
                        {
                            break;
                        }
                    }
                    if (i == 0)
                    {
                        break;
                    }
                }
            }
            // Mit kleinerer Matrix fortsetzen
            if (row > 0 && result)
            {
                result = ReverseSolveFromPivot(ref matrix, row - 1, col - 1);
            }
            return(result);
        }
예제 #7
0
        /// <summary>
        /// Invertiert eine Matrix
        /// </summary>
        /// <param name="A">Zu intertierende Matrix</param>
        /// <returns>Inverse Matrix 1/A</returns>
        public static Matrix InvertMatrix(Matrix A)
        {
            if (A == null)
            {
                throw new ArgumentNullException("Matrix must not be null.");
            }
            if (A.Rows != A.Columns)
            {
                throw new NotSupportedException("Only quadratic matrices are invertable.");
            }
            //erweiterte Matrix erzeugen
            MatrixEx enhMat = new MatrixEx(A.Rows, A.Columns * 2);

            for (uint i = 0; i < A.Rows; i++)
            {
                for (uint j = 0; j < A.Columns; j++)
                {
                    enhMat[i, j] = new Fraction(A[i, j]);
                    if (i == j)
                    {
                        enhMat[i, j + A.Columns] = new Fraction(1);
                    }
                    else
                    {
                        enhMat[i, j + A.Columns] = new Fraction(0);
                    }
                }
            }
            if (SolveFromPivot(ref enhMat, 0, 0))
            {
                //Rang der Matrix prüfen (wenn kleiner Rows -> nicht eindeutig lösbar)
                if (Rank(enhMat, A.Rows, A.Columns) != A.Rows)
                {
                    return(null);
                }
                ReverseSolveFromPivot(ref enhMat, A.Rows - 1, A.Columns - 1);
            }
            //Ergebnis aus erw. Matrix lesen
            Matrix result = new Matrix(A.Rows, A.Columns);

            for (uint i = 0; i < A.Rows; i++)
            {
                for (uint j = 0; j < A.Columns; j++)
                {
                    result[i, j] = enhMat[i, j + A.Columns].Value;
                }
            }
            return(result);
        }
예제 #8
0
        /// <summary>
        /// Addition
        /// </summary>
        /// <param name="m1"></param>
        /// <param name="m2"></param>
        /// <returns></returns>
        public static MatrixEx operator +(MatrixEx m1, MatrixEx m2)
        {
            if (m1.Columns != m2.Columns ||
                m1.Rows != m2.Rows)
            {
                throw new ArgumentException("Dimensions of matrices do not match.");
            }
            MatrixEx matrix = new MatrixEx(m1);

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    matrix._components[i][j] += m2._components[i][j];
                }
            }
            return(matrix);
        }
예제 #9
0
        private static uint Rank(MatrixEx enhMat, uint rows, uint columns)
        {
            uint     count = 0;
            Fraction rowsum;

            for (uint i = 0; i < rows; i++)
            {
                rowsum = new Fraction(0);
                for (uint j = 0; j < columns; j++)
                {
                    rowsum += enhMat[i, j];
                }
                if (rowsum.Numerator != 0)
                {
                    count++;
                }
            }
            return(count);
        }
예제 #10
0
        /// <summary>
        /// Multiplikation
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        public static MatrixEx operator *(MatrixEx m1, MatrixEx m2)
        {
            if (m1.Columns != m2.Rows)
            {
                throw new ArgumentException("Inner dimensions of matrices need to match.");
            }
            MatrixEx matrix = new MatrixEx(m1.Rows, m2.Columns);

            for (uint i = 0; i < matrix.Rows; i++)
            {
                for (uint j = 0; j < matrix.Columns; j++)
                {
                    Fraction sum = new Fraction(0);
                    for (uint k = 0; k < m1.Columns; k++)
                    {
                        sum += m1[i, k] * m2[k, j];
                    }
                    matrix._components[i][j] = sum;
                }
            }
            return(matrix);
        }
예제 #11
0
        /// <summary>
        /// Löst ein Gleichungssystem "A*x=b" und gibt den Lösungsvektor x zurück.
        /// </summary>
        /// <param name="A">Matrix A</param>
        /// <param name="b">Vektor b</param>
        /// <returns>Lösungsvektor x</returns>
        public static Vector SolveEquation(Matrix A, Vector b)
        {
            if (A == null || b == null)
            {
                throw new ArgumentNullException("Parameters must not be null.");
            }
            if (A.Rows != b.Dimensions)
            {
                throw new NotSupportedException("Dimensions of matrix and vector do not match.");
            }
            //erweiterte Matrix erzeugen
            MatrixEx enhMat = new MatrixEx(A.Rows, A.Columns + 1);

            for (uint i = 0; i < A.Rows; i++)
            {
                for (uint j = 0; j < A.Columns; j++)
                {
                    enhMat[i, j] = new Fraction(A[i, j]);
                }
                enhMat[i, A.Columns] = new Fraction(b[i]);
            }
            if (SolveFromPivot(ref enhMat, 0, 0))
            {
                //Rang der Matrix prüfen (wenn kleiner Rows -> nicht eindeutig lösbar)
                if (Rank(enhMat, A.Rows, A.Columns) != A.Rows)
                {
                    return(null);
                }
                ReverseSolveFromPivot(ref enhMat, A.Rows - 1, A.Columns - 1);
            }
            //Ergebnis aus erw. Matrix lesen
            Vector result = new Vector(b.Dimensions);

            for (uint i = 0; i < A.Rows; i++)
            {
                result[i] = enhMat[i, A.Columns].Value;
            }
            return(result);
        }
예제 #12
0
        public override bool Equals(object other)
        {
            if (other is MatrixEx == false)
            {
                return(false);
            }
            MatrixEx oMatrix = (MatrixEx)other;
            bool     equal   = this.Columns == oMatrix.Columns;

            equal &= this.Rows == oMatrix.Rows;
            if (!equal)
            {
                return(false);
            }
            for (int i = 0; i < oMatrix.Rows; i++)
            {
                for (int j = 0; j < oMatrix.Columns; j++)
                {
                    equal &= this._components[i][j] == oMatrix._components[i][j];
                }
            }
            return(equal);
        }