CrossGammaMultiCurveCalculator { public DoubleMatrix2D calculateCrossGammaCrossCurve(final InstrumentDerivative instrument, final MulticurveProviderDiscount multicurve) { ArgumentChecker.notNull(instrument, "instrument"); ArgumentChecker.notNull(multicurve, "multi-curve provider"); Set<String> names = multicurve.getAllNames(); int nbCurve = names.size(); String[] namesArray = names.toArray(new String[nbCurve]); Currency ccy = checkUniqueCurrency(multicurve); InterpolatedDoublesCurve[] interpolatedCurves = interpolatedCurves(multicurve, nbCurve, namesArray); double[][] y = new double[nbCurve][]; double[][] x = new double[nbCurve][]; int[] nbNodeByCurve = new int[nbCurve]; int nbNodeTotal = 0; for (int loopcurve = 0; loopcurve < nbCurve; loopcurve++) { y[loopcurve] = interpolatedCurves[loopcurve].getYDataAsPrimitive(); x[loopcurve] = interpolatedCurves[loopcurve].getXDataAsPrimitive(); nbNodeByCurve[loopcurve] = x[loopcurve].length; nbNodeTotal += nbNodeByCurve[loopcurve]; } MultipleCurrencyParameterSensitivity ps0 = _psc.calculateSensitivity(instrument, multicurve); double[][] ps0Array = sensitivitiesAsArrayOfMatrix(nbCurve, namesArray, ccy, nbNodeByCurve, ps0); double[][] gammaArray = new double[nbNodeTotal][nbNodeTotal]; int loopnodetotal = 0; for (int loopcurve = 0; loopcurve < nbCurve; loopcurve++) { MultipleCurrencyParameterSensitivity[] psShift = new MultipleCurrencyParameterSensitivity[nbNodeByCurve[loopcurve]]; for (int loopnode = 0; loopnode < nbNodeByCurve[loopcurve]; loopnode++) { final double[] yieldBumped = y[loopcurve].clone(); yieldBumped[loopnode] += _shift; MulticurveProviderDiscount multicurveBumped = bumpedProvider(multicurve, namesArray[loopcurve], interpolatedCurves[loopcurve].getInterpolator(), x[loopcurve], yieldBumped); psShift[loopnode] = _psc.calculateSensitivity(instrument, multicurveBumped); int loopnodetotal2 = 0; for (int loopcurve2 = 0; loopcurve2 < nbCurve; loopcurve2++) { DoubleMatrix1D sensiCurve = psShift[loopnode].getSensitivity(namesArray[loopcurve2], ccy); double[] psShiftArray = new double[nbNodeByCurve[loopcurve2]]; if (sensiCurve != null) { psShiftArray = sensiCurve.getData(); } for (int loopnode2 = 0; loopnode2 < nbNodeByCurve[loopcurve2]; loopnode2++) { gammaArray[loopnodetotal][loopnodetotal2] = (psShiftArray[loopnode2] - ps0Array[loopcurve2][loopnode2]) / _shift; loopnodetotal2++; } } loopnodetotal++; } } return new DoubleMatrix2D(gammaArray); } CrossGammaMultiCurveCalculator(final double shift,
      final InstrumentDerivativeVisitor<ParameterProviderInterface, MultipleCurrencyMulticurveSensitivity> curveSensitivityCalculator);  CrossGammaMultiCurveCalculator(final InstrumentDerivativeVisitor<ParameterProviderInterface, MultipleCurrencyMulticurveSensitivity> curveSensitivityCalculator); HashMap<String, DoubleMatrix2D> calculateCrossGammaIntraCurve(final InstrumentDerivative instrument, final MulticurveProviderDiscount multicurve); DoubleMatrix2D calculateCrossGammaCrossCurve(final InstrumentDerivative instrument, final MulticurveProviderDiscount multicurve);  }
@Test public void constructor() { CrossGammaMultiCurveCalculator cgcShift = new CrossGammaMultiCurveCalculator(BP1 * 10, PVCSDC); DoubleMatrix2D gammaCrossCurve10 = cgcShift.calculateCrossGammaCrossCurve(SWAP_FIXED_IBOR, MULTICURVE); int nbNode = GAMMA_CROSS_CURVES.getNumberOfColumns(); boolean unchanged = true; for (int i = 0; i < nbNode; i++) { for (int j = 0; j < nbNode; j++) { unchanged = unchanged && (Math.abs(GAMMA_CROSS_CURVES.getEntry(i, j) - gammaCrossCurve10.getEntry(i, j)) > TOLERANCE_PV_GAMMA); } } assertFalse("CrossGammaMultiCurveCalculator", unchanged); }