LinearInterpolator.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.analysis.interpolation;

  22. import java.lang.reflect.Array;

  23. import org.hipparchus.CalculusFieldElement;
  24. import org.hipparchus.analysis.polynomials.FieldPolynomialFunction;
  25. import org.hipparchus.analysis.polynomials.FieldPolynomialSplineFunction;
  26. import org.hipparchus.analysis.polynomials.PolynomialFunction;
  27. import org.hipparchus.analysis.polynomials.PolynomialSplineFunction;
  28. import org.hipparchus.exception.LocalizedCoreFormats;
  29. import org.hipparchus.exception.MathIllegalArgumentException;
  30. import org.hipparchus.util.MathArrays;
  31. import org.hipparchus.util.MathUtils;

  32. /**
  33.  * Implements a linear function for interpolation of real univariate functions.
  34.  *
  35.  */
  36. public class LinearInterpolator implements UnivariateInterpolator, FieldUnivariateInterpolator {

  37.     /** Empty constructor.
  38.      * <p>
  39.      * This constructor is not strictly necessary, but it prevents spurious
  40.      * javadoc warnings with JDK 18 and later.
  41.      * </p>
  42.      * @since 3.0
  43.      */
  44.     public LinearInterpolator() { // NOPMD - unnecessary constructor added intentionally to make javadoc happy
  45.         // nothing to do
  46.     }

  47.     /**
  48.      * Computes a linear interpolating function for the data set.
  49.      *
  50.      * @param x the arguments for the interpolation points
  51.      * @param y the values for the interpolation points
  52.      * @return a function which interpolates the data set
  53.      * @throws MathIllegalArgumentException if {@code x} and {@code y}
  54.      * have different sizes.
  55.      * @throws MathIllegalArgumentException if {@code x} is not sorted in
  56.      * strict increasing order.
  57.      * @throws MathIllegalArgumentException if the size of {@code x} is smaller
  58.      * than 2.
  59.      */
  60.     @Override
  61.     public PolynomialSplineFunction interpolate(double[] x, double[] y)
  62.         throws MathIllegalArgumentException {
  63.         MathUtils.checkNotNull(x);
  64.         MathUtils.checkNotNull(y);
  65.         MathArrays.checkEqualLength(x, y);

  66.         if (x.length < 2) {
  67.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_POINTS,
  68.                                                 x.length, 2, true);
  69.         }

  70.         // Number of intervals.  The number of data points is n + 1.
  71.         int n = x.length - 1;

  72.         MathArrays.checkOrder(x);

  73.         // Slope of the lines between the datapoints.
  74.         final double[] m = new double[n];
  75.         for (int i = 0; i < n; i++) {
  76.             m[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]);
  77.         }

  78.         final PolynomialFunction[] polynomials = new PolynomialFunction[n];
  79.         final double[] coefficients = new double[2];
  80.         for (int i = 0; i < n; i++) {
  81.             coefficients[0] = y[i];
  82.             coefficients[1] = m[i];
  83.             polynomials[i] = new PolynomialFunction(coefficients);
  84.         }

  85.         return new PolynomialSplineFunction(x, polynomials);
  86.     }

  87.     /**
  88.      * Computes a linear interpolating function for the data set.
  89.      *
  90.      * @param x the arguments for the interpolation points
  91.      * @param y the values for the interpolation points
  92.      * @param <T> the type of the field elements
  93.      * @return a function which interpolates the data set
  94.      * @throws MathIllegalArgumentException if {@code x} and {@code y}
  95.      * have different sizes.
  96.      * @throws MathIllegalArgumentException if {@code x} is not sorted in
  97.      * strict increasing order.
  98.      * @throws MathIllegalArgumentException if the size of {@code x} is smaller
  99.      * than 2.
  100.      * @since 1.5
  101.      */
  102.     @Override
  103.     public <T extends CalculusFieldElement<T>> FieldPolynomialSplineFunction<T> interpolate(final T[] x, final T[] y)
  104.         throws MathIllegalArgumentException {
  105.         MathUtils.checkNotNull(x);
  106.         MathUtils.checkNotNull(y);
  107.         MathArrays.checkEqualLength(x, y);

  108.         if (x.length < 2) {
  109.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_POINTS,
  110.                                                 x.length, 2, true);
  111.         }

  112.         // Number of intervals.  The number of data points is n + 1.
  113.         int n = x.length - 1;

  114.         MathArrays.checkOrder(x);

  115.         // Slope of the lines between the datapoints.
  116.         final T[] m = MathArrays.buildArray(x[0].getField(), n);
  117.         for (int i = 0; i < n; i++) {
  118.             m[i] = y[i + 1].subtract(y[i]).divide(x[i + 1].subtract(x[i]));
  119.         }

  120.         @SuppressWarnings("unchecked")
  121.         final FieldPolynomialFunction<T>[] polynomials =
  122.                         (FieldPolynomialFunction<T>[]) Array.newInstance(FieldPolynomialFunction.class, n);
  123.         final T[] coefficients = MathArrays.buildArray(x[0].getField(), 2);
  124.         for (int i = 0; i < n; i++) {
  125.             coefficients[0] = y[i];
  126.             coefficients[1] = m[i];
  127.             polynomials[i] = new FieldPolynomialFunction<>(coefficients);
  128.         }

  129.         return new FieldPolynomialSplineFunction<>(x, polynomials);
  130.     }

  131. }