/******************************************************************************* * Copyright 2015 alladin-IT GmbH * * 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 at.alladin.rmbt.shared.smoothing; import java.util.ArrayList; import java.util.List; /** * * @author lb * */ public enum SmoothingFunction implements SmoothingFunctionCalculation { /** * equal number of data on each side */ CENTRAL_MOVING_AVARAGE { @Override public double smoothYPoint(final List<? extends Smoothable> valueList, final int index, final int dataAmount) { final int i = Math.max(index - (dataAmount / 2), 0); final int j = Math.min(index + (dataAmount / 2), valueList.size()); double sum = 0; String s = "("; for (int x = i; x <= j; x++) { sum += valueList.get(x).getYValue(); s += valueList.get(x).getYValue() + " "; } //System.out.println("smoothing i: " + index + " start i: " + i + ", end i: " + j + ", result: " + (sum / (double)(j-i+1)) + " -> " + s +")"); return sum / (double)(j-i+1); } @Override public double smoothXPoint(List<? extends Smoothable> valueList, int index, int dataAmount) { final int i = Math.max(index - (dataAmount / 2), 0); final int j = Math.min(index + (dataAmount / 2), valueList.size()); double sum = 0; String s = "("; for (int x = i; x <= j; x++) { sum += valueList.get(x).getXValue(); s += valueList.get(x).getXValue() + " "; } //System.out.println("smoothing i: " + index + " start i: " + i + ", end i: " + j + ", result: " + (sum / (double)(j-i+1)) + " -> " + s +")"); return sum / (double)(j-i+1); } @Override public int getStartingIndex(List<? extends Smoothable> valueList, int dataAmount) { return Math.min(dataAmount/2, valueList.size()); } @Override public int getEndingIndex(List<? extends Smoothable> valueList, int dataAmount) { return Math.max(valueList.size() - dataAmount/2 - 1, 0); } }, /** * previous n number of data */ SIMPLE_MOVING_AVARAGE { @Override public double smoothYPoint(final List<? extends Smoothable> valueList, final int index, final int dataAmount) { final int i = Math.max(index - dataAmount + 1, 0); final int j = Math.min(index, valueList.size()); double sum = 0; for (int x = i; x <= j; x++) { sum += valueList.get(x).getYValue(); } return sum / (double)(j-i+1); } @Override public double smoothXPoint(final List<? extends Smoothable> valueList, final int index, final int dataAmount) { final int i = Math.max(index - dataAmount + 1, 0); final int j = Math.min(index, valueList.size()); double sum = 0; for (int x = i; x <= j; x++) { sum += valueList.get(x).getXValue(); } return sum / (double)(j-i+1); } @Override public int getStartingIndex(List<? extends Smoothable> valueList, int dataAmount) { return Math.min(dataAmount-1, valueList.size()); } @Override public int getEndingIndex(List<? extends Smoothable> valueList, int dataAmount) { return valueList.size() - 1; } }; public static List<? extends Smoothable> smooth(final SmoothingFunction smoothingFunction, final List<? extends Smoothable> valueList, final int dataAmount) { if (valueList == null || valueList.size() < dataAmount) { return valueList; } final int startingIndex = smoothingFunction.getStartingIndex(valueList, dataAmount); final int endingIndex = smoothingFunction.getEndingIndex(valueList, dataAmount); System.out.println("smoothing " + smoothingFunction + " width: " + dataAmount + ", start: " + startingIndex + ", end: " + endingIndex); if (startingIndex > endingIndex) { return valueList; } final List<Smoothable> resultList = new ArrayList<Smoothable>(); for (int i = startingIndex; i <= endingIndex; i++) { resultList.add(new SmoothableImpl(smoothingFunction.smoothXPoint(valueList, i, dataAmount), smoothingFunction.smoothYPoint(valueList, i, dataAmount))); } return resultList; } /** * * @author lb * */ private final static class SmoothableImpl implements Smoothable { double xValue; double yValue; public SmoothableImpl(double xValue, double yValue) { this.xValue = xValue; this.yValue = yValue; } @Override public double getXValue() { return xValue; } @Override public double getYValue() { return yValue; } @Override public String toString() { return "SmoothableImpl [xValue=" + xValue + ", yValue=" + yValue + "]"; } } }