View Javadoc
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.util.Random;
25  
26  import org.hipparchus.analysis.UnivariateFunction;
27  import org.hipparchus.exception.MathIllegalArgumentException;
28  import org.hipparchus.util.FastMath;
29  import org.junit.Assert;
30  import org.junit.Test;
31  
32  
33  /**
34   * Test for {@link UnivariatePeriodicInterpolator}.
35   */
36  public class UnivariatePeriodicInterpolatorTest {
37      private final Random rng = new Random(1224465L);
38  
39      @Test
40      public void testSine() {
41          final int n = 30;
42          final double[] xval = new double[n];
43          final double[] yval = new double[n];
44          final double period = 12.3;
45          final double offset = 45.67;
46  
47          double delta = 0;
48          for (int i = 0; i < n; i++) {
49              delta += rng.nextDouble() * period / n;
50              xval[i] = offset + delta;
51              yval[i] = FastMath.sin(xval[i]);
52          }
53  
54          final UnivariateInterpolator inter = new LinearInterpolator();
55          final UnivariateFunction f = inter.interpolate(xval, yval);
56  
57          final UnivariateInterpolator interP
58              = new UnivariatePeriodicInterpolator(new LinearInterpolator(),
59                                                       period, 1);
60          final UnivariateFunction fP = interP.interpolate(xval, yval);
61  
62          // Comparing with original interpolation algorithm.
63          final double xMin = xval[0];
64          final double xMax = xval[n - 1];
65          for (int i = 0; i < n; i++) {
66              final double x = xMin + (xMax - xMin) * rng.nextDouble();
67              final double y = f.value(x);
68              final double yP = fP.value(x);
69  
70              Assert.assertEquals("x=" + x, y, yP, Math.ulp(1d));
71          }
72  
73          // Test interpolation outside the primary interval.
74          for (int i = 0; i < n; i++) {
75              final double xIn = offset + rng.nextDouble() * period;
76              final double xOut = xIn + rng.nextInt(123456789) * period;
77              final double yIn = fP.value(xIn);
78              final double yOut = fP.value(xOut);
79  
80              Assert.assertEquals(yIn, yOut, 1e-7);
81          }
82      }
83  
84      @Test
85      public void testLessThanOnePeriodCoverage() {
86          final int n = 30;
87          final double[] xval = new double[n];
88          final double[] yval = new double[n];
89          final double period = 12.3;
90          final double offset = 45.67;
91  
92          double delta = period / 2;
93          for (int i = 0; i < n; i++) {
94              delta += period / (2 * n) * rng.nextDouble();
95              xval[i] = offset + delta;
96              yval[i] = FastMath.sin(xval[i]);
97          }
98  
99          final UnivariateInterpolator interP
100             = new UnivariatePeriodicInterpolator(new LinearInterpolator(),
101                                                      period, 1);
102         final UnivariateFunction fP = interP.interpolate(xval, yval);
103 
104         // Test interpolation outside the sample data interval.
105         for (int i = 0; i < n; i++) {
106             final double xIn = offset + rng.nextDouble() * period;
107             final double xOut = xIn + rng.nextInt(123456789) * period;
108             final double yIn = fP.value(xIn);
109             final double yOut = fP.value(xOut);
110 
111             Assert.assertEquals(yIn, yOut, 1e-7);
112         }
113     }
114 
115     @Test
116     public void testMoreThanOnePeriodCoverage() {
117         final int n = 30;
118         final double[] xval = new double[n];
119         final double[] yval = new double[n];
120         final double period = 12.3;
121         final double offset = 45.67;
122 
123         double delta = period / 2;
124         for (int i = 0; i < n; i++) {
125             delta += 10 * period / n * rng.nextDouble();
126             xval[i] = offset + delta;
127             yval[i] = FastMath.sin(xval[i]);
128         }
129 
130         final UnivariateInterpolator interP
131             = new UnivariatePeriodicInterpolator(new LinearInterpolator(),
132                                                      period, 1);
133         final UnivariateFunction fP = interP.interpolate(xval, yval);
134 
135         // Test interpolation outside the sample data interval.
136         for (int i = 0; i < n; i++) {
137             final double xIn = offset + rng.nextDouble() * period;
138             final double xOut = xIn + rng.nextInt(123456789) * period;
139             final double yIn = fP.value(xIn);
140             final double yOut = fP.value(xOut);
141 
142             Assert.assertEquals(yIn, yOut, 1e-6);
143         }
144     }
145 
146     @Test(expected=MathIllegalArgumentException.class)
147     public void testTooFewSamples() {
148         final double[] xval = { 2, 3, 7 };
149         final double[] yval = { 1, 6, 5 };
150         final double period = 10;
151 
152         final UnivariateInterpolator interpolator
153             = new UnivariatePeriodicInterpolator(new LinearInterpolator(), period);
154         interpolator.interpolate(xval, yval);
155     }
156 
157     @Test(expected=MathIllegalArgumentException.class)
158     public void testUnsortedSamples() {
159         final double[] xval = { 2, 3, 7, 4, 6 };
160         final double[] yval = { 1, 6, 5, -1, -2 };
161         final double period = 10;
162 
163         final UnivariateInterpolator interpolator
164             = new UnivariatePeriodicInterpolator(new LinearInterpolator(), period);
165         interpolator.interpolate(xval, yval);
166     }
167 }