/**
   * This calibrated to all the cap volatilities (excluding ATM) at once
   *
   * <p>The output is this surface sampled on a grid (101 by 101), such that it can be plotted as an
   * Excel surface plot (or imported into some other visualisation tool).
   */
  @Test(description = "Demo of infering a caplet volatility surface")
  public void globalVolFitExATMDemo() {
    final double lambda = 0.03; // this is chosen to give a chi2/DoF of around 1
    final MultiCapFloorPricerGrid pricer =
        new MultiCapFloorPricerGrid(getAllCapsExATM(), getYieldCurves());
    final CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda);

    final double[] capVols = getAllCapVolsExATM();
    final int n = capVols.length;
    final double[] errors = new double[n];
    Arrays.fill(errors, 1e-4); // 1bps
    final DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), 0.7);

    final CapletStrippingResult res = stripper.solve(capVols, MarketDataType.VOL, errors, guess);
    System.out.println(res);

    // print the caplet volatilities
    System.out.println("\n");
    res.printCapletVols(System.out);

    System.out.println("Caplet volatility surface");
    res.printSurface(System.out, 101, 101);
  }