@Test
 /** Tests long/short parity. */
 public void presentValueHullWhiteSensitivitylongShortParityExplicit() {
   final double[] pvhwsLong =
       METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final double[] pvhwsShort =
       METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_SHORT_PAYER, HW_MULTICURVES);
   for (int loophw = 0; loophw < pvhwsLong.length; loophw++) {
     assertEquals(
         "Swaption physical - Hull-White - presentValueHullWhiteSensitivity - long/short parity",
         pvhwsLong[loophw],
         -pvhwsShort[loophw],
         TOLERANCE_PV_DELTA);
   }
 }
 @Test
 /** Tests payer/receiver/swap parity. */
 public void presentValueHullWhiteSensitivitypayerReceiverParityExplicit() {
   final double[] pvhwsReceiverLong =
       METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_RECEIVER, HW_MULTICURVES);
   final double[] pvhwsPayerShort =
       METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_SHORT_PAYER, HW_MULTICURVES);
   for (int loophw = 0; loophw < pvhwsReceiverLong.length; loophw++) {
     assertEquals(
         "Swaption physical - Hull-White - present value - payer/receiver/swap parity",
         0,
         pvhwsReceiverLong[loophw] + pvhwsPayerShort[loophw],
         TOLERANCE_PV_DELTA);
   }
 }
 @Test
 /** Tests the Hull-White parameters sensitivity for the explicit formula. */
 public void presentValueHullWhiteSensitivityExplicit() {
   final double[] hwSensitivity =
       METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final int nbVolatility = HW_PARAMETERS.getVolatility().length;
   final double shiftVol = 1.0E-6;
   final double[] volatilityBumped = new double[nbVolatility];
   System.arraycopy(HW_PARAMETERS.getVolatility(), 0, volatilityBumped, 0, nbVolatility);
   final double[] volatilityTime = new double[nbVolatility - 1];
   System.arraycopy(HW_PARAMETERS.getVolatilityTime(), 1, volatilityTime, 0, nbVolatility - 1);
   final double[] pvBumpedPlus = new double[nbVolatility];
   final double[] pvBumpedMinus = new double[nbVolatility];
   final HullWhiteOneFactorPiecewiseConstantParameters parametersBumped =
       new HullWhiteOneFactorPiecewiseConstantParameters(
           HW_PARAMETERS.getMeanReversion(), volatilityBumped, volatilityTime);
   final HullWhiteOneFactorProviderDiscount bundleBumped =
       new HullWhiteOneFactorProviderDiscount(MULTICURVES, parametersBumped, EUR);
   for (int loopvol = 0; loopvol < nbVolatility; loopvol++) {
     volatilityBumped[loopvol] += shiftVol;
     parametersBumped.setVolatility(volatilityBumped);
     pvBumpedPlus[loopvol] =
         METHOD_HW.presentValue(SWAPTION_LONG_PAYER, bundleBumped).getAmount(EUR);
     volatilityBumped[loopvol] -= 2 * shiftVol;
     parametersBumped.setVolatility(volatilityBumped);
     pvBumpedMinus[loopvol] =
         METHOD_HW.presentValue(SWAPTION_LONG_PAYER, bundleBumped).getAmount(EUR);
     assertEquals(
         "Swaption - Hull-White sensitivity adjoint: derivative "
             + loopvol
             + " - difference:"
             + ((pvBumpedPlus[loopvol] - pvBumpedMinus[loopvol]) / (2 * shiftVol)
                 - hwSensitivity[loopvol]),
         (pvBumpedPlus[loopvol] - pvBumpedMinus[loopvol]) / (2 * shiftVol),
         hwSensitivity[loopvol],
         TOLERANCE_PV_DELTA);
     volatilityBumped[loopvol] = HW_PARAMETERS.getVolatility()[loopvol];
   }
 }
  @Test(enabled = false)
  /** Tests of performance. "enabled = false" for the standard testing. */
  public void performance() {
    long startTime, endTime;
    final int nbTest = 1000;
    MultipleCurrencyAmount pvPayerLongExplicit = MultipleCurrencyAmount.of(EUR, 0.0);
    MultipleCurrencyAmount pvPayerLongIntegration = MultipleCurrencyAmount.of(EUR, 0.0);
    MultipleCurrencyAmount pvPayerLongApproximation = MultipleCurrencyAmount.of(EUR, 0.0);
    @SuppressWarnings("unused")
    MultipleCurrencyAmount pvPayerLongMC = MultipleCurrencyAmount.of(EUR, 0.0);
    double[] pvhws =
        METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    MultipleCurrencyMulticurveSensitivity pvcs =
        METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);

    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvPayerLongExplicit = METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest + " pv swaption Hull-White explicit method: " + (endTime - startTime) + " ms");
    // Performance note: HW price: 19-Nov-2012: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 380 ms for
    // 10000 swaptions.
    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvhws = METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " HW sensitivity swaption Hull-White explicit method: "
            + (endTime - startTime)
            + " ms");
    // Performance note: HW sensitivity (3): 19-Nov-2012: On Mac Pro 3.2 GHz Quad-Core Intel Xeon:
    // 430 ms for 10000 swaptions.
    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvcs = METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " curve sensitivity swaption Hull-White explicit method: "
            + (endTime - startTime)
            + " ms");
    // Performance note: curve sensitivity (40): 19-Nov-2012: On Mac Pro 3.2 GHz Quad-Core Intel
    // Xeon: 855 ms for 10000 swaptions.
    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvhws = METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
      pvcs = METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
      pvhws = METHOD_HW.presentValueHullWhiteSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " price/delta/vega swaption Hull-White explicit method: "
            + (endTime - startTime)
            + " ms");
    // Performance note: present value/delta/vega: 19-Nov-2012: On Mac Pro 3.2 GHz Quad-Core Intel
    // Xeon: 1730 ms for 10000 swaptions.
    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvPayerLongIntegration =
          METHOD_HW_INTEGRATION.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " swaption Hull-White numerical integration method: "
            + (endTime - startTime)
            + " ms");
    // Performance note: HW numerical integration: 19-Nov-2012: On Mac Pro 3.2 GHz Quad-Core Intel
    // Xeon: 1700 ms for 10000 swaptions.
    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvPayerLongApproximation =
          METHOD_HW_APPROXIMATION.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest + " swaption Hull-White approximation method: " + (endTime - startTime) + " ms");
    // Performance note: HW approximation: 19-Nov-2012: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 250
    // ms for 10000 swaptions.

    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvPayerLongMC = METHOD_HW_MONTECARLO.presentValue(SWAPTION_LONG_PAYER, EUR, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " swaption Hull-White Monte Carlo method ("
            + NB_PATH
            + " paths): "
            + (endTime - startTime)
            + " ms");
    // Performance note: HW approximation: 18-Aug-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 9200
    // ms for 1000 swaptions (12500 paths).

    final double difference =
        pvPayerLongExplicit.getAmount(EUR) - pvPayerLongIntegration.getAmount(EUR);
    final double difference2 =
        pvPayerLongExplicit.getAmount(EUR) - pvPayerLongApproximation.getAmount(EUR);
    //      double difference3 = pvPayerLongExplicit.getAmount(CUR) - pvPayerLongMC.getAmount(CUR);
    System.out.println("Difference explicit-integration: " + difference);
    System.out.println("Difference explicit-approximation: " + difference2);
    //      System.out.println("Difference explicit-Monte Carlo: " + difference3);
    System.out.println("Curve sensitivity: " + pvcs.toString());
    System.out.println("HW sensitivity: " + Arrays.toString(pvhws));
  }