    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.math.analysis.interpolation;
    018
    019    import org.apache.commons.math.exception.DimensionMismatchException;
    020    import org.apache.commons.math.exception.util.LocalizedFormats;
    021    import org.apache.commons.math.exception.NumberIsTooSmallException;
    022    import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
    023    import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
    024    import org.apache.commons.math.util.MathUtils;
    025
    026    /**
    027     * Implements a linear function for interpolation of real univariate functions.
    028     * @version $Revision$ $Date$
    029     * @since 2.2
    030     */
    031    public class LinearInterpolator implements UnivariateRealInterpolator {
    032        /**
    033         * Computes a linear interpolating function for the data set.
    034         * @param x the arguments for the interpolation points
    035         * @param y the values for the interpolation points
    036         * @return a function which interpolates the data set
    037         * @throws DimensionMismatchException if {@code x} and {@code y}
    038         * have different sizes.
    039         * @throws org.apache.commons.math.exception.NonMonotonousSequenceException
    040         * if {@code x} is not sorted in strict increasing order.
    041         * @throws NumberIsTooSmallException if the size of {@code x} is smaller
    042         * than 2.
    043         */
    044        public PolynomialSplineFunction interpolate(double x[], double y[]) {
    045            if (x.length != y.length) {
    046                throw new DimensionMismatchException(x.length, y.length);
    047            }
    048
    049            if (x.length < 2) {
    050                throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS,
    051                                                    x.length, 2, true);
    052            }
    053
    054            // Number of intervals.  The number of data points is n + 1.
    055            int n = x.length - 1;
    056
    057            MathUtils.checkOrder(x);
    058
    059            // Slope of the lines between the datapoints.
    060            final double m[] = new double[n];
    061            for (int i = 0; i < n; i++) {
    062                m[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]);
    063            }
    064
    065            PolynomialFunction polynomials[] = new PolynomialFunction[n];
    066            final double coefficients[] = new double[2];
    067            for (int i = 0; i < n; i++) {
    068                coefficients[0] = y[i];
    069                coefficients[1] = m[i];
    070                polynomials[i] = new PolynomialFunction(coefficients);
    071            }
    072
    073            return new PolynomialSplineFunction(x, polynomials);
    074        }
    075    }