DiscreteVolatilityFunctionProviderFromVolSurface extends DiscreteVolatilityFunctionProvider { @Override public DiscreteVolatilityFunction from(final DoublesPair[] expiryStrikePoints) { ArgumentChecker.notNull(expiryStrikePoints, "strikeExpiryPoints"); final int n = expiryStrikePoints.length; return new DiscreteVolatilityFunction() { @Override public DoubleMatrix1D evaluate(final DoubleMatrix1D x) { ArgumentChecker.notNull(x, "x"); DoubleMatrix1D res = new DoubleMatrix1D(n); double[] data = res.getData(); final VolatilitySurface vs = _volatilitySurfacePro.getVolSurface(x); for (int i = 0; i < n; i++) { data[i] = vs.getVolatility(expiryStrikePoints[i]); } return res; } @Override public DoubleMatrix2D calculateJacobian(final DoubleMatrix1D x) { ArgumentChecker.notNull(x, "x"); final Surface<Double, Double, DoubleMatrix1D> volSurfaceAdjoint = _volatilitySurfacePro.getParameterSensitivitySurface(x); final DoubleMatrix2D res = new DoubleMatrix2D(n, _volatilitySurfacePro.getNumModelParameters()); for (int i = 0; i < n; i++) { res.getData()[i] = volSurfaceAdjoint.getZValue(expiryStrikePoints[i]).getData(); } return res; } @Override public int getLengthOfDomain() { return _volatilitySurfacePro.getNumModelParameters(); } @Override public int getLengthOfRange() { return n; } }; } DiscreteVolatilityFunctionProviderFromVolSurface(final VolatilitySurfaceProvider volSurfacePro); @Override DiscreteVolatilityFunction from(final DoublesPair[] expiryStrikePoints);  }
@Test public void test() { final DiscreteVolatilityFunctionProvider discPro = new DiscreteVolatilityFunctionProviderFromVolSurface(VOL_SURF_PRO); final int nSamples = 35; final DoublesPair[] points = new DoublesPair[nSamples]; for (int i = 0; i < nSamples; i++) { final double t = RANDOM.nextDouble() * 20.0; final double k = RANDOM.nextDouble() * 0.15; points[i] = DoublesPair.of(t, k); } final DiscreteVolatilityFunction func = discPro.from(points); final DoubleMatrix1D a = new DoubleMatrix1D(0.3, -0.02, -0.4, 0.003, 15.6, -0.05); final DoubleMatrix1D vols = func.evaluate(a); final Function1D<DoublesPair, Double> volFunc = SURFACE.asFunctionOfArguments(a); for (int i = 0; i < nSamples; i++) { assertEquals(volFunc.evaluate(points[i]), vols.getEntry(i), 1e-15); } final DoubleMatrix2D jac = func.calculateJacobian(a); final DoubleMatrix2D fdJac = func.calculateJacobianViaFD(a); AssertMatrix.assertEqualsMatrix(fdJac, jac, 1e-11); assertEquals(SURFACE.getNumberOfParameters(), func.getLengthOfDomain()); assertEquals(nSamples, func.getLengthOfRange()); }