1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  package org.apache.commons.math4.legacy.analysis.polynomials;
18  
19  
20  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
22  import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
23  import org.apache.commons.math4.legacy.exception.OutOfRangeException;
24  import org.junit.Assert;
25  import org.junit.Test;
26  
27  
28  
29  
30  
31  public class PolynomialSplineFunctionTest {
32  
33      
34      protected double tolerance = 1.0e-12;
35  
36      
37  
38  
39  
40  
41  
42  
43  
44  
45  
46      protected PolynomialFunction[] polynomials = {
47          new PolynomialFunction(new double[] {0d, 1d, 1d}),
48          new PolynomialFunction(new double[] {2d, 1d, 1d}),
49          new PolynomialFunction(new double[] {4d, 1d, 1d})
50      };
51  
52      
53      protected double[] knots = {-1, 0, 1, 2};
54  
55      
56      protected PolynomialFunction dp =
57          new PolynomialFunction(new double[] {1d, 2d});
58  
59  
60      @Test
61      public void testConstructor() {
62          PolynomialSplineFunction spline =
63              new PolynomialSplineFunction(knots, polynomials);
64          Assert.assertArrayEquals(knots, spline.getKnots(), 0.0);
65          Assert.assertEquals(1d, spline.getPolynomials()[0].getCoefficients()[2], 0);
66          Assert.assertEquals(3, spline.getN());
67  
68          try { 
69              new PolynomialSplineFunction(new double[] {0}, polynomials);
70              Assert.fail("Expecting MathIllegalArgumentException");
71          } catch (MathIllegalArgumentException ex) {
72              
73          }
74  
75          try { 
76              new PolynomialSplineFunction(new double[] {0,1,2,3,4}, polynomials);
77              Assert.fail("Expecting MathIllegalArgumentException");
78          } catch (MathIllegalArgumentException ex) {
79              
80          }
81  
82          try { 
83              new PolynomialSplineFunction(new double[] {0,1, 3, 2}, polynomials);
84              Assert.fail("Expecting MathIllegalArgumentException");
85          } catch (MathIllegalArgumentException ex) {
86              
87          }
88      }
89  
90      @Test
91      public void testValues() {
92          PolynomialSplineFunction spline =
93              new PolynomialSplineFunction(knots, polynomials);
94          UnivariateFunction dSpline = spline.polynomialSplineDerivative();
95  
96          
97  
98  
99  
100 
101         double x = -1;
102         int index = 0;
103         for (int i = 0; i < 10; i++) {
104            x+=0.25;
105            index = findKnot(knots, x);
106            Assert.assertEquals("spline function evaluation failed for x=" + x,
107                    polynomials[index].value(x - knots[index]), spline.value(x), tolerance);
108            Assert.assertEquals("spline derivative evaluation failed for x=" + x,
109                    dp.value(x - knots[index]), dSpline.value(x), tolerance);
110         }
111 
112         
113         for (int i = 0; i < 3; i++) {
114             Assert.assertEquals("spline function evaluation failed for knot=" + knots[i],
115                     polynomials[i].value(0), spline.value(knots[i]), tolerance);
116             Assert.assertEquals("spline function evaluation failed for knot=" + knots[i],
117                     dp.value(0), dSpline.value(knots[i]), tolerance);
118         }
119 
120         try { 
121             x = spline.value(-1.5);
122             Assert.fail("Expecting OutOfRangeException");
123         } catch (OutOfRangeException ex) {
124             
125         }
126 
127         try { 
128             x = spline.value(2.5);
129             Assert.fail("Expecting OutOfRangeException");
130         } catch (OutOfRangeException ex) {
131             
132         }
133     }
134 
135     @Test
136     public void testIsValidPoint() {
137         final PolynomialSplineFunction spline =
138             new PolynomialSplineFunction(knots, polynomials);
139         final double xMin = knots[0];
140         final double xMax = knots[knots.length - 1];
141 
142         double x;
143 
144         x = xMin;
145         Assert.assertTrue(spline.isValidPoint(x));
146         
147         spline.value(x);
148 
149         x = xMax;
150         Assert.assertTrue(spline.isValidPoint(x));
151         
152         spline.value(x);
153 
154         final double xRange = xMax - xMin;
155         x = xMin + xRange / 3.4;
156         Assert.assertTrue(spline.isValidPoint(x));
157         
158         spline.value(x);
159 
160         final double small = 1e-8;
161         x = xMin - small;
162         Assert.assertFalse(spline.isValidPoint(x));
163         
164         try {
165             spline.value(x);
166             Assert.fail("OutOfRangeException expected");
167         } catch (OutOfRangeException expected) {}
168     }
169 
170     
171 
172 
173 
174      protected int findKnot(double[] knots, double x) {
175          if (x < knots[0] || x >= knots[knots.length -1]) {
176              throw new OutOfRangeException(x, knots[0], knots[knots.length -1]);
177          }
178          for (int i = 0; i < knots.length; i++) {
179              if (knots[i] > x) {
180                  return i - 1;
181              }
182          }
183          throw new MathIllegalStateException();
184      }
185 }
186