static void Main()
        {
            try
            {
                //методы на подпространствах Крылова: CSlR-формат матрицы
                var T3 = new Thread(() =>
                {
                    //разреженная матрица
                    var A = new CSlR_Matrix("Data\\Sparse_Format\\Systems1\\NonSPD\\");
                    //заполнение вектора истинного решения и правой части
                    var F      = new Vector(A.N);
                    var X_True = new Vector(A.N);
                    int pre    = 1;
                    //заполнение вектора истинного решения и правой части
                    for (int i = 0; i < A.N; i++)
                    {
                        X_True.Elem[i] = 1.0;
                    }
                    A.Mult_MV(X_True, F);
                    var Solver = new BCG(30000, 1e-12);
                    var X      = Solver.Start_Solver(A, F, 2);
                    Console.WriteLine(Tools.Relative_Error(X, X_True));
                });

                //время решения
                Console.WriteLine(Tools.Measurement_Time(T3));
            }
            catch (Exception E)
            {
                Console.WriteLine("\n*** Error! ***");
                Console.WriteLine("Method:  {0}", E.TargetSite);
                Console.WriteLine("Message: {0}\n", E.Message);
            }
        }
 public Diag_Predconditioner(CSlR_Matrix A)
 {
     Diag = new Vector(A.N);
     for (int i = 0; i < A.N; i++)
     {
         Diag.Elem[i] = A.di[i];
     }
 }
 public Diagonal_Preconditioner(CSlR_Matrix A)
 {
     Diag = new Vector(A.N);
     for (int i = 0; i < A.N; i++)
     {
         if (Math.Abs(A.di[i]) < CONST.EPS)
         {
             throw new Exception("Diagonal_Preconditioner: " + (i + 1).ToString() + " position on di = " + A.di[i].ToString());
         }
         Diag.Elem[i] = A.di[i];
     }
 }
        //-------------------------------------------------------------------------------------------------

        //операция неполного ILU-разложения (Incomplete LU-decomposition) в формате CSlR
        public CSlR_Matrix Create_ILU_Decomposition()
        {
            var Matrix = new CSlR_Matrix();

            Matrix.N    = N;
            Matrix.iptr = iptr;
            Matrix.jptr = jptr;
            int N_autr = autr.Length;

            Matrix.autr = new double[N_autr];
            Matrix.altr = new double[N_autr];
            Matrix.di   = new double[N];

            for (int i = 0; i < N_autr; i++)
            {
                Matrix.altr[i] = altr[i]; Matrix.autr[i] = autr[i];
            }
            for (int i = 0; i < N; i++)
            {
                Matrix.di[i] = di[i];
            }

            //начинаем с i = 1, т.к. в первой строке нижнего треугольника только диагональный элемент
            for (int i = 1; i < N; i++)
            {
                for (int j = iptr[i] - 1; j < iptr[i + 1] - 1; j++)
                {
                    for (int a = iptr[i] - 1; a < j; a++)
                    {
                        for (int b = iptr[jptr[j] - 1] - 1; b < iptr[jptr[j]] - 1; b++)
                        {
                            if (jptr[a] == jptr[b])
                            {
                                Matrix.altr[j] -= Matrix.altr[a] * Matrix.autr[b];
                                Matrix.autr[j] -= Matrix.autr[a] * Matrix.altr[b];
                            }
                        }
                    }
                    Matrix.autr[j] /= Matrix.di[jptr[j] - 1];
                    Matrix.di[i]   -= Matrix.autr[j] * Matrix.altr[j];
                }
            }
            return(Matrix);
        }
Beispiel #5
0
        //конструктор
        public Incomplete_LU_Decomposition_CSlR(CSlR_Matrix A)
        {
            ILU      = new CSlR_Matrix();
            ILU.N    = A.N;
            ILU.iptr = A.iptr;
            ILU.jptr = A.jptr;
            int N_autr = A.autr.Length;

            ILU.autr = new double[N_autr];
            ILU.altr = new double[N_autr];
            ILU.di   = new double[A.N];

            for (int i = 0; i < N_autr; i++)
            {
                ILU.altr[i] = A.altr[i]; ILU.autr[i] = A.autr[i];
            }
            for (int i = 0; i < A.N; i++)
            {
                ILU.di[i] = A.di[i];
            }

            //начинаем с i = 1, т.к. в первой строке нижнего треугольника только диагональный элемент
            for (int i = 1; i < A.N; i++)
            {
                for (int j = A.iptr[i] - 1; j < A.iptr[i + 1] - 1; j++)
                {
                    for (int a = A.iptr[i] - 1; a < j; a++)
                    {
                        for (int b = A.iptr[A.jptr[j] - 1] - 1; b < A.iptr[A.jptr[j]] - 1; b++)
                        {
                            if (A.jptr[a] == A.jptr[b])
                            {
                                ILU.altr[j] -= ILU.altr[a] * ILU.autr[b];
                                ILU.autr[j] -= ILU.autr[a] * ILU.altr[b];
                            }
                        }
                    }
                    ILU.autr[j] /= ILU.di[A.jptr[j] - 1];
                    ILU.di[i]   -= ILU.autr[j] * ILU.altr[j];
                }
            }
        }
        public Vector Start_Solver(CSlR_Matrix A, Vector F, Preconditioner.Type_Preconditioner PREC)
        {
            switch (PREC)
            {
            case Preconditioner.Type_Preconditioner.Diagonal_Preconditioner:
            {
                Preconditioner = new Diagonal_Preconditioner(A);
                break;
            }

            case Preconditioner.Type_Preconditioner.LU_Decomposition:
            {
                Preconditioner = new LU_Preconditioner(A);
                break;
            }
            }

            int    n   = A.N;
            Vector RES = new Vector(n);

            for (int i = 0; i < n; i++)
            {
                RES.Elem[i] = 0.0;
            }

            Vector r    = new Vector(n);
            Vector rs   = new Vector(n);
            Vector p    = new Vector(n);
            Vector ps   = new Vector(n);
            Vector vec  = new Vector(n);
            Vector vec2 = new Vector(n);

            double alpha, beta, sc1, sc2;
            bool   Flag = true;

            A.Mult_MV(RES, vec);
            for (int i = 0; i < n; i++)
            {
                r.Elem[i] = F.Elem[i] - vec.Elem[i];
            }

            Preconditioner.Start_Preconditioner(r, ps);

            for (int i = 0; i < n; i++)
            {
                r.Elem[i]  = ps.Elem[i];
                rs.Elem[i] = ps.Elem[i];
                p.Elem[i]  = ps.Elem[i];
            }

            while (Flag && Iter < Max_Iter)
            {
                sc1 = r * rs;

                A.Mult_MV(p, vec);
                Preconditioner.Start_Preconditioner(vec, vec2);
                sc2 = vec2 * ps;

                alpha = sc1 / sc2;

                for (int i = 0; i < n; i++)
                {
                    RES.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec2.Elem[i];
                }

                Preconditioner.Start_Tr_Preconditioner(ps, vec);
                A.Mult_MtV(vec, vec2);
                for (int i = 0; i < n; i++)
                {
                    rs.Elem[i] -= alpha * vec2.Elem[i];
                }
                sc2 = r * rs;

                beta = sc2 / sc1;

                double Norma_r = r.Norma();
                if (Norma_r < Eps)
                {
                    Flag = false;
                }

                if (Math.Abs(beta) < Double.Epsilon)
                {
                    throw new Exception("BiConjurate_Gradient_Method: diverges given ~r(0)");
                }

                for (int i = 0; i < n; i++)
                {
                    p.Elem[i]  = r.Elem[i] + beta * p.Elem[i];
                    ps.Elem[i] = rs.Elem[i] + beta * ps.Elem[i];
                }

                Iter++;
                Console.WriteLine("{0,-20}    {1,-20}", Iter, Norma_r);
            }

            return(RES);
        }
Beispiel #7
0
        static void Main()
        {
            try
            {
                //прямые методы: Гаусс, LU-разложение, QR-разложение
                var T1 = new Thread(() =>
                {
                    int N      = 5;
                    var A      = new Matrix(N, N);
                    var X_true = new Vector(N);

                    //заполнение СЛАУ
                    for (int i = 0; i < N; i++)
                    {
                        for (int j = 0; j < N; j++)
                        {
                            A.Elem[i][j] = 1.0 / (i + j + 2.0);
                        }
                        X_true.Elem[i] = 1;
                    }

                    //правая часть
                    var F = A * X_true;

                    //метод Гаусса
                    var Solver = new Gauss_Method();
                    var X      = Solver.Start_Solver(A, F);
                });

                //итерационные блочные методы: Якоби, Гаусса-Зейделя и SOR
                var T2 = new Thread(() =>
                {
                    //матрица
                    var A = new Matrix("Data\\Dense_Format\\");
                    //вектор правой части
                    var F = new Vector("Data\\Dense_Format\\");
                    //метод SOR при w = 1.8 (максимальное число итераций = 30000, точность = 1e-12)
                    var Solver = new SOR_Method(30000, 1e-12);
                    var X      = Solver.Start_Solver(A, F, 1.85);
                });

                //методы на подпространствах Крылова: CSlR-формат матрицы
                var T3 = new Thread(() =>
                {
                    //разреженная СЛАУ
                    var A      = new CSlR_Matrix("Data\\Sparse_Format\\Systems2\\NonSPD\\");
                    var F      = new Vector(A.N);
                    var X_True = new Vector(A.N);
                    //заполнение вектора истинного решения и правой части
                    for (int i = 0; i < A.N; i++)
                    {
                        X_True.Elem[i] = 1.0;
                    }
                    A.Mult_MV(X_True, F);
                });

                //время решения задачи
                Console.WriteLine(Tools.Measurement_Time(T3));
            }

            catch (Exception E)
            {
                Console.WriteLine("\n*** Error! ***");
                Console.WriteLine("Method:  {0}", E.TargetSite);
                Console.WriteLine("Message: {0}\n", E.Message);
            }
        }
 //конструктор LU-преобусловливателя
 public LU_Preconditioner(CSlR_Matrix A)
 {
     ILU = new Incomplete_LU_Decomposition_CSlR(A);
 }
Beispiel #9
0
        public Vector Start_Solver(CSlR_Matrix A, Vector F, Preconditioner.Type_Preconditioner PREC)
        {
            switch (PREC)
            {
            case Preconditioner.Type_Preconditioner.Diagonal_Preconditioner:
            {
                Preconditioner = new Diagonal_Preconditioner(A);
                break;
            }

            case Preconditioner.Type_Preconditioner.LU_Decomposition:
            {
                Preconditioner = new LU_Preconditioner(A);
                break;
            }
            }

            int n = A.N;

            Vector RES = new Vector(n);

            for (int i = 0; i < n; i++)
            {
                RES.Elem[i] = 0.0;
            }

            Vector r   = new Vector(n);
            Vector p   = new Vector(n);
            Vector vec = new Vector(n);

            double alpha, beta, sc1, sc2;
            bool   Flag = true;

            double Norma_r = 0;

            A.Mult_MV(RES, vec);
            for (int i = 0; i < n; i++)
            {
                r.Elem[i] = F.Elem[i] - vec.Elem[i];
            }
            Preconditioner.Start_Preconditioner(r, p);

            while (Flag && Iter < Max_Iter)
            {
                sc1 = p * r;
                A.Mult_MV(p, vec);
                sc2   = vec * p;
                alpha = sc1 / sc2;

                for (int i = 0; i < n; i++)
                {
                    RES.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec.Elem[i];
                }

                Preconditioner.Start_Preconditioner(r, vec);

                sc2     = vec * r;
                beta    = sc2 / sc1;
                Norma_r = r.Norma();
                if (Norma_r < Eps)
                {
                    Flag = false;
                }

                if (Flag)
                {
                    for (int i = 0; i < n; i++)
                    {
                        p.Elem[i] = vec.Elem[i] + beta * p.Elem[i];
                    }
                }

                Iter++;
                Console.WriteLine("{0,-20}    {1,-20}", Iter, Norma_r.ToString("E"));
            }

            return(RES);
        }
Beispiel #10
0
        public Vector Start_Solver(CSlR_Matrix A, Vector F, int PREC)
        {
            int n = A.N;
            // решение
            Vector RES = new Vector(n);

            for (int i = 0; i < n; i++)
            {
                RES.Elem[i] = 0.0;
            }
            //реализация предобусловливателя
            switch (PREC)
            {
            case 1: { Pr = new Diag_Predconditioner(A); break; }

            case 2: { Pr = new ILU_Decomposition(A); break; }
                //default: { Pr = new E_Predconditioner(); break; }
            }
            var r   = new Vector(n);
            var p   = new Vector(n);
            var vec = new Vector(n);

            // параметры
            double alpha, betta, sc1, sc2;

            // флаг для остановки
            int Flag = 0;

            // ||r||
            double nev_r = 0;

            // начало CG


            A.Mult_MV(RES, vec);
            for (int i = 0; i < n; i++)
            {
                r.Elem[i] = F.Elem[i] - vec.Elem[i];
            }
            Pr.Start_Predconditioner(r, p); // в r предобусловленная система-невязка

            while (Flag != 1 && Iter < Max_Iter)
            {
                sc1 = p * r;
                A.Mult_MV(p, vec);
                sc2   = vec * p;
                alpha = sc1 / sc2;
                for (int i = 0; i < n; i++)
                {
                    RES.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec.Elem[i];
                }
                Pr.Start_Tr_Predconditioner(r, vec);

                sc2   = vec * p;
                betta = sc2 / sc1;
                nev_r = r.Norm();
                if (nev_r < Eps)
                {
                    Flag = 1;
                }
                if (Flag == 0)
                {
                    for (int i = 0; i < n; i++)
                    {
                        p.Elem[i] = vec.Elem[i] + betta * p.Elem[i];
                    }
                }
                Console.WriteLine("{0,-20} {1,-20}", Iter, nev_r.ToString("E"));
                Iter++;
            }
            return(RES);
        }
Beispiel #11
0
        static void Main()
        {
            try
            {
                //прямые методы: Гаусс, LU-разложение, QR-разложение
                var T1 = new Thread(() =>
                {
                    //int N = 10;
                    //var A = new Matrix(N, N);
                    //var X_true = new Vector(N);

                    //заполнение СЛАУ
                    //for (int i = 0; i < N; i++)
                    //{
                    //    for (int j = 0; j < N; j++)
                    //    {
                    //        A.Elem[i][j] = 1.0 / (i + j + 1.0);
                    //    }
                    //    X_true.Elem[i] = 1;
                    //}

                    //                for (int i = 0; i < N; i++)
                    //                {
                    //                    for (int j = 0; j < N; j++)
                    //                    {
                    //                        //A.Elem[i][j] = 1.0 / (i + j + 1.0);
                    //                    }
                    //                    X_true.Elem[i] = 1;
                    //                }

                    //                var ElemMatrix = new double[][]
                    //                {
                    //                    //new double[]{-2,-2,-1},
                    //                    //new double[]{1,0,-2},
                    //                    //new double[]{0,1,2}
                    //                    new double[]{5,1,9},
                    //                    new double[]{1,4,1},
                    //                    new double[]{5,1,3}

                    //                };
                    //                A.Elem = ElemMatrix;

                    //                //правая часть
                    //                var F = A * X_true;

                    //                //решатель
                    //                //var Solver = new Gauss_Method();
                    //                //var Solver = new LU_Decomposition(A);
                    //                var Solver = new QR_Decomposition(A, QR_Decomposition.QR_Algorithm.Householder);

                    //                var X = Solver.Start_Solver(F);
                    //                //X.Console_Write_Vector();
                    //                Console.WriteLine("\nError: {0}\n", Tools.Relative_Error(X, X_true));
                });

                //Итерационные методы
                var T2 = new Thread(() =>
                {
                });

                //итерационные методы: Якоби и SOR
                var T3 = new Thread(() =>
                {
                    int SIZE_BLOCK = 450;
                    double m       = 1e+4;
                    double z       = 1.2;
                    for (int k = 0; k < 1; k++)
                    {
                        //var Solver = new Jacobi_Method(30000, 1e-12);
                        var Solver = new SOR_Method(30000, 1e-4);


                        //Вычисление точного решения

                        //var A_g = new Matrix("Data\\System3\\", m);
                        //var F_g = new Vector("Data\\System3\\");
                        //var GSolver = new Gauss_Method();

                        //var sw = new Stopwatch();
                        //sw.Start();

                        //var X_true = GSolver.Start_Solver(A_g, F_g);

                        //sw.Stop();
                        //Console.WriteLine($"\nTime: {sw.Elapsed}");


                        //Блочная или обычная матрица/вектор

                        //var A = new Block_Matrix("Data\\System3\\", SIZE_BLOCK, m);
                        //var F = new Block_Vector("Data\\System3\\", SIZE_BLOCK);
                        //var A = new Matrix("Data\\System3\\", m);
                        //var F = new Vector("Data\\System3\\");
                        var A          = new Matrix(3, 3);
                        var F          = new Vector(3);
                        F.Elem[0]      = 8;
                        F.Elem[1]      = 8;
                        F.Elem[2]      = 11;
                        var ElemMatrix = new double[][]
                        {
                            //new double[]{-2,-2,-1},
                            //new double[]{1,0,-2},
                            //new double[]{0,1,2}
                            new double[] { 10, 1, 0 },
                            new double[] { 1, 10, 0 },
                            new double[] { 0, 0, 10 }
                        };
                        A.Elem = ElemMatrix;
                        var sw = new Stopwatch();
                        sw.Start();


                        //var X = Solver.Start_Solver(A, F);
                        var X = Solver.Start_Solver(A, F, 1);
                        //var X = Solver.Start_Solver(A, F, z);


                        sw.Stop();
                        Console.WriteLine($"\nTime: {sw.Elapsed}");



                        //var X_true_Norm = X_true.Norma();

                        //ДЛЯ ОБЫЧНОЙ МАТРИЦЫ

                        //for (int j = 0; j < 900; j++)
                        //{
                        //    X_true.Elem[j] = X.Elem[j] - X_true.Elem[j];
                        //}


                        //ДЛЯ БЛОЧНОЙ МАТРИЦЫ


                        //int q = 0;
                        //for (int i = 0; i < X.N; i++)
                        //{
                        //    for (int j = 0; j < SIZE_BLOCK; j++)
                        //    {
                        //        X_true.Elem[q] = X.Block[i].Elem[j] - X_true.Elem[q];
                        //        q++;
                        //    }
                        //}

                        //Console.WriteLine("delta = " + (X_true.Norma() / X_true_Norm));
                        //Console.WriteLine("Cond(A) = " + A.Cond_InfinityNorm() + "\n");
                        //Console.WriteLine("m = " + m);
                        //Console.WriteLine("z = " + z);
                        Console.WriteLine("--------------------------");

                        //m /= 100;
                        //z += 0.1;
                    }
                });

                var T4 = new Thread(() =>
                {
                    var A      = new CSlR_Matrix("Data\\Sparse_Format\\Systems2\\nonSPD\\");
                    var X_true = new Vector(A.N);
                    var F      = new Vector(A.N);

                    for (int i = 0; i < A.N; i++)
                    {
                        X_true.Elem[i] = 1.0;
                    }
                    A.Mult_MV(X_true, F);

                    var Solver = new Conjurate_Gradient_Method(30000, 1e-12);
                    //var Solver = new BiConjurate_Gradient_Method(30000, 1e-12);

                    var sw = new Stopwatch();
                    sw.Start();

                    var X = Solver.Start_Solver(A, F, Preconditioner.Type_Preconditioner.LU_Decomposition);

                    sw.Stop();
                    Console.WriteLine($"\nTime: {sw.Elapsed}");

                    Console.WriteLine("Relative_Error: {0}", Tools.Relative_Error(X, X_true));
                    Console.ReadLine();
                    for (int i = 0; i < X.N; i++)
                    {
                        Console.WriteLine("X[{0}] = {1}", i + 1, X.Elem[i]);
                    }
                });
                //время решения
                Console.WriteLine(Tools.Measurement_Time(T4));
            }
            catch (Exception E)
            {
                Console.WriteLine("\n*** Error! ***");
                Console.WriteLine("Method:  {0}", E.TargetSite);
                Console.WriteLine("Message: {0}\n", E.Message);
            }
            Console.ReadLine();
        }
 public ILU_Decomposition(CSlR_Matrix A)
 {
     LU = A.Create_ILU_Decomposition();
 }