@Override public DoubleArray apply(Double x) { Function<DoubleArray, Double> f = asFunctionOfParameters(x); Function<DoubleArray, DoubleArray> g = FIRST_ORDER_DIFF.differentiate(f); return g.apply(params); } };
@Test public void derivatives() { // AD v Finite Difference ScalarFieldFirstOrderDifferentiator differentiator = new ScalarFieldFirstOrderDifferentiator(FiniteDifferenceType.CENTRAL, 1.0E-5); for (int i = 0; i < N; i++) { Function<DoubleArray, Double> function = new Function<DoubleArray, Double>() { @Override public Double apply(DoubleArray x) { SsviFormulaData data = SsviFormulaData.of(x.get(3), x.get(4), x.get(5)); return SSVI_FUNCTION.volatility(x.get(0), x.get(1), x.get(2), data); } }; Function<DoubleArray, DoubleArray> d = differentiator.differentiate(function); DoubleArray fd = d.apply(DoubleArray.of(FORWARD, STRIKES[i], TIME_EXP, VOL_ATM, RHO, ETA)); ValueDerivatives ad = SSVI_FUNCTION.volatilityAdjoint(FORWARD, STRIKES[i], TIME_EXP, DATA); for (int j = 0; j < 6; j++) { assertEquals(fd.get(j), ad.getDerivatives().get(j), TOLERANCE_AD); } } }
@Override public DoubleArray apply(DoublesPair xy) { Function<DoubleArray, Double> f = asFunctionOfParameters(xy); Function<DoubleArray, DoubleArray> g = FIRST_ORDER_DIFF.differentiate(f); return g.apply(params); } };
@Test public void testSin() { final DoubleArray parms = DoubleArray.of(-1.0, 0.5); assertEquals(-Math.sin(1.0), VECTOR_PARAMS.evaluate(2.0, parms), 0.0); final Function<Double, Double> func = VECTOR_PARAMS.asFunctionOfArguments(parms); assertEquals(1.0, func.apply(-Math.PI), 0.0); final ScalarFirstOrderDifferentiator diff = new ScalarFirstOrderDifferentiator(); final Function<Double, Double> grad = diff.differentiate(func); assertEquals(-0.5, grad.apply(0.0), 1e-8); final Function<DoubleArray, Double> params_func = VECTOR_PARAMS.asFunctionOfParameters(1.0); final ScalarFieldFirstOrderDifferentiator vdiff = new ScalarFieldFirstOrderDifferentiator(); final Function<DoubleArray, DoubleArray> vgrad = vdiff.differentiate(params_func); final DoubleArray res = vgrad.apply(DoubleArray.of(Math.PI, 0)); assertEquals(0.0, res.get(0), 1e-8); assertEquals(Math.PI, res.get(1), 1e-8); } }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullFunction() { CENTRAL.differentiate((Function<DoubleArray, Double>) null); }
@Test public void test() { final DoubleArray x = DoubleArray.of(.2245, -1.2344); final DoubleArray anGrad = G.apply(x); final DoubleArray fdFwdGrad = FORWARD.differentiate(F).apply(x); final DoubleArray fdCentGrad = CENTRAL.differentiate(F).apply(x); final DoubleArray fdBackGrad = BACKWARD.differentiate(F).apply(x); for (int i = 0; i < 2; i++) { assertEquals(fdFwdGrad.get(i), anGrad.get(i), 10 * EPS); assertEquals(fdCentGrad.get(i), anGrad.get(i), EPS * EPS); assertEquals(fdBackGrad.get(i), anGrad.get(i), 10 * EPS); } }
@Test public void domainTest() { final DoubleArray[] x = new DoubleArray[3]; x[0] = DoubleArray.of(0.2245, -1.2344); x[1] = DoubleArray.of(0.0, 12.6); x[2] = DoubleArray.of(Math.PI, 0.0); final Function<DoubleArray, DoubleArray> fdGradFunc = CENTRAL.differentiate(F, DOMAIN); for (int k = 0; k < 3; k++) { final DoubleArray fdRes = fdGradFunc.apply(x[k]); final DoubleArray alRes = G.apply(x[k]); for (int i = 0; i < 2; i++) { assertEquals(fdRes.get(i), alRes.get(i), 1e-7); } } }
Function<DoubleArray, DoubleArray> paramSensiFunc = PARAM_SENSI.differentiate(w -> SW_FUNCTION.value(t, alpha, nodes, w)); DoubleArray paramSensiExp = paramSensiFunc.apply(weights); assertTrue(DoubleArrayMath.fuzzyEquals(paramSensiCmp.toArray(), paramSensiExp.toArray(), EPS));
public void test_derivative_sensitivity() { BoundCurveInterpolator bind = CurveInterpolators.DOUBLE_QUADRATIC.bind(X_DATA, Y_DATA, EXTRAP, EXTRAP); Function<Double, Double> derivFunc = x -> bind.interpolate(x); for (int i = 0; i < X_LEFT_TEST.size(); ++i) { assertEquals(bind.firstDerivative(X_LEFT_TEST.get(i)), DIFF_CALC.differentiate(derivFunc).apply(X_LEFT_TEST.get(i)), EPS); int index = i; Function<DoubleArray, Double> sensFunc = y -> CurveInterpolators.DOUBLE_QUADRATIC.bind(X_DATA, y, EXTRAP, EXTRAP).interpolate(X_LEFT_TEST.get(index)); assertTrue(DoubleArrayMath.fuzzyEquals(bind.parameterSensitivity(X_LEFT_TEST.get(index)).toArray(), SENS_CALC.differentiate(sensFunc).apply(Y_DATA).toArray(), EPS)); } for (int i = 0; i < X_RIGHT_TEST.size(); ++i) { assertEquals(bind.firstDerivative(X_RIGHT_TEST.get(i)), DIFF_CALC.differentiate(derivFunc).apply(X_RIGHT_TEST.get(i)), EPS); int index = i; Function<DoubleArray, Double> sensFunc = y -> CurveInterpolators.DOUBLE_QUADRATIC.bind(X_DATA, y, EXTRAP, EXTRAP).interpolate(X_RIGHT_TEST.get(index)); assertTrue(DoubleArrayMath.fuzzyEquals(bind.parameterSensitivity(X_RIGHT_TEST.get(index)).toArray(), SENS_CALC.differentiate(sensFunc).apply(Y_DATA).toArray(), EPS)); } }
public void positiveDataTest() { DoubleArray xValues = DoubleArray.of(0.5, 1.0, 2.5, 4.2, 10.0, 15.0, 30.0); DoubleArray yValues = DoubleArray.of(4.0, 2.0, 1.0, 5.0, 10.0, 3.5, -2.0); int nData = yValues.size(); DoubleArray pValues = DoubleArray.of(nData, i -> xValues.get(i) * yValues.get(i)); Function<Double, Boolean> domain = new Function<Double, Boolean>() { @Override public Boolean apply(Double x) { return x >= xValues.get(0) && x <= xValues.get(nData - 1); } }; DoubleArray keys = DoubleArray.of(xValues.get(0), 0.7, 1.2, 7.8, 9.99, 17.52, 25.0, xValues.get(nData - 1)); int nKeys = keys.size(); BoundCurveInterpolator bound = INTERP.bind(xValues, yValues); BoundCurveInterpolator boundBase = BASE_INTERP.bind(xValues, pValues); Function<Double, Double> funcDeriv = x -> bound.interpolate(x); for (int i = 0; i < nKeys; ++i) { // interpolate assertEquals(bound.interpolate(keys.get(i)), boundBase.interpolate(keys.get(i)) / keys.get(i), TOL); // first derivative double firstExp = DIFF_CALC.differentiate(funcDeriv, domain).apply(keys.get(i)); assertEquals(bound.firstDerivative(keys.get(i)), firstExp, EPS); // parameter sensitivity int index = i; Function<DoubleArray, Double> funcSensi = x -> INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS)); } }
public void sampleDataTest() { DoubleArray xValues = DoubleArray.of(0.5, 1.0, 2.5, 4.2, 10.0, 15.0, 30.0); DoubleArray yValues = DoubleArray.of(4.0, 2.0, 1.0, 5.0, 10.0, 3.5, -2.0); int nData = yValues.size(); DoubleArray pValues = DoubleArray.of(nData, i -> xValues.get(i) * yValues.get(i)); Function<Double, Boolean> domain = new Function<Double, Boolean>() { @Override public Boolean apply(Double x) { return x >= xValues.get(0) && x <= xValues.get(nData - 1); } }; DoubleArray keys = DoubleArray.of(xValues.get(0), 0.7, 1.2, 7.8, 10.0, 17.52, 25.0, xValues.get(nData - 1)); int nKeys = keys.size(); BoundCurveInterpolator bound = INTERP.bind(xValues, yValues); BoundCurveInterpolator boundBase = BASE_INTERP.bind(xValues, pValues); Function<Double, Double> funcDeriv = x -> bound.interpolate(x); for (int i = 0; i < nKeys; ++i) { // interpolate assertEquals(bound.interpolate(keys.get(i)), boundBase.interpolate(keys.get(i)) / keys.get(i), TOL); // first derivative double firstExp = DIFF_CALC.differentiate(funcDeriv, domain).apply(keys.get(i)); assertEquals(bound.firstDerivative(keys.get(i)), firstExp, EPS); // parameter sensitivity int index = i; Function<DoubleArray, Double> funcSensi = x -> INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS)); } }
public void negativeDataTest() { DoubleArray xValues = DoubleArray.of(-34.5, -27.0, -22.5, -14.2, -10.0, -5.0, -0.3); DoubleArray yValues = DoubleArray.of(4.0, 2.0, 1.0, 5.0, 10.0, 3.5, -2.0); int nData = yValues.size(); DoubleArray pValues = DoubleArray.of(nData, i -> xValues.get(i) * yValues.get(i)); Function<Double, Boolean> domain = new Function<Double, Boolean>() { @Override public Boolean apply(Double x) { return x >= xValues.get(0) && x <= xValues.get(nData - 1); } }; DoubleArray keys = DoubleArray.of(xValues.get(0), -27.7, -21.2, -17.8, -9.99, -1.52, -0.35, xValues.get(nData - 1)); int nKeys = keys.size(); BoundCurveInterpolator bound = INTERP.bind(xValues, yValues); BoundCurveInterpolator boundBase = BASE_INTERP.bind(xValues, pValues); Function<Double, Double> funcDeriv = x -> bound.interpolate(x); for (int i = 0; i < nKeys; ++i) { // interpolate assertEquals(bound.interpolate(keys.get(i)), boundBase.interpolate(keys.get(i)) / keys.get(i), TOL); // first derivative double firstExp = DIFF_CALC.differentiate(funcDeriv, domain).apply(keys.get(i)); assertEquals(bound.firstDerivative(keys.get(i)), firstExp, EPS); // parameter sensitivity int index = i; Function<DoubleArray, Double> funcSensi = x -> INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS)); } }
public void negativeDataTest() { DoubleArray xValues = DoubleArray.of(-34.5, -27.0, -22.5, -14.2, -10.0, -5.0, -0.3); DoubleArray yValues = DoubleArray.of(4.0, 2.0, 1.0, 5.0, 10.0, 3.5, -2.0); int nData = yValues.size(); DoubleArray pValues = DoubleArray.of(nData, i -> xValues.get(i) * yValues.get(i)); Function<Double, Boolean> domain = new Function<Double, Boolean>() { @Override public Boolean apply(Double x) { return x >= xValues.get(0) && x <= xValues.get(nData - 1); } }; DoubleArray keys = DoubleArray.of(xValues.get(0), -27.7, -21.2, -17.8, -10.0, -1.52, -0.35, xValues.get(nData - 1)); int nKeys = keys.size(); BoundCurveInterpolator bound = INTERP.bind(xValues, yValues); BoundCurveInterpolator boundBase = BASE_INTERP.bind(xValues, pValues); Function<Double, Double> funcDeriv = x -> bound.interpolate(x); for (int i = 0; i < nKeys; ++i) { // interpolate assertEquals(bound.interpolate(keys.get(i)), boundBase.interpolate(keys.get(i)) / keys.get(i), TOL); // first derivative double firstExp = DIFF_CALC.differentiate(funcDeriv, domain).apply(keys.get(i)); assertEquals(bound.firstDerivative(keys.get(i)), firstExp, EPS); // parameter sensitivity int index = i; Function<DoubleArray, Double> funcSensi = x -> INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS)); } }
public void linearDataTest() { DoubleArray xValues = DoubleArray.of(0.5, 2.0, 3.0, 4.0, 5.0); DoubleArray yValues = DoubleArray.of(1.0, 4.0, 6.0, 8.0, 10.0); int nData = yValues.size(); DoubleArray pValues = DoubleArray.of(nData, i -> xValues.get(i) * yValues.get(i)); Function<Double, Boolean> domain = new Function<Double, Boolean>() { @Override public Boolean apply(Double x) { return x >= xValues.get(0) && x <= xValues.get(nData - 1); } }; DoubleArray keys = DoubleArray.of(xValues.get(0), 1.1, 2.0, 4.7, xValues.get(nData - 1)); int nKeys = keys.size(); BoundCurveInterpolator bound = INTERP.bind(xValues, yValues); BoundCurveInterpolator boundBase = BASE_INTERP.bind(xValues, pValues); Function<Double, Double> funcDeriv = x -> bound.interpolate(x); for (int i = 0; i < nKeys; ++i) { // interpolate assertEquals(bound.interpolate(keys.get(i)), boundBase.interpolate(keys.get(i)) / keys.get(i), TOL); // first derivative double firstExp = DIFF_CALC.differentiate(funcDeriv, domain).apply(keys.get(i)); assertEquals(bound.firstDerivative(keys.get(i)), firstExp, EPS); // parameter sensitivity int index = i; Function<DoubleArray, Double> funcSensi = x -> INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS)); } }
DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS));
DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS));
Function<DoubleArray, Double> funcSensi = x -> INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS));