/******************************************************************************* * Copyright (c) 2012 jnect.org. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eugen Neufeld - initial API and implementation * Istvan Rath - IncQuery-specific additions *******************************************************************************/ package bodymodel; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import org.eclipse.xtext.xbase.lib.Pure; /** * This class helps to calculate a moving average, this way the data can be cleaned. * @author Philip Achenbach * @author Eugen Neufeld * * Originally found in http://code.google.com/a/eclipselabs.org/p/jnect/ * * XXX foreign IP * * @author istvanrath - modifications to allow factory-style operation so that it can be meaningfully used from IncQuery queries */ public class MovingAverageCalculator { private final Queue<Float> window = new LinkedList<Float>(); private final int numPeriods; private float sum; /** * instantiate the {@link MovingAverageCalculator} with a number of periods to build the average over * @param numPeriods - number of values to build the average over */ public MovingAverageCalculator(int numPeriods) { this.numPeriods = numPeriods; } /** * add a value to the moving average, if the number of periods is exceeded, then the oldest value is removed. * @param num - the value to add to the moving average */ //@Pure public MovingAverageCalculator addValue(float num) { sum += num; window.add(num); if (window.size() > numPeriods) { sum -= window.remove(); } return this; } /** * get the current moving average * @return - current value of the moving average */ //@Pure public float getMovingAvg() { return (window.size() == 0) ? 0 : sum / window.size(); } /* istvanrath's modifications below */ static Map<String, MovingAverageCalculator> calculators = new HashMap<String, MovingAverageCalculator>(); public static int periodLength = 10; @Pure public static MovingAverageCalculator getCalculator(String key) { if (calculators.containsKey(key)) { return calculators.get(key); } else { MovingAverageCalculator mac = new MovingAverageCalculator(periodLength); calculators.put(key, mac); return mac; } } }