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