1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.hipparchus.optim.nonlinear.vector.leastsquares;
15
16 import java.awt.geom.Point2D;
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import org.hipparchus.UnitTestUtils;
21 import org.hipparchus.linear.ArrayRealVector;
22 import org.hipparchus.linear.DiagonalMatrix;
23 import org.hipparchus.linear.RealVector;
24 import org.hipparchus.util.FastMath;
25 import org.junit.Assert;
26 import org.junit.Ignore;
27 import org.junit.Test;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class EvaluationTestValidation {
47
48 private static final int MONTE_CARLO_RUNS = Integer.parseInt(System.getProperty("mcRuns",
49 "100"));
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 @Ignore
67 @Test
68 public void testParametersErrorMonteCarloObservations() {
69
70 final double yError = 15;
71
72
73 final double slope = 123.456;
74 final double offset = -98.765;
75
76
77 final RandomStraightLinePointGenerator lineGenerator
78 = new RandomStraightLinePointGenerator(slope, offset,
79 yError,
80 -1e3, 1e4,
81 138577L);
82
83
84 final int numObs = 100;
85
86 final int numParams = 2;
87
88
89 final UnitTestUtils.SimpleStatistics[] paramsFoundByDirectSolution = new UnitTestUtils.SimpleStatistics[numParams];
90
91
92 final UnitTestUtils.SimpleStatistics[] sigmaEstimate = new UnitTestUtils.SimpleStatistics[numParams];
93
94
95 for (int i = 0; i < numParams; i++) {
96 paramsFoundByDirectSolution[i] = new UnitTestUtils.SimpleStatistics();
97 sigmaEstimate[i] = new UnitTestUtils.SimpleStatistics();
98 }
99
100 final RealVector init = new ArrayRealVector(new double[]{ slope, offset }, false);
101
102
103 final int mcRepeat = MONTE_CARLO_RUNS;
104 int mcCount = 0;
105 while (mcCount < mcRepeat) {
106
107 final Point2D.Double[] obs = lineGenerator.generate(numObs);
108
109 final StraightLineProblem problem = new StraightLineProblem(yError);
110 for (int i = 0; i < numObs; i++) {
111 final Point2D.Double p = obs[i];
112 problem.addPoint(p.x, p.y);
113 }
114
115
116 final double[] regress = problem.solve();
117
118
119
120 final LeastSquaresProblem lsp = builder(problem).build();
121
122 final RealVector sigma = lsp.evaluate(init).getSigma(1e-14);
123
124
125 for (int i = 0; i < numParams; i++) {
126 paramsFoundByDirectSolution[i].addValue(regress[i]);
127 sigmaEstimate[i].addValue(sigma.getEntry(i));
128 }
129
130
131 ++mcCount;
132 }
133
134
135 final String line = "--------------------------------------------------------------";
136 System.out.println(" True value Mean Std deviation");
137 for (int i = 0; i < numParams; i++) {
138 System.out.println(line);
139 System.out.println("Parameter #" + i);
140
141 System.out.printf(" %+.6e %+.6e %+.6e\n",
142 init.getEntry(i),
143 paramsFoundByDirectSolution[i].getMean(),
144 paramsFoundByDirectSolution[i].getStandardDeviation());
145
146 System.out.printf("sigma: %+.6e (%+.6e)\n",
147 sigmaEstimate[i].getMean(),
148 sigmaEstimate[i].getStandardDeviation());
149 }
150 System.out.println(line);
151
152
153 for (int i = 0; i < numParams; i++) {
154 Assert.assertEquals(paramsFoundByDirectSolution[i].getStandardDeviation(),
155 sigmaEstimate[i].getMean(),
156 8e-2);
157 }
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 @Ignore
185 @Test
186 public void testParametersErrorMonteCarloParameters() {
187
188 final double yError = 15;
189
190
191 final double slope = 123.456;
192 final double offset = -98.765;
193
194
195 final RandomStraightLinePointGenerator lineGenerator
196 = new RandomStraightLinePointGenerator(slope, offset,
197 yError,
198 -1e3, 1e4,
199 13839013L);
200
201
202 final int numObs = 10;
203
204
205
206 final Point2D.Double[] obs = lineGenerator.generate(numObs);
207
208 final StraightLineProblem problem = new StraightLineProblem(yError);
209 for (int i = 0; i < numObs; i++) {
210 final Point2D.Double p = obs[i];
211 problem.addPoint(p.x, p.y);
212 }
213
214
215 final RealVector regress = new ArrayRealVector(problem.solve(), false);
216
217
218 final LeastSquaresProblem lsp = builder(problem).build();
219
220
221
222 final double bestChi2N = getChi2N(lsp, regress);
223 final RealVector sigma = lsp.evaluate(regress).getSigma(1e-14);
224
225
226 final int mcRepeat = MONTE_CARLO_RUNS;
227 final int gridSize = (int) FastMath.sqrt(mcRepeat);
228
229
230
231
232
233 final List<double[]> paramsAndChi2 = new ArrayList<double[]>(gridSize * gridSize);
234
235 final double slopeRange = 10 * sigma.getEntry(0);
236 final double offsetRange = 10 * sigma.getEntry(1);
237 final double minSlope = slope - 0.5 * slopeRange;
238 final double minOffset = offset - 0.5 * offsetRange;
239 final double deltaSlope = slopeRange/ gridSize;
240 final double deltaOffset = offsetRange / gridSize;
241 for (int i = 0; i < gridSize; i++) {
242 final double s = minSlope + i * deltaSlope;
243 for (int j = 0; j < gridSize; j++) {
244 final double o = minOffset + j * deltaOffset;
245 final double chi2N = getChi2N(lsp,
246 new ArrayRealVector(new double[] {s, o}, false));
247
248 paramsAndChi2.add(new double[] {s, o, chi2N});
249 }
250 }
251
252
253
254
255
256
257 final double chi2NPlusOne = bestChi2N + 1;
258 int numLarger = 0;
259
260 final String lineFmt = "%+.10e %+.10e %.8e\n";
261
262
263 System.out.printf(lineFmt, regress.getEntry(0), regress.getEntry(1), bestChi2N);
264 System.out.println();
265
266
267 for (double[] d : paramsAndChi2) {
268 if (d[2] <= chi2NPlusOne) {
269 System.out.printf(lineFmt, d[0], d[1], d[2]);
270 }
271 }
272 System.out.println();
273
274
275 for (double[] d : paramsAndChi2) {
276 if (d[2] > chi2NPlusOne) {
277 ++numLarger;
278 System.out.printf(lineFmt, d[0], d[1], d[2]);
279 }
280 }
281 System.out.println();
282
283 System.out.println("# sigma=" + sigma.toString());
284 System.out.println("# " + numLarger + " sets filtered out");
285 }
286
287 LeastSquaresBuilder builder(StraightLineProblem problem){
288 return new LeastSquaresBuilder()
289 .model(problem.getModelFunction(), problem.getModelFunctionJacobian())
290 .target(problem.target())
291 .weight(new DiagonalMatrix(problem.weight()))
292
293 .start(new double[2]);
294 }
295
296
297
298 private double getChi2N(LeastSquaresProblem lsp,
299 RealVector params) {
300 final double cost = lsp.evaluate(params).getCost();
301 return cost * cost / (lsp.getObservationSize() - params.getDimension());
302 }
303 }
304