Example #1
0
        /// <summary>
        /// Method is used to get a minor of the matrix.
        /// </summary>
        /// <param name="matrix">initial matrix.</param>
        /// <param name="rowIndex">Row index to exclude.</param>
        /// <param name="columnIndex">Column index to exclude</param>
        /// <returns></returns>
        public static MatrixT <T> GetMinor(MatrixT <T> matrix, int rowIndex, int columnIndex)
        {
            MatrixT <T> result = new MatrixT <T>(matrix.Rows - 1, matrix.Columns - 1);

            int ki = 0;

            for (int i = 0; i < matrix.Rows; i++)
            {
                if (i != rowIndex)
                {
                    for (int j = 0, kj = 0; j < matrix.Columns; j++)
                    {
                        if (j != columnIndex)
                        {
                            result[ki, kj] = matrix[i, j];
                            kj++;
                        }
                    }

                    ki++;
                }
            }

            return(result);
        }
Example #2
0
        private void SortRows(MatrixT <double> matrix, ref double[] rightPart, int sortIndex)
        {
            double maxElement      = matrix[sortIndex, sortIndex];
            int    maxElementIndex = sortIndex;

            for (int i = sortIndex + 1; i < this.Matrix.Rows; i++)
            {
                if (matrix[i, sortIndex] > maxElement)
                {
                    maxElement      = matrix[i, sortIndex];
                    maxElementIndex = i;
                }
            }

            if (maxElement > sortIndex)
            {
                double temp;

                temp = rightPart[maxElementIndex];
                rightPart[maxElementIndex] = rightPart[sortIndex];
                rightPart[sortIndex]       = temp;

                for (int i = 0; i < this.Matrix.Columns; i++)
                {
                    temp = matrix[maxElementIndex, i];
                    matrix[maxElementIndex, i] = matrix[sortIndex, i];
                    matrix[sortIndex, i]       = temp;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Summarizing operator overloading.
        /// </summary>
        /// <param name="A">Left operand.</param>
        /// <param name="B">Right operand.</param>
        /// <returns>The result of summarizing operator.</returns>
        public static MatrixT <T> operator +(MatrixT <T> A, MatrixT <T> B)
        {
            if (Paral)
            {
                MatrixT <T> ans = new MatrixT <T>(new T[A.Elements.GetLength(0), A.Elements.GetLength(1)]);
                Parallel.For(0, A.Elements.GetLength(0), (i) =>
                {
                    for (int j = 0; j < A.Elements.GetLength(1); j++)
                    {
                        ans.Elements[i, j] = (dynamic)(A.Elements[i, j]) + (dynamic)(B.Elements[i, j]);
                    }
                });

                return(ans);
            }
            else
            {
                MatrixT <T> ans = new MatrixT <T>(new T[A.Elements.GetLength(0), A.Elements.GetLength(1)]);
                for (int i = 0; i < A.Elements.GetLength(0); i++)
                {
                    for (int j = 0; j < A.Elements.GetLength(1); j++)
                    {
                        ans.Elements[i, j] = (dynamic)(A.Elements[i, j]) + (dynamic)(B.Elements[i, j]);
                    }
                }

                return(ans);
            }
        }
Example #4
0
        /// <summary>
        /// Method is used to get a determinant of the required matrix.
        /// </summary>
        /// <param name="matrix">Initial matrix to get determinant.</param>
        /// <returns>Matrix determinant.</returns>
        public static double GetMatrixDeterminant(MatrixT <T> matrix)
        {
            if (matrix.Elements.Length == 1)
            {
                return((dynamic)matrix[0, 0]);
            }

            if (matrix.Elements.Length == 4)
            {
                return((dynamic)matrix[0, 0] * (dynamic)matrix[1, 1] - (dynamic)matrix[0, 1] * (dynamic)matrix[1, 0]);
            }

            double sign   = 1;
            double result = 0;

            for (int i = 0; i < matrix.Elements.GetLength(1); i++)
            {
                T[,] minor = MatrixT <T> .GetMinor(matrix.Elements, i);

                result += sign * (dynamic)matrix[0, i] * GetMatrixDeterminant(new MatrixT <T>(minor));

                sign = -sign;
            }

            return(result);
        }
        private LAEAnswer CalculateKramerMethodAsync(out List <LAEVariable> lAEVariables)
        {
            bool systemCompatible = this.CheckLinearAlgebraicEquationSystemCompatibility();

            if (!systemCompatible)
            {
                lAEVariables = null;
                return(LAEAnswer.NoSolutions);
            }

            double matrixDeterminant = MatrixT <double> .GetMatrixDeterminant(this.Matrix);

            ConcurrentBag <LAEVariable> result = new ConcurrentBag <LAEVariable>();

            Parallel.For(0, this.Matrix.Columns, (i) =>
            {
                MatrixT <double> currentMatrix = MatrixT <double> .SubstituteMatrixColumn(this.Matrix, i, this.RightPartEquations);
                double currentDeterminant      = MatrixT <double> .GetMatrixDeterminant(currentMatrix);

                result.Add(new LAEVariable(this.Variables[i].Name, currentDeterminant / matrixDeterminant));
            });

            lAEVariables = result.Cast <LAEVariable>().ToList();
            return(LAEAnswer.OneSolution);
        }
Example #6
0
        /// <summary>
        /// Method is used to get matrix rang.
        /// </summary>
        /// <param name="matrix">Initial matrix to get its rang.</param>
        /// <returns>Matrix rang.</returns>
        public static int GetRang(MatrixT <T> matrix)
        {
            int rank = 0;
            int q    = 1;

            while (q <= MatrixT <int> .GetMinValue(matrix.Elements.GetLength(0), matrix.Elements.GetLength(1)))
            {
                MatrixT <T> matbv = new MatrixT <T>(q, q);

                for (int i = 0; i < (matrix.Elements.GetLength(0) - (q - 1)); i++)
                {
                    for (int j = 0; j < (matrix.Elements.GetLength(1) - (q - 1)); j++)
                    {
                        for (int k = 0; k < q; k++)
                        {
                            for (int c = 0; c < q; c++)
                            {
                                matbv[k, c] = matrix[i + k, j + c];
                            }
                        }

                        if (MatrixT <T> .GetMatrixDeterminant(matbv) != 0)
                        {
                            rank = q;
                        }
                    }
                }

                q++;
            }

            return(rank);
        }
        private LAEAnswer CalculateKramerMethod(out List <LAEVariable> lAEVariables)
        {
            bool systemCompatible = this.CheckLinearAlgebraicEquationSystemCompatibility();

            if (!systemCompatible)
            {
                lAEVariables = null;
                return(LAEAnswer.NoSolutions);
            }

            double matrixDeterminant = MatrixT <double> .GetMatrixDeterminant(this.Matrix);

            List <LAEVariable> result = new List <LAEVariable>();

            for (int i = 0; i < this.Matrix.Columns; i++)
            {
                MatrixT <double> currentMatrix = MatrixT <double> .SubstituteMatrixColumn(this.Matrix, i, this.RightPartEquations);

                double currentDeterminant = MatrixT <double> .GetMatrixDeterminant(currentMatrix);

                result.Add(new LAEVariable(this.Variables[i].Name, currentDeterminant / matrixDeterminant));
            }

            lAEVariables = result;
            return(LAEAnswer.OneSolution);
        }
Example #8
0
        /// <summary>
        /// Method is used to transpone the required matrix.
        /// </summary>
        /// <param name="matrix">Initial matrix.</param>
        /// <returns>Transponed matrix of the initial one.</returns>
        public static MatrixT <T> TransponeMatrix(MatrixT <T> matrix)
        {
            MatrixT <T> result = new MatrixT <T>(matrix.Columns, matrix.Rows);

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    result[j, i] = matrix[i, j];
                }
            }

            return(result);
        }
        /// <summary>
        /// Method is used to check the compatibility of linear algebraic equation system.
        /// </summary>
        /// <returns>The flag which represents if this system is compatibile</returns>
        public bool CheckLinearAlgebraicEquationSystemCompatibility()
        {
            int matrixRank = MatrixT <double> .GetRang(this.Matrix);

            MatrixT <double> extendedMatrix = MatrixT <double> .ExtendMatrix(this.Matrix, this.RightPartEquations.ToArray());

            int extendedMatrixRank = MatrixT <double> .GetRang(extendedMatrix);

            if (matrixRank == extendedMatrixRank)
            {
                return(true);
            }

            return(false);
        }
Example #10
0
        public static void CopyMatrixItems(MatrixT <T> sourceMatrix, MatrixT <T> destinationMatrix)
        {
            if (sourceMatrix.Columns != destinationMatrix.Columns ||
                sourceMatrix.Rows != destinationMatrix.Rows)
            {
                throw new ArgumentException("Matrixes don't have the same amount of rows and columns!");
            }

            for (int i = 0; i < sourceMatrix.Rows; i++)
            {
                for (int j = 0; j < sourceMatrix.Columns; j++)
                {
                    destinationMatrix[i, j] = sourceMatrix[i, j];
                }
            }
        }
Example #11
0
        /// <summary>
        /// Method is used to add one column to a matrix.
        /// </summary>
        /// <param name="matrix">Initial matrix.</param>
        /// <param name="extension">Extra column which will be added.</param>
        /// <returns>The extended matrix.</returns>
        public static MatrixT <T> ExtendMatrix(MatrixT <T> matrix, T[] extension)
        {
            MatrixT <T> result = new MatrixT <T>(matrix.Rows, matrix.Columns + 1);

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    result[i, j] = matrix[i, j];
                }

                result[i, result.Columns - 1] = extension[i];
            }

            return(result);
        }
Example #12
0
 /// <summary>
 /// Method is used to set a basis for a scpecified matrix.
 /// </summary>
 /// <param name="matrix">The matrix to set a basis there.</param>
 public static void SetBaseMatrix(MatrixT <T> matrix)
 {
     for (int i = 0; i < matrix.Rows; i++)
     {
         for (int j = 0; j < matrix.Columns; j++)
         {
             if (i == j)
             {
                 matrix[i, j] = (dynamic)1;
             }
             else
             {
                 matrix[i, j] = (dynamic)0;
             }
         }
     }
 }
        private LAEAnswer CalculateMatrixMethod(out List <LAEVariable> lAEVariables)
        {
            bool systemCompatible = this.CheckLinearAlgebraicEquationSystemCompatibility();

            if (!systemCompatible)
            {
                lAEVariables = null;
                return(LAEAnswer.NoSolutions);
            }

            MatrixT <double> inversedMatrix = MatrixT <double> .GetInverseMatrix(this.Matrix);

            MatrixT <double> resultMatrix = inversedMatrix * new MatrixT <double>(this.RightPartEquations.ToArray());

            lAEVariables = LAEVariable.FillLAEVariablesWithMatrix(resultMatrix, this.Variables);

            return(LAEAnswer.OneSolution);
        }
Example #14
0
        internal static List <LAEVariable> FillLAEVariablesWithMatrix <T>(MatrixT <T> matrix, List <Variable> lAEVariables)
        {
            if (matrix != null && matrix.Columns == 1 && matrix.Rows == lAEVariables.Count)
            {
                List <LAEVariable> result = new List <LAEVariable>();

                for (int i = 0; i < lAEVariables.Count; i++)
                {
                    result.Add(new LAEVariable(lAEVariables[i].Name, (dynamic)matrix[i, 0]));
                }

                return(result);
            }
            else
            {
                throw new ArgumentException("Inapropriate matrix to fill the list of variables!");
            }
        }
Example #15
0
        /// <summary>
        /// Method is used to substitute matrix column with other values.
        /// </summary>
        /// <param name="matrix">Initial matrix for substitution.</param>
        /// <param name="columnIndex">Index of a column which will be substituted.</param>
        /// <param name="newColumn">New values of the column.</param>
        /// <returns></returns>
        public static MatrixT <T> SubstituteMatrixColumn(MatrixT <T> matrix, int columnIndex, List <T> newColumn)
        {
            if (newColumn.Count != matrix.Rows)
            {
                throw new ArgumentException($"Amount of matrix rows: {matrix.Rows} and amount of matrix columns: {newColumn.Count}");
            }

            MatrixT <T> result = new MatrixT <T>(matrix.Rows, matrix.Columns);

            MatrixT <T> .CopyMatrixItems(matrix, result);

            for (int i = 0; i < result.Rows; i++)
            {
                result[i, columnIndex] = newColumn[i];
            }

            return(result);
        }
Example #16
0
        public static void PrintMatrix(MatrixT <T> matrix, StreamWriter streamWriter = null)
        {
            if (streamWriter == null)
            {
                streamWriter           = new StreamWriter(Console.OpenStandardOutput());
                streamWriter.AutoFlush = true;
                Console.SetOut(streamWriter);
            }

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    streamWriter.Write($"{matrix[i, j]} ");
                }

                streamWriter.WriteLine();
            }
        }
Example #17
0
        /// <summary>
        /// Multiplication by a number overloading.
        /// </summary>
        /// <param name="a">Number to multiply a matrix.</param>
        /// <param name="B">Matrix which will be multiplied.</param>
        /// <returns>The result of multiplication by a number.</returns>
        public static MatrixT <T> operator *(dynamic a, MatrixT <T> B)
        {
            Type type     = a.GetType();
            bool isNumber = (type.IsPrimitive && type != typeof(bool) && type != typeof(char));

            if (isNumber)
            {
                MatrixT <T> result = new MatrixT <T>(B.Rows, B.Columns);

                for (int i = 0; i < B.Rows; i++)
                {
                    for (int j = 0; j < B.Columns; j++)
                    {
                        result[i, j] = B[i, j] * a;
                    }
                }

                return(result);
            }

            throw new ArgumentException($"Cannot multiply the matrix by a number {a}.");
        }
Example #18
0
        /// <summary>
        /// Method describes two matrixes equation process.
        /// </summary>
        /// <param name="obj">Matrix to compare.</param>
        /// <returns>Flag if two matrixes are equal.</returns>
        public override bool Equals(object obj)
        {
            MatrixT <T> inputMatrix = (MatrixT <T>)obj;

            if (this.Columns != inputMatrix.Columns || this.Rows != inputMatrix.Rows)
            {
                return(false);
            }

            for (int i = 0; i < this.Rows; i++)
            {
                for (int j = 0; j < this.Columns; j++)
                {
                    if ((dynamic)this.Elements[i, j] != (dynamic)inputMatrix[i, j])
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #19
0
        /// <summary>
        /// Method is used to take inversed matrix.
        /// </summary>
        /// <param name="matrix">Initial matrix.</param>
        /// <returns>Inversed matrix.</returns>
        public static MatrixT <T> GetInverseMatrix(MatrixT <T> matrix)
        {
            double determinant = MatrixT <T> .GetMatrixDeterminant(matrix);

            if (determinant != 0)
            {
                MatrixT <T> reversedMatrix = new MatrixT <T>(matrix.Rows, matrix.Columns);

                for (int i = 0; i < matrix.Rows; i++)
                {
                    for (int j = 0; j < matrix.Columns; j++)
                    {
                        MatrixT <T> tempMatrix = MatrixT <T> .GetMinor(matrix, i, j);

                        reversedMatrix[i, j] = (dynamic)Math.Pow(-1.0, i + j + 2) * (dynamic)MatrixT <T> .GetMatrixDeterminant(tempMatrix) / (dynamic)determinant;
                    }
                }

                return(MatrixT <T> .TransponeMatrix(reversedMatrix));
            }

            return(null);
        }
Example #20
0
        /// <summary>
        /// Multiplication operator overloading.
        /// </summary>
        /// <param name="A">Left operand.</param>
        /// <param name="B">Right operand.</param>
        /// <returns>The result of multiplication operand.</returns>
        public static MatrixT <T> operator *(MatrixT <T> A, MatrixT <T> B)
        {
            if (Paral)
            {
                MatrixT <T> ans = new MatrixT <T>(new T[A.Elements.GetLength(0), B.Elements.GetLength(1)]);
                Parallel.For(0, A.Elements.GetLength(0), (i) =>
                {
                    for (int j = 0; j < B.Elements.GetLength(1); j++)
                    {
                        ans.Elements[i, j] = (dynamic)0;
                        for (int k = 0; k < A.Elements.GetLength(1); k++)
                        {
                            ans.Elements[i, j] += (dynamic)A.Elements[i, k] * (dynamic)B.Elements[k, j];
                        }
                    }
                });

                return(ans);
            }
            else
            {
                MatrixT <T> ans = new MatrixT <T>(new T[A.Elements.GetLength(0), B.Elements.GetLength(1)]);
                for (int i = 0; i < A.Elements.GetLength(0); i++)
                {
                    for (int j = 0; j < B.Elements.GetLength(1); j++)
                    {
                        ans.Elements[i, j] = (dynamic)0;
                        for (int k = 0; k < A.Elements.GetLength(1); k++)
                        {
                            ans.Elements[i, j] += (dynamic)A.Elements[i, k] * (dynamic)B.Elements[k, j];
                        }
                    }
                }

                return(ans);
            }
        }
        /// <summary>
        /// Method is used to set matrix of linear alebraic equation system.
        /// </summary>
        /// <param name="leftEquationsParts">parts of the left equations system.</param>
        /// <param name="variables">LAE system variables.</param>
        /// <param name="constants">LAE system constants.</param>
        /// <returns>matrix of the relevant linear alebraic equation system.</returns>
        private static MatrixT <double> SetMatrix(List <Expression> leftEquationsParts, List <Variable> variables, List <Variable> constants)
        {
            MatrixT <double> result = new MatrixT <double>(leftEquationsParts.Count, variables.Count);

            for (int i = 0; i < leftEquationsParts.Count; i++)
            {
                for (int j = 0; j < variables.Count; j++)
                {
                    List <Variable> currentVariables = variables;

                    LinearAlgebraicEquationSystem.SetVariablesWithValues(currentVariables, 0);
                    currentVariables[j].Value = 1.0;

                    if (constants != null && constants.Count > 0)
                    {
                        currentVariables.AddRange(constants);
                    }

                    result[i, j] = leftEquationsParts[i].GetResultValue(currentVariables);
                }
            }

            return(result);
        }
Example #22
0
        private LAEAnswer CalculateGaussMethod(out List <LAEVariable> results)
        {
            results = null;

            MatrixT <double> currentMatrix = new MatrixT <double>(this.Matrix.Rows, this.Matrix.Columns);

            MatrixT <double> .CopyMatrixItems(this.Matrix, currentMatrix);

            double[] rightPart = new double[this.RightPartEquations.Count];
            for (int i = 0; i < this.RightPartEquations.Count; i++)
            {
                rightPart[i] = this.RightPartEquations[i];
            }

            double[] answer = new double[this.Variables.Count];

            if (currentMatrix.Rows != currentMatrix.Columns)
            {
                results = null;
                return(LAEAnswer.NoSolutions);
            }

            for (int i = 0; i < currentMatrix.Rows - 1; i++)
            {
                SortRows(currentMatrix, ref rightPart, i);

                for (int j = i + 1; j < currentMatrix.Rows; j++)
                {
                    if (currentMatrix[i, i] != 0)
                    {
                        double multElement = currentMatrix[j, i] / currentMatrix[i, i];

                        for (int k = i; k < currentMatrix.Columns; k++)
                        {
                            currentMatrix[j, k] -= currentMatrix[i, k] * multElement;
                        }

                        rightPart[j] -= rightPart[i] * multElement;
                    }
                }
            }

            for (int i = currentMatrix.Rows - 1; i >= 0; i--)
            {
                answer[i] = rightPart[i];

                for (int j = currentMatrix.Rows - 1; j > i; j--)
                {
                    answer[i] -= currentMatrix[i, j] * answer[j];
                }

                if (currentMatrix[i, i] == 0)
                {
                    if (rightPart[i] == 0)
                    {
                        return(LAEAnswer.ManySolutions);
                    }
                    else
                    {
                        return(LAEAnswer.NoSolutions);
                    }
                }

                answer[i] /= currentMatrix[i, i];
            }

            results = new List <LAEVariable>();
            for (int i = 0; i < this.Variables.Count; i++)
            {
                results.Add(new LAEVariable(this.Variables[i].Name, answer[i]));
            }

            return(LAEAnswer.OneSolution);
        }
Example #23
0
        /// <summary>
        /// Method is used to take inversed matrix.
        /// </summary>
        /// <param name="matrix">Initial matrix.</param>
        /// <returns>Inversed matrix.</returns>
        public static MatrixT <T> GetInverseMatrix3(MatrixT <T> matrix)
        {
            if (matrix.Columns == matrix.Rows)
            {
                if (MatrixT <T> .GetMatrixDeterminant(matrix) != 0.0)
                {
                    MatrixT <T> matrixCopy = new MatrixT <T>(matrix.Rows, matrix.Columns);

                    for (int i = 0; i < matrix.Rows; i++)
                    {
                        for (int j = 0; j < matrix.Columns; j++)
                        {
                            matrixCopy[i, j] = matrix[i, j];
                        }
                    }

                    MatrixT <T> reverseMatrix = new MatrixT <T>(matrix.Rows, matrix.Columns);
                    MatrixT <T> .SetBaseMatrix(reverseMatrix);

                    for (int k = 0; k < matrix.Rows; k++)
                    {
                        T div = matrixCopy[k, k];
                        for (int m = 0; m < matrix.Columns; m++)
                        {
                            matrixCopy[k, m]    /= (dynamic)div;
                            reverseMatrix[k, m] /= (dynamic)div;
                        }

                        for (int i = k + 1; i < matrix.Rows; i++)
                        {
                            T multi = matrixCopy[i, k];
                            for (int j = 0; j < matrix.Columns; j++)
                            {
                                matrixCopy[i, j]    -= (dynamic)multi * (dynamic)matrixCopy[k, j];
                                reverseMatrix[i, j] -= (dynamic)multi * (dynamic)reverseMatrix[i, j];
                            }
                        }
                    }

                    for (int kk = matrix.Rows - 1; kk > 0; kk--)
                    {
                        matrixCopy[kk, matrix.Columns - 1]    /= (dynamic)matrixCopy[kk, kk];
                        reverseMatrix[kk, matrix.Columns - 1] /= (dynamic)matrixCopy[kk, kk];

                        for (int i = kk - 1; i + 1 > 0; i--)
                        {
                            T multi2 = matrixCopy[i, kk];
                            for (int j = 0; j < matrix.Columns; j++)
                            {
                                matrixCopy[i, j]    -= (dynamic)multi2 * (dynamic)matrixCopy[kk, j];
                                reverseMatrix[i, j] -= (dynamic)multi2 * (dynamic)reverseMatrix[kk, j];
                            }
                        }
                    }

                    return(MatrixT <T> .TransponeMatrix(reverseMatrix));
                }
            }

            return(null);
        }