/**
* Copyright (C) 2001-2017 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.tools.math.function.window;
import java.lang.reflect.InvocationTargetException;
/**
* A window function applies weights to the data points in a series window. Left, right or center
* justification allows to adjust which data points should get the highest weights. In case of
* center justification the window function is symmetric.
*
* @author Tobias Malbrecht
*/
public abstract class WindowFunction {
@SuppressWarnings("unchecked")
public static final Class<? extends WindowFunction>[] FUNCTIONS = new Class[] { RectangularWindowFunction.class,
TriangularWindowFunction.class, GaussianWindowFunction.class, HannWindowFunction.class,
HammingWindowFunction.class, BlackmanWindowFunction.class, BlackmanHarrisWindowFunction.class,
BartlettWindowFunction.class };
public static final String[] FUNCTION_NAMES = { "Rectangular", "Triangular", "Gaussian", "Hann", "Hamming", "Blackman",
"Blackman-Harris", "Bartlett" };
public static final int RECTANGULAR = 0;
public static final int TRIANGULAR = 1;
public static final int GAUSSIAN = 2;
public static final int HANN = 3;
public static final int HAMMING = 4;
public static final int BLACKMAN = 5;
public static final int BLACKMAN_HARRIS = 6;
public static final int BARTLETT = 7;
public static final int JUSTIFY_CENTER = 0;
public static final int JUSTIFY_LEFT = 1;
public static final int JUSTIFY_RIGHT = 2;
private int width;
private int justifiedWidth;
private int justifiedOffset;
@SuppressWarnings("unchecked")
public static WindowFunction createWindowFunction(String functionName, int justification, int width)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
InvocationTargetException {
int typeIndex = -1;
for (int i = 0; i < FUNCTION_NAMES.length; i++) {
if (FUNCTION_NAMES[i].equals(functionName)) {
typeIndex = i;
break;
}
}
Class<? extends WindowFunction> clazz = null;
if (typeIndex < 0) {
clazz = (Class<? extends WindowFunction>) Class.forName(functionName);
} else {
clazz = FUNCTIONS[typeIndex];
}
return clazz.getConstructor(Integer.class, Integer.class).newInstance(width, justification);
}
public static WindowFunction createWindowFunction(String functionName, int width) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
return createWindowFunction(functionName, JUSTIFY_CENTER, width);
}
public static WindowFunction createWindowFunction(int typeIndex, int justification, int width)
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
if (typeIndex >= 0 && typeIndex < FUNCTION_NAMES.length) {
Class<? extends WindowFunction> clazz = FUNCTIONS[typeIndex];
return clazz.getConstructor(Integer.class, Integer.class).newInstance(width, justification);
} else {
throw new InstantiationException();
}
}
public static WindowFunction createWindowFunction(int typeIndex, int width)
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
return createWindowFunction(typeIndex, JUSTIFY_CENTER, width);
}
public WindowFunction(int width) {
this(width, JUSTIFY_CENTER);
}
public WindowFunction(int width, int justification) {
this.width = width;
switch (justification) {
case JUSTIFY_CENTER:
this.justifiedWidth = width;
this.justifiedOffset = 0;
break;
case JUSTIFY_LEFT:
this.justifiedWidth = width * 2;
this.justifiedOffset = width;
break;
case JUSTIFY_RIGHT:
this.justifiedWidth = width * 2;
this.justifiedOffset = 0;
break;
}
}
public double[] getWeights() {
double[] weights = new double[width];
for (int i = 0; i < width; i++) {
weights[i] = getValue(justifiedWidth, justifiedOffset + i);
}
return weights;
}
protected abstract double getValue(int width, int n);
public double getValue(int n) {
return getValue(width, n);
}
}