*/
public MultipleCurrencyAmount presentValue(final CapFloorIbor cap, final LiborMarketModelDisplacedDiffusionProviderInterface lmmData) {
ArgumentChecker.notNull(cap, "The cap/floor shoud not be null");
ArgumentChecker.notNull(lmmData, "LMM provider");
Currency ccy = cap.getCurrency();
MulticurveProviderInterface multicurves = lmmData.getMulticurveProvider();
LiborMarketModelDisplacedDiffusionParameters parameters = lmmData.getLMMParameters();
int index = lmmData.getLMMParameters().getTimeIndex(cap.getFixingPeriodStartTime());
double volatility = 0;
for (int loopfact = 0; loopfact < lmmData.getLMMParameters().getNbFactor(); loopfact++) {
volatility += parameters.getVolatility()[index][loopfact] * parameters.getVolatility()[index][loopfact];
}
volatility = Math.sqrt(volatility);
double timeDependentFactor = Math.sqrt((Math.exp(2 * parameters.getMeanReversion() * cap.getFixingTime()) - 1.0) / (2.0 * parameters.getMeanReversion()));
volatility *= timeDependentFactor;
double displacement = parameters.getDisplacement()[index];
double forward = multicurves.getForwardRate(cap.getIndex(), cap.getFixingPeriodStartTime(), cap.getFixingPeriodEndTime(), cap.getFixingAccrualFactor());
double beta = (1.0 + cap.getFixingAccrualFactor() * forward) * multicurves.getDiscountFactor(ccy, cap.getFixingPeriodEndTime())
/ multicurves.getDiscountFactor(ccy, cap.getFixingPeriodStartTime());
double strikeAdjusted = (cap.getStrike() - (beta - 1) / cap.getFixingAccrualFactor()) / beta;
EuropeanVanillaOption option = new EuropeanVanillaOption(strikeAdjusted + displacement, 1.0, cap.isCap()); // Time is in timeDependentFactor
double forwardDsc = (multicurves.getDiscountFactor(ccy, cap.getFixingPeriodStartTime()) / multicurves.getDiscountFactor(ccy, cap.getFixingPeriodEndTime()) - 1.0) / cap.getFixingAccrualFactor();
final double df = multicurves.getDiscountFactor(ccy, cap.getPaymentTime());
final BlackFunctionData dataBlack = new BlackFunctionData(forwardDsc + displacement, df, volatility);
final Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(option);
final double price = beta * func.evaluate(dataBlack) * cap.getNotional() * cap.getPaymentYearFraction();
return MultipleCurrencyAmount.of(cap.getCurrency(), price);
}