1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.optimization.fitting;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22
23 import java.util.Random;
24
25 import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
26 import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
27 import org.apache.commons.math.optimization.OptimizationException;
28 import org.apache.commons.math.optimization.general.GaussNewtonOptimizer;
29 import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer;
30 import org.junit.Test;
31
32 public class PolynomialFitterTest {
33
34 @Test
35 public void testNoError() throws OptimizationException {
36 Random randomizer = new Random(64925784252l);
37 for (int degree = 1; degree < 10; ++degree) {
38 PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
39
40 PolynomialFitter fitter =
41 new PolynomialFitter(degree, new LevenbergMarquardtOptimizer());
42 for (int i = 0; i <= degree; ++i) {
43 fitter.addObservedPoint(1.0, i, p.value(i));
44 }
45
46 PolynomialFunction fitted = fitter.fit();
47
48 for (double x = -1.0; x < 1.0; x += 0.01) {
49 double error = Math.abs(p.value(x) - fitted.value(x)) /
50 (1.0 + Math.abs(p.value(x)));
51 assertEquals(0.0, error, 1.0e-6);
52 }
53
54 }
55
56 }
57
58 @Test
59 public void testSmallError() throws OptimizationException {
60 Random randomizer = new Random(53882150042l);
61 double maxError = 0;
62 for (int degree = 0; degree < 10; ++degree) {
63 PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
64
65 PolynomialFitter fitter =
66 new PolynomialFitter(degree, new LevenbergMarquardtOptimizer());
67 for (double x = -1.0; x < 1.0; x += 0.01) {
68 fitter.addObservedPoint(1.0, x,
69 p.value(x) + 0.1 * randomizer.nextGaussian());
70 }
71
72 PolynomialFunction fitted = fitter.fit();
73
74 for (double x = -1.0; x < 1.0; x += 0.01) {
75 double error = Math.abs(p.value(x) - fitted.value(x)) /
76 (1.0 + Math.abs(p.value(x)));
77 maxError = Math.max(maxError, error);
78 assertTrue(Math.abs(error) < 0.1);
79 }
80 }
81 assertTrue(maxError > 0.01);
82
83 }
84
85 @Test
86 public void testRedundantSolvable() {
87
88 checkUnsolvableProblem(new LevenbergMarquardtOptimizer(), true);
89 }
90
91 @Test
92 public void testRedundantUnsolvable() {
93
94 DifferentiableMultivariateVectorialOptimizer optimizer =
95 new GaussNewtonOptimizer(true);
96 checkUnsolvableProblem(optimizer, false);
97 }
98
99 private void checkUnsolvableProblem(DifferentiableMultivariateVectorialOptimizer optimizer,
100 boolean solvable) {
101 Random randomizer = new Random(1248788532l);
102 for (int degree = 0; degree < 10; ++degree) {
103 PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
104
105 PolynomialFitter fitter = new PolynomialFitter(degree, optimizer);
106
107
108
109
110
111 for (double x = -1.0; x < 1.0; x += 0.01) {
112 fitter.addObservedPoint(1.0, 0.0, p.value(0.0));
113 }
114
115 try {
116 fitter.fit();
117 assertTrue(solvable || (degree == 0));
118 } catch(OptimizationException e) {
119 assertTrue((! solvable) && (degree > 0));
120 }
121
122 }
123
124 }
125
126 private PolynomialFunction buildRandomPolynomial(int degree, Random randomizer) {
127 final double[] coefficients = new double[degree + 1];
128 for (int i = 0; i <= degree; ++i) {
129 coefficients[i] = randomizer.nextGaussian();
130 }
131 return new PolynomialFunction(coefficients);
132 }
133
134 }