Example #1
0
        //Получение матрицы смежности по матрице инцидентности
        //Обеспечивает более полное описание графа и дает больше гибкости при работе с данным классом
        private void GetAdjTable()
        {
            adj_table = new NumericMatrix(nodes_num);
            int from_node = 0;
            int to_node   = 0;

            Console.WriteLine(rel_num);

            for (int j = 0; j < rel_num; j++)
            {
                for (int i = 0; i < nodes_num; i++)
                {
                    if (inc_table.GetElement(i, j) == -1)
                    {
                        from_node = i;
                    }
                    else if (inc_table.GetElement(i, j) == 1)
                    {
                        to_node = i;
                    }
                    else if (inc_table.GetElement(i, j) == 2)
                    {
                        from_node = i;
                        to_node   = i;
                    }
                }
                adj_table.SetElement(from_node, to_node, 1);
            }
        }
Example #2
0
        //Метод, возвращающий матрицу минора указанного элемента заданной матрицы matrix
        public static NumericMatrix GetMinorMatrixOfElement(NumericMatrix matrix, int i, int j)
        {
            int           size = matrix.size;
            NumericMatrix result = new NumericMatrix(size - 1);
            int           x = 0, y = 0;

            for (int k = 0; k < size; k++)
            {
                if (k != i)
                {
                    for (int t = 0; t < size; t++)
                    {
                        if (t != j)
                        {
                            result.SetElement(y, x, matrix.GetElement(k, t));
                            x++;
                        }
                    }
                    y++;
                    x = 0;
                }
            }
            Console.WriteLine(result.ToString());
            return(result);
        }
Example #3
0
        //Метод, преобразующий матрицу к треугольному виду и возвращающий ее ранг
        public static int GetRank(NumericMatrix matrix)
        {
            NumericMatrix.ToTriangular(matrix);
            int  rank     = 0;
            bool is_empty = true;

            for (int i = 0; i < matrix.height; i++)
            {
                for (int j = 0; j < matrix.width; j++)
                {
                    if (matrix.GetElement(i, j) != 0)
                    {
                        is_empty = false;
                        break;
                    }
                }
                if (!is_empty)
                {
                    rank++;
                }
                else
                {
                    break;
                }
                is_empty = true;
            }
            return(rank);
        }
Example #4
0
        //Метод возвращает матрицу - результат перемножения matrix2 с данной
        public NumericMatrix Multiple(NumericMatrix matrix2)
        {
            if (matrix2.size == size)
            {
                NumericMatrix result = new NumericMatrix(size);
                double        buf    = 0;

                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        for (int k = 0; k < width; k++)
                        {
                            buf += this.elements[i, k] * matrix2.GetElement(k, j);
                        }
                        result.SetElement(i, j, buf);
                        buf = 0;
                    }
                }

                return(result);
            }
            else
            {
                Console.WriteLine("ERROR using NumericMatrix.Multiply(NumericMatrix matrix)");
                return(null);
            }
        }
        //Метод, осуществляющий нахождение единственного решения системы
        //Происходит последовательное вычисление неизвестных
        //Затем решение представляется в виде строки
        private void BuildSingleSolution()
        {
            int    k = n_x - 1;
            double left_part;

            single_solution.AddRange(new double[n_x]);


            for (int i = rank - 1; i >= 0; i--, k--)
            {
                left_part = 0;
                for (int j = n_x - 1; j >= 0; j--)
                {
                    if (j != k)
                    {
                        left_part += matrix.GetElement(i, j) * single_solution[j];// Чтобы не заполнять List<> значениями 0 по умолчанию
                    }
                }
                // Ранее использовался double[]

                single_solution[i] = (extended_matrix.GetElement(i, n_x) - left_part) / extended_matrix.GetElement(i, k);
            }
            solution = "Решение данной системы единственно и равно : \n";
            for (int i = 0; i < n_x; i++)
            {
                solution += "x" + (i + 1) + " = " + single_solution[i] + ", ";
            }
            solution = solution.Remove(solution.Length - 2);
        }
Example #6
0
        //Метод, преобразующий матрицу к треугольному виду путем последовательного вычитания строк
        public static void ToTriangular(NumericMatrix matrix)
        {
            int    j = 0;
            int    i = 0;
            int    h;
            double coeff = 0;

            for (; i < matrix.height - 1; i++)
            {
                if (matrix.GetElement(i, j) != 0)
                {
                    matrix.DevideRow(i, matrix.GetElement(i, j));
                }
                for (int k = i + 1; k < matrix.height; k++)
                {
                    if (matrix.GetElement(i, j) == 0)
                    {
                        h = j;
                        while (matrix.GetElement(i, h) == 0 && h < matrix.width)
                        {
                            h++;
                        }
                        if (h != matrix.width)
                        {
                            coeff = -(matrix.GetElement(k, j) / matrix.GetElement(i, h));
                        }
                    }
                    else
                    {
                        coeff = -(matrix.GetElement(k, j) / matrix.GetElement(i, j));
                    }

                    matrix.SumRows(k, i, coeff);
                    //Console.WriteLine(matrix.ToString());
                }
                j++;
            }
            if (matrix.GetElement(i, j) != 0)
            {
                matrix.DevideRow(i, matrix.GetElement(i, j));
            }
            //CheckRowsEquality(matrix);
            matrix.SetType(Type.TRIANGULAR);
        }
Example #7
0
        //Получение матрицы инцидентности по матрице смежности
        //Обеспечивает более полное описание графа и дает больше гибкости при работе с данным классом
        private void GetIncTable()
        {
            rel_num = 0;
            for (int i = 0; i < nodes_num; i++)
            {
                for (int j = 0; j < nodes_num; j++)
                {
                    if (adj_table.GetElement(i, j) == 1)
                    {
                        rel_num++;
                    }
                }
            }

            inc_table = new NumericMatrix(nodes_num, rel_num);
            int rel_counter = 0;

            for (int i = 0; i < nodes_num; i++)
            {
                for (int j = 0; j < nodes_num; j++)
                {
                    if (adj_table.GetElement(i, j) == 1)
                    {
                        if (i == j)
                        {
                            inc_table.SetElement(i, rel_counter, 2);
                            rel_counter++;
                        }
                        else
                        {
                            inc_table.SetElement(i, rel_counter, -1);
                            inc_table.SetElement(j, rel_counter, 1);
                            rel_counter++;
                        }
                    }
                    if (rel_counter > rel_num)
                    {
                        Console.WriteLine("Warning");
                    }
                }
            }
        }
Example #8
0
        //Метод, возвращающий определитель переданной матрицы
        public static double GetDeterminant(NumericMatrix matrix)
        {
            int size = matrix.size;

            if (size == 1)
            {
                return(matrix.GetElement(0, 0));
            }

            else if (size == 2)
            {
                return(matrix.GetElement(0, 0) * matrix.GetElement(1, 1) - matrix.GetElement(0, 1) * matrix.GetElement(1, 0));
            }

            else
            {
                double det = 0;
                for (int j = 0; j < size; j++)
                {
                    det += Math.Pow(-1, 0 + j) * matrix.GetElement(0, j) * GetDeterminant(GetMinorMatrixOfElement(matrix, 0, j));
                }
                return(det);
            }
        }
Example #9
0
 //Метод, осуществляющий сложение данной матрицы с переданной в метод, в случае если размерность матриц совпадает
 public void Plus(NumericMatrix matrix2)
 {
     if (matrix2.width == width && matrix2.height == height)
     {
         for (int i = 0; i < height; i++)
         {
             for (int j = 0; j < width; j++)
             {
                 elements[i, j] += matrix2.GetElement(i, j);
             }
         }
     }
     else
     {
         Console.WriteLine("ERROR using NumericMatrix.Plus(NumericMatrix matrix)");
     }
 }
Example #10
0
        public NumericMatrix ConcatHorizontally(NumericMatrix first, List <double> second)
        {
            int           newWidth           = first.width + 1;
            NumericMatrix concatenatedMatrix = new NumericMatrix(first.height, newWidth);

            for (int i = 0; i < first.height; i++)
            {
                for (int j = 0; j < newWidth; j++)
                {
                    if (j < first.width)
                    {
                        concatenatedMatrix.SetElement(i, j, first.GetElement(i, j));
                    }
                    else
                    {
                        concatenatedMatrix.SetElement(i, j, second[i]);
                    }
                }
            }
            return(concatenatedMatrix);
        }
Example #11
0
        //Решение поставленной краевой задачи методом конечных разностей
        public NumericMatrix FiniteDifferencesMethod()
        {
            solutionsField = new NumericMatrix(stepsT, stepsX);
            solutionsField.Fill(0);
            NumericMatrix slaeCoeffs      = new NumericMatrix(stepsT * stepsX, stepsT * stepsX + 1);
            int           currentEquasion = 0;

            //Получить известные u (заданные начальными и граничными условиями)
            //и заполнить их коэффициенты un : 0,0,...,1([n]),0...=sigma(n*h) в итоговой
            //СЛАУ
            //Начальное условие u=phi1(x) - левая вертикаль сетки
            for (int k = 1; k < stepsT; k++)
            {
                solutionsField.SetElement(k, 0, phi1Fun((double)k * tau));

                currentEquasion = k * stepsX;
                slaeCoeffs.SetElement(currentEquasion, currentEquasion,
                                      1);
                slaeCoeffs.SetElement(currentEquasion + stepsX - 1, stepsT * stepsX,
                                      solutionsField.GetElement(k, 0));
            }

            //Начальное условие u=phi2(x) - правая вертикаль сетки
            for (int k = 1; k < stepsT; k++)
            {
                solutionsField.SetElement(k, stepsT - 1, phi2Fun((double)k * h));
                currentEquasion = k * stepsX;
                slaeCoeffs.SetElement(currentEquasion + stepsX - 1, currentEquasion + stepsX - 1,
                                      1);
                slaeCoeffs.SetElement(currentEquasion + stepsX - 1, stepsT * stepsX,
                                      solutionsField.GetElement(k, stepsT - 1));
            }

            //Начальное условие u=sigma1(x) - нижняя горизонталь сетки
            for (int k = 0; k < stepsX; k++)
            {
                solutionsField.SetElement(0, k, sigma1Fun((double)k * h));
                currentEquasion = k % stepsX;
                slaeCoeffs.SetElement(currentEquasion, currentEquasion,
                                      1);
                slaeCoeffs.SetElement(currentEquasion, stepsT * stepsX,
                                      solutionsField.GetElement(0, k));
            }
            //Console.WriteLine(solutionsField.ToString());
            //Явная схема - преобразована в линейное уравнение с известными коэффициентами
            //(2a^2/h^2-2/tau^2) * u[k,j]+
            //+ (1/tau^2) * u[k-1,j]+
            //+ (1/tau^2) * u[k+1,j]-
            //- (a^2/h^2) * u[k,j+1]-
            //- (a^2/h^2) * u[k,j-1]=0
            // 0 + 0
            // + + +
            // 0 + 0
            //Заполнить коэффициенты для внутренней сетки (t = tDistance не трогаем) по явной схеме
            for (int k = 1; k < stepsT - 1; k++)
            {
                for (int j = 1; j < stepsX - 1; j++)
                {
                    currentEquasion = k * stepsX + j;
                    slaeCoeffs.SetElement(currentEquasion, stepsX * (k) + j, 2 * Math.Pow(paramA, 2) / Math.Pow(h, 2)
                                          - 2 / Math.Pow(tau, 2));
                    slaeCoeffs.SetElement(currentEquasion, stepsX * (k - 1) + j, 1 / Math.Pow(tau, 2));
                    slaeCoeffs.SetElement(currentEquasion, stepsX * (k + 1) + j, 1 / Math.Pow(tau, 2));
                    slaeCoeffs.SetElement(currentEquasion, stepsX * (k) + (j + 1), -1 * Math.Pow(paramA, 2)
                                          / Math.Pow(h, 2));
                    slaeCoeffs.SetElement(currentEquasion, stepsX * (k) + (j - 1), -1 * Math.Pow(paramA, 2)
                                          / Math.Pow(h, 2));
                }
            }

            //Console.WriteLine(solutionsField.ToString());
            //Неявная схема - преобразована в линейное уравнение с известными коэффициентами
            //(1/tau^2 + 2a^2/h^2)*u[k+1,j] -
            //- (2/tau^2) * u[k,j] +
            //+ (1/tau^2) * u[k-1,j] -
            //- (a^2/h^2) * u[k+1, j+1] -
            //- (a^2/h^2) * u[k+1, j-1] = 0
            // + + +
            // 0 + 0
            // 0 + 0
            //Заполнить коэффициенты на stepsT*t по неявной схеме
            int kT = stepsT - 1;

            for (int j = 1; j < stepsX - 1; j++)
            {
                currentEquasion = kT * stepsX + j;
                slaeCoeffs.SetElement(currentEquasion, stepsX * (kT) + j, 1 / Math.Pow(tau, 2)
                                      + 2 * Math.Pow(paramA, 2) / Math.Pow(h, 2));
                slaeCoeffs.SetElement(currentEquasion, stepsX * (kT - 1) + j, (-2) / Math.Pow(tau, 2));
                slaeCoeffs.SetElement(currentEquasion, stepsX * (kT - 2) + j, 1 / Math.Pow(tau, 2));
                slaeCoeffs.SetElement(currentEquasion, stepsX * (kT - 1) + (j + 1), -1 * Math.Pow(paramA, 2)
                                      / Math.Pow(h, 2));
                slaeCoeffs.SetElement(currentEquasion, stepsX * (kT) + (j - 1), -1 * Math.Pow(paramA, 2)
                                      / Math.Pow(h, 2));
            }


            solution = new SLAE(slaeCoeffs);
            //Console.WriteLine(solution.ToString());
            solution.BuildSolution();
            if (!solution.isGeneralSolutionExists())
            {
                List <double> tempList = solution.GetSingleSolution();
                //Printer.PrintList(tempList, "TEMP_LIST");
                int i = 0;
                foreach (double sol in tempList)
                {
                    //Console.WriteLine((i / stepsX) + " : " + (i % stepsX));
                    solutionsField.SetElement(i / stepsX, i % stepsX, sol);
                    i++;
                }
                return(solutionsField);
            }
            else
            {
                return(solutionsField);
            }
        }
        //Метод, осуществляющий построение общего решения системы
        //Прежде всего, происходит выбор базисных переменных, стоящих "на ступеньках", остальные переменные считаются свободными
        //Далее базисные переменные выражаются через свободные; происходит заполнение матрицы коэффициентов - general_solution
        //Общее решение представляется в строковом виде
        private void BuildGeneralSolution()
        {
            bool[] is_basis = new bool[n_x];
            int[]  pos      = new int[n_equasions];
            solution = "Данная СЛАУ имеет бесконечное кол-во частных решений, общее же решение: \n " +
                       "(";
            for (int i = 0; i < n_equasions; i++)
            {
                for (int j = 0; j < n_x; j++)
                {
                    if (extended_matrix.GetElement(i, j) != 0)
                    {
                        is_basis[j] = true;
                        pos[i]      = j;
                        break;
                    }
                }
            }

            int var_num = rank - 1;

            for (int i = rank - 1; i >= 0; i--)
            {
                for (int j = n_x - 1; j >= 0; j--)
                {
                    if (is_basis[j] && j <= var_num && extended_matrix.GetElement(i, j) != 0)
                    {
                        for (int h = 0; h < n_x; h++)
                        {
                            if (h != j)
                            {
                                if (is_basis[h] && h > var_num)
                                {
                                    general_solution.SumRows(j, h, -1 * extended_matrix.GetElement(i, h));
                                }
                                else
                                {
                                    general_solution.SetElement(j, h,
                                                                general_solution.GetElement(j, h) - (extended_matrix.GetElement(i, h)) / extended_matrix.GetElement(i, j));
                                }
                            }
                        }
                        general_solution.SetElement(j, n_x, general_solution.GetElement(j, n_x) + (extended_matrix.GetElement(i, n_x))
                                                    / extended_matrix.GetElement(i, j));
                        var_num--;
                        Console.WriteLine(general_solution.ToString());
                        break;
                    }
                }
            }

            for (int i = 0; i < n_x; i++)
            {
                if (is_basis[i])
                {
                    solution += "x" + (i + 1) + " = ";
                    for (int j = 0; j < n_x; j++)
                    {
                        if (general_solution.GetElement(i, j) != 0)
                        {
                            solution += "x" + (j + 1) + "*(" + general_solution.GetElement(i, j) + ") + ";
                        }
                    }
                    if (general_solution.GetElement(i, n_x) != 0)
                    {
                        solution += general_solution.GetElement(i, n_x) + " , ";
                    }
                    else
                    {
                        solution  = solution.Remove(solution.Length - 3);
                        solution += " , ";
                    }
                }
                else
                {
                    solution += "x" + (i + 1) + " , ";
                }
            }
            solution  = solution.Remove(solution.Length - 3);
            solution += ")";
        }