final double bump = 0.001;
final double[][][] sensiBlackFD = new double[NB_EXPIRY][NB_MATURITY][NB_STRIKE];
final double[] pv = new double[NB_INS];
final OperationTimer timer = new OperationTimer(_logger, "Calibrating {}x{}x{}x{} SABR and computing Black sensitivities for {} instruments", NB_INS, NB_EXPIRY, NB_MATURITY, NB_STRIKE, NB_INS);
for (int loopins = 0; loopins < NB_INS; loopins++) {
pv[loopins] = METHOD_SWAPTION_SABR.presentValue(INSTRUMENTS[loopins], sabrBundle).getAmount();
final PresentValueSABRSensitivityDataBundle sensiPoint = INSTRUMENTS[loopins].accept(PVSSC_SABR, sabrBundle);
final PresentValueSABRSensitivityDataBundle sensiNode = SABRSensitivityNodeCalculator.calculateNodeSensitivities(sensiPoint, sabrParameters);
final Map<DoublesPair, DoubleMatrix1D> sensiBlack = BlackSensitivityFromSABRSensitivityCalculator.blackSensitivity(sensiNode, inverseJacobianMap);
for (int loopexpiry = 0; loopexpiry < NB_EXPIRY; loopexpiry++) {
for (int loopmat = 0; loopmat < NB_MATURITY; loopmat++) {
for (int loopstr = 0; loopstr < NB_STRIKE; loopstr++) {
final double[][][] bumpedVol = bump(loopexpiry, loopmat, loopstr, bump);
final ObjectsPair<SABRInterestRateParameters, HashMap<DoublesPair, DoubleMatrix2D>> bumpedResult = calibration(bumpedVol);
final SABRInterestRateDataBundle bumpedSabrBundle = new SABRInterestRateDataBundle(bumpedResult.getFirst(), CURVES);
final double bumpedPv = METHOD_SWAPTION_SABR.presentValue(INSTRUMENTS[loopins], bumpedSabrBundle).getAmount();
sensiBlackFD[loopexpiry][loopmat][loopstr] = (bumpedPv - pv[loopins]) / bump;
final double sensiCalc = sensiBlack.get(DoublesPair.of(EXPIRY_TIME[loopexpiry], MATURITY_TIME[loopmat])).getEntry(loopstr);
if (loopins != 0 && loopexpiry != 1 && loopmat != 2 && loopstr != 0) { // The first point has a larger error wrt FD.
assertTrue("Black Node Sensitivity: FD [" + loopexpiry + ", " + loopmat + ", " + loopstr + "]",
Math.abs(sensiBlackFD[loopexpiry][loopmat][loopstr] - sensiCalc) < 25.0 || Math.abs(sensiBlackFD[loopexpiry][loopmat][loopstr] / sensiCalc - 1) < 0.05);
}
} // end loopstr
} // end loopmat
} // end loopexpiry
} // end loopins
timer.finished();
}