Esempio n. 1
0
        public ResultInfo Solve(NativeVector rightHandSide, NativeVector initialGuess, NativeVector result)
        {
            _iterationCounter = 0;
            var bn = CalculateVectorNorm(rightHandSide);

            if (CheckRightHandSideForZero(bn))
            {
                return(ResultInfo.Converged(0, 0, 0));
            }

            var sb  = CalculateScaleFactorsForBackwardErrorUnprecond(bn);
            var sPb = CalculateScaleFactorsForBackwardErrorPrecond(bn);

            if (Parameters.InitialGuess == InitialGuess.EqualsZero)
            {
                initialGuess.SetAllValuesToZero();
                for (int i = 0; i < _r0.Length; i++)
                {
                    _r0[i] = rightHandSide[i];
                }
            }
            else
            {
                CalculateMatrixVectorMult(initialGuess, _r0);
                for (int i = 0; i < _r0.Length; i++)
                {
                    _r0[i] = rightHandSide[i] - _r0[i];
                }
            }


            ApplyPreconditionerLeft(_r0, _w);
            var beta = CalculateVectorNorm(_w);

            if (CheckForExactSolution(beta))
            {
                UnsafeNativeMethods.Zcopy(_nloc, initialGuess.Ptr, result.Ptr);
                return(ResultInfo.Converged(0, 0, 1));
            }

            double bea  = -1;
            double be   = -1;
            int    iter = 0;

            UnsafeNativeMethods.Zcopy(initialGuess.Length, initialGuess.Ptr, result.Ptr);

            while (true)
            {
                NativeVector.Mult(1 / beta, _w, _krylovBasis.GetColumnVector(0));

                _hessenberg[0, _m] = beta;
                for (int i = 1; i <= _m; i++)
                {
                    _hessenberg[i, _m] = Zero;
                }

                int jH = 0;
                bea = KrylovSubspaceConstruction(bn, ref jH);

                if (bea < Parameters.Tolerance)
                {
                    be = FinalActions(jH, sPb, rightHandSide, result);
                    return(ResultInfo.Converged(bea, be, _iterationCounter));
                }

                iter++;


                if (iter >= Parameters.MaxRepeatNumber)
                {
                    break;
                }

                beta = PrepareRestart(rightHandSide, result, jH);
            }

            be = FinalActions(_m, sPb, rightHandSide, result);//ConstructCurrentSolution(_m, result);
            return(ResultInfo.NonConverged(bea, be, _iterationCounter));
        }