class CapletStrippingDirectGlobalWithPenalty {

  public LeastSquareResults solveForVol(final double[][] capVols) {
    ArgumentChecker.noNulls(capVols, "capVols");

    DoubleMatrix1D capVolVec = toVector(capVols, _nCapsTotal);
    int nObs = capVolVec.getNumberOfElements();
    double[] errors = new double[nObs];
    Arrays.fill(errors, DEFAULT_ERROR);
    int nNodes = _nodalSurfaceProvider.getNumberOfNodes();
    double[] guess = new double[nNodes];
    Arrays.fill(guess, 0.7);

    final Function1D<DoubleMatrix1D, Boolean> allowed = new Function1D<DoubleMatrix1D, Boolean>() {
      @Override
      public Boolean evaluate(final DoubleMatrix1D x) {
        double[] temp = x.getData();
        int m = temp.length;
        for (int i = 0; i < m; i++) {
          if (temp[i] < 0) {
            return false;
          }
        }
        return true;
      }
    };

    try {
      return NLLSWP.solve(capVolVec, new DoubleMatrix1D(errors), _capVols, _capVolsGrad, new DoubleMatrix1D(guess), _penalty, allowed);
    } catch (final Exception e) { //try svd if lu fails
      NonLinearLeastSquareWithPenalty lqWithSvd = new NonLinearLeastSquareWithPenalty();
      return lqWithSvd.solve(capVolVec, new DoubleMatrix1D(errors), _capVols, _capVolsGrad, new DoubleMatrix1D(guess), _penalty, allowed);
    }
  }

  public  CapletStrippingDirectGlobalWithPenalty(final List<CapFloor>[] caps, final MulticurveProviderInterface curves, final CapletVolatilityNodalSurfaceProvider nodalSurfaceProvider);
  @SuppressWarnings("unchecked") public  CapletStrippingDirectGlobalWithPenalty(final List<CapFloor>[] caps, final MulticurveProviderInterface curves, final CapletVolatilityNodalSurfaceProvider nodalSurfaceProvider,
      final double lambdaStrike, final double lambdaTime);

}