1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.analysis;
19
20 import java.util.Arrays;
21 import junit.framework.TestCase;
22
23 import org.apache.commons.math.FunctionEvaluationException;
24
25 /**
26 * Tests the PolynomialSplineFunction implementation.
27 *
28 * @version $Revision: 155427 $
29 */
30 public class PolynomialSplineFunctionTest extends TestCase {
31
32 /** Error tolerance for tests */
33 protected double tolerance = 1.0e-12;
34
35 /**
36 * Quadratic polynomials used in tests:
37 *
38 * x^2 + x [-1, 0)
39 * x^2 + x + 2 [0, 1)
40 * x^2 + x + 4 [1, 2)
41 *
42 * Defined so that evaluation using PolynomialSplineFunction evaluation
43 * algorithm agrees at knot point boundaries.
44 */
45 protected PolynomialFunction[] polynomials = {
46 new PolynomialFunction(new double[] {0d, 1d, 1d}),
47 new PolynomialFunction(new double[] {2d, 1d, 1d}),
48 new PolynomialFunction(new double[] {4d, 1d, 1d})
49 };
50
51 /** Knot points */
52 protected double[] knots = {-1, 0, 1, 2};
53
54 /** Derivative of test polynomials -- 2x + 1 */
55 protected PolynomialFunction dp =
56 new PolynomialFunction(new double[] {1d, 2d});
57
58
59 public void testConstructor() {
60 PolynomialSplineFunction spline =
61 new PolynomialSplineFunction(knots, polynomials);
62 assertTrue(Arrays.equals(knots, spline.getKnots()));
63 assertEquals(1d, spline.getPolynomials()[0].getCoefficients()[2], 0);
64 assertEquals(3, spline.getN());
65
66 try {
67 spline =
68 new PolynomialSplineFunction(new double[] {0}, polynomials);
69 fail("Expecting IllegalArgumentException");
70 } catch (IllegalArgumentException ex) {
71
72 }
73
74 try {
75 spline =
76 new PolynomialSplineFunction(new double[] {0,1,2,3,4}, polynomials);
77 fail("Expecting IllegalArgumentException");
78 } catch (IllegalArgumentException ex) {
79
80 }
81
82 try {
83 spline =
84 new PolynomialSplineFunction(new double[] {0,1, 3, 2}, polynomials);
85 fail("Expecting IllegalArgumentException");
86 } catch (IllegalArgumentException ex) {
87
88 }
89 }
90
91 public void testValues() throws Exception {
92 PolynomialSplineFunction spline =
93 new PolynomialSplineFunction(knots, polynomials);
94 UnivariateRealFunction dSpline = spline.derivative();
95
96 /**
97 * interior points -- spline value at x should equal p(x - knot)
98 * where knot is the largest knot point less than or equal to x and p
99 * is the polynomial defined over the knot segment to which x belongs.
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 assertEquals("spline function evaluation failed for x=" + x,
107 polynomials[index].value(x - knots[index]), spline.value(x), tolerance);
108 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 assertEquals("spline function evaluation failed for knot=" + knots[i],
115 polynomials[i].value(0), spline.value(knots[i]), tolerance);
116 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 fail("Expecting IllegalArgumentException");
123 } catch (FunctionEvaluationException ex) {
124
125 }
126
127 try {
128 x = spline.value(2.5);
129 fail("Expecting IllegalArgumentException");
130 } catch (FunctionEvaluationException ex) {
131
132 }
133 }
134
135 /**
136 * Do linear search to find largest knot point less than or equal to x.
137 * Implementation does binary search.
138 */
139 protected int findKnot(double[] knots, double x) {
140 if (x < knots[0] || x >= knots[knots.length -1]) {
141 throw new IllegalArgumentException("x is out of range");
142 }
143 for (int i = 0; i < knots.length; i++) {
144 if (knots[i] > x) {
145 return i -1;
146 }
147 }
148 throw new IllegalArgumentException("x is out of range");
149 }
150 }
151