Exemplo n.º 1
0
 /// <summary>Initializes a new instance of the <see cref="State"/> class.
 /// </summary>
 /// <param name="classification">The classification of the result.</param>
 /// <param name="infoOutputPackageAction">A method applied to fill a specific <see cref="InfoOutputPackage"/>.</param>
 /// <param name="infoOutputDetailLevel">The info output detail level.</param>
 protected internal State(NumericalIntegratorErrorClassification classification, Action <InfoOutputPackage> infoOutputPackageAction, InfoOutputDetailLevel infoOutputDetailLevel = InfoOutputDetailLevel.Full)
 {
     Classification        = classification;
     InfoOutputDetailLevel = infoOutputDetailLevel;
     if (infoOutputPackageAction == null)
     {
         throw new ArgumentNullException(nameof(infoOutputPackageAction));
     }
     m_InfoOutputPackageAction = infoOutputPackageAction;
 }
Exemplo n.º 2
0
            /// <summary>Creates a new <see cref="State"/> object.
            /// </summary>
            /// <param name="classification">The classification of the result.</param>
            /// <param name="previousEstimatedValue">A estimation of the numerical integration in a previous iteration step.</param>
            /// <param name="finalEstimatedValue">A estimation of the numerical integraton in the final iteration step.</param>
            /// <param name="iterationsNeeded">The number of iterations needed by the algorithm to reach the desired accuracy.</param>
            /// <returns>A <see cref="State"/> object that represents the state of a specific calculation.</returns>
            public static State Create(NumericalIntegratorErrorClassification classification, double previousEstimatedValue = Double.NaN, double finalEstimatedValue = Double.NaN, int iterationsNeeded = Int32.MaxValue)
            {
                double estimatedAbsoluteError = Math.Abs(previousEstimatedValue - finalEstimatedValue);

                double estimatedRelativeError = estimatedAbsoluteError;

                if (Math.Abs(previousEstimatedValue) > 0.0)
                {
                    estimatedRelativeError /= Math.Abs(previousEstimatedValue);
                }

                return(new State(classification, (infoOutputPackage) =>
                {
                    infoOutputPackage.Add("Estimated absolute error", estimatedAbsoluteError);
                    infoOutputPackage.Add("Estimated relative error", estimatedRelativeError);
                    infoOutputPackage.Add("Iterations needed", iterationsNeeded);
                }));
            }
            /// <summary>Numerically integrates the given function of one variable.
            /// </summary>
            /// <param name="lowerBound">The lower bound.</param>
            /// <param name="upperBound">The upper bound.</param>
            /// <param name="valueAtLowerBound">The value of <see cref="IOneDimNumericalIntegratorAlgorithm.FunctionToIntegrate"/> at <paramref name="lowerBound"/>.</param>
            /// <param name="valueAtUpperBound">The value of <see cref="IOneDimNumericalIntegratorAlgorithm.FunctionToIntegrate"/> at <paramref name="upperBound"/>.</param>
            /// <param name="modulusOfTheIntegral">The modulus of the integral, perhaps magnify with respect to the absolute error tolerance. </param>
            /// <param name="state">The state of the algorithm (input is the state in a previous iteration step).</param>
            /// <returns>An approximation of the specified integral from <paramref name="lowerBound"/> to <paramref name="upperBound"/>.
            /// </returns>
            private double OneStepIntegration(double lowerBound, double upperBound, double valueAtLowerBound, double valueAtUpperBound, double modulusOfTheIntegral, ref NumericalIntegratorErrorClassification state)
            {
                double h = (upperBound - lowerBound) / 2.0;
                double m = (lowerBound + upperBound) / 2.0;

                double mll  = m - MathConsts.SqrtTwoOverThree * h;
                double fmll = FunctionToIntegrate(mll);
                double ml   = m - MathConsts.OneOverSqrt5 * h;
                double fml  = FunctionToIntegrate(ml);
                double fm   = FunctionToIntegrate(m);
                double mr   = m + MathConsts.OneOverSqrt5 * h;
                double fmr  = FunctionToIntegrate(mr);
                double mrr  = m + MathConsts.SqrtTwoOverThree * h;
                double fmrr = FunctionToIntegrate(mrr);

                m_FunctionEvaluationsNeeded += 5;

                // calculate two approximations for the sub-integral:
                double value1 = (h / 1470.0) * (77.0 * (valueAtLowerBound + valueAtUpperBound) + 432.0 * (fmll + fmrr) + 625.0 * (fml + fmr) + 672.0 * fm);
                double value2 = (h / 6.0) * (valueAtLowerBound + valueAtUpperBound + 5.0 * (fml + fmr));

                if ((state != NumericalIntegratorErrorClassification.ProperResult) && (state != NumericalIntegratorErrorClassification.NoResult))
                {
                    m_BenchmarkEstimation += value2;
                    return(value1);  // the algorithm already fails
                }
                else
                {
                    if ((m <= lowerBound) || (upperBound <= m))
                    {
                        state = NumericalIntegratorErrorClassification.Divergent;
                        m_BenchmarkEstimation += value2;
                        return(value1);
                    }
                    if (m_IterationsNeeded >= m_IntegratorFactory.ExitCondition.MaxIterations)
                    {
                        state = NumericalIntegratorErrorClassification.IterationLimitExceeded;
                        m_BenchmarkEstimation += value2;
                        return(value1);
                    }
                    if (m_FunctionEvaluationsNeeded >= m_IntegratorFactory.ExitCondition.MaxEvaluations)
                    {
                        state = NumericalIntegratorErrorClassification.EvaluationLimitExceeded;
                        m_BenchmarkEstimation += value2;
                        return(value1);
                    }

                    /* check whether the tolerance is reached: */
                    if (Double.IsNaN(m_IntegratorFactory.ExitCondition.Tolerance) == false)
                    {
                        // Attention! Here we compare two double values, see paper!
                        if ((modulusOfTheIntegral + (value1 - value2) == modulusOfTheIntegral) || (mll <= lowerBound) || (upperBound <= mrr))
                        {
                            if ((m <= lowerBound) || (upperBound <= m))  // Interval contains no more machine number. Required tolerance may not be met.
                            {
                                state = NumericalIntegratorErrorClassification.RoundOffError;
                            }
                            else
                            {
                                state = NumericalIntegratorErrorClassification.ProperResult;
                            }
                            m_BenchmarkEstimation += value2;
                            return(value1);
                        }
                    }
                    m_IterationsNeeded++;
                    return(OneStepIntegration(lowerBound, mll, valueAtLowerBound, fmll, modulusOfTheIntegral, ref state) +
                           OneStepIntegration(mll, ml, fmll, fml, modulusOfTheIntegral, ref state) +
                           OneStepIntegration(ml, m, fml, fm, modulusOfTheIntegral, ref state) +
                           OneStepIntegration(m, mr, fm, fmr, modulusOfTheIntegral, ref state) +
                           OneStepIntegration(mr, mrr, fmr, fmrr, modulusOfTheIntegral, ref state) +
                           OneStepIntegration(mrr, upperBound, fmrr, valueAtUpperBound, modulusOfTheIntegral, ref state));
                }
            }
Exemplo n.º 4
0
 /// <summary>Initializes a new instance of the <see cref="State"/> class.
 /// </summary>
 /// <param name="classification">The classification of the result.</param>
 /// <param name="infoOutputDetailLevel">The info output detail level.</param>
 protected internal State(NumericalIntegratorErrorClassification classification, InfoOutputDetailLevel infoOutputDetailLevel = InfoOutputDetailLevel.Full)
 {
     Classification            = classification;
     InfoOutputDetailLevel     = infoOutputDetailLevel;
     m_InfoOutputPackageAction = null;
 }
Exemplo n.º 5
0
 /// <summary>Creates a new <see cref="State"/> object.
 /// </summary>
 /// <param name="classification">The classification of the result.</param>
 /// <returns>A <see cref="State"/> object that represents the state of a specific calculation.</returns>
 public static State Create(NumericalIntegratorErrorClassification classification)
 {
     return(new State(classification));
 }