@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); } } }
@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); } }