* @return The present value curve sensitivity.
*/
public InterestRateCurveSensitivity presentValueCurveSensitivity(final SwaptionCashFixedIbor swaption, final YieldCurveWithBlackSwaptionBundle curveBlack) {
ArgumentChecker.notNull(swaption, "Swaption");
ArgumentChecker.notNull(curveBlack, "Curves with Black volatility");
final AnnuityCouponFixed annuityFixed = swaption.getUnderlyingSwap().getFixedLeg();
final double tenor = swaption.getMaturityTime();
final double forward = swaption.getUnderlyingSwap().accept(PRC, curveBlack);
// Derivative of the forward with respect to the rates.
final InterestRateCurveSensitivity forwardDr = new InterestRateCurveSensitivity(swaption.getUnderlyingSwap().accept(PRSC, curveBlack));
final double pvbp = METHOD_SWAP.getAnnuityCash(swaption.getUnderlyingSwap(), forward);
// Derivative of the cash annuity with respect to the forward.
final double pvbpDf = METHOD_SWAP.getAnnuityCashDerivative(swaption.getUnderlyingSwap(), forward);
// Implementation note: strictly speaking, the strike equivalent is curve dependent; that dependency is ignored.
final BlackPriceFunction blackFunction = new BlackPriceFunction();
final double volatility = curveBlack.getBlackParameters().getVolatility(swaption.getTimeToExpiry(), tenor);
final double discountFactorSettle = curveBlack.getCurve(annuityFixed.getNthPayment(0).getFundingCurveName()).getDiscountFactor(swaption.getSettlementTime());
final BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatility);
final double[] bsAdjoint = blackFunction.getPriceAdjoint(swaption, dataBlack);
final double sensiDF = -swaption.getSettlementTime() * discountFactorSettle * pvbp * bsAdjoint[0];
final List<DoublesPair> list = new ArrayList<>();
list.add(new DoublesPair(swaption.getSettlementTime(), sensiDF));
final Map<String, List<DoublesPair>> resultMap = new HashMap<>();
resultMap.put(annuityFixed.getNthPayment(0).getFundingCurveName(), list);
InterestRateCurveSensitivity result = new InterestRateCurveSensitivity(resultMap);
result = result.plus(forwardDr.multipliedBy(discountFactorSettle * (pvbpDf * bsAdjoint[0] + pvbp * bsAdjoint[1])));
if (!swaption.isLong()) {
result = result.multipliedBy(-1);
}