/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.model.volatility.discrete; import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurface; import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurfaceProvider; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.analytics.math.matrix.DoubleMatrix2D; import com.opengamma.analytics.math.surface.Surface; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.tuple.DoublesPair; /** * Form a {@link DiscreteVolatilityFunctionProvider} from a {@link VolatilitySurfaceProvider} */ public class DiscreteVolatilityFunctionProviderFromVolSurface extends DiscreteVolatilityFunctionProvider { private final VolatilitySurfaceProvider _volatilitySurfacePro; /** * set up a {@link DiscreteVolatilityFunctionProvider} * @param volSurfacePro a volatility surface provider */ public DiscreteVolatilityFunctionProviderFromVolSurface(final VolatilitySurfaceProvider volSurfacePro) { ArgumentChecker.notNull(volSurfacePro, "volSurfacePro"); _volatilitySurfacePro = volSurfacePro; } @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"); //length of x checked by _volatilitySurfacePro 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"); //length of x checked by _volatilitySurfacePro 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; } }; } }