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 /*
19 * This is not the original file distributed by the Apache Software Foundation
20 * It has been modified by the Hipparchus project
21 */
22 package org.hipparchus.analysis.interpolation;
23
24 import java.lang.reflect.Array;
25
26 import org.hipparchus.CalculusFieldElement;
27 import org.hipparchus.analysis.polynomials.FieldPolynomialFunction;
28 import org.hipparchus.analysis.polynomials.FieldPolynomialSplineFunction;
29 import org.hipparchus.analysis.polynomials.PolynomialFunction;
30 import org.hipparchus.analysis.polynomials.PolynomialSplineFunction;
31 import org.hipparchus.exception.LocalizedCoreFormats;
32 import org.hipparchus.exception.MathIllegalArgumentException;
33 import org.hipparchus.util.MathArrays;
34 import org.hipparchus.util.MathUtils;
35
36 /**
37 * Implements a linear function for interpolation of real univariate functions.
38 *
39 */
40 public class LinearInterpolator implements UnivariateInterpolator, FieldUnivariateInterpolator {
41
42 /** Empty constructor.
43 * <p>
44 * This constructor is not strictly necessary, but it prevents spurious
45 * javadoc warnings with JDK 18 and later.
46 * </p>
47 * @since 3.0
48 */
49 public LinearInterpolator() { // NOPMD - unnecessary constructor added intentionally to make javadoc happy
50 // nothing to do
51 }
52
53 /**
54 * Computes a linear interpolating function for the data set.
55 *
56 * @param x the arguments for the interpolation points
57 * @param y the values for the interpolation points
58 * @return a function which interpolates the data set
59 * @throws MathIllegalArgumentException if {@code x} and {@code y}
60 * have different sizes.
61 * @throws MathIllegalArgumentException if {@code x} is not sorted in
62 * strict increasing order.
63 * @throws MathIllegalArgumentException if the size of {@code x} is smaller
64 * than 2.
65 */
66 @Override
67 public PolynomialSplineFunction interpolate(double[] x, double[] y)
68 throws MathIllegalArgumentException {
69 MathUtils.checkNotNull(x);
70 MathUtils.checkNotNull(y);
71 MathArrays.checkEqualLength(x, y);
72
73 if (x.length < 2) {
74 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_POINTS,
75 x.length, 2, true);
76 }
77
78 // Number of intervals. The number of data points is n + 1.
79 int n = x.length - 1;
80
81 MathArrays.checkOrder(x);
82
83 // Slope of the lines between the datapoints.
84 final double[] m = new double[n];
85 for (int i = 0; i < n; i++) {
86 m[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]);
87 }
88
89 final PolynomialFunction[] polynomials = new PolynomialFunction[n];
90 final double[] coefficients = new double[2];
91 for (int i = 0; i < n; i++) {
92 coefficients[0] = y[i];
93 coefficients[1] = m[i];
94 polynomials[i] = new PolynomialFunction(coefficients);
95 }
96
97 return new PolynomialSplineFunction(x, polynomials);
98 }
99
100 /**
101 * Computes a linear interpolating function for the data set.
102 *
103 * @param x the arguments for the interpolation points
104 * @param y the values for the interpolation points
105 * @param <T> the type of the field elements
106 * @return a function which interpolates the data set
107 * @throws MathIllegalArgumentException if {@code x} and {@code y}
108 * have different sizes.
109 * @throws MathIllegalArgumentException if {@code x} is not sorted in
110 * strict increasing order.
111 * @throws MathIllegalArgumentException if the size of {@code x} is smaller
112 * than 2.
113 * @since 1.5
114 */
115 @Override
116 public <T extends CalculusFieldElement<T>> FieldPolynomialSplineFunction<T> interpolate(final T[] x, final T[] y)
117 throws MathIllegalArgumentException {
118 MathUtils.checkNotNull(x);
119 MathUtils.checkNotNull(y);
120 MathArrays.checkEqualLength(x, y);
121
122 if (x.length < 2) {
123 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_POINTS,
124 x.length, 2, true);
125 }
126
127 // Number of intervals. The number of data points is n + 1.
128 int n = x.length - 1;
129
130 MathArrays.checkOrder(x);
131
132 // Slope of the lines between the datapoints.
133 final T[] m = MathArrays.buildArray(x[0].getField(), n);
134 for (int i = 0; i < n; i++) {
135 m[i] = y[i + 1].subtract(y[i]).divide(x[i + 1].subtract(x[i]));
136 }
137
138 @SuppressWarnings("unchecked")
139 final FieldPolynomialFunction<T>[] polynomials =
140 (FieldPolynomialFunction<T>[]) Array.newInstance(FieldPolynomialFunction.class, n);
141 final T[] coefficients = MathArrays.buildArray(x[0].getField(), 2);
142 for (int i = 0; i < n; i++) {
143 coefficients[0] = y[i];
144 coefficients[1] = m[i];
145 polynomials[i] = new FieldPolynomialFunction<>(coefficients);
146 }
147
148 return new FieldPolynomialSplineFunction<>(x, polynomials);
149 }
150
151 }