public void Build(DateTime originDate, double[][] strikes, DateTime[] expiries, double[][] vols, Func <double, double> forwardCurve) { OriginDate = originDate; Expiries = expiries; ExpiriesDouble = Expiries.Select(t => TimeBasis.CalculateYearFraction(originDate, t)).ToArray(); if (Expiries.Length != strikes.Length) { throw new InvalidOperationException("Expiries and first dimension of Strikes must of same length"); } if (Expiries.Length != vols.Length) { throw new InvalidOperationException("Expiries and first dimension of Vols must of same length"); } Alphas = new double[Expiries.Length]; Betas = new double[Expiries.Length]; Nus = new double[Expiries.Length]; Rhos = new double[Expiries.Length]; for (var i = 0; i < expiries.Length; i++) { var vs = vols[i]; var ks = strikes[i]; var t = ExpiriesDouble[i]; var fwd = forwardCurve(t); Betas[i] = 1.0; Func <double[], double[]> errorFunc = (x => { var err = ks.Select((k, ix) => vs[ix] - SABR.CalcImpVol_Beta1(fwd, k, t, x[0], x[1], x[2])); return(err.ToArray()); }); var n2Sol = new Math.Solvers.GaussNewton { ObjectiveFunction = errorFunc, InitialGuess = new double[] { vs.Average(), 0.1, 0.1 }, Tollerance = 1e-8, JacobianBump = 0.0000001 }; var paramArr = n2Sol.Solve(); Alphas[i] = paramArr[0]; Rhos[i] = paramArr[1]; Nus[i] = paramArr[2]; } _alphaInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Alphas, TimeInterpolatorType); _betaInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Betas, TimeInterpolatorType); _rhoInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Rhos, TimeInterpolatorType); _nuInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Nus, TimeInterpolatorType); }
public void CanSolveTameExample() { var n2Sol = new Math.Solvers.GaussNewton { ObjectiveFunction = Residuals, InitialGuess = new double[] { 6, 0.3 }, Tollerance = 1e-8 }; var output = n2Sol.Solve(); var functionOutput = Residuals(output); var functionOutputUp = Residuals(output.Select(x => x + 0.0001).ToArray()); var functionOutputDown = Residuals(output.Select(x => x - 0.0001).ToArray()); //verify that the solution is better than two neighboruing solutions Assert.True(functionOutput.Select(x => x * x).Sum() < functionOutputUp.Select(x => x * x).Sum()); Assert.True(functionOutput.Select(x => x * x).Sum() < functionOutputDown.Select(x => x * x).Sum()); }
public void Dim2NRFacts() { var ws0 = new double[] { 76, 5, -2 }; var nExamples = 100; var predictors = new double[nExamples][]; var predictions = new double[nExamples]; var R = new System.Random(); for (var e = 0; e < nExamples; e++) { predictors[e] = new double[2] { R.NextDouble(), R.NextDouble() }; } var testFunc = new Func <double[], double[], double>((xs, ws) => { var intercept = ws[0]; var w1 = ws[1]; var w2 = ws[2]; return(intercept + xs[0] * w1 + xs[1] * w2); }); var solveFunc = new Func <double[], double[]>(ws => { return(predictors.Select(x => testFunc(x, ws) - testFunc(x, ws0)).ToArray()); }); var solver = new Math.Solvers.GaussNewton { ObjectiveFunction = solveFunc, InitialGuess = new double[3] }; var weights = solver.Solve(); Assert.Equal(ws0[0], weights[0], 8); Assert.Equal(ws0[1], weights[1], 8); Assert.Equal(ws0[2], weights[2], 8); }