public double rpv01(IsdaCompliantCreditCurve creditCurve, CdsPriceType cleanOrDirty) {

      double pv = 0.0;
      for (int i = 0; i < _nPayments; i++) {
        CdsCoupon c = _cds.getCoupon(i);
        double q = creditCurve.getDiscountFactor(c.getEffEnd());
        pv += c.getYearFrac() * _paymentDF[i] * q;
      }

      if (_cds.isPayAccOnDefault()) {
        double accPV = 0.0;
        for (int i = 0; i < _nPayments; i++) {
          accPV += calculateSinglePeriodAccrualOnDefault(i, creditCurve);
        }
        pv += accPV;
      }

      pv /= _valuationDF;

      if (cleanOrDirty == CdsPriceType.CLEAN) {
        pv -= _cds.getAccruedYearFraction();
      }
      return pv;
    }
    public Pricer(
        CdsAnalytic cds,
        IsdaCompliantYieldCurve yieldCurve,
        double[] creditCurveKnots,
        double fractionalSpread,
        double pointsUpfront) {

      _cds = cds;
      _fracSpread = fractionalSpread;
      _pointsUpfront = pointsUpfront;

      // protection leg
      _proLegIntPoints =
          getIntegrationsPoints(
              cds.getEffectiveProtectionStart(),
              cds.getProtectionEnd(),
              yieldCurve.getKnotTimes(),
              creditCurveKnots);
      _nProPoints = _proLegIntPoints.length;
      double lgd = cds.getLGD();
      _valuationDF = yieldCurve.getDiscountFactor(cds.getCashSettleTime());
      _lgdDF = lgd / _valuationDF;
      _proYieldCurveRT = new double[_nProPoints];
      _proDF = new double[_nProPoints];
      for (int i = 0; i < _nProPoints; i++) {
        _proYieldCurveRT[i] = yieldCurve.getRT(_proLegIntPoints[i]);
        _proDF[i] = Math.exp(-_proYieldCurveRT[i]);
      }

      // premium leg
      _nPayments = cds.getNumPayments();
      _paymentDF = new double[_nPayments];
      for (int i = 0; i < _nPayments; i++) {
        _paymentDF[i] = yieldCurve.getDiscountFactor(cds.getCoupon(i).getPaymentTime());
      }

      if (cds.isPayAccOnDefault()) {
        double tmp =
            cds.getNumPayments() == 1 ? cds.getEffectiveProtectionStart() : cds.getAccStart();
        double[] integrationSchedule =
            getIntegrationsPoints(
                tmp, cds.getProtectionEnd(), yieldCurve.getKnotTimes(), creditCurveKnots);

        _accRate = new double[_nPayments];
        _offsetAccStart = new double[_nPayments];
        _premLegIntPoints = new double[_nPayments][];
        _premDF = new double[_nPayments][];
        _rt = new double[_nPayments][];
        _premDt = new double[_nPayments][];
        for (int i = 0; i < _nPayments; i++) {
          CdsCoupon c = cds.getCoupon(i);
          _offsetAccStart[i] = c.getEffStart();
          double offsetAccEnd = c.getEffEnd();
          _accRate[i] = c.getYFRatio();
          double start = Math.max(_offsetAccStart[i], cds.getEffectiveProtectionStart());
          if (start >= offsetAccEnd) {
            continue;
          }
          _premLegIntPoints[i] = truncateSetInclusive(start, offsetAccEnd, integrationSchedule);
          int n = _premLegIntPoints[i].length;
          _rt[i] = new double[n];
          _premDF[i] = new double[n];
          for (int k = 0; k < n; k++) {
            _rt[i][k] = yieldCurve.getRT(_premLegIntPoints[i][k]);
            _premDF[i][k] = Math.exp(-_rt[i][k]);
          }
          _premDt[i] = new double[n - 1];

          for (int k = 1; k < n; k++) {
            double dt = _premLegIntPoints[i][k] - _premLegIntPoints[i][k - 1];
            _premDt[i][k - 1] = dt;
          }
        }
      } else {
        _accRate = null;
        _offsetAccStart = null;
        _premDF = null;
        _premDt = null;
        _rt = null;
        _premLegIntPoints = null;
      }
    }