Exemplo n.º 1
0
        public void NoRoot()
        {
            Func <double, double> f1  = x => x * x + 4;
            Func <double, double> df1 = x => 2 * x;

            Assert.That(() => RobustNewtonRaphson.FindRoot(f1, df1, -5, 5, 1e-14, 50, 20), Throws.TypeOf <NonConvergenceException>());
        }
Exemplo n.º 2
0
        public void Pole()
        {
            Func <double, double> f1  = x => 1 / (x - 2) + 2;
            Func <double, double> df1 = x => - 1 / (x * x - 4 * x + 4);

            Assert.AreEqual(1.5, RobustNewtonRaphson.FindRoot(f1, df1, 1, 2, 1e-14, 100, 20));
            Assert.AreEqual(1.5, RobustNewtonRaphson.FindRoot(f1, df1, 1, 6, 1e-14, 100, 20));
            Assert.AreEqual(1.5, FindRoots.OfFunctionDerivative(f1, df1, 1, 6));

            Func <double, double> f2  = x => - 1 / (x - 2) + 2;
            Func <double, double> df2 = x => 1 / (x * x - 4 * x + 4);

            Assert.AreEqual(2.5, RobustNewtonRaphson.FindRoot(f2, df2, 2, 3, 1e-14, 100, 20));
            Assert.AreEqual(2.5, RobustNewtonRaphson.FindRoot(f2, df2, -2, 3, 1e-14, 100, 20));
            Assert.AreEqual(2.5, FindRoots.OfFunctionDerivative(f2, df2, -2, 3));

            Func <double, double> f3  = x => 1 / (x - 2) + x + 2;
            Func <double, double> df3 = x => - 1 / (x * x - 4 * x + 4) + 1;

            Assert.AreEqual(-Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f3, df3, -2, -1, 1e-14, 100, 20), 1e-14);
            Assert.AreEqual(Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f3, df3, 1, 1.99, 1e-14, 100, 20));
            Assert.AreEqual(Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f3, df3, -1.5, 1.99, 1e-14, 100, 20));
            Assert.AreEqual(Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f3, df3, 1, 6, 1e-14, 100, 20));

            Func <double, double> f4  = x => 1 / (2 - x) - x + 6;
            Func <double, double> df4 = x => 1 / (x * x - 4 * x + 4) - 1;

            Assert.AreEqual(4 + Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f4, df4, 5, 6, 1e-14, 100, 20), 1e-14);
            Assert.AreEqual(4 - Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f4, df4, 2.01, 3, 1e-14, 100, 20));
            Assert.AreEqual(4 - Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f4, df4, 2.01, 5, 1e-14, 100, 20));
            Assert.AreEqual(4 - Constants.Sqrt3, RobustNewtonRaphson.FindRoot(f4, df4, -2, 4, 1e-14, 100, 20));
        }
        public double IV(OptionContractType optionType, double S, double K, double T, double r, double q, double optionMarketPrice)
        {
            Func <double, double> f  = sigma => Premium(optionType, S, K, T, sigma, r, q) - optionMarketPrice;
            Func <double, double> df = sigma => Vega(S, K, T, sigma, r, q);

            return(RobustNewtonRaphson.FindRoot(f, df, lowerBound: 0, upperBound: 100, accuracy: 0.001));
        }
Exemplo n.º 4
0
        public void LocalMinima()
        {
            Func <double, double> f1  = x => x * x * x - 2 * x + 2;
            Func <double, double> df1 = x => 3 * x * x - 2;

            Assert.AreEqual(0, f1(RobustNewtonRaphson.FindRoot(f1, df1, -5, 5, 1e-14, 100, 20)));
            Assert.AreEqual(0, f1(RobustNewtonRaphson.FindRoot(f1, df1, -2, 4, 1e-14, 100, 20)));
        }
Exemplo n.º 5
0
        static public double IV(OptionType type, double s, double x, double r, double q, decimal optionPrice, int days)
        {
            double t = Convert.ToDouble(days) / 365;

            Func <double, double> f  = sigma => Convert.ToDouble(Price(type, s, x, r, q, sigma, days) - optionPrice);
            Func <double, double> df = sigma => Vega(s, x, r, q, sigma, days);

            return(RobustNewtonRaphson.FindRoot(f, df, lowerBound: 0, upperBound: 100, accuracy: 0.001));
        }
Exemplo n.º 6
0
        /// <summary>Find a solution of the equation f(x)=0.</summary>
        /// <param name="f">The function to find roots from.</param>
        /// <param name="df">The first derivative of the function to find roots from.</param>
        /// <param name="lowerBound">The low value of the range where the root is supposed to be.</param>
        /// <param name="upperBound">The high value of the range where the root is supposed to be.</param>
        /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14.</param>
        /// <param name="maxIterations">Maximum number of iterations. Example: 100.</param>
        public static double OfFunctionDerivative(Func <double, double> f, Func <double, double> df, double lowerBound, double upperBound, double accuracy = 1e-8, int maxIterations = 100)
        {
            double root;

            if (RobustNewtonRaphson.TryFindRoot(f, df, lowerBound, upperBound, accuracy, maxIterations, 20, out root))
            {
                return(root);
            }

            return(OfFunction(f, lowerBound, upperBound, accuracy, maxIterations));
        }
Exemplo n.º 7
0
        /// <summary>Find a solution of the equation f(x)=0.</summary>
        /// <param name="f">The function to find roots from.</param>
        /// <param name="df">The first derivative of the function to find roots from.</param>
        /// <param name="lowerBound">The low value of the range where the root is supposed to be.</param>
        /// <param name="upperBound">The high value of the range where the root is supposed to be.</param>
        /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14.</param>
        /// <param name="maxIterations">Maximum number of iterations. Example: 100.</param>
        public static double OfFunctionDerivative(Func <double, double> f, Func <double, double> df, double lowerBound, double upperBound, double accuracy = 1e-8, int maxIterations = 100)
        {
            double root;

            if (RobustNewtonRaphson.TryFindRoot(f, df, lowerBound, upperBound, accuracy, maxIterations, 20, out root))
            {
                return(root);
            }

            if (Bisection.TryFindRoot(f, lowerBound, upperBound, accuracy, maxIterations, out root))
            {
                return(root);
            }

            throw new NonConvergenceException(Resources.RootFindingFailed);
        }
Exemplo n.º 8
0
        public void Cubic()
        {
            // with complex roots (looking for the real root only): 3x^3 + 4x^2 + 5x + 6, derivative 9x^2 + 8x + 5
            Func <double, double> f1  = x => Evaluate.Polynomial(x, 6, 5, 4, 3);
            Func <double, double> df1 = x => Evaluate.Polynomial(x, 5, 8, 9);

            Assert.AreEqual(-1.265328088928, RobustNewtonRaphson.FindRoot(f1, df1, -2, -1, 1e-10, 100, 20), 1e-6);
            Assert.AreEqual(-1.265328088928, RobustNewtonRaphson.FindRoot(f1, df1, -5, 5, 1e-10, 100, 20), 1e-6);

            // real roots only: 2x^3 + 4x^2 - 50x + 6, derivative 6x^2 + 8x - 50
            Func <double, double> f2  = x => Evaluate.Polynomial(x, 6, -50, 4, 2);
            Func <double, double> df2 = x => Evaluate.Polynomial(x, -50, 8, 6);

            Assert.AreEqual(-6.1466562197069, RobustNewtonRaphson.FindRoot(f2, df2, -8, -5, 1e-10, 100, 20), 1e-6);
            Assert.AreEqual(0.12124737195841, RobustNewtonRaphson.FindRoot(f2, df2, -1, 1, 1e-10, 100, 20), 1e-6);
            Assert.AreEqual(4.0254088477485, RobustNewtonRaphson.FindRoot(f2, df2, 3, 5, 1e-10, 100, 20), 1e-6);
        }
Exemplo n.º 9
0
        public void MultipleRoots()
        {
            // Roots at -2, 2
            Func <double, double> f1  = x => x * x - 4;
            Func <double, double> df1 = x => 2 * x;

            Assert.AreEqual(0, f1(RobustNewtonRaphson.FindRoot(f1, df1, -5, 5, 1e-14, 100, 20)));
            Assert.AreEqual(-2, RobustNewtonRaphson.FindRoot(f1, df1, -5, -1, 1e-14, 100, 20));
            Assert.AreEqual(2, RobustNewtonRaphson.FindRoot(f1, df1, 1, 4, 1e-14, 100, 20));
            Assert.AreEqual(0, f1(RobustNewtonRaphson.FindRoot(x => - f1(x), x => - df1(x), -5, 5, 1e-14, 100, 20)));
            Assert.AreEqual(-2, RobustNewtonRaphson.FindRoot(x => - f1(x), x => - df1(x), -5, -1, 1e-14, 100, 20));
            Assert.AreEqual(2, RobustNewtonRaphson.FindRoot(x => - f1(x), x => - df1(x), 1, 4, 1e-14, 100, 20));

            // Roots at 3, 4
            Func <double, double> f2  = x => (x - 3) * (x - 4);
            Func <double, double> df2 = x => 2 * x - 7;

            Assert.AreEqual(0, f2(RobustNewtonRaphson.FindRoot(f2, df2, -5, 5, 1e-14, 100, 20)));
            Assert.AreEqual(3, RobustNewtonRaphson.FindRoot(f2, df2, -5, 3.5, 1e-14, 100, 20));
            Assert.AreEqual(4, RobustNewtonRaphson.FindRoot(f2, df2, 3.2, 5, 1e-14, 100, 20));
            Assert.AreEqual(3, RobustNewtonRaphson.FindRoot(f2, df2, 2.1, 3.9, 0.001, 50, 20), 0.001);
            Assert.AreEqual(3, RobustNewtonRaphson.FindRoot(f2, df2, 2.1, 3.4, 0.001, 50, 20), 0.001);
        }
        public double InventorySpaceUpperBound(double nextPeriodInventorySpaceLowerBound,
                                               double nextPeriodInventorySpaceUpperBound, double currentPeriodMinInventory,
                                               double currentPeriodMaxInventory, double inventoryPercentLoss)
        {
            double currentPeriodMaxInjectWithdrawAtMaxInventory = _maxInjectWithdrawPolynomial.Evaluate(currentPeriodMaxInventory);
            double currentPeriodMinInjectWithdrawAtMaxInventory = _minInjectWithdrawPolynomial.Evaluate(currentPeriodMaxInventory);

            double nextPeriodMaxInventoryFromThisPeriodMaxInventory = currentPeriodMaxInventory + currentPeriodMaxInjectWithdrawAtMaxInventory;
            double nextPeriodMinInventoryFromThisPeriodMaxInventory = currentPeriodMaxInventory + currentPeriodMinInjectWithdrawAtMaxInventory;

            if (nextPeriodMinInventoryFromThisPeriodMaxInventory <= nextPeriodInventorySpaceUpperBound &&
                nextPeriodInventorySpaceLowerBound <= nextPeriodMaxInventoryFromThisPeriodMaxInventory)
            {
                // No need to solve root as next period inventory space can be reached from the current period max inventory
                return(currentPeriodMaxInventory);
            }

            double PolyToSolve(double inventory) => inventory * (1 - inventoryPercentLoss)
            + _minInjectWithdrawPolynomial.Evaluate(inventory)
            - nextPeriodInventorySpaceUpperBound;
            double PolyToSolve1StDeriv(double inventory) => (1 - inventoryPercentLoss) + _minInjectWithdrawPolynomial1StDeriv.Evaluate(inventory);

            if (!RobustNewtonRaphson.TryFindRoot(PolyToSolve, PolyToSolve1StDeriv, currentPeriodMinInventory,
                                                 currentPeriodMaxInventory, _newtonRaphsonAccuracy, _newtonRaphsonMaxNumIterations,
                                                 _newtonRaphsonSubdivision, out double thisPeriodMaxInventory))
            {
                throw new ApplicationException("Cannot solve for the current period inventory space upper bound. Try changing Newton Raphson parameters.");
            }

            if (thisPeriodMaxInventory < currentPeriodMinInventory)// TODO allow tolerance? If so, need to think how this will feed through to other parts of code.
            {
                throw new ApplicationException("Inventory constraints cannot be satisfied.");
            }

            return(Math.Min(thisPeriodMaxInventory, currentPeriodMaxInventory));
        }
Exemplo n.º 11
0
        public Vector <double>[] bvpsolver_zzz(Func <double, Vector <double>, Vector <double> > system,
                                               double ya, double yb,
                                               double xa, double xb,
                                               int N)
        {
            //先求解方程得到初始斜率的估计值,再进行打靶法迭代。--zzz
            Vector <double>[] res;
            Vector <double>   y0;

            double s_guess, s_guess_pre;
            double fais, fais_pre;
            double dfai, ds;
            int    count = 0;

            //计算20组s_guess和fais,然后样条插值得到连续函数,再通过解方程,得到使fais=0的初始s_guess
            int M = 50;

            double[] sLst = Vector <double> .Build.Dense(M, i => yb / M *i).ToArray();

            double[] faisLst = new double[M];
            count = 0;
            while (count < M)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, sLst[count] });

                // observer_pr ob_pr = this->write_targetFunc_end;
                res            = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                faisLst[count] = res[N - 1][0] - yb;
                count++;
            }
            //样条插值得到连续函数
            var cubicSpl = CubicSpline.InterpolateNatural(sLst, faisLst);

            /*如果初始值离解太远,牛顿法会不收敛。故采用Mathnet包中的RobustNewtonRaphson
             * double s_cur = 0, s_next;
             * count = 0;
             * while (count < 1000)
             * {
             *  fais = cubicSpl.Interpolate(s_cur);
             *  dfaids = cubicSpl.Differentiate(s_cur);
             *  if (fais < 1e-5 && fais > -1e-5)
             *  {
             *      break;
             *  }
             *
             *  s_next = s_cur - fais / dfaids;
             *  s_cur = s_next;
             *  count += 1;
             * }*/

            //解方程fais=0,得到初始斜率s_guess。该法先尝试牛顿法,如失败会采用二分法(bisection)。
            s_guess = RobustNewtonRaphson.FindRoot(cubicSpl.Interpolate, cubicSpl.Differentiate, 0, yb, 1e-5);

            //利用解得的s_guess,构造s_guess_pre,目的是求导数dfai/ds。
            if (s_guess == 0)
            {
                s_guess_pre = 1e-2;
            }
            else
            {
                s_guess_pre = s_guess * 0.99;
            }
            //求s_guess_pre对应的fais_pre,目的是求导数dfai/ds。
            y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess_pre });

            res      = RungeKutta.FourthOrder(y0, xa, xb, N, system);
            fais_pre = res[N - 1][0] - yb;

            count = 0;
            while (count < 50)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess });

                res  = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                fais = res[N - 1][0] - yb;

                dfai = fais - fais_pre;
                ds   = s_guess - s_guess_pre;
                if (fais < 1e-5 && fais > -1e-5)
                {
                    break;
                }

                fais_pre    = fais;
                s_guess_pre = s_guess;
                s_guess     = s_guess - fais * ds / dfai;
                count++;
            }

            return(res);
        }