class 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);
  }

}