/* * JaamSim Discrete Event Simulation * Copyright (C) 2013 Ausenco Engineering Canada Inc. * Copyright (C) 2016 JaamSim Software Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jaamsim.CalculationObjects; import com.jaamsim.input.IntegerInput; import com.jaamsim.input.Keyword; /** * The MovingAverage block returns the average of the current input and the N-1 previous inputs. * Output(i) = 1/N * [ Input(i) + Input(i-1) + ... + Input(i-N+1) ] * where Input(i) = input value to the block for the i-th update, * and Output(i) = output value from the block for the i-th update. * @author Harry King * */ public class MovingAverage extends DoubleCalculation { @Keyword(description = "The number of input values over which to average.", exampleList = {"10"}) private final IntegerInput numberOfSamples; private double[] samples; // The previous input values over which to average private int index; // The next index to overwrite (the oldest value on the list) private int n; // The number of inputs values over which to average private double average; // The present value for the moving average { numberOfSamples = new IntegerInput("NumberOfSamples", "Key Inputs", 1); numberOfSamples.setValidRange(1, Integer.MAX_VALUE); this.addInput(numberOfSamples); } public MovingAverage() { samples = new double[1]; } @Override public void earlyInit() { super.earlyInit(); samples = new double[numberOfSamples.getValue()]; index = 0; n = numberOfSamples.getValue(); average = 0.0; } @Override public double calculateValue(double simTime, double inputVal, double lastTime, double lastInputVal, double lastVal) { return average + (inputVal - samples[index])/n; } @Override public void update(double simTime) { super.update(simTime); // Overwrite the oldest value in the list samples[index] = this.getInputValue(simTime); // Set the index to the next oldest value index++; if (index >= n) { index = 0; } // Calculate the average value double val = 0.0; for (int i=0; i<n; i++) { val += samples[i]; } average = val/n; return; } }