1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.estimation;
19
20 import java.util.Arrays;
21
22 import org.apache.commons.math.estimation.EstimatedParameter;
23 import org.apache.commons.math.estimation.EstimationException;
24 import org.apache.commons.math.estimation.EstimationProblem;
25 import org.apache.commons.math.estimation.LevenbergMarquardtEstimator;
26 import org.apache.commons.math.estimation.WeightedMeasurement;
27
28 import junit.framework.*;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 @Deprecated
93 public class MinpackTest
94 extends TestCase {
95
96 public MinpackTest(String name) {
97 super(name);
98 }
99
100 public void testMinpackLinearFullRank() {
101 minpackTest(new LinearFullRankFunction(10, 5, 1.0,
102 5.0, 2.23606797749979), false);
103 minpackTest(new LinearFullRankFunction(50, 5, 1.0,
104 8.06225774829855, 6.70820393249937), false);
105 }
106
107 public void testMinpackLinearRank1() {
108 minpackTest(new LinearRank1Function(10, 5, 1.0,
109 291.521868819476, 1.4638501094228), false);
110 minpackTest(new LinearRank1Function(50, 5, 1.0,
111 3101.60039334535, 3.48263016573496), false);
112 }
113
114 public void testMinpackLinearRank1ZeroColsAndRows() {
115 minpackTest(new LinearRank1ZeroColsAndRowsFunction(10, 5, 1.0), false);
116 minpackTest(new LinearRank1ZeroColsAndRowsFunction(50, 5, 1.0), false);
117 }
118
119 public void testMinpackRosenbrok() {
120 minpackTest(new RosenbrockFunction(new double[] { -1.2, 1.0 },
121 Math.sqrt(24.2)), false);
122 minpackTest(new RosenbrockFunction(new double[] { -12.0, 10.0 },
123 Math.sqrt(1795769.0)), false);
124 minpackTest(new RosenbrockFunction(new double[] { -120.0, 100.0 },
125 11.0 * Math.sqrt(169000121.0)), false);
126 }
127
128 public void testMinpackHelicalValley() {
129 minpackTest(new HelicalValleyFunction(new double[] { -1.0, 0.0, 0.0 },
130 50.0), false);
131 minpackTest(new HelicalValleyFunction(new double[] { -10.0, 0.0, 0.0 },
132 102.95630140987), false);
133 minpackTest(new HelicalValleyFunction(new double[] { -100.0, 0.0, 0.0},
134 991.261822123701), false);
135 }
136
137 public void testMinpackPowellSingular() {
138 minpackTest(new PowellSingularFunction(new double[] { 3.0, -1.0, 0.0, 1.0 },
139 14.6628782986152), false);
140 minpackTest(new PowellSingularFunction(new double[] { 30.0, -10.0, 0.0, 10.0 },
141 1270.9838708654), false);
142 minpackTest(new PowellSingularFunction(new double[] { 300.0, -100.0, 0.0, 100.0 },
143 126887.903284750), false);
144 }
145
146 public void testMinpackFreudensteinRoth() {
147 minpackTest(new FreudensteinRothFunction(new double[] { 0.5, -2.0 },
148 20.0124960961895, 6.99887517584575,
149 new double[] {
150 11.4124844654993,
151 -0.896827913731509
152 }), false);
153 minpackTest(new FreudensteinRothFunction(new double[] { 5.0, -20.0 },
154 12432.833948863, 6.9988751744895,
155 new double[] {
156 11.4130046614746,
157 -0.896796038685958
158 }), false);
159 minpackTest(new FreudensteinRothFunction(new double[] { 50.0, -200.0 },
160 11426454.595762, 6.99887517242903,
161 new double[] {
162 11.4127817857886,
163 -0.89680510749204
164 }), false);
165 }
166
167 public void testMinpackBard() {
168 minpackTest(new BardFunction(1.0, 6.45613629515967, 0.0906359603390466,
169 new double[] {
170 0.0824105765758334,
171 1.1330366534715,
172 2.34369463894115
173 }), false);
174 minpackTest(new BardFunction(10.0, 36.1418531596785, 4.17476870138539,
175 new double[] {
176 0.840666673818329,
177 -158848033.259565,
178 -164378671.653535
179 }), false);
180 minpackTest(new BardFunction(100.0, 384.114678637399, 4.17476870135969,
181 new double[] {
182 0.840666673867645,
183 -158946167.205518,
184 -164464906.857771
185 }), false);
186 }
187
188 public void testMinpackKowalikOsborne() {
189 minpackTest(new KowalikOsborneFunction(new double[] { 0.25, 0.39, 0.415, 0.39 },
190 0.0728915102882945,
191 0.017535837721129,
192 new double[] {
193 0.192807810476249,
194 0.191262653354071,
195 0.123052801046931,
196 0.136053221150517
197 }), false);
198 minpackTest(new KowalikOsborneFunction(new double[] { 2.5, 3.9, 4.15, 3.9 },
199 2.97937007555202,
200 0.032052192917937,
201 new double[] {
202 728675.473768287,
203 -14.0758803129393,
204 -32977797.7841797,
205 -20571594.1977912
206 }), false);
207 minpackTest(new KowalikOsborneFunction(new double[] { 25.0, 39.0, 41.5, 39.0 },
208 29.9590617016037,
209 0.0175364017658228,
210 new double[] {
211 0.192948328597594,
212 0.188053165007911,
213 0.122430604321144,
214 0.134575665392506
215 }), true);
216 }
217
218 public void testMinpackMeyer() {
219 minpackTest(new MeyerFunction(new double[] { 0.02, 4000.0, 250.0 },
220 41153.4665543031, 9.37794514651874,
221 new double[] {
222 0.00560963647102661,
223 6181.34634628659,
224 345.223634624144
225 }), false);
226 minpackTest(new MeyerFunction(new double[] { 0.2, 40000.0, 2500.0 },
227 4168216.89130846, 792.917871779501,
228 new double[] {
229 1.42367074157994e-11,
230 33695.7133432541,
231 901.268527953801
232 }), true);
233 }
234
235 public void testMinpackWatson() {
236
237 minpackTest(new WatsonFunction(6, 0.0,
238 5.47722557505166, 0.0478295939097601,
239 new double[] {
240 -0.0157249615083782, 1.01243488232965,
241 -0.232991722387673, 1.26043101102818,
242 -1.51373031394421, 0.99299727291842
243 }), false);
244 minpackTest(new WatsonFunction(6, 10.0,
245 6433.12578950026, 0.0478295939096951,
246 new double[] {
247 -0.0157251901386677, 1.01243485860105,
248 -0.232991545843829, 1.26042932089163,
249 -1.51372776706575, 0.99299573426328
250 }), false);
251 minpackTest(new WatsonFunction(6, 100.0,
252 674256.040605213, 0.047829593911544,
253 new double[] {
254 -0.0157247019712586, 1.01243490925658,
255 -0.232991922761641, 1.26043292929555,
256 -1.51373320452707, 0.99299901922322
257 }), false);
258
259 minpackTest(new WatsonFunction(9, 0.0,
260 5.47722557505166, 0.00118311459212420,
261 new double[] {
262 -0.153070644166722e-4, 0.999789703934597,
263 0.0147639634910978, 0.146342330145992,
264 1.00082109454817, -2.61773112070507,
265 4.10440313943354, -3.14361226236241,
266 1.05262640378759
267 }), false);
268 minpackTest(new WatsonFunction(9, 10.0,
269 12088.127069307, 0.00118311459212513,
270 new double[] {
271 -0.153071334849279e-4, 0.999789703941234,
272 0.0147639629786217, 0.146342334818836,
273 1.00082107321386, -2.61773107084722,
274 4.10440307655564, -3.14361222178686,
275 1.05262639322589
276 }), false);
277 minpackTest(new WatsonFunction(9, 100.0,
278 1269109.29043834, 0.00118311459212384,
279 new double[] {
280 -0.153069523352176e-4, 0.999789703958371,
281 0.0147639625185392, 0.146342341096326,
282 1.00082104729164, -2.61773101573645,
283 4.10440301427286, -3.14361218602503,
284 1.05262638516774
285 }), false);
286
287 minpackTest(new WatsonFunction(12, 0.0,
288 5.47722557505166, 0.217310402535861e-4,
289 new double[] {
290 -0.660266001396382e-8, 1.00000164411833,
291 -0.000563932146980154, 0.347820540050756,
292 -0.156731500244233, 1.05281515825593,
293 -3.24727109519451, 7.2884347837505,
294 -10.271848098614, 9.07411353715783,
295 -4.54137541918194, 1.01201187975044
296 }), false);
297 minpackTest(new WatsonFunction(12, 10.0,
298 19220.7589790951, 0.217310402518509e-4,
299 new double[] {
300 -0.663710223017410e-8, 1.00000164411787,
301 -0.000563932208347327, 0.347820540486998,
302 -0.156731503955652, 1.05281517654573,
303 -3.2472711515214, 7.28843489430665,
304 -10.2718482369638, 9.07411364383733,
305 -4.54137546533666, 1.01201188830857
306 }), false);
307 minpackTest(new WatsonFunction(12, 100.0,
308 2018918.04462367, 0.217310402539845e-4,
309 new double[] {
310 -0.663806046485249e-8, 1.00000164411786,
311 -0.000563932210324959, 0.347820540503588,
312 -0.156731504091375, 1.05281517718031,
313 -3.24727115337025, 7.28843489775302,
314 -10.2718482410813, 9.07411364688464,
315 -4.54137546660822, 1.0120118885369
316 }), false);
317
318 }
319
320 public void testMinpackBox3Dimensional() {
321 minpackTest(new Box3DimensionalFunction(10, new double[] { 0.0, 10.0, 20.0 },
322 32.1115837449572), false);
323 }
324
325 public void testMinpackJennrichSampson() {
326 minpackTest(new JennrichSampsonFunction(10, new double[] { 0.3, 0.4 },
327 64.5856498144943, 11.1517793413499,
328 new double[] {
329 0.257819926636811, 0.257829976764542
330 }), false);
331 }
332
333 public void testMinpackBrownDennis() {
334 minpackTest(new BrownDennisFunction(20,
335 new double[] { 25.0, 5.0, -5.0, -1.0 },
336 2815.43839161816, 292.954288244866,
337 new double[] {
338 -11.59125141003, 13.2024883984741,
339 -0.403574643314272, 0.236736269844604
340 }), false);
341 minpackTest(new BrownDennisFunction(20,
342 new double[] { 250.0, 50.0, -50.0, -10.0 },
343 555073.354173069, 292.954270581415,
344 new double[] {
345 -11.5959274272203, 13.2041866926242,
346 -0.403417362841545, 0.236771143410386
347 }), false);
348 minpackTest(new BrownDennisFunction(20,
349 new double[] { 2500.0, 500.0, -500.0, -100.0 },
350 61211252.2338581, 292.954306151134,
351 new double[] {
352 -11.5902596937374, 13.2020628854665,
353 -0.403688070279258, 0.236665033746463
354 }), false);
355 }
356
357 public void testMinpackChebyquad() {
358 minpackTest(new ChebyquadFunction(1, 8, 1.0,
359 1.88623796907732, 1.88623796907732,
360 new double[] { 0.5 }), false);
361 minpackTest(new ChebyquadFunction(1, 8, 10.0,
362 5383344372.34005, 1.88424820499951,
363 new double[] { 0.9817314924684 }), false);
364 minpackTest(new ChebyquadFunction(1, 8, 100.0,
365 0.118088726698392e19, 1.88424820499347,
366 new double[] { 0.9817314852934 }), false);
367 minpackTest(new ChebyquadFunction(8, 8, 1.0,
368 0.196513862833975, 0.0593032355046727,
369 new double[] {
370 0.0431536648587336, 0.193091637843267,
371 0.266328593812698, 0.499999334628884,
372 0.500000665371116, 0.733671406187302,
373 0.806908362156733, 0.956846335141266
374 }), false);
375 minpackTest(new ChebyquadFunction(9, 9, 1.0,
376 0.16994993465202, 0.0,
377 new double[] {
378 0.0442053461357828, 0.199490672309881,
379 0.23561910847106, 0.416046907892598,
380 0.5, 0.583953092107402,
381 0.764380891528940, 0.800509327690119,
382 0.955794653864217
383 }), false);
384 minpackTest(new ChebyquadFunction(10, 10, 1.0,
385 0.183747831178711, 0.0806471004038253,
386 new double[] {
387 0.0596202671753563, 0.166708783805937,
388 0.239171018813509, 0.398885290346268,
389 0.398883667870681, 0.601116332129320,
390 0.60111470965373, 0.760828981186491,
391 0.833291216194063, 0.940379732824644
392 }), false);
393 }
394
395 public void testMinpackBrownAlmostLinear() {
396 minpackTest(new BrownAlmostLinearFunction(10, 0.5,
397 16.5302162063499, 0.0,
398 new double[] {
399 0.979430303349862, 0.979430303349862,
400 0.979430303349862, 0.979430303349862,
401 0.979430303349862, 0.979430303349862,
402 0.979430303349862, 0.979430303349862,
403 0.979430303349862, 1.20569696650138
404 }), false);
405 minpackTest(new BrownAlmostLinearFunction(10, 5.0,
406 9765624.00089211, 0.0,
407 new double[] {
408 0.979430303349865, 0.979430303349865,
409 0.979430303349865, 0.979430303349865,
410 0.979430303349865, 0.979430303349865,
411 0.979430303349865, 0.979430303349865,
412 0.979430303349865, 1.20569696650135
413 }), false);
414 minpackTest(new BrownAlmostLinearFunction(10, 50.0,
415 0.9765625e17, 0.0,
416 new double[] {
417 1.0, 1.0, 1.0, 1.0, 1.0,
418 1.0, 1.0, 1.0, 1.0, 1.0
419 }), false);
420 minpackTest(new BrownAlmostLinearFunction(30, 0.5,
421 83.476044467848, 0.0,
422 new double[] {
423 0.997754216442807, 0.997754216442807,
424 0.997754216442807, 0.997754216442807,
425 0.997754216442807, 0.997754216442807,
426 0.997754216442807, 0.997754216442807,
427 0.997754216442807, 0.997754216442807,
428 0.997754216442807, 0.997754216442807,
429 0.997754216442807, 0.997754216442807,
430 0.997754216442807, 0.997754216442807,
431 0.997754216442807, 0.997754216442807,
432 0.997754216442807, 0.997754216442807,
433 0.997754216442807, 0.997754216442807,
434 0.997754216442807, 0.997754216442807,
435 0.997754216442807, 0.997754216442807,
436 0.997754216442807, 0.997754216442807,
437 0.997754216442807, 1.06737350671578
438 }), false);
439 minpackTest(new BrownAlmostLinearFunction(40, 0.5,
440 128.026364472323, 0.0,
441 new double[] {
442 1.00000000000002, 1.00000000000002,
443 1.00000000000002, 1.00000000000002,
444 1.00000000000002, 1.00000000000002,
445 1.00000000000002, 1.00000000000002,
446 1.00000000000002, 1.00000000000002,
447 1.00000000000002, 1.00000000000002,
448 1.00000000000002, 1.00000000000002,
449 1.00000000000002, 1.00000000000002,
450 1.00000000000002, 1.00000000000002,
451 1.00000000000002, 1.00000000000002,
452 1.00000000000002, 1.00000000000002,
453 1.00000000000002, 1.00000000000002,
454 1.00000000000002, 1.00000000000002,
455 1.00000000000002, 1.00000000000002,
456 1.00000000000002, 1.00000000000002,
457 1.00000000000002, 1.00000000000002,
458 1.00000000000002, 1.00000000000002,
459 0.999999999999121
460 }), false);
461 }
462
463 public void testMinpackOsborne1() {
464 minpackTest(new Osborne1Function(new double[] { 0.5, 1.5, -1.0, 0.01, 0.02, },
465 0.937564021037838, 0.00739249260904843,
466 new double[] {
467 0.375410049244025, 1.93584654543108,
468 -1.46468676748716, 0.0128675339110439,
469 0.0221227011813076
470 }), false);
471 }
472
473 public void testMinpackOsborne2() {
474
475 minpackTest(new Osborne2Function(new double[] {
476 1.3, 0.65, 0.65, 0.7, 0.6,
477 3.0, 5.0, 7.0, 2.0, 4.5, 5.5
478 },
479 1.44686540984712, 0.20034404483314,
480 new double[] {
481 1.30997663810096, 0.43155248076,
482 0.633661261602859, 0.599428560991695,
483 0.754179768272449, 0.904300082378518,
484 1.36579949521007, 4.82373199748107,
485 2.39868475104871, 4.56887554791452,
486 5.67534206273052
487 }), false);
488 }
489
490 private void minpackTest(MinpackFunction function, boolean exceptionExpected) {
491 LevenbergMarquardtEstimator estimator = new LevenbergMarquardtEstimator();
492 estimator.setMaxCostEval(100 * (function.getN() + 1));
493 estimator.setCostRelativeTolerance(Math.sqrt(2.22044604926e-16));
494 estimator.setParRelativeTolerance(Math.sqrt(2.22044604926e-16));
495 estimator.setOrthoTolerance(2.22044604926e-16);
496 assertTrue(function.checkTheoreticalStartCost(estimator.getRMS(function)));
497 try {
498 estimator.estimate(function);
499 assertFalse(exceptionExpected);
500 } catch (EstimationException lsse) {
501 assertTrue(exceptionExpected);
502 }
503 assertTrue(function.checkTheoreticalMinCost(estimator.getRMS(function)));
504 assertTrue(function.checkTheoreticalMinParams());
505 }
506
507 private static abstract class MinpackFunction implements EstimationProblem {
508
509 protected MinpackFunction(int m,
510 double[] startParams,
511 double theoreticalStartCost,
512 double theoreticalMinCost,
513 double[] theoreticalMinParams) {
514 this.m = m;
515 this.n = startParams.length;
516 parameters = new EstimatedParameter[n];
517 for (int i = 0; i < n; ++i) {
518 parameters[i] = new EstimatedParameter("p" + i, startParams[i]);
519 }
520 this.theoreticalStartCost = theoreticalStartCost;
521 this.theoreticalMinCost = theoreticalMinCost;
522 this.theoreticalMinParams = theoreticalMinParams;
523 this.costAccuracy = 1.0e-8;
524 this.paramsAccuracy = 1.0e-5;
525 }
526
527 protected static double[] buildArray(int n, double x) {
528 double[] array = new double[n];
529 Arrays.fill(array, x);
530 return array;
531 }
532
533 protected void setCostAccuracy(double costAccuracy) {
534 this.costAccuracy = costAccuracy;
535 }
536
537 protected void setParamsAccuracy(double paramsAccuracy) {
538 this.paramsAccuracy = paramsAccuracy;
539 }
540
541 public int getN() {
542 return parameters.length;
543 }
544
545 public boolean checkTheoreticalStartCost(double rms) {
546 double threshold = costAccuracy * (1.0 + theoreticalStartCost);
547 return Math.abs(Math.sqrt(m) * rms - theoreticalStartCost) <= threshold;
548 }
549
550 public boolean checkTheoreticalMinCost(double rms) {
551 double threshold = costAccuracy * (1.0 + theoreticalMinCost);
552 return Math.abs(Math.sqrt(m) * rms - theoreticalMinCost) <= threshold;
553 }
554
555 public boolean checkTheoreticalMinParams() {
556 if (theoreticalMinParams != null) {
557 for (int i = 0; i < theoreticalMinParams.length; ++i) {
558 double mi = theoreticalMinParams[i];
559 double vi = parameters[i].getEstimate();
560 if (Math.abs(mi - vi) > (paramsAccuracy * (1.0 + Math.abs(mi)))) {
561 return false;
562 }
563 }
564 }
565 return true;
566 }
567
568 public WeightedMeasurement[] getMeasurements() {
569 WeightedMeasurement[] measurements = new WeightedMeasurement[m];
570 for (int i = 0; i < m; ++i) {
571 measurements[i] = new MinpackMeasurement(this, i);
572 }
573 return measurements;
574 }
575
576 public EstimatedParameter[] getUnboundParameters() {
577 return parameters;
578 }
579
580 public EstimatedParameter[] getAllParameters() {
581 return parameters;
582 }
583
584 protected abstract double[][] getJacobian();
585
586 protected abstract double[] getResiduals();
587
588 private static class MinpackMeasurement extends WeightedMeasurement {
589
590 public MinpackMeasurement(MinpackFunction f, int index) {
591 super(1.0, 0.0);
592 this.index = index;
593 this.f = f;
594 }
595
596 @Override
597 public double getTheoreticalValue() {
598
599
600
601
602 return f.getResiduals()[index];
603 }
604
605 @Override
606 public double getPartial(EstimatedParameter parameter) {
607
608
609
610
611 for (int j = 0; j < f.n; ++j) {
612 if (parameter == f.parameters[j]) {
613 return f.getJacobian()[index][j];
614 }
615 }
616 return 0;
617 }
618
619 private int index;
620 private transient final MinpackFunction f;
621 private static final long serialVersionUID = 1L;
622
623 }
624
625 protected int n;
626 protected int m;
627 protected EstimatedParameter[] parameters;
628 protected double theoreticalStartCost;
629 protected double theoreticalMinCost;
630 protected double[] theoreticalMinParams;
631 protected double costAccuracy;
632 protected double paramsAccuracy;
633
634 }
635
636 private static class LinearFullRankFunction extends MinpackFunction {
637
638 public LinearFullRankFunction(int m, int n, double x0,
639 double theoreticalStartCost,
640 double theoreticalMinCost) {
641 super(m, buildArray(n, x0), theoreticalStartCost,
642 theoreticalMinCost, buildArray(n, -1.0));
643 }
644
645 @Override
646 protected double[][] getJacobian() {
647 double t = 2.0 / m;
648 double[][] jacobian = new double[m][];
649 for (int i = 0; i < m; ++i) {
650 jacobian[i] = new double[n];
651 for (int j = 0; j < n; ++j) {
652 jacobian[i][j] = (i == j) ? (1 - t) : -t;
653 }
654 }
655 return jacobian;
656 }
657
658 @Override
659 protected double[] getResiduals() {
660 double sum = 0;
661 for (int i = 0; i < n; ++i) {
662 sum += parameters[i].getEstimate();
663 }
664 double t = 1 + 2 * sum / m;
665 double[] f = new double[m];
666 for (int i = 0; i < n; ++i) {
667 f[i] = parameters[i].getEstimate() - t;
668 }
669 Arrays.fill(f, n, m, -t);
670 return f;
671 }
672
673 }
674
675 private static class LinearRank1Function extends MinpackFunction {
676
677 public LinearRank1Function(int m, int n, double x0,
678 double theoreticalStartCost,
679 double theoreticalMinCost) {
680 super(m, buildArray(n, x0), theoreticalStartCost, theoreticalMinCost, null);
681 }
682
683 @Override
684 protected double[][] getJacobian() {
685 double[][] jacobian = new double[m][];
686 for (int i = 0; i < m; ++i) {
687 jacobian[i] = new double[n];
688 for (int j = 0; j < n; ++j) {
689 jacobian[i][j] = (i + 1) * (j + 1);
690 }
691 }
692 return jacobian;
693 }
694
695 @Override
696 protected double[] getResiduals() {
697 double[] f = new double[m];
698 double sum = 0;
699 for (int i = 0; i < n; ++i) {
700 sum += (i + 1) * parameters[i].getEstimate();
701 }
702 for (int i = 0; i < m; ++i) {
703 f[i] = (i + 1) * sum - 1;
704 }
705 return f;
706 }
707
708 }
709
710 private static class LinearRank1ZeroColsAndRowsFunction extends MinpackFunction {
711
712 public LinearRank1ZeroColsAndRowsFunction(int m, int n, double x0) {
713 super(m, buildArray(n, x0),
714 Math.sqrt(m + (n+1)*(n-2)*(m-2)*(m-1) * ((n+1)*(n-2)*(2*m-3) - 12) / 24.0),
715 Math.sqrt((m * (m + 3) - 6) / (2.0 * (2 * m - 3))),
716 null);
717 }
718
719 @Override
720 protected double[][] getJacobian() {
721 double[][] jacobian = new double[m][];
722 for (int i = 0; i < m; ++i) {
723 jacobian[i] = new double[n];
724 jacobian[i][0] = 0;
725 for (int j = 1; j < (n - 1); ++j) {
726 if (i == 0) {
727 jacobian[i][j] = 0;
728 } else if (i != (m - 1)) {
729 jacobian[i][j] = i * (j + 1);
730 } else {
731 jacobian[i][j] = 0;
732 }
733 }
734 jacobian[i][n - 1] = 0;
735 }
736 return jacobian;
737 }
738
739 @Override
740 protected double[] getResiduals() {
741 double[] f = new double[m];
742 double sum = 0;
743 for (int i = 1; i < (n - 1); ++i) {
744 sum += (i + 1) * parameters[i].getEstimate();
745 }
746 for (int i = 0; i < (m - 1); ++i) {
747 f[i] = i * sum - 1;
748 }
749 f[m - 1] = -1;
750 return f;
751 }
752
753 }
754
755 private static class RosenbrockFunction extends MinpackFunction {
756
757 public RosenbrockFunction(double[] startParams, double theoreticalStartCost) {
758 super(2, startParams, theoreticalStartCost, 0.0, buildArray(2, 1.0));
759 }
760
761 @Override
762 protected double[][] getJacobian() {
763 double x1 = parameters[0].getEstimate();
764 return new double[][] { { -20 * x1, 10 }, { -1, 0 } };
765 }
766
767 @Override
768 protected double[] getResiduals() {
769 double x1 = parameters[0].getEstimate();
770 double x2 = parameters[1].getEstimate();
771 return new double[] { 10 * (x2 - x1 * x1), 1 - x1 };
772 }
773
774 }
775
776 private static class HelicalValleyFunction extends MinpackFunction {
777
778 public HelicalValleyFunction(double[] startParams,
779 double theoreticalStartCost) {
780 super(3, startParams, theoreticalStartCost, 0.0,
781 new double[] { 1.0, 0.0, 0.0 });
782 }
783
784 @Override
785 protected double[][] getJacobian() {
786 double x1 = parameters[0].getEstimate();
787 double x2 = parameters[1].getEstimate();
788 double tmpSquare = x1 * x1 + x2 * x2;
789 double tmp1 = twoPi * tmpSquare;
790 double tmp2 = Math.sqrt(tmpSquare);
791 return new double[][] {
792 { 100 * x2 / tmp1, -100 * x1 / tmp1, 10 },
793 { 10 * x1 / tmp2, 10 * x2 / tmp2, 0 },
794 { 0, 0, 1 }
795 };
796 }
797
798 @Override
799 protected double[] getResiduals() {
800 double x1 = parameters[0].getEstimate();
801 double x2 = parameters[1].getEstimate();
802 double x3 = parameters[2].getEstimate();
803 double tmp1;
804 if (x1 == 0) {
805 tmp1 = (x2 >= 0) ? 0.25 : -0.25;
806 } else {
807 tmp1 = Math.atan(x2 / x1) / twoPi;
808 if (x1 < 0) {
809 tmp1 += 0.5;
810 }
811 }
812 double tmp2 = Math.sqrt(x1 * x1 + x2 * x2);
813 return new double[] {
814 10.0 * (x3 - 10 * tmp1),
815 10.0 * (tmp2 - 1),
816 x3
817 };
818 }
819
820 private static final double twoPi = 2.0 * Math.PI;
821
822 }
823
824 private static class PowellSingularFunction extends MinpackFunction {
825
826 public PowellSingularFunction(double[] startParams,
827 double theoreticalStartCost) {
828 super(4, startParams, theoreticalStartCost, 0.0, buildArray(4, 0.0));
829 }
830
831 @Override
832 protected double[][] getJacobian() {
833 double x1 = parameters[0].getEstimate();
834 double x2 = parameters[1].getEstimate();
835 double x3 = parameters[2].getEstimate();
836 double x4 = parameters[3].getEstimate();
837 return new double[][] {
838 { 1, 10, 0, 0 },
839 { 0, 0, sqrt5, -sqrt5 },
840 { 0, 2 * (x2 - 2 * x3), -4 * (x2 - 2 * x3), 0 },
841 { 2 * sqrt10 * (x1 - x4), 0, 0, -2 * sqrt10 * (x1 - x4) }
842 };
843 }
844
845 @Override
846 protected double[] getResiduals() {
847 double x1 = parameters[0].getEstimate();
848 double x2 = parameters[1].getEstimate();
849 double x3 = parameters[2].getEstimate();
850 double x4 = parameters[3].getEstimate();
851 return new double[] {
852 x1 + 10 * x2,
853 sqrt5 * (x3 - x4),
854 (x2 - 2 * x3) * (x2 - 2 * x3),
855 sqrt10 * (x1 - x4) * (x1 - x4)
856 };
857 }
858
859 private static final double sqrt5 = Math.sqrt( 5.0);
860 private static final double sqrt10 = Math.sqrt(10.0);
861
862 }
863
864 private static class FreudensteinRothFunction extends MinpackFunction {
865
866 public FreudensteinRothFunction(double[] startParams,
867 double theoreticalStartCost,
868 double theoreticalMinCost,
869 double[] theoreticalMinParams) {
870 super(2, startParams, theoreticalStartCost,
871 theoreticalMinCost, theoreticalMinParams);
872 }
873
874 @Override
875 protected double[][] getJacobian() {
876 double x2 = parameters[1].getEstimate();
877 return new double[][] {
878 { 1, x2 * (10 - 3 * x2) - 2 },
879 { 1, x2 * ( 2 + 3 * x2) - 14, }
880 };
881 }
882
883 @Override
884 protected double[] getResiduals() {
885 double x1 = parameters[0].getEstimate();
886 double x2 = parameters[1].getEstimate();
887 return new double[] {
888 -13.0 + x1 + ((5.0 - x2) * x2 - 2.0) * x2,
889 -29.0 + x1 + ((1.0 + x2) * x2 - 14.0) * x2
890 };
891 }
892
893 }
894
895 private static class BardFunction extends MinpackFunction {
896
897 public BardFunction(double x0,
898 double theoreticalStartCost,
899 double theoreticalMinCost,
900 double[] theoreticalMinParams) {
901 super(15, buildArray(3, x0), theoreticalStartCost,
902 theoreticalMinCost, theoreticalMinParams);
903 }
904
905 @Override
906 protected double[][] getJacobian() {
907 double x2 = parameters[1].getEstimate();
908 double x3 = parameters[2].getEstimate();
909 double[][] jacobian = new double[m][];
910 for (int i = 0; i < m; ++i) {
911 double tmp1 = i + 1;
912 double tmp2 = 15 - i;
913 double tmp3 = (i <= 7) ? tmp1 : tmp2;
914 double tmp4 = x2 * tmp2 + x3 * tmp3;
915 tmp4 *= tmp4;
916 jacobian[i] = new double[] { -1, tmp1 * tmp2 / tmp4, tmp1 * tmp3 / tmp4 };
917 }
918 return jacobian;
919 }
920
921 @Override
922 protected double[] getResiduals() {
923 double x1 = parameters[0].getEstimate();
924 double x2 = parameters[1].getEstimate();
925 double x3 = parameters[2].getEstimate();
926 double[] f = new double[m];
927 for (int i = 0; i < m; ++i) {
928 double tmp1 = i + 1;
929 double tmp2 = 15 - i;
930 double tmp3 = (i <= 7) ? tmp1 : tmp2;
931 f[i] = y[i] - (x1 + tmp1 / (x2 * tmp2 + x3 * tmp3));
932 }
933 return f;
934 }
935
936 private static final double[] y = {
937 0.14, 0.18, 0.22, 0.25, 0.29,
938 0.32, 0.35, 0.39, 0.37, 0.58,
939 0.73, 0.96, 1.34, 2.10, 4.39
940 };
941
942 }
943
944 private static class KowalikOsborneFunction extends MinpackFunction {
945
946 public KowalikOsborneFunction(double[] startParams,
947 double theoreticalStartCost,
948 double theoreticalMinCost,
949 double[] theoreticalMinParams) {
950 super(11, startParams, theoreticalStartCost,
951 theoreticalMinCost, theoreticalMinParams);
952 if (theoreticalStartCost > 20.0) {
953 setCostAccuracy(2.0e-4);
954 setParamsAccuracy(5.0e-3);
955 }
956 }
957
958 @Override
959 protected double[][] getJacobian() {
960 double x1 = parameters[0].getEstimate();
961 double x2 = parameters[1].getEstimate();
962 double x3 = parameters[2].getEstimate();
963 double x4 = parameters[3].getEstimate();
964 double[][] jacobian = new double[m][];
965 for (int i = 0; i < m; ++i) {
966 double tmp = v[i] * (v[i] + x3) + x4;
967 double j1 = -v[i] * (v[i] + x2) / tmp;
968 double j2 = -v[i] * x1 / tmp;
969 double j3 = j1 * j2;
970 double j4 = j3 / v[i];
971 jacobian[i] = new double[] { j1, j2, j3, j4 };
972 }
973 return jacobian;
974 }
975
976 @Override
977 protected double[] getResiduals() {
978 double x1 = parameters[0].getEstimate();
979 double x2 = parameters[1].getEstimate();
980 double x3 = parameters[2].getEstimate();
981 double x4 = parameters[3].getEstimate();
982 double[] f = new double[m];
983 for (int i = 0; i < m; ++i) {
984 f[i] = y[i] - x1 * (v[i] * (v[i] + x2)) / (v[i] * (v[i] + x3) + x4);
985 }
986 return f;
987 }
988
989 private static final double[] v = {
990 4.0, 2.0, 1.0, 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625
991 };
992
993 private static final double[] y = {
994 0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627,
995 0.0456, 0.0342, 0.0323, 0.0235, 0.0246
996 };
997
998 }
999
1000 private static class MeyerFunction extends MinpackFunction {
1001
1002 public MeyerFunction(double[] startParams,
1003 double theoreticalStartCost,
1004 double theoreticalMinCost,
1005 double[] theoreticalMinParams) {
1006 super(16, startParams, theoreticalStartCost,
1007 theoreticalMinCost, theoreticalMinParams);
1008 if (theoreticalStartCost > 1.0e6) {
1009 setCostAccuracy(7.0e-3);
1010 setParamsAccuracy(2.0e-2);
1011 }
1012 }
1013
1014 @Override
1015 protected double[][] getJacobian() {
1016 double x1 = parameters[0].getEstimate();
1017 double x2 = parameters[1].getEstimate();
1018 double x3 = parameters[2].getEstimate();
1019 double[][] jacobian = new double[m][];
1020 for (int i = 0; i < m; ++i) {
1021 double temp = 5.0 * (i + 1) + 45.0 + x3;
1022 double tmp1 = x2 / temp;
1023 double tmp2 = Math.exp(tmp1);
1024 double tmp3 = x1 * tmp2 / temp;
1025 jacobian[i] = new double[] { tmp2, tmp3, -tmp1 * tmp3 };
1026 }
1027 return jacobian;
1028 }
1029
1030 @Override
1031 protected double[] getResiduals() {
1032 double x1 = parameters[0].getEstimate();
1033 double x2 = parameters[1].getEstimate();
1034 double x3 = parameters[2].getEstimate();
1035 double[] f = new double[m];
1036 for (int i = 0; i < m; ++i) {
1037 f[i] = x1 * Math.exp(x2 / (5.0 * (i + 1) + 45.0 + x3)) - y[i];
1038 }
1039 return f;
1040 }
1041
1042 private static final double[] y = {
1043 34780.0, 28610.0, 23650.0, 19630.0,
1044 16370.0, 13720.0, 11540.0, 9744.0,
1045 8261.0, 7030.0, 6005.0, 5147.0,
1046 4427.0, 3820.0, 3307.0, 2872.0
1047 };
1048
1049 }
1050
1051 private static class WatsonFunction extends MinpackFunction {
1052
1053 public WatsonFunction(int n, double x0,
1054 double theoreticalStartCost,
1055 double theoreticalMinCost,
1056 double[] theoreticalMinParams) {
1057 super(31, buildArray(n, x0), theoreticalStartCost,
1058 theoreticalMinCost, theoreticalMinParams);
1059 }
1060
1061 @Override
1062 protected double[][] getJacobian() {
1063
1064 double[][] jacobian = new double[m][];
1065
1066 for (int i = 0; i < (m - 2); ++i) {
1067 double div = (i + 1) / 29.0;
1068 double s2 = 0.0;
1069 double dx = 1.0;
1070 for (int j = 0; j < n; ++j) {
1071 s2 += dx * parameters[j].getEstimate();
1072 dx *= div;
1073 }
1074 double temp= 2 * div * s2;
1075 dx = 1.0 / div;
1076 jacobian[i] = new double[n];
1077 for (int j = 0; j < n; ++j) {
1078 jacobian[i][j] = dx * (j - temp);
1079 dx *= div;
1080 }
1081 }
1082
1083 jacobian[m - 2] = new double[n];
1084 jacobian[m - 2][0] = 1;
1085
1086 jacobian[m - 1] = new double[n];
1087 jacobian[m - 1][0]= -2 * parameters[0].getEstimate();
1088 jacobian[m - 1][1]= 1;
1089
1090 return jacobian;
1091
1092 }
1093
1094 @Override
1095 protected double[] getResiduals() {
1096 double[] f = new double[m];
1097 for (int i = 0; i < (m - 2); ++i) {
1098 double div = (i + 1) / 29.0;
1099 double s1 = 0;
1100 double dx = 1;
1101 for (int j = 1; j < n; ++j) {
1102 s1 += j * dx * parameters[j].getEstimate();
1103 dx *= div;
1104 }
1105 double s2 =0;
1106 dx =1;
1107 for (int j = 0; j < n; ++j) {
1108 s2 += dx * parameters[j].getEstimate();
1109 dx *= div;
1110 }
1111 f[i] = s1 - s2 * s2 - 1;
1112 }
1113
1114 double x1 = parameters[0].getEstimate();
1115 double x2 = parameters[1].getEstimate();
1116 f[m - 2] = x1;
1117 f[m - 1] = x2 - x1 * x1 - 1;
1118
1119 return f;
1120
1121 }
1122
1123 }
1124
1125 private static class Box3DimensionalFunction extends MinpackFunction {
1126
1127 public Box3DimensionalFunction(int m, double[] startParams,
1128 double theoreticalStartCost) {
1129 super(m, startParams, theoreticalStartCost,
1130 0.0, new double[] { 1.0, 10.0, 1.0 });
1131 }
1132
1133 @Override
1134 protected double[][] getJacobian() {
1135 double x1 = parameters[0].getEstimate();
1136 double x2 = parameters[1].getEstimate();
1137 double[][] jacobian = new double[m][];
1138 for (int i = 0; i < m; ++i) {
1139 double tmp = (i + 1) / 10.0;
1140 jacobian[i] = new double[] {
1141 -tmp * Math.exp(-tmp * x1),
1142 tmp * Math.exp(-tmp * x2),
1143 Math.exp(-i - 1) - Math.exp(-tmp)
1144 };
1145 }
1146 return jacobian;
1147 }
1148
1149 @Override
1150 protected double[] getResiduals() {
1151 double x1 = parameters[0].getEstimate();
1152 double x2 = parameters[1].getEstimate();
1153 double x3 = parameters[2].getEstimate();
1154 double[] f = new double[m];
1155 for (int i = 0; i < m; ++i) {
1156 double tmp = (i + 1) / 10.0;
1157 f[i] = Math.exp(-tmp * x1) - Math.exp(-tmp * x2)
1158 + (Math.exp(-i - 1) - Math.exp(-tmp)) * x3;
1159 }
1160 return f;
1161 }
1162
1163 }
1164
1165 private static class JennrichSampsonFunction extends MinpackFunction {
1166
1167 public JennrichSampsonFunction(int m, double[] startParams,
1168 double theoreticalStartCost,
1169 double theoreticalMinCost,
1170 double[] theoreticalMinParams) {
1171 super(m, startParams, theoreticalStartCost,
1172 theoreticalMinCost, theoreticalMinParams);
1173 }
1174
1175 @Override
1176 protected double[][] getJacobian() {
1177 double x1 = parameters[0].getEstimate();
1178 double x2 = parameters[1].getEstimate();
1179 double[][] jacobian = new double[m][];
1180 for (int i = 0; i < m; ++i) {
1181 double t = i + 1;
1182 jacobian[i] = new double[] { -t * Math.exp(t * x1), -t * Math.exp(t * x2) };
1183 }
1184 return jacobian;
1185 }
1186
1187 @Override
1188 protected double[] getResiduals() {
1189 double x1 = parameters[0].getEstimate();
1190 double x2 = parameters[1].getEstimate();
1191 double[] f = new double[m];
1192 for (int i = 0; i < m; ++i) {
1193 double temp = i + 1;
1194 f[i] = 2 + 2 * temp - Math.exp(temp * x1) - Math.exp(temp * x2);
1195 }
1196 return f;
1197 }
1198
1199 }
1200
1201 private static class BrownDennisFunction extends MinpackFunction {
1202
1203 public BrownDennisFunction(int m, double[] startParams,
1204 double theoreticalStartCost,
1205 double theoreticalMinCost,
1206 double[] theoreticalMinParams) {
1207 super(m, startParams, theoreticalStartCost,
1208 theoreticalMinCost, theoreticalMinParams);
1209 setCostAccuracy(2.5e-8);
1210 }
1211
1212 @Override
1213 protected double[][] getJacobian() {
1214 double x1 = parameters[0].getEstimate();
1215 double x2 = parameters[1].getEstimate();
1216 double x3 = parameters[2].getEstimate();
1217 double x4 = parameters[3].getEstimate();
1218 double[][] jacobian = new double[m][];
1219 for (int i = 0; i < m; ++i) {
1220 double temp = (i + 1) / 5.0;
1221 double ti = Math.sin(temp);
1222 double tmp1 = x1 + temp * x2 - Math.exp(temp);
1223 double tmp2 = x3 + ti * x4 - Math.cos(temp);
1224 jacobian[i] = new double[] {
1225 2 * tmp1, 2 * temp * tmp1, 2 * tmp2, 2 * ti * tmp2
1226 };
1227 }
1228 return jacobian;
1229 }
1230
1231 @Override
1232 protected double[] getResiduals() {
1233 double x1 = parameters[0].getEstimate();
1234 double x2 = parameters[1].getEstimate();
1235 double x3 = parameters[2].getEstimate();
1236 double x4 = parameters[3].getEstimate();
1237 double[] f = new double[m];
1238 for (int i = 0; i < m; ++i) {
1239 double temp = (i + 1) / 5.0;
1240 double tmp1 = x1 + temp * x2 - Math.exp(temp);
1241 double tmp2 = x3 + Math.sin(temp) * x4 - Math.cos(temp);
1242 f[i] = tmp1 * tmp1 + tmp2 * tmp2;
1243 }
1244 return f;
1245 }
1246
1247 }
1248
1249 private static class ChebyquadFunction extends MinpackFunction {
1250
1251 private static double[] buildChebyquadArray(int n, double factor) {
1252 double[] array = new double[n];
1253 double inv = factor / (n + 1);
1254 for (int i = 0; i < n; ++i) {
1255 array[i] = (i + 1) * inv;
1256 }
1257 return array;
1258 }
1259
1260 public ChebyquadFunction(int n, int m, double factor,
1261 double theoreticalStartCost,
1262 double theoreticalMinCost,
1263 double[] theoreticalMinParams) {
1264 super(m, buildChebyquadArray(n, factor), theoreticalStartCost,
1265 theoreticalMinCost, theoreticalMinParams);
1266 }
1267
1268 @Override
1269 protected double[][] getJacobian() {
1270
1271 double[][] jacobian = new double[m][];
1272 for (int i = 0; i < m; ++i) {
1273 jacobian[i] = new double[n];
1274 }
1275
1276 double dx = 1.0 / n;
1277 for (int j = 0; j < n; ++j) {
1278 double tmp1 = 1;
1279 double tmp2 = 2 * parameters[j].getEstimate() - 1;
1280 double temp = 2 * tmp2;
1281 double tmp3 = 0;
1282 double tmp4 = 2;
1283 for (int i = 0; i < m; ++i) {
1284 jacobian[i][j] = dx * tmp4;
1285 double ti = 4 * tmp2 + temp * tmp4 - tmp3;
1286 tmp3 = tmp4;
1287 tmp4 = ti;
1288 ti = temp * tmp2 - tmp1;
1289 tmp1 = tmp2;
1290 tmp2 = ti;
1291 }
1292 }
1293
1294 return jacobian;
1295
1296 }
1297
1298 @Override
1299 protected double[] getResiduals() {
1300
1301 double[] f = new double[m];
1302
1303 for (int j = 0; j < n; ++j) {
1304 double tmp1 = 1;
1305 double tmp2 = 2 * parameters[j].getEstimate() - 1;
1306 double temp = 2 * tmp2;
1307 for (int i = 0; i < m; ++i) {
1308 f[i] += tmp2;
1309 double ti = temp * tmp2 - tmp1;
1310 tmp1 = tmp2;
1311 tmp2 = ti;
1312 }
1313 }
1314
1315 double dx = 1.0 / n;
1316 boolean iev = false;
1317 for (int i = 0; i < m; ++i) {
1318 f[i] *= dx;
1319 if (iev) {
1320 f[i] += 1.0 / (i * (i + 2));
1321 }
1322 iev = ! iev;
1323 }
1324
1325 return f;
1326
1327 }
1328
1329 }
1330
1331 private static class BrownAlmostLinearFunction extends MinpackFunction {
1332
1333 public BrownAlmostLinearFunction(int m, double factor,
1334 double theoreticalStartCost,
1335 double theoreticalMinCost,
1336 double[] theoreticalMinParams) {
1337 super(m, buildArray(m, factor), theoreticalStartCost,
1338 theoreticalMinCost, theoreticalMinParams);
1339 }
1340
1341 @Override
1342 protected double[][] getJacobian() {
1343 double[][] jacobian = new double[m][];
1344 for (int i = 0; i < m; ++i) {
1345 jacobian[i] = new double[n];
1346 }
1347
1348 double prod = 1;
1349 for (int j = 0; j < n; ++j) {
1350 prod *= parameters[j].getEstimate();
1351 for (int i = 0; i < n; ++i) {
1352 jacobian[i][j] = 1;
1353 }
1354 jacobian[j][j] = 2;
1355 }
1356
1357 for (int j = 0; j < n; ++j) {
1358 EstimatedParameter vj = parameters[j];
1359 double temp = vj.getEstimate();
1360 if (temp == 0) {
1361 temp = 1;
1362 prod = 1;
1363 for (int k = 0; k < n; ++k) {
1364 if (k != j) {
1365 prod *= parameters[k].getEstimate();
1366 }
1367 }
1368 }
1369 jacobian[n - 1][j] = prod / temp;
1370 }
1371
1372 return jacobian;
1373
1374 }
1375
1376 @Override
1377 protected double[] getResiduals() {
1378 double[] f = new double[m];
1379 double sum = -(n + 1);
1380 double prod = 1;
1381 for (int j = 0; j < n; ++j) {
1382 sum += parameters[j].getEstimate();
1383 prod *= parameters[j].getEstimate();
1384 }
1385 for (int i = 0; i < n; ++i) {
1386 f[i] = parameters[i].getEstimate() + sum;
1387 }
1388 f[n - 1] = prod - 1;
1389 return f;
1390 }
1391
1392 }
1393
1394 private static class Osborne1Function extends MinpackFunction {
1395
1396 public Osborne1Function(double[] startParams,
1397 double theoreticalStartCost,
1398 double theoreticalMinCost,
1399 double[] theoreticalMinParams) {
1400 super(33, startParams, theoreticalStartCost,
1401 theoreticalMinCost, theoreticalMinParams);
1402 }
1403
1404 @Override
1405 protected double[][] getJacobian() {
1406 double x2 = parameters[1].getEstimate();
1407 double x3 = parameters[2].getEstimate();
1408 double x4 = parameters[3].getEstimate();
1409 double x5 = parameters[4].getEstimate();
1410 double[][] jacobian = new double[m][];
1411 for (int i = 0; i < m; ++i) {
1412 double temp = 10.0 * i;
1413 double tmp1 = Math.exp(-temp * x4);
1414 double tmp2 = Math.exp(-temp * x5);
1415 jacobian[i] = new double[] {
1416 -1, -tmp1, -tmp2, temp * x2 * tmp1, temp * x3 * tmp2
1417 };
1418 }
1419 return jacobian;
1420 }
1421
1422 @Override
1423 protected double[] getResiduals() {
1424 double x1 = parameters[0].getEstimate();
1425 double x2 = parameters[1].getEstimate();
1426 double x3 = parameters[2].getEstimate();
1427 double x4 = parameters[3].getEstimate();
1428 double x5 = parameters[4].getEstimate();
1429 double[] f = new double[m];
1430 for (int i = 0; i < m; ++i) {
1431 double temp = 10.0 * i;
1432 double tmp1 = Math.exp(-temp * x4);
1433 double tmp2 = Math.exp(-temp * x5);
1434 f[i] = y[i] - (x1 + x2 * tmp1 + x3 * tmp2);
1435 }
1436 return f;
1437 }
1438
1439 private static final double[] y = {
1440 0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881, 0.850, 0.818, 0.784, 0.751,
1441 0.718, 0.685, 0.658, 0.628, 0.603, 0.580, 0.558, 0.538, 0.522, 0.506, 0.490,
1442 0.478, 0.467, 0.457, 0.448, 0.438, 0.431, 0.424, 0.420, 0.414, 0.411, 0.406
1443 };
1444
1445 }
1446
1447 private static class Osborne2Function extends MinpackFunction {
1448
1449 public Osborne2Function(double[] startParams,
1450 double theoreticalStartCost,
1451 double theoreticalMinCost,
1452 double[] theoreticalMinParams) {
1453 super(65, startParams, theoreticalStartCost,
1454 theoreticalMinCost, theoreticalMinParams);
1455 }
1456
1457 @Override
1458 protected double[][] getJacobian() {
1459 double x01 = parameters[0].getEstimate();
1460 double x02 = parameters[1].getEstimate();
1461 double x03 = parameters[2].getEstimate();
1462 double x04 = parameters[3].getEstimate();
1463 double x05 = parameters[4].getEstimate();
1464 double x06 = parameters[5].getEstimate();
1465 double x07 = parameters[6].getEstimate();
1466 double x08 = parameters[7].getEstimate();
1467 double x09 = parameters[8].getEstimate();
1468 double x10 = parameters[9].getEstimate();
1469 double x11 = parameters[10].getEstimate();
1470 double[][] jacobian = new double[m][];
1471 for (int i = 0; i < m; ++i) {
1472 double temp = i / 10.0;
1473 double tmp1 = Math.exp(-x05 * temp);
1474 double tmp2 = Math.exp(-x06 * (temp - x09) * (temp - x09));
1475 double tmp3 = Math.exp(-x07 * (temp - x10) * (temp - x10));
1476 double tmp4 = Math.exp(-x08 * (temp - x11) * (temp - x11));
1477 jacobian[i] = new double[] {
1478 -tmp1,
1479 -tmp2,
1480 -tmp3,
1481 -tmp4,
1482 temp * x01 * tmp1,
1483 x02 * (temp - x09) * (temp - x09) * tmp2,
1484 x03 * (temp - x10) * (temp - x10) * tmp3,
1485 x04 * (temp - x11) * (temp - x11) * tmp4,
1486 -2 * x02 * x06 * (temp - x09) * tmp2,
1487 -2 * x03 * x07 * (temp - x10) * tmp3,
1488 -2 * x04 * x08 * (temp - x11) * tmp4
1489 };
1490 }
1491 return jacobian;
1492 }
1493
1494 @Override
1495 protected double[] getResiduals() {
1496 double x01 = parameters[0].getEstimate();
1497 double x02 = parameters[1].getEstimate();
1498 double x03 = parameters[2].getEstimate();
1499 double x04 = parameters[3].getEstimate();
1500 double x05 = parameters[4].getEstimate();
1501 double x06 = parameters[5].getEstimate();
1502 double x07 = parameters[6].getEstimate();
1503 double x08 = parameters[7].getEstimate();
1504 double x09 = parameters[8].getEstimate();
1505 double x10 = parameters[9].getEstimate();
1506 double x11 = parameters[10].getEstimate();
1507 double[] f = new double[m];
1508 for (int i = 0; i < m; ++i) {
1509 double temp = i / 10.0;
1510 double tmp1 = Math.exp(-x05 * temp);
1511 double tmp2 = Math.exp(-x06 * (temp - x09) * (temp - x09));
1512 double tmp3 = Math.exp(-x07 * (temp - x10) * (temp - x10));
1513 double tmp4 = Math.exp(-x08 * (temp - x11) * (temp - x11));
1514 f[i] = y[i] - (x01 * tmp1 + x02 * tmp2 + x03 * tmp3 + x04 * tmp4);
1515 }
1516 return f;
1517 }
1518
1519 private static final double[] y = {
1520 1.366, 1.191, 1.112, 1.013, 0.991,
1521 0.885, 0.831, 0.847, 0.786, 0.725,
1522 0.746, 0.679, 0.608, 0.655, 0.616,
1523 0.606, 0.602, 0.626, 0.651, 0.724,
1524 0.649, 0.649, 0.694, 0.644, 0.624,
1525 0.661, 0.612, 0.558, 0.533, 0.495,
1526 0.500, 0.423, 0.395, 0.375, 0.372,
1527 0.391, 0.396, 0.405, 0.428, 0.429,
1528 0.523, 0.562, 0.607, 0.653, 0.672,
1529 0.708, 0.633, 0.668, 0.645, 0.632,
1530 0.591, 0.559, 0.597, 0.625, 0.739,
1531 0.710, 0.729, 0.720, 0.636, 0.581,
1532 0.428, 0.292, 0.162, 0.098, 0.054
1533 };
1534
1535 }
1536
1537 public static Test suite() {
1538 return new TestSuite(MinpackTest.class);
1539 }
1540
1541 }