001/*
002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003 * Copyright (C) 2006 - JScience (http://jscience.org/)
004 * All rights reserved.
005 * 
006 * Permission to use, copy, modify, and distribute this software is
007 * freely granted, provided that this notice is preserved.
008 */
009package org.jscience.mathematics.function;
010
011import java.io.Serializable;
012import java.util.SortedMap;
013
014import javolution.lang.Immutable;
015
016import org.jscience.mathematics.structure.Field;
017
018/**
019 * <p> This interface represents an estimator of the values at a certain point 
020 *     using surrounding points and values. Interpolators are typically used 
021 *     with {@link DiscreteFunction discrete functions}.</p>
022 * 
023 * <p> As a convenience {@link Interpolator.Linear linear} interpolator class
024 *     for point-values of the same {@link Field field} is provided.</p>
025 *     
026 * <p> Custom interpolators can be used between Java objects of different kind.
027 *     For example:[code]
028 *     // Creates a linear interpolator between the java.util.Date and Measures<Mass>
029 *     Interpolator<Date, Amount<Mass>> linear 
030 *          = new Interpolator<Date, Amount<Mass>>() { ... }
031 *     DiscreteFunction<Date, Amount<Mass>> weight 
032 *         = new DiscreteFunction<Date, Amount<Mass>>(samples, linear, t);
033 *     [/code]</p>
034 *     
035 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle </a>
036 * @version 3.0, February 13, 2006
037 */
038public interface Interpolator<P, V> extends Immutable, Serializable {
039
040    /**
041     * Estimates the value at the specified point.
042     * 
043     * @param point the point for which the value is estimated.
044     * @param pointValues the point-value entries.
045     * @return the estimated value at the specified point.
046     */
047    V interpolate(P point, SortedMap<P, V> pointValues);
048    
049    
050    /**
051     * <p> This class represents a linear interpolator for {@link Field field}
052     *     instances (point and values from the same field).</p>
053     * 
054     * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle </a>
055     * @version 3.0, February 13, 2006
056     */
057    public static class Linear<F extends Field<F>> implements Interpolator<F, F> {
058
059        public F interpolate(F point, SortedMap<F, F> pointValues) {
060            // Searches exact.
061            F y = pointValues.get(point);
062            if (y != null)
063                return y;
064
065            // Searches surrounding points/values.
066            SortedMap<F, F> headMap = pointValues.headMap(point);
067            F x1 = headMap.lastKey();
068            F y1 = headMap.get(x1);
069            SortedMap<F, F> tailMap = pointValues.tailMap(point);
070            F x2 = tailMap.firstKey();
071            F y2 = tailMap.get(x2);
072
073            // Interpolates.
074            final F x = point;
075            F deltaInv = (x2.plus(x1.opposite())).inverse();
076            F k1 = (x2.plus(x.opposite())).times(deltaInv);
077            F k2 = (x.plus(x1.opposite())).times(deltaInv);
078            return ((y1.times(k1))).plus(y2.times(k2));
079        }        
080
081        private static final long serialVersionUID = 1L;
082    }
083
084}