package edu.stanford.rsl.conrad.utils.interpolation; import java.util.TreeMap; import edu.stanford.rsl.conrad.utils.LinearInterpolatingDoubleArray; /** * This is a generic implementation of {@link LinearInterpolatingDoubleArray} * used in modeling an interpolated table. <div>In this implementation:</div> * <blockquote class="webkit-indent-blockquote" * style="margin: 0 0 0 40px; border: none; padding: 0px;"> <div> Keys represent * Input and Values represent the Output. </div></blockquote> <blockquote * class="webkit-indent-blockquote" * style="margin: 0 0 0 40px; border: none; padding: 0px;"> <div> Entries added * to this data structure are automatically sorted by key value. * </div></blockquote> <div>The default interpolation scheme used is this class * is linear, however developers can create custom interpolation schemes.</div> * * @see LinearInterpolatingDoubleArray * @see Interpolator * @see TreeMap * @author Rotimi X Ojo * */ public class NumberInterpolatingTreeMap extends TreeMap<Number, Number> { private static final long serialVersionUID = -5328843102124736133L; private Interpolator interpolator = new LinearInterpolator(); /** * Returns the intepolated value of key * @param key is the input to the intepolating function * @return throws {@link RuntimeException} if provided key is out of bounds */ public Number interpolateValue(Number key) { if (containsKey(key)) { return get(key); } if ((key.doubleValue() < firstKey().doubleValue()) || (key.doubleValue() > lastKey().doubleValue())) { throw new RuntimeException("Cannot interpolate outside range: " + key + " Range: [ " + firstKey() + ", " + lastKey() + " ]"); } double dkey = key.doubleValue(); Number floor = floorKey(dkey); Number ceiling = ceilingKey(dkey); double floorVal = get(floor).doubleValue(); double ceilingVal = get(ceiling).doubleValue(); interpolator.setXPoints(floor.doubleValue(), ceiling.doubleValue()); interpolator.setYPoints(floorVal, ceilingVal); return interpolator.InterpolateYValue(key.doubleValue()); } /** * Set the interpolating scheme used by the class. A linear interpolator is used by default * @param interpolator is interpolator used by the class */ public void setInterpolator(Interpolator interpolator) { this.interpolator = interpolator; } /** * Retrieve the intepolator used by the class * @return the interpolator used by the class */ public Interpolator getInterpolator() { return interpolator; } /** * Insert a array of input and corresponding output to data structure. input-output pairs are automatially sorted by key value * @param keys is an array of input values. * @param values is corresponding array of output values. */ public void put(Number[] keys, Number[] values) { for (int i = 0; i < keys.length; i++) { put(keys[i], values[i]); } } /** * Insert a array of input and corresponding output to data structure. input-output pairs are automatially sorted by key value * @param keys is an array of input values. * @param values is corresponding array of output values. */ public void put(double[] keys, double[] values) { for (int i = 0; i < keys.length; i++) { put(keys[i], values[i]); } } } /* * Copyright (C) 2010-2014 Rotimi X Ojo * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */