예제 #1
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;
        }
예제 #2
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;
        }
예제 #3
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;
        }