TimeSeriesRelativeWeightedDifferenceOperator extends Function2D<DateDoubleTimeSeries<?>, DateDoubleTimeSeries<?>> { @Override public DateDoubleTimeSeries<?> evaluate(DateDoubleTimeSeries<?> ts, DateDoubleTimeSeries<?> weights) { DateDoubleTimeSeries<?> differenceSeries = DIFFERENCE.evaluate(ts); if (differenceSeries.size() != weights.size()) { throw new IllegalArgumentException("Difference series has " + differenceSeries.size() + " points but weighting series has " + weights.size()); } int n = differenceSeries.size(); double endWeight = weights.getLatestValueFast(); double[] weightedDifferences = new double[n]; for (int i = 0; i < n; i++) { double weight = weights.getValueAtIndexFast(i); weightedDifferences[i] = weight == 0 ? 0 : differenceSeries.getValueAtIndexFast(i) * endWeight / weight; } return ImmutableLocalDateDoubleTimeSeries.of(differenceSeries.timesArrayFast(), weightedDifferences); }  @Override DateDoubleTimeSeries<?> evaluate(DateDoubleTimeSeries<?> ts, DateDoubleTimeSeries<?> weights);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void nullSeriesCausesException() { _operator.evaluate(null, ImmutableLocalDateDoubleTimeSeries.EMPTY_SERIES); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nullWeightsCausesException() { _operator.evaluate(ImmutableLocalDateDoubleTimeSeries.EMPTY_SERIES, null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void seriesMustHaveOneMoreElementThanWeights() { LocalDate[] dates = {LocalDate.of(2014, 1, 1), LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}; double[] values = {1.23, 2.34, 3.45}; LocalDateDoubleTimeSeries series = ImmutableLocalDateDoubleTimeSeries.of(dates, values); LocalDateDoubleTimeSeries weights = series.tail(1); _operator.evaluate(series, weights); }
@Test @SuppressWarnings("unchecked") public void constantWeightsJustProducesSeriesDifference() { LocalDate[] dates = {LocalDate.of(2014, 1, 1), LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}; double[] values = {1.23, 2.34, 3.45}; LocalDateDoubleTimeSeries series = ImmutableLocalDateDoubleTimeSeries.of(dates, values); LocalDate[] weightDates = {LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}; double[] weightValues = {2, 2}; LocalDateDoubleTimeSeries weights = ImmutableLocalDateDoubleTimeSeries.of(weightDates, weightValues); DateDoubleTimeSeries<LocalDate> result = (DateDoubleTimeSeries<LocalDate>) _operator.evaluate(series, weights); DateDoubleTimeSeries<LocalDate> expected = ImmutableLocalDateDoubleTimeSeries.of( new LocalDate[]{LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}, new double[]{1.11, 1.11}); compareTimeseries(result, expected); }
@Test @SuppressWarnings("unchecked") public void zeroWeightsAreHandled() { LocalDate[] dates = {LocalDate.of(2014, 1, 1), LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}; double[] values = {1.23, 2.34, 3.45}; LocalDateDoubleTimeSeries series = ImmutableLocalDateDoubleTimeSeries.of(dates, values); LocalDate[] weightDates = {LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}; double[] weightValues = {0, 2}; LocalDateDoubleTimeSeries weights = ImmutableLocalDateDoubleTimeSeries.of(weightDates, weightValues); DateDoubleTimeSeries<LocalDate> result = (DateDoubleTimeSeries<LocalDate>) _operator.evaluate(series, weights); DateDoubleTimeSeries<LocalDate> expected = ImmutableLocalDateDoubleTimeSeries.of( new LocalDate[]{LocalDate.of(2014, 1, 2), LocalDate.of(2014, 1, 3)}, new double[]{1.11, 1.11}); compareTimeseries(result, expected); }