예제 #1
0
        public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }
            this.x0         = x0;
            this.b          = b;
            this.A          = A;
            this.Factorizer = Factorizer;
            norm_b          = b.Norm;
            currentIter     = 0;

            if (Factorizer != null)
            {
                r = Factorizer.LSolve(b.Add(A.Multiply(x0), -1));
                z = Factorizer.USolve(r);
                p = Factorizer.LSolve(A.Multiply(z));
            }
            else
            {
                r = b.Add(A.Multiply(x0), -1);
                z = r.Clone();
                p = A.Multiply(z);
            }

            dotproduct_pp = p.DotProduct(p);
            init          = true;
            return(init);
        }
예제 #2
0
        public void MakeStep(out int iter, out double residual)
        {
            if (!init)
            {
                throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно");
            }

            currentIter++;
            iter = currentIter;

            if (Factorizer != null)
            {
                coefficient = p.DotProduct(r) / dotproduct_pp;
                if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
                {
                    residual = -1;
                    return;
                }

                x  = x.Add(z, coefficient);
                r  = r.Add(p, -coefficient);
                Ar = Factorizer.LSolve(A.Multiply(Factorizer.USolve(r)));

                coefficient = -p.DotProduct(Ar) / dotproduct_pp;
                if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
                {
                    residual = -1;
                    return;
                }

                z = Factorizer.USolve(r).Add(z, coefficient);
            }
            else
            {
                coefficient = p.DotProduct(r) / dotproduct_pp;
                if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
                {
                    residual = -1;
                    return;
                }

                x  = x.Add(z, coefficient);
                r  = r.Add(p, -coefficient);
                Ar = A.Multiply(r);

                coefficient = -p.DotProduct(Ar) / dotproduct_pp;
                if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
                {
                    residual = -1;
                    return;
                }

                z = r.Add(z, coefficient);
            }

            p             = Ar.Add(p, coefficient);
            dotproduct_pp = p.DotProduct(p);

            residual = r.Norm / norm_b;
        }
예제 #3
0
        public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }
            xk              = x0.Clone();
            this.b          = b;
            this.A          = A;
            this.Factorizer = Factorizer;
            norm_b          = b.Norm;
            currentIter     = 0;

            if (Factorizer != null)
            {
                r_prev = Factorizer.LSolve(b.Add(A.Multiply(xk), -1));
                r0     = r_prev.Clone();
                z      = Factorizer.USolve(r_prev.Clone());
            }
            else
            {
                r_prev = b.Add(A.Multiply(xk), -1);
                r0     = r_prev.Clone();
                z      = r_prev.Clone();
            }

            dotproduct_rr      = r_prev.DotProduct(r_prev);
            dotproduct_rprevr0 = dotproduct_rr;
            init = true;
            return(init);
        }
예제 #4
0
        public void MakeStep(out int iter, out double residual)
        {
            if (!init)
            {
                throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно");
            }

            if (currentIter % 20 == 0)
            {
                r_prev             = A.LSolve(b.Add(A.Multiply(xk), -1), true);
                r0                 = r_prev.Clone();
                z                  = A.USolve(r_prev.Clone(), true);
                dotproduct_rr      = r_prev.DotProduct(r_prev);
                dotproduct_rprevr0 = dotproduct_rr;
            }

            currentIter++;
            iter = currentIter;

            LAUz = A.LSolve(A.Multiply(A.USolve(z, true)), true);
            var alfa = dotproduct_rprevr0 / (LAUz.DotProduct(r0));

            var p = r_prev.Add(LAUz, -alfa);

            LAUp = A.LSolve(A.Multiply(A.USolve(p, true)), true);
            var gamma = (LAUp.DotProduct(p)) / (LAUp.DotProduct(LAUp));

            xk = xk.Add(z, alfa).Add(p, gamma);
            r  = p.Add(LAUp, -gamma);

            dotproduct_rkr0 = r.DotProduct(r0);
            var betta = alfa * dotproduct_rkr0 / (gamma * dotproduct_rprevr0);

            z = r.Add(z, betta).Add(LAUz, -betta * gamma);

            dotproduct_rprevr0 = dotproduct_rkr0;
            r_prev             = r;
            dotproduct_rr      = r.DotProduct(r);

            if (Double.IsNaN(alfa) || Double.IsNaN(betta) || Double.IsNaN(gamma))
            {
                residual = -1;
                return;
            }

            x        = A.USolve(xk, true);
            residual = Math.Sqrt(dotproduct_rr) / norm_b;
        }
예제 #5
0
        public void MakeStep(out int iter, out double residual)
        {
            if (!init)
            {
                throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно");
            }
            currentIter++;
            iter = currentIter;

            Az            = A.Multiply(z);
            coefficient   = dotproduct_rr / Az.DotProduct(z);
            x             = x.Add(z, coefficient);
            r             = r.Add(Az, -coefficient);
            coefficient   = dotproduct_rr;
            dotproduct_rr = r.DotProduct(r);
            coefficient   = dotproduct_rr / coefficient;
            z             = r.Add(z, coefficient);

            if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
            {
                residual = -1;
                return;
            }
            residual = Math.Sqrt(dotproduct_rr) / norm_b;
        }
예제 #6
0
        public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }

            this.x0     = x0;
            this.b      = b;
            this.A      = A;
            currentIter = 0;
            norm_b      = b.Norm;

            lastResidual = A.Multiply(x0).Add(b, -1).Norm / norm_b;
            if (Double.IsNaN(lastResidual) || Double.IsInfinity(lastResidual))
            {
                return(false);
            }
            init   = true;
            x_temp = new Vector(x.Size);
            Ux     = A.UMult(x0, false, 0);
            return(true);
        }
예제 #7
0
        public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }

            this.x0     = x0;
            this.b      = b;
            this.A      = A;
            currentIter = 0;
            norm_b      = b.Norm;

            lastResidual = A.Multiply(x0).Add(b, -1).Norm / norm_b;
            if (Double.IsNaN(lastResidual) || Double.IsInfinity(lastResidual))
            {
                return(false);
            }
            init            = true;
            x_temp          = new Vector(x.Size);
            inverseDioganal = A.Diagonal.Clone();
            for (int i = 0; i < inverseDioganal.Size; i++)
            {
                inverseDioganal[i] = 1.0 / inverseDioganal[i];
            }
            L_Ux = A.LMult(x0, false, 0).Add(A.UMult(x0, false, 0));
            return(true);
        }
        public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }

            this.x0     = x0;
            this.b      = b;
            this.A      = A;
            currentIter = 0;
            norm_b      = b.Norm;
            try
            {
                lastResidual = A.Multiply(x0).Add(b, -1).Norm / norm_b;
            }
            catch (DivideByZeroException e)
            {
                return(false);
            }
            init   = true;
            x_temp = new Vector(x.Size);
            Ux     = A.UMult(x0, false, 0);
            return(true);
        }
예제 #9
0
        public IVector InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }

            this.x0     = x0;
            this.b      = b;
            this.A      = A;
            currentIter = 0;
            norm_b      = b.Norm;

            try
            {
                lastResidual = A.Multiply(x0).Add(b, -1).Norm / norm_b;
            }
            catch (DivideByZeroException e)
            {
                return(null);
            }
            init            = true;
            x_temp          = new Vector(x.Size);
            inverseDioganal = A.Diagonal.Clone();
            for (int i = 0; i < inverseDioganal.Size; i++)
            {
                inverseDioganal[i] = 1.0 / inverseDioganal[i];
            }
            L_Ux = A.LMult(x0, false, 0).Add(A.UMult(x0, false, 0));
            return(x);
        }
예제 #10
0
        public static double[] Multiply(ILinearOperator <double> A, double[] x)
        {
            var b = new double[A.RowCount];

            A.Multiply(1.0, x, 0.0, b);

            return(b);
        }
예제 #11
0
 //не предобусловленная система
 public IVector InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false)
 {
     if (malloc)
     {
         x = new Vector(x0.Size);
     }
     else
     {
         x = x0;
     }
     this.x0       = x0;
     this.b        = b;
     this.A        = A;
     norm_b        = b.Norm;
     currentIter   = 0;
     r             = b.Add(A.Multiply(x0), -1);
     z             = r.Clone();
     p             = A.Multiply(r);
     dotproduct_pp = p.DotProduct(p);
     init          = true;
     return(x);
 }
예제 #12
0
파일: CGM.cs 프로젝트: alandre/SLAE-solver
        public void MakeStep(out int iter, out double residual)
        {
            if (!init)
            {
                throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно");
            }

            currentIter++;
            iter = currentIter;

            if (Factorizer != null)
            {
                Az = Factorizer.UTransposeSolve(At.Multiply(Factorizer.LTransposeSolve(Factorizer.LSolve(A.Multiply(Factorizer.USolve(z))))));;
            }
            else
            {
                Az = At.Multiply(A.Multiply(z));
            }

            coefficient = dotproduct_rr / Az.DotProduct(z);

            if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
            {
                residual = -1;
                return;
            }

            xk            = xk.Add(z, coefficient);
            r             = r.Add(Az, -coefficient);
            coefficient   = dotproduct_rr;
            dotproduct_rr = r.DotProduct(r);
            coefficient   = dotproduct_rr / coefficient;

            if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient))
            {
                residual = -1;
                return;
            }

            z        = r.Add(z, coefficient);
            residual = Math.Sqrt(dotproduct_rr) / norm_b;
        }
예제 #13
0
파일: CGM.cs 프로젝트: alandre/SLAE-solver
        public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }

            xk              = x0.Clone();
            this.x0         = x0;
            this.b          = b;
            this.A          = A;
            this.Factorizer = Factorizer;

            At          = A.Transpose;
            norm_b      = b.Norm;
            currentIter = 0;

            if (Factorizer != null)
            {
                r  = Factorizer.UTransposeSolve(At.Multiply(Factorizer.LTransposeSolve(Factorizer.LSolve(b.Add(A.Multiply(x0), -1)))));
                z  = r.Clone();
                xk = Factorizer.UMult(x0);
            }
            else
            {
                r = At.Multiply(b).Add(At.Multiply(A.Multiply(x0)), -1);
                z = r.Clone();
            }


            dotproduct_rr = r.DotProduct(r);
            init          = true;
            return(init);
        }
예제 #14
0
        public IVector InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false)
        {
            if (malloc)
            {
                x = new Vector(x0.Size);
            }
            else
            {
                x = x0;
            }

            xk                 = x0;
            this.b             = b;
            this.A             = A;
            norm_b             = b.Norm;
            currentIter        = 0;
            r_prev             = A.LSolve(b.Add(A.Multiply(xk), -1), true);
            r0                 = r_prev.Clone();
            z                  = A.USolve(r_prev.Clone(), true);
            dotproduct_rr      = r_prev.DotProduct(r_prev);
            dotproduct_rprevr0 = dotproduct_rr;
            init               = true;
            return(x);
        }
예제 #15
0
 public IVector Multiply(IVector vector)
 {
     Counters.Mult.Inc();
     return(linear.Multiply(vector));
 }
예제 #16
0
        public void MakeStep(out int iter, out double residual)
        {
            if (!init)
            {
                throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно");
            }

            currentIter++;
            iter = currentIter;

            if (Factorizer != null)
            {
                if (currentIter % 5 == 0)
                {
                    r_prev             = Factorizer.LSolve(b.Add(A.Multiply(xk), -1));
                    r0                 = r_prev.Clone();
                    z                  = Factorizer.USolve(r_prev.Clone());
                    dotproduct_rr      = r_prev.DotProduct(r_prev);
                    dotproduct_rprevr0 = dotproduct_rr;
                }

                LAUz = Factorizer.LSolve(A.Multiply(Factorizer.USolve(z)));
                var alpha = dotproduct_rprevr0 / (LAUz.DotProduct(r0));

                p = r_prev.Add(LAUz, -alpha);

                LAUp = Factorizer.LSolve(A.Multiply(Factorizer.USolve(p)));
                var gamma = (LAUp.DotProduct(p)) / (LAUp.DotProduct(LAUp));

                xk = xk.Add(z, alpha).Add(p, gamma);
                r  = p.Add(LAUp, -gamma);

                dotproduct_rkr0 = r.DotProduct(r0);
                var beta = alpha * dotproduct_rkr0 / (gamma * dotproduct_rprevr0);
                z = r.Add(z, beta).Add(LAUz, -beta * gamma);

                dotproduct_rprevr0 = dotproduct_rkr0;
                r_prev             = r;


                if (Double.IsNaN(beta) || Double.IsInfinity(beta))
                {
                    residual = -1;
                    return;
                }
            }
            else
            {
                if (currentIter % 5 == 0)
                {
                    r_prev             = b.Add(A.Multiply(xk), -1);
                    r0                 = r_prev.Clone();
                    z                  = r_prev.Clone();
                    dotproduct_rr      = r_prev.DotProduct(r_prev);
                    dotproduct_rprevr0 = dotproduct_rr;
                }

                Az = A.Multiply(z);
                var alpha = dotproduct_rprevr0 / (Az.DotProduct(r0));

                p = r_prev.Add(Az, -alpha);

                Ap = A.Multiply(p);
                var gamma = (Ap.DotProduct(p)) / (Ap.DotProduct(Ap));

                xk = xk.Add(z, alpha).Add(p, gamma);
                r  = p.Add(Ap, -gamma);

                dotproduct_rkr0 = r.DotProduct(r0);
                var beta = alpha * dotproduct_rkr0 / (gamma * dotproduct_rprevr0);
                z = r.Add(z, beta).Add(Az, -beta * gamma);

                dotproduct_rprevr0 = dotproduct_rkr0;
                r_prev             = r;

                if (Double.IsNaN(beta) || Double.IsInfinity(beta))
                {
                    residual = -1;
                    return;
                }
            }

            dotproduct_rr = r.DotProduct(r);
            residual      = Math.Sqrt(dotproduct_rr) / norm_b;
        }