public AffineDivCurveUtils(DividendQuote[] dividends, DiscountCurve discountCurve, ITimeMeasure time) { Contract.Requires(EnumerableUtils.IsSorted(dividends.Select(div => div.Date))); if (dividends.Length > 0) { double[] divDates = dividends.Map(div => time[div.Date]); double[] spotYieldGrowths = dividends.Scan(1.0, (prev, div) => prev * (1.0 - div.Yield)); var spotYieldGrowth = new StepFunction(divDates, spotYieldGrowths, 1.0); assetGrowth = t => spotYieldGrowth.Eval(t) / discountCurve.Zc(t); double[] discountedCashs = dividends.Map(div => div.Cash / assetGrowth(time[div.Date])); double[] cashBpvs = discountedCashs.Scan(0.0, (prev, c) => prev + c); cashDivBpv = new StepFunction(divDates, cashBpvs, 0.0); cashBpvIntegral = cashDivBpv.Integral(0.0); double[] squareTimeWeightedCashs = discountedCashs.ZipWith(divDates, (c, t) => c * t * t); squareTimeWeightedCash = new StepFunction(divDates, squareTimeWeightedCashs, 0.0); } else { assetGrowth = t => 1.0 / discountCurve.Zc(t); cashDivBpv = new StepFunction(new[] { 0.0 }, new[] { 0.0 }, double.NaN); cashBpvIntegral = RrFunctions.Zero; squareTimeWeightedCash = new StepFunction(new[] { 0.0 }, new[] { 0.0 }, double.NaN); } }
public void TestIntegral(double[] pillars, double[] vals, double leftVal, double[] refIntegralVals) { var stepFunc = new StepFunction(pillars, vals, leftVal); var integral = stepFunc.Integral(pillars[0]); Assert.IsTrue(integral is SplineInterpoler); for (int i = 0; i < pillars.Length - 1; i++) { var integralVal = integral.Eval(pillars[i]); Assert.IsTrue(DoubleUtils.MachineEquality(integralVal, refIntegralVals[i])); } }