@Test
 /** Approximation analysis. */
 public void presentValueApproximationAnalysis() {
   final NormalImpliedVolatilityFormula implied = new NormalImpliedVolatilityFormula();
   final int nbStrike = 20;
   final double[] pvExplicit = new double[nbStrike + 1];
   final double[] pvApproximation = new double[nbStrike + 1];
   final double[] strike = new double[nbStrike + 1];
   final double[] volExplicit = new double[nbStrike + 1];
   final double[] volApprox = new double[nbStrike + 1];
   final double strikeRange = 0.010;
   final SwapFixedCoupon<Coupon> swap = SWAP_PAYER_DEFINITION.toDerivative(REFERENCE_DATE);
   final double forward = swap.accept(PRDC, MULTICURVES);
   final double pvbp = METHOD_SWAP.presentValueBasisPoint(swap, MULTICURVES);
   for (int loopstrike = 0; loopstrike <= nbStrike; loopstrike++) {
     strike[loopstrike] =
         forward
             - strikeRange
             + 3
                 * strikeRange
                 * loopstrike
                 / nbStrike; // From forward-strikeRange to forward+2*strikeRange
     final SwapFixedIborDefinition swapDefinition =
         SwapFixedIborDefinition.from(
             SETTLEMENT_DATE,
             SWAP_TENOR,
             EUR1YEURIBOR6M,
             NOTIONAL,
             strike[loopstrike],
             FIXED_IS_PAYER);
     final SwaptionPhysicalFixedIborDefinition swaptionDefinition =
         SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, swapDefinition, IS_LONG);
     final SwaptionPhysicalFixedIbor swaption = swaptionDefinition.toDerivative(REFERENCE_DATE);
     pvExplicit[loopstrike] = METHOD_HW.presentValue(swaption, HW_MULTICURVES).getAmount(EUR);
     pvApproximation[loopstrike] =
         METHOD_HW_APPROXIMATION.presentValue(swaption, HW_MULTICURVES).getAmount(EUR);
     final NormalFunctionData data = new NormalFunctionData(forward, pvbp, 0.01);
     volExplicit[loopstrike] =
         implied.getImpliedVolatility(data, swaption, pvExplicit[loopstrike]);
     volApprox[loopstrike] =
         implied.getImpliedVolatility(data, swaption, pvApproximation[loopstrike]);
     assertEquals(
         "Swaption physical - Hull-White - implied volatility - explicit/approximation",
         volExplicit[loopstrike],
         volApprox[loopstrike],
         1.0E-3); // 0.10%
   }
 }
 @Test
 public void presentValue() {
   final MultipleCurrencyAmount pvMethod =
       METHOD_BLACK.presentValue(SWAPTION_LONG_REC, BLACK_MULTICURVES);
   final double forward = SWAPTION_LONG_REC.getUnderlyingSwap().accept(PRDC, MULTICURVES);
   final double pvbp =
       METHOD_SWAP.presentValueBasisPoint(SWAPTION_LONG_REC.getUnderlyingSwap(), MULTICURVES);
   final double volatility =
       BLACK.getVolatility(
           SWAPTION_LONG_REC.getTimeToExpiry(), SWAPTION_LONG_REC.getMaturityTime());
   final BlackPriceFunction blackFunction = new BlackPriceFunction();
   final BlackFunctionData dataBlack = new BlackFunctionData(forward, pvbp, volatility);
   final Function1D<BlackFunctionData, Double> func =
       blackFunction.getPriceFunction(SWAPTION_LONG_REC);
   final double pvExpected = func.evaluate(dataBlack);
   assertEquals(
       "Swaption Black method: present value", pvExpected, pvMethod.getAmount(EUR), TOLERANCE_PV);
 }
 @Test
 /** Compare explicit formula with approximated formula. */
 public void presentValueApproximation() {
   final BlackImpliedVolatilityFormula implied = new BlackImpliedVolatilityFormula();
   final double forward =
       SWAPTION_LONG_PAYER
           .getUnderlyingSwap()
           .accept(ParRateDiscountingCalculator.getInstance(), MULTICURVES);
   final double pvbp =
       METHOD_SWAP.presentValueBasisPoint(SWAPTION_LONG_PAYER.getUnderlyingSwap(), MULTICURVES);
   final MultipleCurrencyAmount pvPayerLongExplicit =
       METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvPayerLongApproximation =
       METHOD_HW_APPROXIMATION.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final BlackFunctionData data = new BlackFunctionData(forward, pvbp, 0.20);
   final double volExplicit =
       implied.getImpliedVolatility(data, SWAPTION_LONG_PAYER, pvPayerLongExplicit.getAmount(EUR));
   final double volApprox =
       implied.getImpliedVolatility(
           data, SWAPTION_LONG_PAYER, pvPayerLongApproximation.getAmount(EUR));
   assertEquals(
       "Swaption physical - Hull-White - present value - explicit/approximation",
       pvPayerLongExplicit.getAmount(EUR),
       pvPayerLongApproximation.getAmount(EUR),
       5.0E+2);
   assertEquals(
       "Swaption physical - Hull-White - present value - explicit/approximation",
       volExplicit,
       volApprox,
       2.5E-4); // 0.025%
   final MultipleCurrencyAmount pvReceiverLongExplicit =
       METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvReceiverLongApproximation =
       METHOD_HW_APPROXIMATION.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   assertEquals(
       "Swaption physical - Hull-White - present value - explicit/numerical integration",
       pvReceiverLongExplicit.getAmount(EUR),
       pvReceiverLongApproximation.getAmount(EUR),
       5.0E+2);
 }