1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  package org.apache.commons.math4.legacy.analysis.interpolation;
18  
19  import org.junit.Assert;
20  import org.junit.Test;
21  
22  import org.apache.commons.rng.UniformRandomProvider;
23  import org.apache.commons.rng.simple.RandomSource;
24  
25  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
26  import org.apache.commons.math4.legacy.exception.NonMonotonicSequenceException;
27  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
28  import org.apache.commons.math4.core.jdkmath.JdkMath;
29  
30  
31  
32  
33  
34  public class UnivariatePeriodicInterpolatorTest {
35      private final UniformRandomProvider rng = RandomSource.KISS.create();
36  
37      @Test
38      public void testSine() {
39          final int n = 30;
40          final double[] xval = new double[n];
41          final double[] yval = new double[n];
42          final double period = 12.3;
43          final double offset = 45.67;
44  
45          double delta = 0;
46          for (int i = 0; i < n; i++) {
47              delta += rng.nextDouble() * period / n;
48              xval[i] = offset + delta;
49              yval[i] = JdkMath.sin(xval[i]);
50          }
51  
52          final UnivariateInterpolator inter = new LinearInterpolator();
53          final UnivariateFunction f = inter.interpolate(xval, yval);
54  
55          final UnivariateInterpolator interP
56              = new UnivariatePeriodicInterpolator(new LinearInterpolator(),
57                                                       period, 1);
58          final UnivariateFunction fP = interP.interpolate(xval, yval);
59  
60          
61          final double xMin = xval[0];
62          final double xMax = xval[n - 1];
63          for (int i = 0; i < n; i++) {
64              final double x = xMin + (xMax - xMin) * rng.nextDouble();
65              final double y = f.value(x);
66              final double yP = fP.value(x);
67  
68              Assert.assertEquals("(Delta: ulp(1)) x=" + x, y, yP, Math.ulp(1d));
69          }
70  
71          
72          for (int i = 0; i < n; i++) {
73              final double xIn = offset + rng.nextDouble() * period;
74              final double xOut = xIn + rng.nextInt(123456789) * period;
75              final double yIn = fP.value(xIn);
76              final double yOut = fP.value(xOut);
77  
78              Assert.assertEquals("Delta: 1e-7", yIn, yOut, 1e-7);
79          }
80      }
81  
82      @Test
83      public void testLessThanOnePeriodCoverage() {
84          final int n = 30;
85          final double[] xval = new double[n];
86          final double[] yval = new double[n];
87          final double period = 12.3;
88          final double offset = 45.67;
89  
90          double delta = period / 2;
91          for (int i = 0; i < n; i++) {
92              delta += period / (2 * n) * rng.nextDouble();
93              xval[i] = offset + delta;
94              yval[i] = JdkMath.sin(xval[i]);
95          }
96  
97          final UnivariateInterpolator interP
98              = new UnivariatePeriodicInterpolator(new LinearInterpolator(),
99                                                       period, 1);
100         final UnivariateFunction fP = interP.interpolate(xval, yval);
101 
102         
103         for (int i = 0; i < n; i++) {
104             final double xIn = offset + rng.nextDouble() * period;
105             final double xOut = xIn + rng.nextInt(123456789) * period;
106             final double yIn = fP.value(xIn);
107             final double yOut = fP.value(xOut);
108 
109             Assert.assertEquals(yIn, yOut, 1e-7);
110         }
111     }
112 
113     @Test
114     public void testMoreThanOnePeriodCoverage() {
115         final int n = 30;
116         final double[] xval = new double[n];
117         final double[] yval = new double[n];
118         final double period = 12.3;
119         final double offset = 45.67;
120 
121         double delta = period / 2;
122         for (int i = 0; i < n; i++) {
123             delta += 10 * period / n * rng.nextDouble();
124             xval[i] = offset + delta;
125             yval[i] = JdkMath.sin(xval[i]);
126         }
127 
128         final UnivariateInterpolator interP
129             = new UnivariatePeriodicInterpolator(new LinearInterpolator(),
130                                                      period, 1);
131         final UnivariateFunction fP = interP.interpolate(xval, yval);
132 
133         
134         for (int i = 0; i < n; i++) {
135             final double xIn = offset + rng.nextDouble() * period;
136             final double xOut = xIn + rng.nextInt(123456789) * period;
137             final double yIn = fP.value(xIn);
138             final double yOut = fP.value(xOut);
139 
140             Assert.assertEquals(yIn, yOut, 1e-6);
141         }
142     }
143 
144     @Test(expected=NumberIsTooSmallException.class)
145     public void testTooFewSamples() {
146         final double[] xval = { 2, 3, 7 };
147         final double[] yval = { 1, 6, 5 };
148         final double period = 10;
149 
150         final UnivariateInterpolator interpolator
151             = new UnivariatePeriodicInterpolator(new LinearInterpolator(), period);
152         interpolator.interpolate(xval, yval);
153     }
154 
155     @Test(expected=NonMonotonicSequenceException.class)
156     public void testUnsortedSamples() {
157         final double[] xval = { 2, 3, 7, 4, 6 };
158         final double[] yval = { 1, 6, 5, -1, -2 };
159         final double period = 10;
160 
161         final UnivariateInterpolator interpolator
162             = new UnivariatePeriodicInterpolator(new LinearInterpolator(), period);
163         interpolator.interpolate(xval, yval);
164     }
165 }