WeightedMovingAverage { public List<DataPoint> learn() { List<DataPoint> result = new ArrayList<>(dataPoints.size()); EvictingQueue<Double> window = EvictingQueue.create(weights.length); int endHalf = weights.length / 2; for (int i = 0; i < (weights.length - endHalf) - 1; i++) { result.add(new DataPoint(null, dataPoints.get(i).getTimestamp())); } for (int i = 0; i < dataPoints.size(); i++) { window.add(dataPoints.get(i).getValue()); if (window.remainingCapacity() == 0) { Iterator<Double> iterator = window.iterator(); int counter = 0; double sum = 0; while (iterator.hasNext()) { double value = iterator.next(); sum += value*weights[counter++]; } result.add(new DataPoint(sum, dataPoints.get(i - endHalf).getTimestamp())); } } for (int i = result.size(); i < dataPoints.size(); i++) { result.add(new DataPoint(null, dataPoints.get(i).getTimestamp())); } return result; } WeightedMovingAverage(List<DataPoint> dataPoints, double[] weights); List<DataPoint> learn();  }
@Test public void testResultLength() { List<DataPoint> points = Arrays.asList(new DataPoint(1D, 0L), new DataPoint(1D, 5L), new DataPoint(1D, 10L), new DataPoint(1D, 15L), new DataPoint(1D, 20L), new DataPoint(1D, 25L), new DataPoint(1D, 30L)); WeightedMovingAverage weightedMovingAverage = new WeightedMovingAverage(points, new double[]{1, 1}); List<DataPoint> result = weightedMovingAverage.learn(); int nullAtBeginning = nullAt(result, true); int nullAtEnd = nullAt(result, false); Assert.assertTrue(nullAtBeginning == 0); Assert.assertTrue(nullAtEnd == 1); long timestamp = 0; for (DataPoint point: result) { if (point.getValue() != null) { Assert.assertTrue(point.getValue().equals(2.0)); } Assert.assertTrue(point.getTimestamp().equals(timestamp)); timestamp += 5; } weightedMovingAverage = new WeightedMovingAverage(points, new double[]{0.5, 0.5}); result = weightedMovingAverage.learn(); nullAtBeginning = nullAt(result, true); nullAtEnd = nullAt(result, false); Assert.assertTrue(nullAtBeginning == 0); Assert.assertTrue(nullAtEnd == 1); for (DataPoint point: result) { if (point.getValue() != null) { Assert.assertTrue(point.getValue().equals(1.0)); } } weightedMovingAverage = new WeightedMovingAverage(points, new double[]{0.5, 0.5, 0.5, 0.5}); result = weightedMovingAverage.learn(); nullAtBeginning = nullAt(result, true); nullAtEnd = nullAt(result, false); Assert.assertTrue(nullAtBeginning == 1); Assert.assertTrue(nullAtEnd == 2); weightedMovingAverage = new WeightedMovingAverage(points, new double[]{0.5, 0.5, 0.5, 0.5, 0.5}); result = weightedMovingAverage.learn(); nullAtBeginning = nullAt(result, true); nullAtEnd = nullAt(result, false); Assert.assertTrue(nullAtBeginning == 2); Assert.assertTrue(nullAtEnd == 2); }