public DiagonalPreconditioner(CSlRMatrix A)
 {
     diag = new Vector(A.Row);
     for (int i = 0; i < A.Row; i++)
     {
         diag.Elem[i] = A.di[i];
     }
 }
예제 #2
0
        public static double RelativeDiscrepancy(CSlRMatrix A, Vector x, Vector f)
        {
            var q = new Vector(A.Row);

            A.MultMtV(x, q);
            for (int i = 0; i < x.Size; i++)
            {
                q.Elem[i] -= f.Elem[i];
            }
            return(Math.Sqrt((q * q) / (f * f)));
        }
        //-------------------------------------------------------------------------------------------------

        //операция неполного LU-разложения в формате CSlR
        public CSlRMatrix ILU_CSlR()
        {
            var matrix = new CSlRMatrix();

            matrix.Column = Column;
            matrix.Row    = Row;
            matrix.iptr   = iptr;
            matrix.jptr   = jptr;
            int nAutr = autr.Length;

            matrix.autr = new double[nAutr];
            matrix.altr = new double[nAutr];
            matrix.di   = new double[Column];

            for (int i = 0; i < nAutr; i++)
            {
                matrix.altr[i] = altr[i];
                matrix.autr[i] = autr[i];
            }

            for (int i = 0; i < Column; i++)
            {
                matrix.di[i] = di[i];
            }

            for (int i = 1; i < Column; 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]] - 2; 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);
        }
 public IncompleteLUPreconditioner(CSlRMatrix A)
 {
     ILU = A.ILU_CSlR();
 }
예제 #5
0
        public Vector StartSolver(CSlRMatrix A, Vector F, Preconditioner.PreconditionerType prec)
        {
            switch (prec)
            {
            case ComMethods.Preconditioner.PreconditionerType.Diagonal:
            {
                Preconditioner = new DiagonalPreconditioner(A);
                break;
            }

            case ComMethods.Preconditioner.PreconditionerType.ILU:
            {
                Preconditioner = new IncompleteLUPreconditioner(A);
                break;
            }
            }

            int n   = A.Row;
            var res = new Vector(n);

            // auxiliary vectors
            var r   = new Vector(n);
            var p   = new Vector(n);
            var vec = new Vector(n);

            // methods parameters
            double alpha, beta, sc1, sc2;
            bool   flag = true;

            // residual norm
            double rNorm = 0;

            // residual: r = F - Ax
            A.MultMtV(res, vec);
            for (int i = 0; i < n; i++)
            {
                r.Elem[i] = F.Elem[i] - vec.Elem[i];
            }

            // search vector: Mp = r
            Preconditioner.StartPreconditioner(r, p);

            // iterative process
            while (flag && Iter < MaxIter)
            {
                sc1 = p * r;       // (M^(-1) * r; r)
                A.MultMtV(p, vec); // vec = A * p
                sc2   = vec * p;   // sc2 = (A * p; p)
                alpha = sc1 / sc2; // linear search coefficient

                // result vector & residual
                for (int i = 0; i < n; i++)
                {
                    res.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec.Elem[i];
                }

                Preconditioner.StartPreconditioner(r, vec); // vec := M^(-1) * r
                sc2   = vec * r;                            // (M^(-1) * r; r)
                beta  = sc2 / sc1;                          // coefficient in choosing a search direction
                rNorm = r.Normal();                         // residual norm

                if (rNorm < 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("\n{0, -20} {1, 20:E}", Iter, rNorm);
            }
            Console.WriteLine("Iter: {0, -20} \nNorm: {1, 20:E}", Iter, rNorm);

            return(res);
        }
        public Vector StartSolver(CSlRMatrix A, Vector F, Preconditioner.PreconditionerType prec)
        {
            switch (prec)
            {
            case ComMethods.Preconditioner.PreconditionerType.Diagonal:
            {
                Preconditioner = new DiagonalPreconditioner(A);
                break;
            }

            case ComMethods.Preconditioner.PreconditionerType.ILU:
            {
                Preconditioner = new IncompleteLUPreconditioner(A);
                break;
            }
            }

            int n   = A.Row;
            var res = new Vector(n);

            // auxiliary vectors
            var r        = new Vector(n);       // ordinary residual
            var r_       = new Vector(n);       // new residual
            var p        = new Vector(n);
            var p_       = new Vector(n);
            var vec      = new Vector(n);
            var vec_     = new Vector(n);
            var vec_help = new Vector(n);

            // methods parameters
            double alpha, beta, sc1, sc2;
            bool   flag = true;

            // residual norm
            double rNorm = 0;

            // residual: r = M^-1 * (F - Ax)
            A.MultMtV(res, vec_help);
            for (int i = 0; i < n; i++)
            {
                vec_help.Elem[i] = F.Elem[i] - vec_help.Elem[i];
            }

            Preconditioner.StartPreconditioner(vec_help, r);

            for (int i = 0; i < n; i++)
            {
                res.Elem[i] = 0.0;
                p.Elem[i]   = r_.Elem[i] = p_.Elem[i] = r.Elem[i];
            }

            while (flag && Iter < MaxIter)
            {
                sc1 = r * r_;          // scalar product sc1 = (r; r_)
                A.MultMV(p, vec_help); // vec_help = A * p

                // vec = M^(-1) * A * p
                Preconditioner.StartPreconditioner(vec_help, vec);

                sc2   = vec * p_;         // (M^(-1) * A * p; p_)
                alpha = sc1 / sc2;        // linear search coefficient

                // result vector & residual
                for (int i = 0; i < n; i++)
                {
                    res.Elem[i] += alpha * p.Elem[i];
                    r.Elem[i]   -= alpha * vec.Elem[i];
                }

                // p_ into the preconditioned system
                Preconditioner.StartTrPreconditioner(p_, vec_help);

                A.MultMtV(vec_help, vec_);    // vec_ = A_t * M^(-t) * p_

                // new residual r_
                for (int i = 0; i < n; i++)
                {
                    r_.Elem[i] -= alpha * vec_.Elem[i];
                }

                sc2   = r * r_;          // (r_new; (r_)_new)
                beta  = sc2 / sc1;       // coefficient in choosing a search direction
                rNorm = r.Normal();      // ordinary residual norm

                if (rNorm < Eps)
                {
                    flag = false;
                }

                // new search directions
                if (flag)
                {
                    for (int i = 0; i < n; i++)
                    {
                        p.Elem[i]  = r.Elem[i] + beta * p.Elem[i];
                        p_.Elem[i] = r_.Elem[i] + beta * p_.Elem[i];
                    }
                }

                Iter++;

//                Console.WriteLine("\n{0, -20} {1, 20:E}", Iter, rNorm);
            }
            Console.WriteLine("Iter: {0, -20} \nNorm: {0, 20:E}", Iter, rNorm);

            return(res);
        }