Example #1
0
 /// <summary>
 /// Implementation of the actual code to search for the zeroes of
 /// the <see cref="IObjectiveFunction"/>.
 /// </summary>
 /// <remarks>
 /// It assumes that:
 /// <list type="bullet">
 /// <item>
 ///   <description>
 ///		<see cref="Solver1D.XMin"/> and <see cref="Solver1D.XMax"/> form a valid bracket;
 ///	  </description>
 /// </item>
 /// <item>
 ///   <description>
 ///     <see cref="Solver1D.FXMin"/> and <see cref="Solver1D.FXMax"/> contain the values of the
 ///		function in <see cref="Solver1D.XMin"/> and <see cref="Solver1D.XMax"/>;
 ///	  </description>
 /// </item>
 /// <item>
 ///   <description>
 ///     <see cref="Solver1D.Root"/> was initialized to a valid initial guess.
 ///	  </description>
 /// </item>
 /// </list>
 /// </remarks>
 /// <param name="objectiveFunction">The <see cref="IObjectiveFunction"/>.</param>
 /// <param name="xAccuracy">Given accuracy.</param>
 /// <returns>The zero of the objective function.</returns>
 /// <exception cref="ApplicationException">
 /// Thrown when a bracket is not found after the maximum
 /// number of evaluations (see <see cref="Solver1D.MaxEvaluations"/>).
 /// </exception>
 /// <exception cref="NotImplementedException">
 /// Thrown by the <see cref="ObjectiveFunction"/> base class
 /// when the function's derivative has not been implemented.
 /// </exception>
 protected override double SolveImpl(IObjectiveFunction objectiveFunction,
                                     double xAccuracy)
 {
     while (EvaluationNumber++ < MaxEvaluations)
     {
         double froot  = objectiveFunction.Value(Root);
         double dfroot = objectiveFunction.Derivative(Root);
         double dx     = froot / dfroot;
         Root -= dx;
         // jumped out of brackets, switch to NewtonSafe
         if ((XMin - Root) * (Root - XMax) < 0.0)
         {
             ISolver1D newtonSafe = new NewtonSafe();
             newtonSafe.MaxEvaluations -= EvaluationNumber;
             return(newtonSafe.Solve(objectiveFunction, xAccuracy,
                                     Root + dx, XMin, XMax));
         }
         if (Math.Abs(dx) < xAccuracy)
         {
             return(Root);
         }
     }
     throw new ApplicationException("SlvMaxEval");
 }
Example #2
0
        /// <summary>
        /// Implementation of the actual code to search for the zeroes of
        /// the <see cref="IObjectiveFunction"/>.
        /// </summary>
        /// <remarks>
        /// It assumes that:
        /// <list type="bullet">
        /// <item>
        ///   <description>
        ///		<see cref="Solver1D.XMin"/> and <see cref="Solver1D.XMax"/> form a valid bracket;
        ///	  </description>
        /// </item>
        /// <item>
        ///   <description>
        ///     <see cref="Solver1D.FXMin"/> and <see cref="Solver1D.FXMax"/> contain the values of the
        ///		function in <see cref="Solver1D.XMin"/> and <see cref="Solver1D.XMax"/>;
        ///	  </description>
        /// </item>
        /// <item>
        ///   <description>
        ///     <see cref="Solver1D.Root"/> was initialized to a valid initial guess.
        ///	  </description>
        /// </item>
        /// </list>
        /// </remarks>
        /// <param name="objectiveFunction">The <see cref="IObjectiveFunction"/>.</param>
        /// <param name="xAccuracy">Given accuracy.</param>
        /// <returns>The zero of the objective function.</returns>
        /// <exception cref="ApplicationException">
        /// Thrown when a bracket is not found after the maximum
        /// number of evaluations (see <see cref="Solver1D.MaxEvaluations"/>).
        /// </exception>
        /// <exception cref="NotImplementedException">
        /// Thrown by the <see cref="ObjectiveFunction"/> base class
        /// when the function's derivative has not been implemented.
        /// </exception>
        protected override double SolveImpl(IObjectiveFunction objectiveFunction,
                                            double xAccuracy)
        {
            // Orient the search so that f(xl) < 0
            double xh, xl;

            if (FXMin < 0.0)
            {
                xl = XMin; xh = XMax;
            }
            else
            {
                xh = XMin; xl = XMax;
            }

            // the "stepsize before last"
            double dxold = XMax - XMin;
            // it was dxold=QL_FABS(_xMax_-_xMin_); in Numerical Recipes
            // here (_xMax_-_xMin_ > 0) is verified in the constructor
            // and the last step
            double dx     = dxold;
            double froot  = objectiveFunction.Value(Root);
            double dfroot = objectiveFunction.Derivative(Root);

            // the objectiveFunction throws  System.NotImplementedException
            while (++EvaluationNumber < MaxEvaluations)
            {
                // Bisect if (out of range || not decreasing fast enough)
                if ((((Root - xh) * dfroot - froot) * ((Root - xl) * dfroot - froot) > 0.0) ||
                    (Math.Abs(2.0 * froot) > Math.Abs(dxold * dfroot)))
                {
                    dxold = dx;
                    dx    = (xh - xl) / 2.0;
                    Root  = xl + dx;
                }
                else
                {
                    dxold = dx;
                    dx    = froot / dfroot;
                    Root -= dx;
                }
                // Convergence criterion
                if (Math.Abs(dx) < xAccuracy)
                {
                    return(Root);
                }

                froot  = objectiveFunction.Value(Root);
                dfroot = objectiveFunction.Derivative(Root);

                if (froot < 0.0)
                {
                    xl = Root;
                }
                else
                {
                    xh = Root;
                }
            }
            throw new ApplicationException(String.Format(
                                               "SlvMaxEval")
                                           );
        }