Пример #1
0
        /* Simple routine to print the fit results */
        private static void PrintResult(double[] x, double[] xact, mp_result result)
        {
            int i;

            if (x == null)
            {
                return;
            }

            Console.Write("  CHI-SQUARE = {0}    ({1} DOF)\n",
                          result.bestnorm, result.nfunc - result.nfree);
            Console.Write("        NPAR = {0}\n", result.npar);
            Console.Write("       NFREE = {0}\n", result.nfree);
            Console.Write("     NPEGGED = {0}\n", result.npegged);
            Console.Write("       NITER = {0}\n", result.niter);
            Console.Write("        NFEV = {0}\n", result.nfev);
            Console.Write("\n");
            if (xact != null)
            {
                for (i = 0; i < result.npar; i++)
                {
                    Console.Write("  P[{0}] = {1} +/- {2}     (ACTUAL {3})\n",
                                  i, x[i], result.xerror[i], xact[i]);
                }
            }
            else
            {
                for (i = 0; i < result.npar; i++)
                {
                    Console.Write("  P[{0}] = {1} +/- {2}\n",
                                  i, x[i], result.xerror[i]);
                }
            }
        }
        protected override OptimizationRunProperties RunOptimization()
        {
            try
            {
                var result = new mp_result(_constraints.Count);

                var pars = createMPConstraints();

                var startValues = CreateVectorFor(x => x.StartValue);

                var config = new mp_config
                {
                    ftol          = ftol,
                    xtol          = xtol,
                    gtol          = gtol,
                    stepfactor    = stepfactor,
                    maxiter       = maxiter,
                    maxfev        = maxfev,
                    epsfcn        = epsfcn,
                    nofinitecheck = 0
                };

                _objectiveFunctionErrorMessage = string.Empty;
                int status = MPFit.Solve(objectiveFunction, _numberOfResiduals, _constraints.Count, startValues, pars, config, null, ref result);
                evaluateStatus(status);

                return(new OptimizationRunProperties(result.nfev));
            }

            finally
            {
                _constraints   = null;
                _objectiveFunc = null;
            }
        }
Пример #3
0
        private static void TestAnalyticDerivatives()
        {
            const double intercept = 7.0;
            const double slope     = -3.0;
            var          pactual   = new double[] { intercept, slope };
            var          p         = new double[] { 5.9, -1.1 };
            var          x         = new double[] { -5, -3, -1, 0, 1, 3, 5 };
            var          y         = new double[x.Length];


            for (uint i = 0; i < x.Length; i++)
            {
                y[i] = intercept + slope * x[i];
            }

            var mpPar = new mp_par[] { new mp_par(), new mp_par() };

            mpPar[0].side = 3;
            mpPar[1].side = 3;

            var result = new mp_result(2);

            var status = MPFit.Solve(ForwardModels.LineFunc, x.Length, 2, p, mpPar, null, new LineFitData(x, y), ref result);

            Console.Write("*** TestLineFit status = {0}\n", status);
            PrintResult(p, pactual, result);
        }
Пример #4
0
        /// <summary>
        /// Optimization method.  This calls MPFit Levenberg Marquardt solver with constraints.
        /// </summary>
        /// <param name="a">optimization parameter initial guess</param>
        /// <param name="ia">accompanying array to <paramref name="a"/> that specifies which parameters to fit (held constant otherwise)</param>
        /// <param name="lowerBounds">accompanying array that specifies lower bounds for parameters</param>
        /// <param name="upperBounds">accompanying array that specifies upper bounds</param>
        /// <param name="y">"measured" values</param>
        /// <param name="ey">standard deviation values of <paramref name="y"/></param>
        /// <param name="forwardFunc">delegate function that evaluates the objective function given a parameter optimization array and (optional) constant variables</param>
        /// <param name="forwardVariables"></param>
        public double[] SolveWithConstraints(double[] a, bool[] ia, double[] lowerBounds, double[] upperBounds, double[] y, double[] ey, Func <double[], object[], double[]> forwardFunc, params object[] forwardVariables)
        {
            var data = new OptimizationData
            {
                Y                = y,
                Ey               = ey,
                ForwardFunc      = forwardFunc,
                ForwardVariables = forwardVariables
            };

            mp_par[] pars = a.Select((ai, i) => new mp_par {
                isFixed = ia[i] ? 0 : 1
            }).ToArray();
            for (int i = 0; i < pars.Length; i++)
            {
                pars[i].limited[0] = 1; // specify lower bound exists
                pars[i].limited[1] = 1; // specify upper bound exists
                pars[i].limits[0]  = lowerBounds[i];
                pars[i].limits[1]  = upperBounds[i];
            }

            mp_result result = new mp_result(a.Length);

            int status = MPFit.Solve(MPFitFunc, data.Y.Length, pars.Length, a, pars, null, data, ref result);

            return(a);
        }
Пример #5
0
        /* Test harness routine, which contains test gaussian-peak data
         *
         * Example of fixing two parameter
         *
         * Commented example of how to put boundary constraints
         */
        private static int TestGaussFix()
        {
            double[] x = { -1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
                           -2.8394297E-01, 1.3416969E+00,  1.3757038E+00,
                           -1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
                           8.2065094E-01 };
            double[] y = { -4.4494256E-02, 8.7324673E-01, 7.4443483E-01,
                           4.7631559E+00,  1.7187297E-01, 1.1639182E-01,
                           1.5646480E+00,  5.2322268E+00, 4.2543168E+00,
                           6.2792623E-01 };
            double[] ey      = new double[10];
            double[] p       = { 0.0, 1.0, 0.0, 0.1 };  /* Initial conditions */
            double[] pactual = { 0.0, 4.70, 0.0, 0.5 }; /* Actual values used to make data*/
            //double[] perror = new double[4];			   /* Returned parameter errors */
            int i;
            int status;

            mp_result result = new mp_result(4);

            //result.xerror = perror;

            mp_par[] pars = new mp_par[4]/* Parameter constraints */
            {
                new mp_par {
                    isFixed = 1
                },                                           /* Fix parameters 0 and 2 */
                new mp_par(),
                new mp_par {
                    isFixed = 1
                },
                new mp_par()
            };

            /* How to put limits on a parameter.  In this case, parameter 3 is
             * limited to be between -0.3 and +0.2.
             * pars[3].limited[0] = 0;
             * pars[3].limited[1] = 1;
             * pars[3].limits[0] = -0.3;
             * pars[3].limits[1] = +0.2;
             */

            for (i = 0; i < 10; i++)
            {
                ey[i] = 0.5;
            }

            CustomUserVariable v = new CustomUserVariable {
                X = x, Y = y, Ey = ey
            };

            /* Call fitting function for 10 data points and 4 parameters (2
             * parameters fixed) */
            status = MPFit.Solve(ForwardModels.GaussFunc, 10, 4, p, pars, null, v, ref result);

            Console.Write("*** TestGaussFix status = {0}\n", status);
            PrintResult(p, pactual, result);

            return(0);
        }
Пример #6
0
        private static void TestGaussianWithDerivs()
        {
            double[] x =
            {
                -1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
                -2.8394297E-01, 1.3416969E+00,  1.3757038E+00,
                -1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
                8.2065094E-01
            };
            double[] y =
            {
                -4.4494256E-02, 8.7324673E-01, 7.4443483E-01,
                4.7631559E+00,  1.7187297E-01, 1.1639182E-01,
                1.5646480E+00,  5.2322268E+00, 4.2543168E+00,
                6.2792623E-01
            };
            double[] ey      = new double[10];
            double[] p       = { 0.0, 1.0, 1.0, 1.0 };  // Initial conditions
            double[] pactual = { 0.0, 4.70, 0.0, 0.5 }; // Actual values used to make data
            mp_par[] pars    =
            {
                new mp_par {
                    side = 3, deriv_debug = 0
                },
                new mp_par {
                    side = 1, deriv_debug = 0
                },
                new mp_par {
                    side = 3, deriv_debug = 0
                },
                new mp_par {
                    side = 1, deriv_debug = 0
                }
            };

            mp_result result = new mp_result(4);

            /* No constraints */

            for (uint i = 0; i < 10; i++)
            {
                ey[i] = 0.5;
            }

            CustomUserVariable v = new CustomUserVariable {
                X = x, Y = y, Ey = ey
            };

            /* Call fitting function for 10 data points and 4 parameters (no
             * parameters fixed) */

            var logger = new System.IO.StringWriter();
            int status = MPFit.Solve(ForwardModels.GaussianFuncAndDerivs, 10, 4, p, pars, null, v, ref result, logger);

            Console.Write("*** TestGaussFitWithDerivs status = {0}\n", status);
            PrintResult(p, pactual, result);
            Console.WriteLine(logger.ToString());
        }
Пример #7
0
        /* Test harness routine, which contains test quadratic data;
         * Example of how to fix a parameter
         */
        private static int TestQuadFix()
        {
            double[] x = { -1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
                           -2.8394297E-01, 1.3416969E+00,  1.3757038E+00,
                           -1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
                           8.2065094E-01 };
            double[] y = { 2.3095947E+01, 2.6449392E+01, 1.0204468E+01,
                           5.40507,       1.5787588E+01, 1.6520903E+01,
                           1.5971818E+01, 4.7668524E+00, 4.9337711E+00,
                           8.7348375E+00 };

            double[] ey      = new double[10];
            double[] p       = { 1.0, 0.0, 1.0 };  /* Initial conditions */
            double[] pactual = { 4.7, 0.0, 6.2 };  /* Actual values used to make data */
            //double[] perror = new double[3];		       /* Returned parameter errors */
            int i;
            int status;

            mp_result result = new mp_result(3);

            //result.xerror = perror;

            mp_par[] pars = new mp_par[3] /* Parameter constraints */
            {
                new mp_par(),
                new mp_par()
                {
                    isFixed = 1
                },                                              /* Fix parameter 1 */
                new mp_par()
            };

            for (i = 0; i < 10; i++)
            {
                ey[i] = 0.2;
            }

            CustomUserVariable v = new CustomUserVariable()
            {
                X = x, Y = y, Ey = ey
            };

            /* Call fitting function for 10 data points and 3 parameters (1
             * parameter fixed) */
            status = MPFit.Solve(ForwardModels.QuadFunc, 10, 3, p, pars, null, v, ref result);

            Console.Write("*** TestQuadFix status = {0}\n", status);

            PrintResult(p, pactual, result);

            return(0);
        }
Пример #8
0
        /* Test harness routine, which contains test gaussian-peak data */
        public static double[] TestGaussFit(double[] xinc, double[] yinc, double[] p)
        {
            double[] x = xinc;
            double[] y = yinc;

            double[] ey = new double[yinc.Length];
            //double[] p = { 0.0, 1.0, 1.0, 1.0 };       /* Initial conditions */
            double[] pactual = { 0.0, 4.70, 0.0, 0.5 }; /* Actual values used to make data*/
            //double[] perror = new double[4];			   /* Returned parameter errors */
            mp_par[] pars = new mp_par[4]               /* Parameter constraints */
            {
                new mp_par(),
                new mp_par(),
                new mp_par(),
                new mp_par()
            };
            int i;
            int status;

            mp_result result = new mp_result(4);

            //result.xerror = perror;

            /* No constraints */

            for (i = 0; i < yinc.Length; i++)
            {
                ey[i] = 0.02;
            }

            for (i = 0; i < p.Length; i++)
            {
                Console.Write("P" + i + " : " + p[i]);
            }

            CustomUserVariable v = new CustomUserVariable {
                X = x, Y = y, Ey = ey
            };

            /* Call fitting function for 10 data points and 4 parameters (no
             * parameters fixed) */
            status = MPFit.Solve(ForwardModels.GaussFunc, yinc.Length, 4, p, pars, null, v, ref result);

            Console.Write("*** TestGaussFit status = {0}\n", status);
            PrintResult(p, pactual, result);
            double[] retval = { p[0], p[1], p[2], p[3], result.xerror[0], result.xerror[1], result.xerror[2], result.xerror[3] };

            return(retval);
        }
Пример #9
0
        /* Test harness routine, which contains test data, invokes mpfit() */
        private static int TestLinFit()
        {
            double[] x = { -1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
                           -2.8394297E-01, 1.3416969E+00,  1.3757038E+00,
                           -1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
                           8.2065094E-01 };
            double[] y = { 1.9000429E-01, 6.5807428E+00, 1.4582725E+00,
                           2.7270851E+00, 5.5969253E+00, 5.6249280E+00,
                           0.787615,      3.2599759E+00, 2.9771762E+00,
                           4.5936475E+00 };

            double[] ey = new double[10];
            /*        y = a + b * x */
            /*               a    b */
            double[] p       = { 1.0, 1.0 };     /* Parameter initial conditions */
            double[] pactual = { 3.20, 1.78 };   /* Actual values used to make data */
            //double[] perror = { 0.0, 0.0 };                   /* Returned parameter errors */
            int i;
            int status;

            mp_result result = new mp_result(2);

            //result.xerror = perror;

            for (i = 0; i < 10; i++)
            {
                ey[i] = 0.07; /* Data errors */
            }

            CustomUserVariable v = new CustomUserVariable();

            v.X  = x;
            v.Y  = y;
            v.Ey = ey;

            /* Call fitting function for 10 data points and 2 parameters */
            status = MPFit.Solve(ForwardModels.LinFunc, 10, 2, p, null, null, v, ref result);

            Console.Write("*** TestLinFit status = {0}\n", status);
            PrintResult(p, pactual, result);

            return(0);
        }
Пример #10
0
        /// <summary>
        /// Optimization method.  This calls MPFit Levenberg Marquardt solver.
        /// For examples of usage, see TestMPFit.cs:
        /// https://csmpfit.codeplex.com/SourceControl/latest#src/MPFitLib.Test/TestMPFit.cs
        /// For an example of a call with the objective function:
        /// https://csmpfit.codeplex.com/SourceControl/latest#src/MPFitLib.Test/ForwardModels.cs
        /// </summary>
        /// <param name="a">optimization parameter initial guess</param>
        /// <param name="ia">accompanying array to <paramref name="a"/> that specifies which parameters to fit (held constant otherwise)</param>
        /// <param name="y">"measured" values</param>
        /// <param name="ey">standard deviation values of <paramref name="y"/></param>
        /// <param name="forwardFunc">delegate function that evaluates the objective function given a parameter optimization array and (optional) constant variables</param>
        /// <param name="forwardVariables"></param>
        public double[] Solve(double[] a, bool[] ia, double[] y, double[] ey, Func <double[], object[], double[]> forwardFunc, params object[] forwardVariables)
        {
            var data = new OptimizationData
            {
                Y                = y,
                Ey               = ey,
                ForwardFunc      = forwardFunc,
                ForwardVariables = forwardVariables
            };

            mp_par[] pars = a.Select((ai, i) => new mp_par {
                isFixed = ia[i] ? 0 : 1
            }).ToArray();

            mp_result result = new mp_result(a.Length);

            int status = MPFit.Solve(MPFitFunc, data.Y.Length, pars.Length, a, pars, null, data, ref result);

            return(a);
        }
Пример #11
0
        public SabrCoeffOptimizer(
            double maturity,
            double spotPrice,
            double atmVol,
            IList <double> strikes,
            IList <double> marketVols,
            bool estimateAlpha,
            bool useFineTune,
            double initAlpha = 0.3,
            double initBeta  = 0.5,
            double initNu    = 0.3,
            double initRho   = 0.3)
        {
            MaturityInYears = maturity;
            _spotPrice      = spotPrice;
            AtmVol          = atmVol;
            _strikes        = strikes;
            _marketVols     = marketVols;
            _estimateAlpha  = estimateAlpha;
            _useFineTune    = useFineTune;

            _initBeta = initBeta;

            if (strikes.Count != marketVols.Count)
            {
                throw new PricingLibraryException("strikes and marketVols should have same number of elements!");
            }

            double bestAlpha, bestBeta, bestRho, bestNu;
            var    nDataPoints = _marketVols.Count();

            double[] ey = new double[nDataPoints];
            for (int i = 0; i < nDataPoints; ++i)
            {
                ey[i] = 0.1;                  // error for data points, we do not need to use this
            }
            const int nParams = 3;

            mp_par[] pars = new mp_par[nParams] // parameter constraints
            {
                new mp_par(),                   // no constraint
                new mp_par(),
                new mp_par()
            };
            if (!estimateAlpha)             // fix alpha
            {
                pars[2] = new mp_par()
                {
                    isFixed = 1
                };
            }
            CustomUserVariable v = new CustomUserVariable()
            {
                X = _strikes.ToArray(), Y = _marketVols.ToArray(), Ey = ey
            };

            double[] p = new double[nParams] {
                initRho, initNu, initAlpha
            };
            mp_result result = new mp_result(nParams);
            int       status = MPFit.Solve(SabrFunc, nDataPoints, nParams, p, pars, null, v, ref result);

            bestRho   = p[0];
            bestNu    = p[1];
            bestAlpha = estimateAlpha ? p[2] : FindAlpha(_initBeta, p[0], p[1], MaturityInYears, _spotPrice, AtmVol);
            bestBeta  = _initBeta;
            Result    = new SabrCoeffOptimizerResult(MaturityInYears, bestAlpha, bestBeta, bestRho, bestNu);
        }