Exemplo n.º 1
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));
        }
Exemplo n.º 2
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>());
        }
        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
        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.º 7
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);
        }
Exemplo n.º 8
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);
        }