Пример #1
0
        public void UpdateResidual(CGAlgorithm cg, IVector residual, out double resDotRes)
        {
            // Update the residual vector normally: r = r - α * A*d
            residual.AxpyIntoThis(cg.MatrixTimesDirection, -cg.StepSize);
            resDotRes = residual.DotProduct(residual); //TODO: it is weird that this sets resDotRes and cg.ResDotRes

            // Check if the CG will converge. TODO: Remove duplicate comutations: this check will also be done by CG later.
            double residualNormRatio = convergence.EstimateResidualNormRatio(cg); // let's pray that ICGResidualConvergence does not mutate any fields
            bool   hasConverged      = residualNormRatio <= residualTolerance;

            // Avoid premature convergence by calculating th exact residual.
            if (hasConverged)
            {
                // Exact residual: r = b - A * x
                ExactResidual.Calculate(cg.Matrix, cg.Rhs, cg.Solution, residual);

                // Recalculate the r * r
                resDotRes = residual.DotProduct(residual);
            }
        }
        /// <summary>
        /// See <see cref="ICGResidualUpdater.UpdateResidual(CGAlgorithm, IVector, out double)"/>
        /// </summary>
        public void UpdateResidual(CGAlgorithm cg, IVector residual, out double resDotRes)
        {
            //TODO: perhaps this should be done in an Initialize() method
            if (numIterationsBeforeCorrection == int.MinValue)
            {
                numIterationsBeforeCorrection = (int)Math.Floor(Math.Sqrt(cg.Rhs.Length));
            }

            if ((cg.Iteration % numIterationsBeforeCorrection == 0) && (cg.Iteration != 0)) //The first iteration uses the correct residual.
            {
                // Calculate the exact residual: r = b - A * x
                ExactResidual.Calculate(cg.Matrix, cg.Rhs, cg.Solution, residual);
            }
            else
            {
                // Normally the residual vector is updated as: r = r - α * A*d
                residual.AxpyIntoThis(cg.MatrixTimesDirection, -cg.StepSize);
            }
            resDotRes = residual.DotProduct(residual);
        }
 /// <summary>
 /// See <see cref="ICGResidualUpdater.UpdateResidual(CGAlgorithm, IVector, out double)"/>
 /// </summary>
 public void UpdateResidual(CGAlgorithm cg, IVector residual, out double resDotRes)
 {
     // Normally the residual vector is updated as: r = r - α * A*d
     residual.AxpyIntoThis(cg.MatrixTimesDirection, -cg.StepSize);
     resDotRes = residual.DotProduct(residual);
 }
 /// <summary>
 /// See <see cref="ICGResidualConvergence.Initialize(CGAlgorithm)"/>
 /// </summary>
 public void Initialize(CGAlgorithm cg) => this.residualNormInitial = Math.Sqrt(cg.ResDotRes);
 /// <summary>
 /// See <see cref="ICGResidualConvergence.EstimateResidualNormRatio(CGAlgorithm)"/>
 /// </summary>
 public double EstimateResidualNormRatio(CGAlgorithm cg) => Math.Sqrt(cg.ResDotRes) / residualNormInitial;