示例#1
0
        protected override double solveImpl(ISolver1d f, double xAccuracy) {

            /* The implementation of the algorithm was inspired by
               Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition, Cambridge
               University Press
            */

            double dx, xMid, fMid;

            // Orient the search so that f>0 lies at root_+dx
            if (fxMin_ < 0.0) {
                dx = xMax_-xMin_;
                root_ = xMin_;
            } else {
                dx = xMin_-xMax_;
                root_ = xMax_;
            }

            while (evaluationNumber_ <= maxEvaluations_) {
                dx /= 2.0;
                xMid = root_ + dx;
                fMid = f.value(xMid);
                evaluationNumber_++;
                if (fMid <= 0.0)
                    root_ = xMid;
                if (Math.Abs(dx) < xAccuracy || fMid == 0.0) {
                    return root_;
                }
            }
             throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#2
0
文件: Newton.cs 项目: akasolace/qlnet
        protected override double solveImpl(ISolver1d f, double xAccuracy) {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double froot, dfroot, dx;

            froot = f.value(root_);
            dfroot = f.derivative(root_);

            if (dfroot == default(double))
                throw new ArgumentException("Newton requires function's derivative");
            evaluationNumber_++;

            while (evaluationNumber_<=maxEvaluations_) {
                dx=froot/dfroot;
                root_ -= dx;
                // jumped out of brackets, switch to NewtonSafe
                if ((xMin_-root_)*(root_-xMax_) < 0.0) {
                    NewtonSafe s = new NewtonSafe();
                    s.setMaxEvaluations(maxEvaluations_-evaluationNumber_);
                    return s.solve(f, xAccuracy, root_+dx, xMin_, xMax_);
                }
                if (Math.Abs(dx) < xAccuracy)
                    return root_;
                froot = f.value(root_);
                dfroot = f.derivative(root_);
                evaluationNumber_++;
            }

            throw new ApplicationException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#3
0
文件: Ridder.cs 项目: ammachado/QLNet
        protected override double solveImpl(ISolver1d f, double xAcc)
        {
            /* The implementation of the algorithm was inspired by
               Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition, Cambridge
               University Press
            */

            double fxMid, froot, s, xMid, nextRoot;

            // test on Black-Scholes implied volatility show that
            // Ridder solver algorithm actually provides an
            // accuracy 100 times below promised
            double xAccuracy = xAcc/100.0;

            // Any highly unlikely value, to simplify logic below
            root_ = double.MinValue;

            while (evaluationNumber_ <= maxEvaluations_) {
                xMid = 0.5*(xMin_ + xMax_);
                // First of two function evaluations per iteraton
                fxMid = f.value(xMid);
                evaluationNumber_++;
                s = Math.Sqrt(fxMid*fxMid - fxMin_*fxMax_);
                if (s == 0.0)
                    return root_;
                // Updating formula
                nextRoot = xMid + (xMid - xMin_) *
                    ((fxMin_  >= fxMax_ ? 1.0 : -1.0) * fxMid / s);
                if (Math.Abs(nextRoot-root_) <= xAccuracy)
                    return root_;

                root_ = nextRoot;
                // Second of two function evaluations per iteration
                froot = f.value(root_);
                evaluationNumber_++;
                if (froot == 0.0)
                    return root_;

                // Bookkeeping to keep the root bracketed on next iteration
                if (sign(fxMid,froot) != fxMid) {
                    xMin_ = xMid;
                    fxMin_ = fxMid;
                    xMax_ = root_;
                    fxMax_ = froot;
                } else if (sign(fxMin_,froot) != fxMin_) {
                    xMax_ = root_;
                    fxMax_ = froot;
                } else if (sign(fxMax_,froot) != fxMax_) {
                    xMin_ = root_;
                    fxMin_ = froot;
                } else {
                    throw new Exception("never get here.");
                }

                if (Math.Abs(xMax_-xMin_) <= xAccuracy) return root_;
            }

             throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#4
0
        /*! This method returns the zero of the function \f$ f \f$, determined with the given accuracy \f$ \epsilon \f$;
            depending on the particular solver, this might mean that the returned \f$ x \f$ is such that \f$ |f(x)| < \epsilon
            \f$, or that \f$ |x-\xi| < \epsilon \f$ where \f$ \xi \f$ is the real zero.

            This method contains a bracketing routine to which an initial guess must be supplied as well as a step used to
            scan the range of the possible bracketing values.
        */
        public double solve(ISolver1d f, double accuracy, double guess, double step) {

            if (accuracy <= 0.0)
                throw new ArgumentException("accuracy (" + accuracy + ") must be positive");

            // check whether we really want to use epsilon
            accuracy = Math.Max(accuracy, Const.QL_EPSILON);

            const double growthFactor = 1.6;
            int flipflop = -1;

            root_ = guess;
            fxMax_ = f.value(root_);

            // monotonically crescent bias, as in optionValue(volatility)
            if (fxMax_ == 0.0)
                return root_;
            else if (fxMax_ > 0.0) {
                xMin_ = enforceBounds_(root_ - step);
                fxMin_ = f.value(xMin_);
                xMax_ = root_;
            } else {
                xMin_ = root_;
                fxMin_ = fxMax_;
                xMax_ = enforceBounds_(root_ + step);
                fxMax_ = f.value(xMax_);
            }

            evaluationNumber_ = 2;
            while (evaluationNumber_ <= maxEvaluations_) {
                if (fxMin_ * fxMax_ <= 0.0) {
                    if (fxMin_ == 0.0) return xMin_;
                    if (fxMax_ == 0.0) return xMax_;
                    root_ = (xMax_ + xMin_) / 2.0;
                    return solveImpl(f, accuracy);
                }
                if (Math.Abs(fxMin_) < Math.Abs(fxMax_)) {
                    xMin_ = enforceBounds_(xMin_ + growthFactor * (xMin_ - xMax_));
                    fxMin_ = f.value(xMin_);
                } else if (Math.Abs(fxMin_) > Math.Abs(fxMax_)) {
                    xMax_ = enforceBounds_(xMax_ + growthFactor * (xMax_ - xMin_));
                    fxMax_ = f.value(xMax_);
                } else if (flipflop == -1) {
                    xMin_ = enforceBounds_(xMin_ + growthFactor * (xMin_ - xMax_));
                    fxMin_ = f.value(xMin_);
                    evaluationNumber_++;
                    flipflop = 1;
                } else if (flipflop == 1) {
                    xMax_ = enforceBounds_(xMax_ + growthFactor * (xMax_ - xMin_));
                    fxMax_ = f.value(xMax_);
                    flipflop = -1;
                }
                evaluationNumber_++;
            }

            throw new ArgumentException("unable to bracket root in " + maxEvaluations_
                + " function evaluations (last bracket attempt: " + "f[" + xMin_ + "," + xMax_ + "] "
                + "-> [" + fxMin_ + "," + fxMax_ + "])");
        }
示例#5
0
        //! safe %Newton 1-D solver
        /*! \note This solver requires that the passed function object
                  implement a method <tt>Real derivative(Real)</tt>.
        */
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double froot, dfroot, dx, dxold;
            double xh, xl;

            // Orient the search so that f(xl) < 0
            if (fxMin_ < 0.0) {
                xl=xMin_;
                xh=xMax_;
            } else {
                xh=xMin_;
                xl=xMax_;
            }

            // the "stepsize before last"
            dxold=xMax_-xMin_;
            // it was dxold=std::fabs(xMax_-xMin_); in Numerical Recipes
            // here (xMax_-xMin_ > 0) is verified in the constructor

            // and the last step
            dx=dxold;

            froot = f.value(root_);
            dfroot = f.derivative(root_);
            if (dfroot == default(double))
                throw new ArgumentException("Newton requires function's derivative");
            evaluationNumber_++;

            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 = f.value(root_);
                dfroot = f.derivative(root_);
                evaluationNumber_++;
                if (froot < 0.0)
                    xl=root_;
                else
                    xh=root_;
            }

            throw new ApplicationException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#6
0
        /*! This method returns the zero of the function \f$ f \f$, determined with the given accuracy \f$ \epsilon \f$;
         *  depending on the particular solver, this might mean that the returned \f$ x \f$ is such that \f$ |f(x)| < \epsilon
         *  \f$, or that \f$ |x-\xi| < \epsilon \f$ where \f$ \xi \f$ is the real zero.
         *
         *  An initial guess must be supplied, as well as two values \f$ x_\mathrm{min} \f$ and \f$ x_\mathrm{max} \f$ which
         *  must bracket the zero (i.e., either \f$ f(x_\mathrm{min}) \leq 0 \leq f(x_\mathrm{max}) \f$, or \f$
         *  f(x_\mathrm{max}) \leq 0 \leq f(x_\mathrm{min}) \f$ must be true).
         */
        public double solve(ISolver1d f, double accuracy, double guess, double xMin, double xMax)
        {
            if (accuracy <= 0.0)
            {
                throw new ArgumentException("accuracy (" + accuracy + ") must be positive");
            }

            // check whether we really want to use epsilon
            accuracy = Math.Max(accuracy, Const.QL_Epsilon);

            xMin_ = xMin;
            xMax_ = xMax;

            if (!(xMin_ < xMax_))
            {
                throw new ArgumentException("invalid range: xMin_ (" + xMin_ + ") >= xMax_ (" + xMax_ + ")");
            }
            if (!(!lowerBoundEnforced_ || xMin_ >= lowerBound_))
            {
                throw new ArgumentException("xMin_ (" + xMin_ + ") < enforced low bound (" + lowerBound_ + ")");
            }
            if (!(!upperBoundEnforced_ || xMax_ <= upperBound_))
            {
                throw new ArgumentException("xMax_ (" + xMax_ + ") > enforced hi bound (" + upperBound_ + ")");
            }

            fxMin_ = f.value(xMin_);
            if (fxMin_ == 0.0)
            {
                return(xMin_);
            }

            fxMax_ = f.value(xMax_);
            if (fxMax_ == 0.0)
            {
                return(xMax_);
            }

            evaluationNumber_ = 2;

            if (!(fxMin_ * fxMax_ < 0.0))
            {
                throw new ArgumentException("root not bracketed: f[" + xMin_ + "," + xMax_ + "] -> [" + fxMin_ + "," + fxMax_ + "]");
            }
            if (!(guess > xMin_))
            {
                throw new ArgumentException("guess (" + guess + ") < xMin_ (" + xMin_ + ")");
            }
            if (!(guess < xMax_))
            {
                throw new ArgumentException("guess (" + guess + ") > xMax_ (" + xMax_ + ")");
            }

            root_ = guess;

            return(solveImpl(f, accuracy));
        }
示例#7
0
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by
             * Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition,
             * Cambridge University Press
             */

            double fl, fh, xl, xh, dx, del, froot;

            // Identify the limits so that xl corresponds to the low side
            if (fxMin_ < 0.0)
            {
                xl = xMin_;
                fl = fxMin_;
                xh = xMax_;
                fh = fxMax_;
            }
            else
            {
                xl = xMax_;
                fl = fxMax_;
                xh = xMin_;
                fh = fxMin_;
            }
            dx = xh - xl;

            while (evaluationNumber_ <= maxEvaluations_)
            {
                // Increment with respect to latest value
                root_ = xl + dx * fl / (fl - fh);
                froot = f.value(root_);
                evaluationNumber_++;
                if (froot < 0.0)     // Replace appropriate limit
                {
                    del = xl - root_;
                    xl  = root_;
                    fl  = froot;
                }
                else
                {
                    del = xh - root_;
                    xh  = root_;
                    fh  = froot;
                }
                dx = xh - xl;
                // Convergence criterion
                if (Math.Abs(del) < xAccuracy || Utils.close(froot, 0.0))
                {
                    return(root_);
                }
            }
            Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded",
                          QLNetExceptionEnum.MaxNumberFuncEvalExceeded);
            return(0);
        }
		protected override double solveImpl(ISolver1d f, 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_;
			}

			double froot = f.value(root_);
			++evaluationNumber_;
			// first order finite difference derivative
			double dfroot = xMax_-root_ < root_-xMin_ ?
			(fxMax_-froot)/(xMax_-root_) :
			(fxMin_-froot)/(xMin_-root_) ;

			// xMax_-xMin_>0 is verified in the constructor
			double dx = xMax_-xMin_;
			while (evaluationNumber_<=maxEvaluations_) {
			double frootold = froot;
			double rootold = root_;
			double dxold = dx;
			// 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))) {

				dx = (xh-xl)/2.0;
				root_ = xl+dx;
			} else { // Newton
				dx = froot/dfroot;
				root_ -= dx;
			}

			// Convergence criterion
			if (Math.Abs(dx) < xAccuracy)
				return root_;

			froot = f.value(root_);
			++evaluationNumber_;
			dfroot = (frootold-froot)/(rootold-root_);

			if (froot < 0.0)
				xl=root_;
			else
				xh=root_;
			}

			throw new ArgumentException( "maximum number of function evaluations (" + maxEvaluations_ + ") exceeded" );

		}
示例#9
0
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by
               Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition,
               Cambridge University Press
            */

            double fl, fh, xl, xh, dx, del, froot;

            // Identify the limits so that xl corresponds to the low side
            if (fxMin_ < 0.0) {
                xl = xMin_;
                fl = fxMin_;
                xh = xMax_;
                fh = fxMax_;
            } else {
                xl = xMax_;
                fl = fxMax_;
                xh = xMin_;
                fh = fxMin_;
            }
            dx = xh - xl ;

            while (evaluationNumber_ <= maxEvaluations_) {
                // Increment with respect to latest value
                root_ = xl + dx*fl/(fl-fh);
                froot = f.value(root_);
                evaluationNumber_++;
                if (froot < 0.0) {       // Replace appropriate limit
                    del = xl - root_;
                    xl = root_;
                    fl = froot;
                } else {
                    del = xh - root_;
                    xh = root_;
                    fh = froot;
                }
                dx = xh - xl;
                // Convergence criterion
                if (Math.Abs(del) < xAccuracy || froot == 0.0)  {
                    return root_;
                }
            }
             throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#10
0
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by
             * Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge
             * University Press
             */

            double fl, froot, dx, xl;

            // Pick the bound with the smaller function value
            // as the most recent guess
            if (Math.Abs(fxMin_) < Math.Abs(fxMax_))
            {
                root_ = xMin_;
                froot = fxMin_;
                xl    = xMax_;
                fl    = fxMax_;
            }
            else
            {
                root_ = xMax_;
                froot = fxMax_;
                xl    = xMin_;
                fl    = fxMin_;
            }
            while (evaluationNumber_ <= maxEvaluations_)
            {
                dx     = (xl - root_) * froot / (froot - fl);
                xl     = root_;
                fl     = froot;
                root_ += dx;
                froot  = f.value(root_);
                ++evaluationNumber_;
                if (Math.Abs(dx) < xAccuracy || Utils.close(froot, 0.0))
                {
                    return(root_);
                }
            }

            Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded",
                          QLNetExceptionEnum.MaxNumberFuncEvalExceeded);
            return(0);
        }
示例#11
0
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by
             * Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge
             * University Press
             */

            double dx, xMid, fMid;

            // Orient the search so that f>0 lies at root_+dx
            if (fxMin_ < 0.0)
            {
                dx    = xMax_ - xMin_;
                root_ = xMin_;
            }
            else
            {
                dx    = xMin_ - xMax_;
                root_ = xMax_;
            }

            while (evaluationNumber_ <= maxEvaluations_)
            {
                dx  /= 2.0;
                xMid = root_ + dx;
                fMid = f.value(xMid);
                evaluationNumber_++;
                if (fMid <= 0.0)
                {
                    root_ = xMid;
                }
                if (Math.Abs(dx) < xAccuracy || Utils.close(fMid, 0.0))
                {
                    return(root_);
                }
            }
            Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded",
                          QLNetExceptionEnum.MaxNumberFuncEvalExceeded);
            return(0);
        }
示例#12
0
文件: Newton.cs 项目: vivasvan/QLNet
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double froot, dfroot, dx;

            froot  = f.value(root_);
            dfroot = f.derivative(root_);

            if (dfroot.IsEqual(default(double)))
            {
                throw new ArgumentException("Newton requires function's derivative");
            }
            ++evaluationNumber_;

            while (evaluationNumber_ <= maxEvaluations_)
            {
                dx     = froot / dfroot;
                root_ -= dx;
                // jumped out of brackets, switch to NewtonSafe
                if ((xMin_ - root_) * (root_ - xMax_) < 0.0)
                {
                    NewtonSafe s = new NewtonSafe();
                    s.setMaxEvaluations(maxEvaluations_ - evaluationNumber_);
                    return(s.solve(f, xAccuracy, root_ + dx, xMin_, xMax_));
                }
                if (Math.Abs(dx) < xAccuracy)
                {
                    return(root_);
                }
                froot  = f.value(root_);
                dfroot = f.derivative(root_);
                evaluationNumber_++;
            }

            Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded",
                          QLNetExceptionEnum.MaxNumberFuncEvalExceeded);
            return(0);
        }
示例#13
0
文件: Solver1d.cs 项目: igitur/qlnet
        /*! This method returns the zero of the function \f$ f \f$, determined with the given accuracy \f$ \epsilon \f$
         *  depending on the particular solver, this might mean that the returned \f$ x \f$ is such that \f$ |f(x)| < \epsilon
         *  \f$, or that \f$ |x-\xi| < \epsilon \f$ where \f$ \xi \f$ is the real zero.
         *
         *  An initial guess must be supplied, as well as two values \f$ x_\mathrm{min} \f$ and \f$ x_\mathrm{max} \f$ which
         *  must bracket the zero (i.e., either \f$ f(x_\mathrm{min}) \leq 0 \leq f(x_\mathrm{max}) \f$, or \f$
         *  f(x_\mathrm{max}) \leq 0 \leq f(x_\mathrm{min}) \f$ must be true).
         */

        public double solve(ISolver1d f, double accuracy, double guess, double xMin, double xMax)
        {
            Utils.QL_REQUIRE(accuracy > 0.0, () => "accuracy (" + accuracy + ") must be positive");

            // check whether we really want to use epsilon
            accuracy = Math.Max(accuracy, Const.QL_EPSILON);

            xMin_ = xMin;
            xMax_ = xMax;

            Utils.QL_REQUIRE(xMin_ < xMax_, () => "invalid range: xMin_ (" + xMin_ + ") >= xMax_ (" + xMax_ + ")");
            Utils.QL_REQUIRE(!lowerBoundEnforced_ || xMin_ >= lowerBound_, () =>
                             "xMin_ (" + xMin_ + ") < enforced low bound (" + lowerBound_ + ")");
            Utils.QL_REQUIRE(!upperBoundEnforced_ || xMax_ <= upperBound_, () =>
                             "xMax_ (" + xMax_ + ") > enforced hi bound (" + upperBound_ + ")");

            fxMin_ = f.value(xMin_);
            if (Utils.close(fxMin_, 0.0))
            {
                return(xMin_);
            }

            fxMax_ = f.value(xMax_);
            if (Utils.close(fxMax_, 0.0))
            {
                return(xMax_);
            }

            evaluationNumber_ = 2;

            Utils.QL_REQUIRE(fxMin_ * fxMax_ < 0.0, () =>
                             "root not bracketed: f[" + xMin_ + "," + xMax_ + "] -> [" + fxMin_ + "," + fxMax_ + "]");
            Utils.QL_REQUIRE(guess > xMin_, () => "guess (" + guess + ") < xMin_ (" + xMin_ + ")");
            Utils.QL_REQUIRE(guess < xMax_, () => "guess (" + guess + ") > xMax_ (" + xMax_ + ")");

            root_ = guess;

            return(solveImpl(f, accuracy));
        }
示例#14
0
文件: Secant.cs 项目: vdt/QLNet
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by
               Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition, Cambridge
               University Press
            */

            double fl, froot, dx, xl;

            // Pick the bound with the smaller function value
            // as the most recent guess
            if (Math.Abs(fxMin_) < Math.Abs(fxMax_)) {
                root_ = xMin_;
                froot = fxMin_;
                xl = xMax_;
                fl = fxMax_;
            } else {
                root_ = xMax_;
                froot = fxMax_;
                xl = xMin_;
                fl = fxMin_;
            }
            while (evaluationNumber_ <= maxEvaluations_) {
                dx = (xl-root_)*froot/(froot-fl);
                xl = root_;
                fl = froot;
                root_ += dx;
                froot = f.value(root_);
                evaluationNumber_++;
                if (Math.Abs(dx) < xAccuracy || froot == 0.0)
                    return root_;
            }

             throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#15
0
        //! safe %Newton 1-D solver

        /*! \note This solver requires that the passed function object
         *        implement a method <tt>Real derivative(Real)</tt>.
         */
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double froot, dfroot, dx, dxold;
            double xh, xl;

            // Orient the search so that f(xl) < 0
            if (fxMin_ < 0.0)
            {
                xl = xMin_;
                xh = xMax_;
            }
            else
            {
                xh = xMin_;
                xl = xMax_;
            }

            // the "stepsize before last"
            dxold = xMax_ - xMin_;
            // it was dxold=std::fabs(xMax_-xMin_); in Numerical Recipes
            // here (xMax_-xMin_ > 0) is verified in the constructor

            // and the last step
            dx = dxold;

            froot  = f.value(root_);
            dfroot = f.derivative(root_);
            if (dfroot == default(double))
            {
                throw new ArgumentException("Newton requires function's derivative");
            }
            ++evaluationNumber_;

            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  = f.value(root_);
                dfroot = f.derivative(root_);
                evaluationNumber_++;
                if (froot < 0.0)
                {
                    xl = root_;
                }
                else
                {
                    xh = root_;
                }
            }

            throw new ApplicationException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#16
0
文件: Solver1d.cs 项目: vdt/QLNet
 protected abstract double solveImpl(ISolver1d f, double xAccuracy);
示例#17
0
文件: Solver1d.cs 项目: vdt/QLNet
        /*! This method returns the zero of the function \f$ f \f$, determined with the given accuracy \f$ \epsilon \f$;
            depending on the particular solver, this might mean that the returned \f$ x \f$ is such that \f$ |f(x)| < \epsilon
            \f$, or that \f$ |x-\xi| < \epsilon \f$ where \f$ \xi \f$ is the real zero.

            An initial guess must be supplied, as well as two values \f$ x_\mathrm{min} \f$ and \f$ x_\mathrm{max} \f$ which
            must bracket the zero (i.e., either \f$ f(x_\mathrm{min}) \leq 0 \leq f(x_\mathrm{max}) \f$, or \f$
            f(x_\mathrm{max}) \leq 0 \leq f(x_\mathrm{min}) \f$ must be true).
        */
        public double solve(ISolver1d f, double accuracy, double guess, double xMin, double xMax)
        {
            if (accuracy <= 0.0)
                throw new ArgumentException("accuracy (" + accuracy + ") must be positive");

            // check whether we really want to use epsilon
            accuracy = Math.Max(accuracy, Const.QL_Epsilon);

            xMin_ = xMin;
            xMax_ = xMax;

            if (!(xMin_ < xMax_))
                throw new ArgumentException("invalid range: xMin_ (" + xMin_ + ") >= xMax_ (" + xMax_ + ")");
            if (!(!lowerBoundEnforced_ || xMin_ >= lowerBound_))
                throw new ArgumentException("xMin_ (" + xMin_ + ") < enforced low bound (" + lowerBound_ + ")");
            if (!(!upperBoundEnforced_ || xMax_ <= upperBound_))
                throw new ArgumentException("xMax_ (" + xMax_ + ") > enforced hi bound (" + upperBound_ + ")");

            fxMin_ = f.value(xMin_);
            if (fxMin_ == 0.0) return xMin_;

            fxMax_ = f.value(xMax_);
            if (fxMax_ == 0.0) return xMax_;

            evaluationNumber_ = 2;

            if (!(fxMin_ * fxMax_ < 0.0))
                throw new ArgumentException("root not bracketed: f[" + xMin_ + "," + xMax_ + "] -> [" + fxMin_ + "," + fxMax_ + "]");
            if (!(guess > xMin_))
                throw new ArgumentException("guess (" + guess + ") < xMin_ (" + xMin_ + ")");
            if (!(guess < xMax_))
                throw new ArgumentException("guess (" + guess + ") > xMax_ (" + xMax_ + ")");

            root_ = guess;

            return solveImpl(f, accuracy);
        }
示例#18
0
文件: Solver1d.cs 项目: igitur/qlnet
 protected abstract double solveImpl(ISolver1d f, double xAccuracy);
示例#19
0
文件: Solver1d.cs 项目: igitur/qlnet
        /*! This method returns the zero of the function \f$ f \f$, determined with the given accuracy \f$ \epsilon \f$
         *          depending on the particular solver, this might mean that the returned \f$ x \f$ is such that \f$ |f(x)| < \epsilon
         *          \f$, or that \f$ |x-\xi| < \epsilon \f$ where \f$ \xi \f$ is the real zero.
         *
         *          This method contains a bracketing routine to which an initial guess must be supplied as well as a step used to
         *          scan the range of the possible bracketing values.
         */

        public double solve(ISolver1d f, double accuracy, double guess, double step)
        {
            Utils.QL_REQUIRE(accuracy > 0.0, () => "accuracy (" + accuracy + ") must be positive");

            // check whether we really want to use epsilon
            accuracy = Math.Max(accuracy, Const.QL_EPSILON);

            const double growthFactor = 1.6;
            int          flipflop     = -1;

            root_  = guess;
            fxMax_ = f.value(root_);

            // monotonically crescent bias, as in optionValue(volatility)
            if (Utils.close(fxMax_, 0.0))
            {
                return(root_);
            }
            else if (fxMax_ > 0.0)
            {
                xMin_  = enforceBounds_(root_ - step);
                fxMin_ = f.value(xMin_);
                xMax_  = root_;
            }
            else
            {
                xMin_  = root_;
                fxMin_ = fxMax_;
                xMax_  = enforceBounds_(root_ + step);
                fxMax_ = f.value(xMax_);
            }

            evaluationNumber_ = 2;
            while (evaluationNumber_ <= maxEvaluations_)
            {
                if (fxMin_ * fxMax_ <= 0.0)
                {
                    if (Utils.close(fxMin_, 0.0))
                    {
                        return(xMin_);
                    }
                    if (Utils.close(fxMax_, 0.0))
                    {
                        return(xMax_);
                    }
                    root_ = (xMax_ + xMin_) / 2.0;
                    return(solveImpl(f, accuracy));
                }
                if (Math.Abs(fxMin_) < Math.Abs(fxMax_))
                {
                    xMin_  = enforceBounds_(xMin_ + growthFactor * (xMin_ - xMax_));
                    fxMin_ = f.value(xMin_);
                }
                else if (Math.Abs(fxMin_) > Math.Abs(fxMax_))
                {
                    xMax_  = enforceBounds_(xMax_ + growthFactor * (xMax_ - xMin_));
                    fxMax_ = f.value(xMax_);
                }
                else if (flipflop == -1)
                {
                    xMin_  = enforceBounds_(xMin_ + growthFactor * (xMin_ - xMax_));
                    fxMin_ = f.value(xMin_);
                    evaluationNumber_++;
                    flipflop = 1;
                }
                else if (flipflop == 1)
                {
                    xMax_    = enforceBounds_(xMax_ + growthFactor * (xMax_ - xMin_));
                    fxMax_   = f.value(xMax_);
                    flipflop = -1;
                }
                evaluationNumber_++;
            }

            Utils.QL_FAIL("unable to bracket root in " + maxEvaluations_
                          + " function evaluations (last bracket attempt: " + "f[" + xMin_ + "," + xMax_ +
                          "] "
                          + "-> [" + fxMin_ + "," + fxMax_ + "])");
            return(0);
        }
示例#20
0
文件: Ridder.cs 项目: igitur/qlnet
        protected override double solveImpl(ISolver1d f, double xAcc)
        {
            /* The implementation of the algorithm was inspired by
             * Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge
             * University Press
             */

            double fxMid, froot, s, xMid, nextRoot;

            // test on Black-Scholes implied volatility show that
            // Ridder solver algorithm actually provides an
            // accuracy 100 times below promised
            double xAccuracy = xAcc / 100.0;

            // Any highly unlikely value, to simplify logic below
            root_ = double.MinValue;

            while (evaluationNumber_ <= maxEvaluations_)
            {
                xMid = 0.5 * (xMin_ + xMax_);
                // First of two function evaluations per iteraton
                fxMid = f.value(xMid);
                ++evaluationNumber_;
                s = Math.Sqrt(fxMid * fxMid - fxMin_ * fxMax_);
                if (Utils.close(s, 0.0))
                {
                    return(root_);
                }
                // Updating formula
                nextRoot = xMid + (xMid - xMin_) *
                           ((fxMin_ >= fxMax_ ? 1.0 : -1.0) * fxMid / s);
                if (Math.Abs(nextRoot - root_) <= xAccuracy)
                {
                    return(root_);
                }

                root_ = nextRoot;
                // Second of two function evaluations per iteration
                froot = f.value(root_);
                ++evaluationNumber_;
                if (Utils.close(froot, 0.0))
                {
                    return(root_);
                }

                // Bookkeeping to keep the root bracketed on next iteration
                if (sign(fxMid, froot).IsNotEqual(fxMid))
                {
                    xMin_  = xMid;
                    fxMin_ = fxMid;
                    xMax_  = root_;
                    fxMax_ = froot;
                }
                else if (sign(fxMin_, froot).IsNotEqual(fxMin_))
                {
                    xMax_  = root_;
                    fxMax_ = froot;
                }
                else if (sign(fxMax_, froot).IsNotEqual(fxMax_))
                {
                    xMin_  = root_;
                    fxMin_ = froot;
                }
                else
                {
                    Utils.QL_FAIL("never get here.");
                }

                if (Math.Abs(xMax_ - xMin_) <= xAccuracy)
                {
                    return(root_);
                }
            }

            throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#21
0
文件: Brent.cs 项目: akasolace/qlnet
        protected override double solveImpl(ISolver1d f, double xAccuracy) {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
               "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double min1, min2;
            double froot, p, q, r, s, xAcc1, xMid;
            // dummy assignements to avoid compiler warning
            double d = 0.0, e = 0.0;

            root_ = xMax_;
            froot = fxMax_;
            while (evaluationNumber_ <= maxEvaluations_) {
                if ((froot > 0.0 && fxMax_ > 0.0) ||
                    (froot < 0.0 && fxMax_ < 0.0)) {

                    // Rename xMin_, root_, xMax_ and adjust bounds
                    xMax_ = xMin_;
                    fxMax_ = fxMin_;
                    e = d = root_ - xMin_;
                }
                if (Math.Abs(fxMax_) < Math.Abs(froot)) {
                    xMin_ = root_;
                    root_ = xMax_;
                    xMax_ = xMin_;
                    fxMin_ = froot;
                    froot = fxMax_;
                    fxMax_ = fxMin_;
                }
                // Convergence check
                xAcc1 = 2.0 * Const.QL_EPSILON * Math.Abs(root_) + 0.5 * xAccuracy;
                xMid = (xMax_ - root_) / 2.0;
                if (Math.Abs(xMid) <= xAcc1 || froot == 0.0)
                    return root_;
                if (Math.Abs(e) >= xAcc1 &&
                    Math.Abs(fxMin_) > Math.Abs(froot)) {

                    // Attempt inverse quadratic interpolation
                    s = froot / fxMin_;
                    if (xMin_ == xMax_) {
                        p = 2.0 * xMid * s;
                        q = 1.0 - s;
                    } else {
                        q = fxMin_ / fxMax_;
                        r = froot / fxMax_;
                        p = s * (2.0 * xMid * q * (q - r) - (root_ - xMin_) * (r - 1.0));
                        q = (q - 1.0) * (r - 1.0) * (s - 1.0);
                    }
                    if (p > 0.0) q = -q;  // Check whether in bounds
                    p = Math.Abs(p);
                    min1 = 3.0 * xMid * q - Math.Abs(xAcc1 * q);
                    min2 = Math.Abs(e * q);
                    if (2.0 * p < (min1 < min2 ? min1 : min2)) {
                        e = d;                // Accept interpolation
                        d = p / q;
                    } else {
                        d = xMid;  // Interpolation failed, use bisection
                        e = d;
                    }
                } else {
                    // Bounds decreasing too slowly, use bisection
                    d = xMid;
                    e = d;
                }
                xMin_ = root_;
                fxMin_ = froot;
                if (Math.Abs(d) > xAcc1)
                    root_ += d;
                else
                    root_ += Math.Abs(xAcc1) * Math.Sign(xMid);
                froot = f.value(root_);
                evaluationNumber_++;
            }
            throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#22
0
        protected override double solveImpl(ISolver1d f, 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_;
            }

            double froot = f.value(root_);

            ++evaluationNumber_;
            // first order finite difference derivative
            double dfroot = xMax_ - root_ < root_ - xMin_ ?
                            (fxMax_ - froot) / (xMax_ - root_) :
                            (fxMin_ - froot) / (xMin_ - root_);

            // xMax_-xMin_>0 is verified in the constructor
            double dx = xMax_ - xMin_;

            while (evaluationNumber_ <= maxEvaluations_)
            {
                double frootold = froot;
                double rootold  = root_;
                double dxold    = dx;
                // 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)))
                {
                    dx    = (xh - xl) / 2.0;
                    root_ = xl + dx;
                }
                else // Newton
                {
                    dx     = froot / dfroot;
                    root_ -= dx;
                }

                // Convergence criterion
                if (Math.Abs(dx) < xAccuracy)
                {
                    return(root_);
                }

                froot = f.value(root_);
                ++evaluationNumber_;
                dfroot = (frootold - froot) / (rootold - root_);

                if (froot < 0.0)
                {
                    xl = root_;
                }
                else
                {
                    xh = root_;
                }
            }

            throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }
示例#23
0
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double min1, min2;
            double froot, p, q, r, s, xAcc1, xMid;
            // dummy assignements to avoid compiler warning
            double d = 0.0, e = 0.0;

            root_ = xMax_;
            froot = fxMax_;
            while (evaluationNumber_ <= maxEvaluations_)
            {
                if ((froot > 0.0 && fxMax_ > 0.0) ||
                    (froot < 0.0 && fxMax_ < 0.0))
                {
                    // Rename xMin_, root_, xMax_ and adjust bounds
                    xMax_  = xMin_;
                    fxMax_ = fxMin_;
                    e      = d = root_ - xMin_;
                }
                if (Math.Abs(fxMax_) < Math.Abs(froot))
                {
                    xMin_  = root_;
                    root_  = xMax_;
                    xMax_  = xMin_;
                    fxMin_ = froot;
                    froot  = fxMax_;
                    fxMax_ = fxMin_;
                }
                // Convergence check
                xAcc1 = 2.0 * Const.QL_Epsilon * Math.Abs(root_) + 0.5 * xAccuracy;
                xMid  = (xMax_ - root_) / 2.0;
                if (Math.Abs(xMid) <= xAcc1 || froot == 0.0)
                {
                    return(root_);
                }
                if (Math.Abs(e) >= xAcc1 &&
                    Math.Abs(fxMin_) > Math.Abs(froot))
                {
                    // Attempt inverse quadratic interpolation
                    s = froot / fxMin_;
                    if (xMin_ == xMax_)
                    {
                        p = 2.0 * xMid * s;
                        q = 1.0 - s;
                    }
                    else
                    {
                        q = fxMin_ / fxMax_;
                        r = froot / fxMax_;
                        p = s * (2.0 * xMid * q * (q - r) - (root_ - xMin_) * (r - 1.0));
                        q = (q - 1.0) * (r - 1.0) * (s - 1.0);
                    }
                    if (p > 0.0)
                    {
                        q = -q;           // Check whether in bounds
                    }
                    p    = Math.Abs(p);
                    min1 = 3.0 * xMid * q - Math.Abs(xAcc1 * q);
                    min2 = Math.Abs(e * q);
                    if (2.0 * p < (min1 < min2 ? min1 : min2))
                    {
                        e = d;                // Accept interpolation
                        d = p / q;
                    }
                    else
                    {
                        d = xMid;  // Interpolation failed, use bisection
                        e = d;
                    }
                }
                else
                {
                    // Bounds decreasing too slowly, use bisection
                    d = xMid;
                    e = d;
                }
                xMin_  = root_;
                fxMin_ = froot;
                if (Math.Abs(d) > xAcc1)
                {
                    root_ += d;
                }
                else
                {
                    root_ += Math.Abs(xAcc1) * Math.Sign(xMid);
                }
                froot = f.value(root_);
                evaluationNumber_++;
            }
            throw new ArgumentException("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded");
        }