@Override
  public boolean setNodeValue(final int iNodeIndex, final double dblNodeDF) {
    if (!org.drip.quant.common.NumberUtil.IsValid(dblNodeDF)) return false;

    int iNumDate = _adblDate.length;

    if (iNodeIndex > iNumDate) return false;

    if (0 == iNodeIndex) {
      _dblLeftFlatForwardRate =
          -365.25 * java.lang.Math.log(_dblLeftNodeDF = dblNodeDF) / (_adblDate[0] - _dblEpochDate);

      return true;
    }

    if (1 == iNodeIndex)
      return _msr.setLeftNode(_dblLeftNodeDF, _dblLeftNodeDFSlope, dblNodeDF, null);

    if (iNumDate - 1 == iNodeIndex) {
      try {
        _dblRightFlatForwardRate =
            -365.25
                * java.lang.Math.log(_msr.responseValue(_adblDate[iNodeIndex]))
                / (_adblDate[iNodeIndex] - _dblEpochDate);
      } catch (java.lang.Exception e) {
        e.printStackTrace();

        return false;
      }
    }

    return _msr.resetNode(iNodeIndex, dblNodeDF);
  }
  @Override
  public double df(final double dblDate) throws java.lang.Exception {
    if (!org.drip.quant.common.NumberUtil.IsValid(dblDate))
      throw new java.lang.Exception("NonlinearDiscountFactorDiscountCurve::df => Invalid Inputs");

    if (dblDate <= _dblEpochDate) return 1.;

    if (dblDate <= _adblDate[0])
      return java.lang.Math.exp(-1. * _dblLeftFlatForwardRate * (dblDate - _dblEpochDate) / 365.25);

    return (dblDate <= _adblDate[_adblDate.length - 1]
            ? _msr.responseValue(dblDate)
            : java.lang.Math.exp(
                -1. * _dblRightFlatForwardRate * (dblDate - _dblEpochDate) / 365.25))
        * turnAdjust(epoch().julian(), dblDate);
  }