private static void TestGauss()
        {
            SLAE equasions = new SLAE();

            equasions.ConsoleInput();
            equasions.BuildSolution();
            Console.WriteLine(equasions.ToString());

            Console.ReadLine();
        }
Example #2
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);
            }
        }
Example #3
0
        //Решение СНАУ методом Ньютона
        // Находим матрицу Якоби для данной системы уравнений
        // На каждой итерации обновляем числовые значения этой матрицы при неизвестных равных текущему приближению
        // На каждой итерации обновляем числовые значения функций при неизвестных равных текущему приближению
        // На каждой итерации получаем текущее deltaX
        // На каждой итерации корректируем текущее приближение на deltaX
        // Сравниваем максимальное deltaX и epsilon, выходим из цикла
        private List <double> GetNewtonSolution()
        {
            int           iterations = 0;
            List <double> solution   = startApproximation;
            List <double> deltaX     = new List <double>();
            List <double> buffer;
            Dictionary <string, FloatingPoint> vars = new Dictionary <string, FloatingPoint>();
            SLAE deltaXIteration;
            int  u;

            currentJakobiMatrix = UpdateJakobi();

            do
            {
                u = 0;
                foreach (Expr var in variables)
                {
                    vars.Add(var.ToString(), solution[u]);
                    u++;
                }
                UpdateJakobiValues(vars);
                //Console.WriteLine(currentJakobiValues.ToString());
                vars.Clear();

                currentFunctionValue = UpdateFunctionsValue(solution);
                currentFunctionValue = currentFunctionValue.Select(p => - p).ToList();
                //ListPrint(currentFunctionValue, "FUNCTION_VALUES");

                deltaXIteration = new SLAE(currentJakobiValues.ConcatHorizontally(currentJakobiValues, currentFunctionValue));
                deltaX          = GetLinearSystemSolution(deltaXIteration);
                //Console.WriteLine(deltaXIteration.ToString());
                //ListPrint(deltaX, "DELTA_X");



                buffer = deltaX.Select(p => Math.Abs(p)).ToList();
                //ListPrint(buffer, "BUFFER");

                for (int i = 0; i < varNumber; i++)
                {
                    solution[i] += deltaX[i];
                }
                //ListPrint(solution, "SOLUTION");

                iterations++;
                currentFunctionValue = currentFunctionValue.Select(p => - p).ToList();

                if (iterations >= MAX_ITERATIONS)
                {
                    Console.WriteLine("Ошибка! Достигнут предел по итерациям!");
                    break;
                }

                //Console.WriteLine(buffer.Max());
            } while (buffer.Max() > epsilon);
            //TODO: исправить добавление уникальных решений
            if (!solutions.Contains(solution))
            {
                solutions.Add(new List <double>(solution));
                iterationsCounter.Add(iterations);
            }

            return(solution);
        }
Example #4
0
 //Решение СЛАУ : Wjakobi * deltaX = -f(x)
 //Нахождение столбца deltaX
 private List <double> GetLinearSystemSolution(SLAE deltaXIteration)
 {
     deltaXIteration.BuildSolution();
     return(deltaXIteration.GetSingleSolution());
 }