/* 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; } }
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); }
/// <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); }
/* 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); }
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()); }
/* 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); }
/* 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); }
/* 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); }
/// <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); }
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); }