blob: d7376b0f55d6a657feaf246af61636a590cade36 [file] [log] [blame]
Narayan Kamathc981c482012-11-02 10:59:05 +00001// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
5
6#include <stdio.h>
7
8#include "main.h"
9#include <unsupported/Eigen/NonLinearOptimization>
10
11// This disables some useless Warnings on MSVC.
12// It is intended to be done for this test only.
13#include <Eigen/src/Core/util/DisableStupidWarnings.h>
14
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -070015using std::sqrt;
16
Narayan Kamathc981c482012-11-02 10:59:05 +000017int fcn_chkder(const VectorXd &x, VectorXd &fvec, MatrixXd &fjac, int iflag)
18{
19 /* subroutine fcn for chkder example. */
20
21 int i;
22 assert(15 == fvec.size());
23 assert(3 == x.size());
24 double tmp1, tmp2, tmp3, tmp4;
25 static const double y[15]={1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,
26 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};
27
28
29 if (iflag == 0)
30 return 0;
31
32 if (iflag != 2)
33 for (i=0; i<15; i++) {
34 tmp1 = i+1;
35 tmp2 = 16-i-1;
36 tmp3 = tmp1;
37 if (i >= 8) tmp3 = tmp2;
38 fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
39 }
40 else {
41 for (i = 0; i < 15; i++) {
42 tmp1 = i+1;
43 tmp2 = 16-i-1;
44
45 /* error introduced into next statement for illustration. */
46 /* corrected statement should read tmp3 = tmp1 . */
47
48 tmp3 = tmp2;
49 if (i >= 8) tmp3 = tmp2;
50 tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4=tmp4*tmp4;
51 fjac(i,0) = -1.;
52 fjac(i,1) = tmp1*tmp2/tmp4;
53 fjac(i,2) = tmp1*tmp3/tmp4;
54 }
55 }
56 return 0;
57}
58
59
60void testChkder()
61{
62 const int m=15, n=3;
63 VectorXd x(n), fvec(m), xp, fvecp(m), err;
64 MatrixXd fjac(m,n);
65 VectorXi ipvt;
66
67 /* the following values should be suitable for */
68 /* checking the jacobian matrix. */
69 x << 9.2e-1, 1.3e-1, 5.4e-1;
70
71 internal::chkder(x, fvec, fjac, xp, fvecp, 1, err);
72 fcn_chkder(x, fvec, fjac, 1);
73 fcn_chkder(x, fvec, fjac, 2);
74 fcn_chkder(xp, fvecp, fjac, 1);
75 internal::chkder(x, fvec, fjac, xp, fvecp, 2, err);
76
77 fvecp -= fvec;
78
79 // check those
80 VectorXd fvec_ref(m), fvecp_ref(m), err_ref(m);
81 fvec_ref <<
82 -1.181606, -1.429655, -1.606344,
83 -1.745269, -1.840654, -1.921586,
84 -1.984141, -2.022537, -2.468977,
85 -2.827562, -3.473582, -4.437612,
86 -6.047662, -9.267761, -18.91806;
87 fvecp_ref <<
88 -7.724666e-09, -3.432406e-09, -2.034843e-10,
89 2.313685e-09, 4.331078e-09, 5.984096e-09,
90 7.363281e-09, 8.53147e-09, 1.488591e-08,
91 2.33585e-08, 3.522012e-08, 5.301255e-08,
92 8.26666e-08, 1.419747e-07, 3.19899e-07;
93 err_ref <<
94 0.1141397, 0.09943516, 0.09674474,
95 0.09980447, 0.1073116, 0.1220445,
96 0.1526814, 1, 1,
97 1, 1, 1,
98 1, 1, 1;
99
100 VERIFY_IS_APPROX(fvec, fvec_ref);
101 VERIFY_IS_APPROX(fvecp, fvecp_ref);
102 VERIFY_IS_APPROX(err, err_ref);
103}
104
105// Generic functor
106template<typename _Scalar, int NX=Dynamic, int NY=Dynamic>
107struct Functor
108{
109 typedef _Scalar Scalar;
110 enum {
111 InputsAtCompileTime = NX,
112 ValuesAtCompileTime = NY
113 };
114 typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;
115 typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;
116 typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;
117
118 const int m_inputs, m_values;
119
120 Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
121 Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}
122
123 int inputs() const { return m_inputs; }
124 int values() const { return m_values; }
125
126 // you should define that in the subclass :
127// void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const;
128};
129
130struct lmder_functor : Functor<double>
131{
132 lmder_functor(void): Functor<double>(3,15) {}
133 int operator()(const VectorXd &x, VectorXd &fvec) const
134 {
135 double tmp1, tmp2, tmp3;
136 static const double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,
137 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};
138
139 for (int i = 0; i < values(); i++)
140 {
141 tmp1 = i+1;
142 tmp2 = 16 - i - 1;
143 tmp3 = (i>=8)? tmp2 : tmp1;
144 fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
145 }
146 return 0;
147 }
148
149 int df(const VectorXd &x, MatrixXd &fjac) const
150 {
151 double tmp1, tmp2, tmp3, tmp4;
152 for (int i = 0; i < values(); i++)
153 {
154 tmp1 = i+1;
155 tmp2 = 16 - i - 1;
156 tmp3 = (i>=8)? tmp2 : tmp1;
157 tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4 = tmp4*tmp4;
158 fjac(i,0) = -1;
159 fjac(i,1) = tmp1*tmp2/tmp4;
160 fjac(i,2) = tmp1*tmp3/tmp4;
161 }
162 return 0;
163 }
164};
165
166void testLmder1()
167{
168 int n=3, info;
169
170 VectorXd x;
171
172 /* the following starting values provide a rough fit. */
173 x.setConstant(n, 1.);
174
175 // do the computation
176 lmder_functor functor;
177 LevenbergMarquardt<lmder_functor> lm(functor);
178 info = lm.lmder1(x);
179
180 // check return value
181 VERIFY_IS_EQUAL(info, 1);
182 VERIFY_IS_EQUAL(lm.nfev, 6);
183 VERIFY_IS_EQUAL(lm.njev, 5);
184
185 // check norm
186 VERIFY_IS_APPROX(lm.fvec.blueNorm(), 0.09063596);
187
188 // check x
189 VectorXd x_ref(n);
190 x_ref << 0.08241058, 1.133037, 2.343695;
191 VERIFY_IS_APPROX(x, x_ref);
192}
193
194void testLmder()
195{
196 const int m=15, n=3;
197 int info;
198 double fnorm, covfac;
199 VectorXd x;
200
201 /* the following starting values provide a rough fit. */
202 x.setConstant(n, 1.);
203
204 // do the computation
205 lmder_functor functor;
206 LevenbergMarquardt<lmder_functor> lm(functor);
207 info = lm.minimize(x);
208
209 // check return values
210 VERIFY_IS_EQUAL(info, 1);
211 VERIFY_IS_EQUAL(lm.nfev, 6);
212 VERIFY_IS_EQUAL(lm.njev, 5);
213
214 // check norm
215 fnorm = lm.fvec.blueNorm();
216 VERIFY_IS_APPROX(fnorm, 0.09063596);
217
218 // check x
219 VectorXd x_ref(n);
220 x_ref << 0.08241058, 1.133037, 2.343695;
221 VERIFY_IS_APPROX(x, x_ref);
222
223 // check covariance
224 covfac = fnorm*fnorm/(m-n);
225 internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm
226
227 MatrixXd cov_ref(n,n);
228 cov_ref <<
229 0.0001531202, 0.002869941, -0.002656662,
230 0.002869941, 0.09480935, -0.09098995,
231 -0.002656662, -0.09098995, 0.08778727;
232
233// std::cout << fjac*covfac << std::endl;
234
235 MatrixXd cov;
236 cov = covfac*lm.fjac.topLeftCorner<n,n>();
237 VERIFY_IS_APPROX( cov, cov_ref);
238 // TODO: why isn't this allowed ? :
239 // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);
240}
241
242struct hybrj_functor : Functor<double>
243{
244 hybrj_functor(void) : Functor<double>(9,9) {}
245
246 int operator()(const VectorXd &x, VectorXd &fvec)
247 {
248 double temp, temp1, temp2;
249 const int n = x.size();
250 assert(fvec.size()==n);
251 for (int k = 0; k < n; k++)
252 {
253 temp = (3. - 2.*x[k])*x[k];
254 temp1 = 0.;
255 if (k) temp1 = x[k-1];
256 temp2 = 0.;
257 if (k != n-1) temp2 = x[k+1];
258 fvec[k] = temp - temp1 - 2.*temp2 + 1.;
259 }
260 return 0;
261 }
262 int df(const VectorXd &x, MatrixXd &fjac)
263 {
264 const int n = x.size();
265 assert(fjac.rows()==n);
266 assert(fjac.cols()==n);
267 for (int k = 0; k < n; k++)
268 {
269 for (int j = 0; j < n; j++)
270 fjac(k,j) = 0.;
271 fjac(k,k) = 3.- 4.*x[k];
272 if (k) fjac(k,k-1) = -1.;
273 if (k != n-1) fjac(k,k+1) = -2.;
274 }
275 return 0;
276 }
277};
278
279
280void testHybrj1()
281{
282 const int n=9;
283 int info;
284 VectorXd x(n);
285
286 /* the following starting values provide a rough fit. */
287 x.setConstant(n, -1.);
288
289 // do the computation
290 hybrj_functor functor;
291 HybridNonLinearSolver<hybrj_functor> solver(functor);
292 info = solver.hybrj1(x);
293
294 // check return value
295 VERIFY_IS_EQUAL(info, 1);
296 VERIFY_IS_EQUAL(solver.nfev, 11);
297 VERIFY_IS_EQUAL(solver.njev, 1);
298
299 // check norm
300 VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);
301
302
303// check x
304 VectorXd x_ref(n);
305 x_ref <<
306 -0.5706545, -0.6816283, -0.7017325,
307 -0.7042129, -0.701369, -0.6918656,
308 -0.665792, -0.5960342, -0.4164121;
309 VERIFY_IS_APPROX(x, x_ref);
310}
311
312void testHybrj()
313{
314 const int n=9;
315 int info;
316 VectorXd x(n);
317
318 /* the following starting values provide a rough fit. */
319 x.setConstant(n, -1.);
320
321
322 // do the computation
323 hybrj_functor functor;
324 HybridNonLinearSolver<hybrj_functor> solver(functor);
325 solver.diag.setConstant(n, 1.);
326 solver.useExternalScaling = true;
327 info = solver.solve(x);
328
329 // check return value
330 VERIFY_IS_EQUAL(info, 1);
331 VERIFY_IS_EQUAL(solver.nfev, 11);
332 VERIFY_IS_EQUAL(solver.njev, 1);
333
334 // check norm
335 VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);
336
337
338// check x
339 VectorXd x_ref(n);
340 x_ref <<
341 -0.5706545, -0.6816283, -0.7017325,
342 -0.7042129, -0.701369, -0.6918656,
343 -0.665792, -0.5960342, -0.4164121;
344 VERIFY_IS_APPROX(x, x_ref);
345
346}
347
348struct hybrd_functor : Functor<double>
349{
350 hybrd_functor(void) : Functor<double>(9,9) {}
351 int operator()(const VectorXd &x, VectorXd &fvec) const
352 {
353 double temp, temp1, temp2;
354 const int n = x.size();
355
356 assert(fvec.size()==n);
357 for (int k=0; k < n; k++)
358 {
359 temp = (3. - 2.*x[k])*x[k];
360 temp1 = 0.;
361 if (k) temp1 = x[k-1];
362 temp2 = 0.;
363 if (k != n-1) temp2 = x[k+1];
364 fvec[k] = temp - temp1 - 2.*temp2 + 1.;
365 }
366 return 0;
367 }
368};
369
370void testHybrd1()
371{
372 int n=9, info;
373 VectorXd x(n);
374
375 /* the following starting values provide a rough solution. */
376 x.setConstant(n, -1.);
377
378 // do the computation
379 hybrd_functor functor;
380 HybridNonLinearSolver<hybrd_functor> solver(functor);
381 info = solver.hybrd1(x);
382
383 // check return value
384 VERIFY_IS_EQUAL(info, 1);
385 VERIFY_IS_EQUAL(solver.nfev, 20);
386
387 // check norm
388 VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);
389
390 // check x
391 VectorXd x_ref(n);
392 x_ref << -0.5706545, -0.6816283, -0.7017325, -0.7042129, -0.701369, -0.6918656, -0.665792, -0.5960342, -0.4164121;
393 VERIFY_IS_APPROX(x, x_ref);
394}
395
396void testHybrd()
397{
398 const int n=9;
399 int info;
400 VectorXd x;
401
402 /* the following starting values provide a rough fit. */
403 x.setConstant(n, -1.);
404
405 // do the computation
406 hybrd_functor functor;
407 HybridNonLinearSolver<hybrd_functor> solver(functor);
408 solver.parameters.nb_of_subdiagonals = 1;
409 solver.parameters.nb_of_superdiagonals = 1;
410 solver.diag.setConstant(n, 1.);
411 solver.useExternalScaling = true;
412 info = solver.solveNumericalDiff(x);
413
414 // check return value
415 VERIFY_IS_EQUAL(info, 1);
416 VERIFY_IS_EQUAL(solver.nfev, 14);
417
418 // check norm
419 VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);
420
421 // check x
422 VectorXd x_ref(n);
423 x_ref <<
424 -0.5706545, -0.6816283, -0.7017325,
425 -0.7042129, -0.701369, -0.6918656,
426 -0.665792, -0.5960342, -0.4164121;
427 VERIFY_IS_APPROX(x, x_ref);
428}
429
430struct lmstr_functor : Functor<double>
431{
432 lmstr_functor(void) : Functor<double>(3,15) {}
433 int operator()(const VectorXd &x, VectorXd &fvec)
434 {
435 /* subroutine fcn for lmstr1 example. */
436 double tmp1, tmp2, tmp3;
437 static const double y[15]={1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,
438 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};
439
440 assert(15==fvec.size());
441 assert(3==x.size());
442
443 for (int i=0; i<15; i++)
444 {
445 tmp1 = i+1;
446 tmp2 = 16 - i - 1;
447 tmp3 = (i>=8)? tmp2 : tmp1;
448 fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
449 }
450 return 0;
451 }
452 int df(const VectorXd &x, VectorXd &jac_row, VectorXd::Index rownb)
453 {
454 assert(x.size()==3);
455 assert(jac_row.size()==x.size());
456 double tmp1, tmp2, tmp3, tmp4;
457
458 int i = rownb-2;
459 tmp1 = i+1;
460 tmp2 = 16 - i - 1;
461 tmp3 = (i>=8)? tmp2 : tmp1;
462 tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4 = tmp4*tmp4;
463 jac_row[0] = -1;
464 jac_row[1] = tmp1*tmp2/tmp4;
465 jac_row[2] = tmp1*tmp3/tmp4;
466 return 0;
467 }
468};
469
470void testLmstr1()
471{
472 const int n=3;
473 int info;
474
475 VectorXd x(n);
476
477 /* the following starting values provide a rough fit. */
478 x.setConstant(n, 1.);
479
480 // do the computation
481 lmstr_functor functor;
482 LevenbergMarquardt<lmstr_functor> lm(functor);
483 info = lm.lmstr1(x);
484
485 // check return value
486 VERIFY_IS_EQUAL(info, 1);
487 VERIFY_IS_EQUAL(lm.nfev, 6);
488 VERIFY_IS_EQUAL(lm.njev, 5);
489
490 // check norm
491 VERIFY_IS_APPROX(lm.fvec.blueNorm(), 0.09063596);
492
493 // check x
494 VectorXd x_ref(n);
495 x_ref << 0.08241058, 1.133037, 2.343695 ;
496 VERIFY_IS_APPROX(x, x_ref);
497}
498
499void testLmstr()
500{
501 const int n=3;
502 int info;
503 double fnorm;
504 VectorXd x(n);
505
506 /* the following starting values provide a rough fit. */
507 x.setConstant(n, 1.);
508
509 // do the computation
510 lmstr_functor functor;
511 LevenbergMarquardt<lmstr_functor> lm(functor);
512 info = lm.minimizeOptimumStorage(x);
513
514 // check return values
515 VERIFY_IS_EQUAL(info, 1);
516 VERIFY_IS_EQUAL(lm.nfev, 6);
517 VERIFY_IS_EQUAL(lm.njev, 5);
518
519 // check norm
520 fnorm = lm.fvec.blueNorm();
521 VERIFY_IS_APPROX(fnorm, 0.09063596);
522
523 // check x
524 VectorXd x_ref(n);
525 x_ref << 0.08241058, 1.133037, 2.343695;
526 VERIFY_IS_APPROX(x, x_ref);
527
528}
529
530struct lmdif_functor : Functor<double>
531{
532 lmdif_functor(void) : Functor<double>(3,15) {}
533 int operator()(const VectorXd &x, VectorXd &fvec) const
534 {
535 int i;
536 double tmp1,tmp2,tmp3;
537 static const double y[15]={1.4e-1,1.8e-1,2.2e-1,2.5e-1,2.9e-1,3.2e-1,3.5e-1,3.9e-1,
538 3.7e-1,5.8e-1,7.3e-1,9.6e-1,1.34e0,2.1e0,4.39e0};
539
540 assert(x.size()==3);
541 assert(fvec.size()==15);
542 for (i=0; i<15; i++)
543 {
544 tmp1 = i+1;
545 tmp2 = 15 - i;
546 tmp3 = tmp1;
547
548 if (i >= 8) tmp3 = tmp2;
549 fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
550 }
551 return 0;
552 }
553};
554
555void testLmdif1()
556{
557 const int n=3;
558 int info;
559
560 VectorXd x(n), fvec(15);
561
562 /* the following starting values provide a rough fit. */
563 x.setConstant(n, 1.);
564
565 // do the computation
566 lmdif_functor functor;
567 DenseIndex nfev;
568 info = LevenbergMarquardt<lmdif_functor>::lmdif1(functor, x, &nfev);
569
570 // check return value
571 VERIFY_IS_EQUAL(info, 1);
572 VERIFY_IS_EQUAL(nfev, 26);
573
574 // check norm
575 functor(x, fvec);
576 VERIFY_IS_APPROX(fvec.blueNorm(), 0.09063596);
577
578 // check x
579 VectorXd x_ref(n);
580 x_ref << 0.0824106, 1.1330366, 2.3436947;
581 VERIFY_IS_APPROX(x, x_ref);
582
583}
584
585void testLmdif()
586{
587 const int m=15, n=3;
588 int info;
589 double fnorm, covfac;
590 VectorXd x(n);
591
592 /* the following starting values provide a rough fit. */
593 x.setConstant(n, 1.);
594
595 // do the computation
596 lmdif_functor functor;
597 NumericalDiff<lmdif_functor> numDiff(functor);
598 LevenbergMarquardt<NumericalDiff<lmdif_functor> > lm(numDiff);
599 info = lm.minimize(x);
600
601 // check return values
602 VERIFY_IS_EQUAL(info, 1);
603 VERIFY_IS_EQUAL(lm.nfev, 26);
604
605 // check norm
606 fnorm = lm.fvec.blueNorm();
607 VERIFY_IS_APPROX(fnorm, 0.09063596);
608
609 // check x
610 VectorXd x_ref(n);
611 x_ref << 0.08241058, 1.133037, 2.343695;
612 VERIFY_IS_APPROX(x, x_ref);
613
614 // check covariance
615 covfac = fnorm*fnorm/(m-n);
616 internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm
617
618 MatrixXd cov_ref(n,n);
619 cov_ref <<
620 0.0001531202, 0.002869942, -0.002656662,
621 0.002869942, 0.09480937, -0.09098997,
622 -0.002656662, -0.09098997, 0.08778729;
623
624// std::cout << fjac*covfac << std::endl;
625
626 MatrixXd cov;
627 cov = covfac*lm.fjac.topLeftCorner<n,n>();
628 VERIFY_IS_APPROX( cov, cov_ref);
629 // TODO: why isn't this allowed ? :
630 // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);
631}
632
633struct chwirut2_functor : Functor<double>
634{
635 chwirut2_functor(void) : Functor<double>(3,54) {}
636 static const double m_x[54];
637 static const double m_y[54];
638 int operator()(const VectorXd &b, VectorXd &fvec)
639 {
640 int i;
641
642 assert(b.size()==3);
643 assert(fvec.size()==54);
644 for(i=0; i<54; i++) {
645 double x = m_x[i];
646 fvec[i] = exp(-b[0]*x)/(b[1]+b[2]*x) - m_y[i];
647 }
648 return 0;
649 }
650 int df(const VectorXd &b, MatrixXd &fjac)
651 {
652 assert(b.size()==3);
653 assert(fjac.rows()==54);
654 assert(fjac.cols()==3);
655 for(int i=0; i<54; i++) {
656 double x = m_x[i];
657 double factor = 1./(b[1]+b[2]*x);
658 double e = exp(-b[0]*x);
659 fjac(i,0) = -x*e*factor;
660 fjac(i,1) = -e*factor*factor;
661 fjac(i,2) = -x*e*factor*factor;
662 }
663 return 0;
664 }
665};
666const double chwirut2_functor::m_x[54] = { 0.500E0, 1.000E0, 1.750E0, 3.750E0, 5.750E0, 0.875E0, 2.250E0, 3.250E0, 5.250E0, 0.750E0, 1.750E0, 2.750E0, 4.750E0, 0.625E0, 1.250E0, 2.250E0, 4.250E0, .500E0, 3.000E0, .750E0, 3.000E0, 1.500E0, 6.000E0, 3.000E0, 6.000E0, 1.500E0, 3.000E0, .500E0, 2.000E0, 4.000E0, .750E0, 2.000E0, 5.000E0, .750E0, 2.250E0, 3.750E0, 5.750E0, 3.000E0, .750E0, 2.500E0, 4.000E0, .750E0, 2.500E0, 4.000E0, .750E0, 2.500E0, 4.000E0, .500E0, 6.000E0, 3.000E0, .500E0, 2.750E0, .500E0, 1.750E0};
667const double chwirut2_functor::m_y[54] = { 92.9000E0 ,57.1000E0 ,31.0500E0 ,11.5875E0 ,8.0250E0 ,63.6000E0 ,21.4000E0 ,14.2500E0 ,8.4750E0 ,63.8000E0 ,26.8000E0 ,16.4625E0 ,7.1250E0 ,67.3000E0 ,41.0000E0 ,21.1500E0 ,8.1750E0 ,81.5000E0 ,13.1200E0 ,59.9000E0 ,14.6200E0 ,32.9000E0 ,5.4400E0 ,12.5600E0 ,5.4400E0 ,32.0000E0 ,13.9500E0 ,75.8000E0 ,20.0000E0 ,10.4200E0 ,59.5000E0 ,21.6700E0 ,8.5500E0 ,62.0000E0 ,20.2000E0 ,7.7600E0 ,3.7500E0 ,11.8100E0 ,54.7000E0 ,23.7000E0 ,11.5500E0 ,61.3000E0 ,17.7000E0 ,8.7400E0 ,59.2000E0 ,16.3000E0 ,8.6200E0 ,81.0000E0 ,4.8700E0 ,14.6200E0 ,81.7000E0 ,17.1700E0 ,81.3000E0 ,28.9000E0 };
668
669// http://www.itl.nist.gov/div898/strd/nls/data/chwirut2.shtml
670void testNistChwirut2(void)
671{
672 const int n=3;
673 int info;
674
675 VectorXd x(n);
676
677 /*
678 * First try
679 */
680 x<< 0.1, 0.01, 0.02;
681 // do the computation
682 chwirut2_functor functor;
683 LevenbergMarquardt<chwirut2_functor> lm(functor);
684 info = lm.minimize(x);
685
686 // check return value
687 VERIFY_IS_EQUAL(info, 1);
688 VERIFY_IS_EQUAL(lm.nfev, 10);
689 VERIFY_IS_EQUAL(lm.njev, 8);
690 // check norm^2
691 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.1304802941E+02);
692 // check x
693 VERIFY_IS_APPROX(x[0], 1.6657666537E-01);
694 VERIFY_IS_APPROX(x[1], 5.1653291286E-03);
695 VERIFY_IS_APPROX(x[2], 1.2150007096E-02);
696
697 /*
698 * Second try
699 */
700 x<< 0.15, 0.008, 0.010;
701 // do the computation
702 lm.resetParameters();
703 lm.parameters.ftol = 1.E6*NumTraits<double>::epsilon();
704 lm.parameters.xtol = 1.E6*NumTraits<double>::epsilon();
705 info = lm.minimize(x);
706
707 // check return value
708 VERIFY_IS_EQUAL(info, 1);
709 VERIFY_IS_EQUAL(lm.nfev, 7);
710 VERIFY_IS_EQUAL(lm.njev, 6);
711 // check norm^2
712 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.1304802941E+02);
713 // check x
714 VERIFY_IS_APPROX(x[0], 1.6657666537E-01);
715 VERIFY_IS_APPROX(x[1], 5.1653291286E-03);
716 VERIFY_IS_APPROX(x[2], 1.2150007096E-02);
717}
718
719
720struct misra1a_functor : Functor<double>
721{
722 misra1a_functor(void) : Functor<double>(2,14) {}
723 static const double m_x[14];
724 static const double m_y[14];
725 int operator()(const VectorXd &b, VectorXd &fvec)
726 {
727 assert(b.size()==2);
728 assert(fvec.size()==14);
729 for(int i=0; i<14; i++) {
730 fvec[i] = b[0]*(1.-exp(-b[1]*m_x[i])) - m_y[i] ;
731 }
732 return 0;
733 }
734 int df(const VectorXd &b, MatrixXd &fjac)
735 {
736 assert(b.size()==2);
737 assert(fjac.rows()==14);
738 assert(fjac.cols()==2);
739 for(int i=0; i<14; i++) {
740 fjac(i,0) = (1.-exp(-b[1]*m_x[i]));
741 fjac(i,1) = (b[0]*m_x[i]*exp(-b[1]*m_x[i]));
742 }
743 return 0;
744 }
745};
746const double misra1a_functor::m_x[14] = { 77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0};
747const double misra1a_functor::m_y[14] = { 10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0};
748
749// http://www.itl.nist.gov/div898/strd/nls/data/misra1a.shtml
750void testNistMisra1a(void)
751{
752 const int n=2;
753 int info;
754
755 VectorXd x(n);
756
757 /*
758 * First try
759 */
760 x<< 500., 0.0001;
761 // do the computation
762 misra1a_functor functor;
763 LevenbergMarquardt<misra1a_functor> lm(functor);
764 info = lm.minimize(x);
765
766 // check return value
767 VERIFY_IS_EQUAL(info, 1);
768 VERIFY_IS_EQUAL(lm.nfev, 19);
769 VERIFY_IS_EQUAL(lm.njev, 15);
770 // check norm^2
771 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.2455138894E-01);
772 // check x
773 VERIFY_IS_APPROX(x[0], 2.3894212918E+02);
774 VERIFY_IS_APPROX(x[1], 5.5015643181E-04);
775
776 /*
777 * Second try
778 */
779 x<< 250., 0.0005;
780 // do the computation
781 info = lm.minimize(x);
782
783 // check return value
784 VERIFY_IS_EQUAL(info, 1);
785 VERIFY_IS_EQUAL(lm.nfev, 5);
786 VERIFY_IS_EQUAL(lm.njev, 4);
787 // check norm^2
788 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.2455138894E-01);
789 // check x
790 VERIFY_IS_APPROX(x[0], 2.3894212918E+02);
791 VERIFY_IS_APPROX(x[1], 5.5015643181E-04);
792}
793
794struct hahn1_functor : Functor<double>
795{
796 hahn1_functor(void) : Functor<double>(7,236) {}
797 static const double m_x[236];
798 int operator()(const VectorXd &b, VectorXd &fvec)
799 {
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -0700800 static const double m_y[236] = { .591E0 , 1.547E0 , 2.902E0 , 2.894E0 , 4.703E0 , 6.307E0 , 7.03E0 , 7.898E0 , 9.470E0 , 9.484E0 , 10.072E0 , 10.163E0 , 11.615E0 , 12.005E0 , 12.478E0 , 12.982E0 , 12.970E0 , 13.926E0 , 14.452E0 , 14.404E0 , 15.190E0 , 15.550E0 , 15.528E0 , 15.499E0 , 16.131E0 , 16.438E0 , 16.387E0 , 16.549E0 , 16.872E0 , 16.830E0 , 16.926E0 , 16.907E0 , 16.966E0 , 17.060E0 , 17.122E0 , 17.311E0 , 17.355E0 , 17.668E0 , 17.767E0 , 17.803E0 , 17.765E0 , 17.768E0 , 17.736E0 , 17.858E0 , 17.877E0 , 17.912E0 , 18.046E0 , 18.085E0 , 18.291E0 , 18.357E0 , 18.426E0 , 18.584E0 , 18.610E0 , 18.870E0 , 18.795E0 , 19.111E0 , .367E0 , .796E0 , 0.892E0 , 1.903E0 , 2.150E0 , 3.697E0 , 5.870E0 , 6.421E0 , 7.422E0 , 9.944E0 , 11.023E0 , 11.87E0 , 12.786E0 , 14.067E0 , 13.974E0 , 14.462E0 , 14.464E0 , 15.381E0 , 15.483E0 , 15.59E0 , 16.075E0 , 16.347E0 , 16.181E0 , 16.915E0 , 17.003E0 , 16.978E0 , 17.756E0 , 17.808E0 , 17.868E0 , 18.481E0 , 18.486E0 , 19.090E0 , 16.062E0 , 16.337E0 , 16.345E0 ,
801 16.388E0 , 17.159E0 , 17.116E0 , 17.164E0 , 17.123E0 , 17.979E0 , 17.974E0 , 18.007E0 , 17.993E0 , 18.523E0 , 18.669E0 , 18.617E0 , 19.371E0 , 19.330E0 , 0.080E0 , 0.248E0 , 1.089E0 , 1.418E0 , 2.278E0 , 3.624E0 , 4.574E0 , 5.556E0 , 7.267E0 , 7.695E0 , 9.136E0 , 9.959E0 , 9.957E0 , 11.600E0 , 13.138E0 , 13.564E0 , 13.871E0 , 13.994E0 , 14.947E0 , 15.473E0 , 15.379E0 , 15.455E0 , 15.908E0 , 16.114E0 , 17.071E0 , 17.135E0 , 17.282E0 , 17.368E0 , 17.483E0 , 17.764E0 , 18.185E0 , 18.271E0 , 18.236E0 , 18.237E0 , 18.523E0 , 18.627E0 , 18.665E0 , 19.086E0 , 0.214E0 , 0.943E0 , 1.429E0 , 2.241E0 , 2.951E0 , 3.782E0 , 4.757E0 , 5.602E0 , 7.169E0 , 8.920E0 , 10.055E0 , 12.035E0 , 12.861E0 , 13.436E0 , 14.167E0 , 14.755E0 , 15.168E0 , 15.651E0 , 15.746E0 , 16.216E0 , 16.445E0 , 16.965E0 , 17.121E0 , 17.206E0 , 17.250E0 , 17.339E0 , 17.793E0 , 18.123E0 , 18.49E0 , 18.566E0 , 18.645E0 , 18.706E0 , 18.924E0 , 19.1E0 , 0.375E0 , 0.471E0 , 1.504E0 , 2.204E0 , 2.813E0 , 4.765E0 , 9.835E0 , 10.040E0 , 11.946E0 , 12.596E0 ,
80213.303E0 , 13.922E0 , 14.440E0 , 14.951E0 , 15.627E0 , 15.639E0 , 15.814E0 , 16.315E0 , 16.334E0 , 16.430E0 , 16.423E0 , 17.024E0 , 17.009E0 , 17.165E0 , 17.134E0 , 17.349E0 , 17.576E0 , 17.848E0 , 18.090E0 , 18.276E0 , 18.404E0 , 18.519E0 , 19.133E0 , 19.074E0 , 19.239E0 , 19.280E0 , 19.101E0 , 19.398E0 , 19.252E0 , 19.89E0 , 20.007E0 , 19.929E0 , 19.268E0 , 19.324E0 , 20.049E0 , 20.107E0 , 20.062E0 , 20.065E0 , 19.286E0 , 19.972E0 , 20.088E0 , 20.743E0 , 20.83E0 , 20.935E0 , 21.035E0 , 20.93E0 , 21.074E0 , 21.085E0 , 20.935E0 };
Narayan Kamathc981c482012-11-02 10:59:05 +0000803
804 // int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;
805
806 assert(b.size()==7);
807 assert(fvec.size()==236);
808 for(int i=0; i<236; i++) {
809 double x=m_x[i], xx=x*x, xxx=xx*x;
810 fvec[i] = (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) / (1.+b[4]*x+b[5]*xx+b[6]*xxx) - m_y[i];
811 }
812 return 0;
813 }
814
815 int df(const VectorXd &b, MatrixXd &fjac)
816 {
817 assert(b.size()==7);
818 assert(fjac.rows()==236);
819 assert(fjac.cols()==7);
820 for(int i=0; i<236; i++) {
821 double x=m_x[i], xx=x*x, xxx=xx*x;
822 double fact = 1./(1.+b[4]*x+b[5]*xx+b[6]*xxx);
823 fjac(i,0) = 1.*fact;
824 fjac(i,1) = x*fact;
825 fjac(i,2) = xx*fact;
826 fjac(i,3) = xxx*fact;
827 fact = - (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) * fact * fact;
828 fjac(i,4) = x*fact;
829 fjac(i,5) = xx*fact;
830 fjac(i,6) = xxx*fact;
831 }
832 return 0;
833 }
834};
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -0700835const double hahn1_functor::m_x[236] = { 24.41E0 , 34.82E0 , 44.09E0 , 45.07E0 , 54.98E0 , 65.51E0 , 70.53E0 , 75.70E0 , 89.57E0 , 91.14E0 , 96.40E0 , 97.19E0 , 114.26E0 , 120.25E0 , 127.08E0 , 133.55E0 , 133.61E0 , 158.67E0 , 172.74E0 , 171.31E0 , 202.14E0 , 220.55E0 , 221.05E0 , 221.39E0 , 250.99E0 , 268.99E0 , 271.80E0 , 271.97E0 , 321.31E0 , 321.69E0 , 330.14E0 , 333.03E0 , 333.47E0 , 340.77E0 , 345.65E0 , 373.11E0 , 373.79E0 , 411.82E0 , 419.51E0 , 421.59E0 , 422.02E0 , 422.47E0 , 422.61E0 , 441.75E0 , 447.41E0 , 448.7E0 , 472.89E0 , 476.69E0 , 522.47E0 , 522.62E0 , 524.43E0 , 546.75E0 , 549.53E0 , 575.29E0 , 576.00E0 , 625.55E0 , 20.15E0 , 28.78E0 , 29.57E0 , 37.41E0 , 39.12E0 , 50.24E0 , 61.38E0 , 66.25E0 , 73.42E0 , 95.52E0 , 107.32E0 , 122.04E0 , 134.03E0 , 163.19E0 , 163.48E0 , 175.70E0 , 179.86E0 , 211.27E0 , 217.78E0 , 219.14E0 , 262.52E0 , 268.01E0 , 268.62E0 , 336.25E0 , 337.23E0 , 339.33E0 , 427.38E0 , 428.58E0 , 432.68E0 , 528.99E0 , 531.08E0 , 628.34E0 , 253.24E0 , 273.13E0 , 273.66E0 ,
836282.10E0 , 346.62E0 , 347.19E0 , 348.78E0 , 351.18E0 , 450.10E0 , 450.35E0 , 451.92E0 , 455.56E0 , 552.22E0 , 553.56E0 , 555.74E0 , 652.59E0 , 656.20E0 , 14.13E0 , 20.41E0 , 31.30E0 , 33.84E0 , 39.70E0 , 48.83E0 , 54.50E0 , 60.41E0 , 72.77E0 , 75.25E0 , 86.84E0 , 94.88E0 , 96.40E0 , 117.37E0 , 139.08E0 , 147.73E0 , 158.63E0 , 161.84E0 , 192.11E0 , 206.76E0 , 209.07E0 , 213.32E0 , 226.44E0 , 237.12E0 , 330.90E0 , 358.72E0 , 370.77E0 , 372.72E0 , 396.24E0 , 416.59E0 , 484.02E0 , 495.47E0 , 514.78E0 , 515.65E0 , 519.47E0 , 544.47E0 , 560.11E0 , 620.77E0 , 18.97E0 , 28.93E0 , 33.91E0 , 40.03E0 , 44.66E0 , 49.87E0 , 55.16E0 , 60.90E0 , 72.08E0 , 85.15E0 , 97.06E0 , 119.63E0 , 133.27E0 , 143.84E0 , 161.91E0 , 180.67E0 , 198.44E0 , 226.86E0 , 229.65E0 , 258.27E0 , 273.77E0 , 339.15E0 , 350.13E0 , 362.75E0 , 371.03E0 , 393.32E0 , 448.53E0 , 473.78E0 , 511.12E0 , 524.70E0 , 548.75E0 , 551.64E0 , 574.02E0 , 623.86E0 , 21.46E0 , 24.33E0 , 33.43E0 , 39.22E0 , 44.18E0 , 55.02E0 , 94.33E0 , 96.44E0 , 118.82E0 , 128.48E0 ,
837141.94E0 , 156.92E0 , 171.65E0 , 190.00E0 , 223.26E0 , 223.88E0 , 231.50E0 , 265.05E0 , 269.44E0 , 271.78E0 , 273.46E0 , 334.61E0 , 339.79E0 , 349.52E0 , 358.18E0 , 377.98E0 , 394.77E0 , 429.66E0 , 468.22E0 , 487.27E0 , 519.54E0 , 523.03E0 , 612.99E0 , 638.59E0 , 641.36E0 , 622.05E0 , 631.50E0 , 663.97E0 , 646.9E0 , 748.29E0 , 749.21E0 , 750.14E0 , 647.04E0 , 646.89E0 , 746.9E0 , 748.43E0 , 747.35E0 , 749.27E0 , 647.61E0 , 747.78E0 , 750.51E0 , 851.37E0 , 845.97E0 , 847.54E0 , 849.93E0 , 851.61E0 , 849.75E0 , 850.98E0 , 848.23E0};
Narayan Kamathc981c482012-11-02 10:59:05 +0000838
839// http://www.itl.nist.gov/div898/strd/nls/data/hahn1.shtml
840void testNistHahn1(void)
841{
842 const int n=7;
843 int info;
844
845 VectorXd x(n);
846
847 /*
848 * First try
849 */
850 x<< 10., -1., .05, -.00001, -.05, .001, -.000001;
851 // do the computation
852 hahn1_functor functor;
853 LevenbergMarquardt<hahn1_functor> lm(functor);
854 info = lm.minimize(x);
855
856 // check return value
857 VERIFY_IS_EQUAL(info, 1);
858 VERIFY_IS_EQUAL(lm.nfev, 11);
859 VERIFY_IS_EQUAL(lm.njev, 10);
860 // check norm^2
861 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.5324382854E+00);
862 // check x
863 VERIFY_IS_APPROX(x[0], 1.0776351733E+00);
864 VERIFY_IS_APPROX(x[1],-1.2269296921E-01);
865 VERIFY_IS_APPROX(x[2], 4.0863750610E-03);
866 VERIFY_IS_APPROX(x[3],-1.426264e-06); // shoulde be : -1.4262662514E-06
867 VERIFY_IS_APPROX(x[4],-5.7609940901E-03);
868 VERIFY_IS_APPROX(x[5], 2.4053735503E-04);
869 VERIFY_IS_APPROX(x[6],-1.2314450199E-07);
870
871 /*
872 * Second try
873 */
874 x<< .1, -.1, .005, -.000001, -.005, .0001, -.0000001;
875 // do the computation
876 info = lm.minimize(x);
877
878 // check return value
879 VERIFY_IS_EQUAL(info, 1);
880 VERIFY_IS_EQUAL(lm.nfev, 11);
881 VERIFY_IS_EQUAL(lm.njev, 10);
882 // check norm^2
883 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.5324382854E+00);
884 // check x
885 VERIFY_IS_APPROX(x[0], 1.077640); // should be : 1.0776351733E+00
886 VERIFY_IS_APPROX(x[1], -0.1226933); // should be : -1.2269296921E-01
887 VERIFY_IS_APPROX(x[2], 0.004086383); // should be : 4.0863750610E-03
888 VERIFY_IS_APPROX(x[3], -1.426277e-06); // shoulde be : -1.4262662514E-06
889 VERIFY_IS_APPROX(x[4],-5.7609940901E-03);
890 VERIFY_IS_APPROX(x[5], 0.00024053772); // should be : 2.4053735503E-04
891 VERIFY_IS_APPROX(x[6], -1.231450e-07); // should be : -1.2314450199E-07
892
893}
894
895struct misra1d_functor : Functor<double>
896{
897 misra1d_functor(void) : Functor<double>(2,14) {}
898 static const double x[14];
899 static const double y[14];
900 int operator()(const VectorXd &b, VectorXd &fvec)
901 {
902 assert(b.size()==2);
903 assert(fvec.size()==14);
904 for(int i=0; i<14; i++) {
905 fvec[i] = b[0]*b[1]*x[i]/(1.+b[1]*x[i]) - y[i];
906 }
907 return 0;
908 }
909 int df(const VectorXd &b, MatrixXd &fjac)
910 {
911 assert(b.size()==2);
912 assert(fjac.rows()==14);
913 assert(fjac.cols()==2);
914 for(int i=0; i<14; i++) {
915 double den = 1.+b[1]*x[i];
916 fjac(i,0) = b[1]*x[i] / den;
917 fjac(i,1) = b[0]*x[i]*(den-b[1]*x[i])/den/den;
918 }
919 return 0;
920 }
921};
922const double misra1d_functor::x[14] = { 77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0};
923const double misra1d_functor::y[14] = { 10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0};
924
925// http://www.itl.nist.gov/div898/strd/nls/data/misra1d.shtml
926void testNistMisra1d(void)
927{
928 const int n=2;
929 int info;
930
931 VectorXd x(n);
932
933 /*
934 * First try
935 */
936 x<< 500., 0.0001;
937 // do the computation
938 misra1d_functor functor;
939 LevenbergMarquardt<misra1d_functor> lm(functor);
940 info = lm.minimize(x);
941
942 // check return value
943 VERIFY_IS_EQUAL(info, 3);
944 VERIFY_IS_EQUAL(lm.nfev, 9);
945 VERIFY_IS_EQUAL(lm.njev, 7);
946 // check norm^2
947 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6419295283E-02);
948 // check x
949 VERIFY_IS_APPROX(x[0], 4.3736970754E+02);
950 VERIFY_IS_APPROX(x[1], 3.0227324449E-04);
951
952 /*
953 * Second try
954 */
955 x<< 450., 0.0003;
956 // do the computation
957 info = lm.minimize(x);
958
959 // check return value
960 VERIFY_IS_EQUAL(info, 1);
961 VERIFY_IS_EQUAL(lm.nfev, 4);
962 VERIFY_IS_EQUAL(lm.njev, 3);
963 // check norm^2
964 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6419295283E-02);
965 // check x
966 VERIFY_IS_APPROX(x[0], 4.3736970754E+02);
967 VERIFY_IS_APPROX(x[1], 3.0227324449E-04);
968}
969
970
971struct lanczos1_functor : Functor<double>
972{
973 lanczos1_functor(void) : Functor<double>(6,24) {}
974 static const double x[24];
975 static const double y[24];
976 int operator()(const VectorXd &b, VectorXd &fvec)
977 {
978 assert(b.size()==6);
979 assert(fvec.size()==24);
980 for(int i=0; i<24; i++)
981 fvec[i] = b[0]*exp(-b[1]*x[i]) + b[2]*exp(-b[3]*x[i]) + b[4]*exp(-b[5]*x[i]) - y[i];
982 return 0;
983 }
984 int df(const VectorXd &b, MatrixXd &fjac)
985 {
986 assert(b.size()==6);
987 assert(fjac.rows()==24);
988 assert(fjac.cols()==6);
989 for(int i=0; i<24; i++) {
990 fjac(i,0) = exp(-b[1]*x[i]);
991 fjac(i,1) = -b[0]*x[i]*exp(-b[1]*x[i]);
992 fjac(i,2) = exp(-b[3]*x[i]);
993 fjac(i,3) = -b[2]*x[i]*exp(-b[3]*x[i]);
994 fjac(i,4) = exp(-b[5]*x[i]);
995 fjac(i,5) = -b[4]*x[i]*exp(-b[5]*x[i]);
996 }
997 return 0;
998 }
999};
1000const double lanczos1_functor::x[24] = { 0.000000000000E+00, 5.000000000000E-02, 1.000000000000E-01, 1.500000000000E-01, 2.000000000000E-01, 2.500000000000E-01, 3.000000000000E-01, 3.500000000000E-01, 4.000000000000E-01, 4.500000000000E-01, 5.000000000000E-01, 5.500000000000E-01, 6.000000000000E-01, 6.500000000000E-01, 7.000000000000E-01, 7.500000000000E-01, 8.000000000000E-01, 8.500000000000E-01, 9.000000000000E-01, 9.500000000000E-01, 1.000000000000E+00, 1.050000000000E+00, 1.100000000000E+00, 1.150000000000E+00 };
1001const double lanczos1_functor::y[24] = { 2.513400000000E+00 ,2.044333373291E+00 ,1.668404436564E+00 ,1.366418021208E+00 ,1.123232487372E+00 ,9.268897180037E-01 ,7.679338563728E-01 ,6.388775523106E-01 ,5.337835317402E-01 ,4.479363617347E-01 ,3.775847884350E-01 ,3.197393199326E-01 ,2.720130773746E-01 ,2.324965529032E-01 ,1.996589546065E-01 ,1.722704126914E-01 ,1.493405660168E-01 ,1.300700206922E-01 ,1.138119324644E-01 ,1.000415587559E-01 ,8.833209084540E-02 ,7.833544019350E-02 ,6.976693743449E-02 ,6.239312536719E-02 };
1002
1003// http://www.itl.nist.gov/div898/strd/nls/data/lanczos1.shtml
1004void testNistLanczos1(void)
1005{
1006 const int n=6;
1007 int info;
1008
1009 VectorXd x(n);
1010
1011 /*
1012 * First try
1013 */
1014 x<< 1.2, 0.3, 5.6, 5.5, 6.5, 7.6;
1015 // do the computation
1016 lanczos1_functor functor;
1017 LevenbergMarquardt<lanczos1_functor> lm(functor);
1018 info = lm.minimize(x);
1019
1020 // check return value
1021 VERIFY_IS_EQUAL(info, 2);
1022 VERIFY_IS_EQUAL(lm.nfev, 79);
1023 VERIFY_IS_EQUAL(lm.njev, 72);
1024 // check norm^2
1025 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.430899764097e-25); // should be 1.4307867721E-25, but nist results are on 128-bit floats
1026 // check x
1027 VERIFY_IS_APPROX(x[0], 9.5100000027E-02);
1028 VERIFY_IS_APPROX(x[1], 1.0000000001E+00);
1029 VERIFY_IS_APPROX(x[2], 8.6070000013E-01);
1030 VERIFY_IS_APPROX(x[3], 3.0000000002E+00);
1031 VERIFY_IS_APPROX(x[4], 1.5575999998E+00);
1032 VERIFY_IS_APPROX(x[5], 5.0000000001E+00);
1033
1034 /*
1035 * Second try
1036 */
1037 x<< 0.5, 0.7, 3.6, 4.2, 4., 6.3;
1038 // do the computation
1039 info = lm.minimize(x);
1040
1041 // check return value
1042 VERIFY_IS_EQUAL(info, 2);
1043 VERIFY_IS_EQUAL(lm.nfev, 9);
1044 VERIFY_IS_EQUAL(lm.njev, 8);
1045 // check norm^2
1046 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.428595533845e-25); // should be 1.4307867721E-25, but nist results are on 128-bit floats
1047 // check x
1048 VERIFY_IS_APPROX(x[0], 9.5100000027E-02);
1049 VERIFY_IS_APPROX(x[1], 1.0000000001E+00);
1050 VERIFY_IS_APPROX(x[2], 8.6070000013E-01);
1051 VERIFY_IS_APPROX(x[3], 3.0000000002E+00);
1052 VERIFY_IS_APPROX(x[4], 1.5575999998E+00);
1053 VERIFY_IS_APPROX(x[5], 5.0000000001E+00);
1054
1055}
1056
1057struct rat42_functor : Functor<double>
1058{
1059 rat42_functor(void) : Functor<double>(3,9) {}
1060 static const double x[9];
1061 static const double y[9];
1062 int operator()(const VectorXd &b, VectorXd &fvec)
1063 {
1064 assert(b.size()==3);
1065 assert(fvec.size()==9);
1066 for(int i=0; i<9; i++) {
1067 fvec[i] = b[0] / (1.+exp(b[1]-b[2]*x[i])) - y[i];
1068 }
1069 return 0;
1070 }
1071
1072 int df(const VectorXd &b, MatrixXd &fjac)
1073 {
1074 assert(b.size()==3);
1075 assert(fjac.rows()==9);
1076 assert(fjac.cols()==3);
1077 for(int i=0; i<9; i++) {
1078 double e = exp(b[1]-b[2]*x[i]);
1079 fjac(i,0) = 1./(1.+e);
1080 fjac(i,1) = -b[0]*e/(1.+e)/(1.+e);
1081 fjac(i,2) = +b[0]*e*x[i]/(1.+e)/(1.+e);
1082 }
1083 return 0;
1084 }
1085};
1086const double rat42_functor::x[9] = { 9.000E0, 14.000E0, 21.000E0, 28.000E0, 42.000E0, 57.000E0, 63.000E0, 70.000E0, 79.000E0 };
1087const double rat42_functor::y[9] = { 8.930E0 ,10.800E0 ,18.590E0 ,22.330E0 ,39.350E0 ,56.110E0 ,61.730E0 ,64.620E0 ,67.080E0 };
1088
1089// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky2.shtml
1090void testNistRat42(void)
1091{
1092 const int n=3;
1093 int info;
1094
1095 VectorXd x(n);
1096
1097 /*
1098 * First try
1099 */
1100 x<< 100., 1., 0.1;
1101 // do the computation
1102 rat42_functor functor;
1103 LevenbergMarquardt<rat42_functor> lm(functor);
1104 info = lm.minimize(x);
1105
1106 // check return value
1107 VERIFY_IS_EQUAL(info, 1);
1108 VERIFY_IS_EQUAL(lm.nfev, 10);
1109 VERIFY_IS_EQUAL(lm.njev, 8);
1110 // check norm^2
1111 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.0565229338E+00);
1112 // check x
1113 VERIFY_IS_APPROX(x[0], 7.2462237576E+01);
1114 VERIFY_IS_APPROX(x[1], 2.6180768402E+00);
1115 VERIFY_IS_APPROX(x[2], 6.7359200066E-02);
1116
1117 /*
1118 * Second try
1119 */
1120 x<< 75., 2.5, 0.07;
1121 // do the computation
1122 info = lm.minimize(x);
1123
1124 // check return value
1125 VERIFY_IS_EQUAL(info, 1);
1126 VERIFY_IS_EQUAL(lm.nfev, 6);
1127 VERIFY_IS_EQUAL(lm.njev, 5);
1128 // check norm^2
1129 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.0565229338E+00);
1130 // check x
1131 VERIFY_IS_APPROX(x[0], 7.2462237576E+01);
1132 VERIFY_IS_APPROX(x[1], 2.6180768402E+00);
1133 VERIFY_IS_APPROX(x[2], 6.7359200066E-02);
1134}
1135
1136struct MGH10_functor : Functor<double>
1137{
1138 MGH10_functor(void) : Functor<double>(3,16) {}
1139 static const double x[16];
1140 static const double y[16];
1141 int operator()(const VectorXd &b, VectorXd &fvec)
1142 {
1143 assert(b.size()==3);
1144 assert(fvec.size()==16);
1145 for(int i=0; i<16; i++)
1146 fvec[i] = b[0] * exp(b[1]/(x[i]+b[2])) - y[i];
1147 return 0;
1148 }
1149 int df(const VectorXd &b, MatrixXd &fjac)
1150 {
1151 assert(b.size()==3);
1152 assert(fjac.rows()==16);
1153 assert(fjac.cols()==3);
1154 for(int i=0; i<16; i++) {
1155 double factor = 1./(x[i]+b[2]);
1156 double e = exp(b[1]*factor);
1157 fjac(i,0) = e;
1158 fjac(i,1) = b[0]*factor*e;
1159 fjac(i,2) = -b[1]*b[0]*factor*factor*e;
1160 }
1161 return 0;
1162 }
1163};
1164const double MGH10_functor::x[16] = { 5.000000E+01, 5.500000E+01, 6.000000E+01, 6.500000E+01, 7.000000E+01, 7.500000E+01, 8.000000E+01, 8.500000E+01, 9.000000E+01, 9.500000E+01, 1.000000E+02, 1.050000E+02, 1.100000E+02, 1.150000E+02, 1.200000E+02, 1.250000E+02 };
1165const double MGH10_functor::y[16] = { 3.478000E+04, 2.861000E+04, 2.365000E+04, 1.963000E+04, 1.637000E+04, 1.372000E+04, 1.154000E+04, 9.744000E+03, 8.261000E+03, 7.030000E+03, 6.005000E+03, 5.147000E+03, 4.427000E+03, 3.820000E+03, 3.307000E+03, 2.872000E+03 };
1166
1167// http://www.itl.nist.gov/div898/strd/nls/data/mgh10.shtml
1168void testNistMGH10(void)
1169{
1170 const int n=3;
1171 int info;
1172
1173 VectorXd x(n);
1174
1175 /*
1176 * First try
1177 */
1178 x<< 2., 400000., 25000.;
1179 // do the computation
1180 MGH10_functor functor;
1181 LevenbergMarquardt<MGH10_functor> lm(functor);
1182 info = lm.minimize(x);
1183
1184 // check return value
1185 VERIFY_IS_EQUAL(info, 2);
1186 VERIFY_IS_EQUAL(lm.nfev, 284 );
1187 VERIFY_IS_EQUAL(lm.njev, 249 );
1188 // check norm^2
1189 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7945855171E+01);
1190 // check x
1191 VERIFY_IS_APPROX(x[0], 5.6096364710E-03);
1192 VERIFY_IS_APPROX(x[1], 6.1813463463E+03);
1193 VERIFY_IS_APPROX(x[2], 3.4522363462E+02);
1194
1195 /*
1196 * Second try
1197 */
1198 x<< 0.02, 4000., 250.;
1199 // do the computation
1200 info = lm.minimize(x);
1201
1202 // check return value
1203 VERIFY_IS_EQUAL(info, 3);
1204 VERIFY_IS_EQUAL(lm.nfev, 126);
1205 VERIFY_IS_EQUAL(lm.njev, 116);
1206 // check norm^2
1207 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7945855171E+01);
1208 // check x
1209 VERIFY_IS_APPROX(x[0], 5.6096364710E-03);
1210 VERIFY_IS_APPROX(x[1], 6.1813463463E+03);
1211 VERIFY_IS_APPROX(x[2], 3.4522363462E+02);
1212}
1213
1214
1215struct BoxBOD_functor : Functor<double>
1216{
1217 BoxBOD_functor(void) : Functor<double>(2,6) {}
1218 static const double x[6];
1219 int operator()(const VectorXd &b, VectorXd &fvec)
1220 {
1221 static const double y[6] = { 109., 149., 149., 191., 213., 224. };
1222 assert(b.size()==2);
1223 assert(fvec.size()==6);
1224 for(int i=0; i<6; i++)
1225 fvec[i] = b[0]*(1.-exp(-b[1]*x[i])) - y[i];
1226 return 0;
1227 }
1228 int df(const VectorXd &b, MatrixXd &fjac)
1229 {
1230 assert(b.size()==2);
1231 assert(fjac.rows()==6);
1232 assert(fjac.cols()==2);
1233 for(int i=0; i<6; i++) {
1234 double e = exp(-b[1]*x[i]);
1235 fjac(i,0) = 1.-e;
1236 fjac(i,1) = b[0]*x[i]*e;
1237 }
1238 return 0;
1239 }
1240};
1241const double BoxBOD_functor::x[6] = { 1., 2., 3., 5., 7., 10. };
1242
1243// http://www.itl.nist.gov/div898/strd/nls/data/boxbod.shtml
1244void testNistBoxBOD(void)
1245{
1246 const int n=2;
1247 int info;
1248
1249 VectorXd x(n);
1250
1251 /*
1252 * First try
1253 */
1254 x<< 1., 1.;
1255 // do the computation
1256 BoxBOD_functor functor;
1257 LevenbergMarquardt<BoxBOD_functor> lm(functor);
1258 lm.parameters.ftol = 1.E6*NumTraits<double>::epsilon();
1259 lm.parameters.xtol = 1.E6*NumTraits<double>::epsilon();
1260 lm.parameters.factor = 10.;
1261 info = lm.minimize(x);
1262
1263 // check return value
1264 VERIFY_IS_EQUAL(info, 1);
1265 VERIFY_IS_EQUAL(lm.nfev, 31);
1266 VERIFY_IS_EQUAL(lm.njev, 25);
1267 // check norm^2
1268 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.1680088766E+03);
1269 // check x
1270 VERIFY_IS_APPROX(x[0], 2.1380940889E+02);
1271 VERIFY_IS_APPROX(x[1], 5.4723748542E-01);
1272
1273 /*
1274 * Second try
1275 */
1276 x<< 100., 0.75;
1277 // do the computation
1278 lm.resetParameters();
1279 lm.parameters.ftol = NumTraits<double>::epsilon();
1280 lm.parameters.xtol = NumTraits<double>::epsilon();
1281 info = lm.minimize(x);
1282
1283 // check return value
1284 VERIFY_IS_EQUAL(info, 1);
1285 VERIFY_IS_EQUAL(lm.nfev, 15 );
1286 VERIFY_IS_EQUAL(lm.njev, 14 );
1287 // check norm^2
1288 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.1680088766E+03);
1289 // check x
1290 VERIFY_IS_APPROX(x[0], 2.1380940889E+02);
1291 VERIFY_IS_APPROX(x[1], 5.4723748542E-01);
1292}
1293
1294struct MGH17_functor : Functor<double>
1295{
1296 MGH17_functor(void) : Functor<double>(5,33) {}
1297 static const double x[33];
1298 static const double y[33];
1299 int operator()(const VectorXd &b, VectorXd &fvec)
1300 {
1301 assert(b.size()==5);
1302 assert(fvec.size()==33);
1303 for(int i=0; i<33; i++)
1304 fvec[i] = b[0] + b[1]*exp(-b[3]*x[i]) + b[2]*exp(-b[4]*x[i]) - y[i];
1305 return 0;
1306 }
1307 int df(const VectorXd &b, MatrixXd &fjac)
1308 {
1309 assert(b.size()==5);
1310 assert(fjac.rows()==33);
1311 assert(fjac.cols()==5);
1312 for(int i=0; i<33; i++) {
1313 fjac(i,0) = 1.;
1314 fjac(i,1) = exp(-b[3]*x[i]);
1315 fjac(i,2) = exp(-b[4]*x[i]);
1316 fjac(i,3) = -x[i]*b[1]*exp(-b[3]*x[i]);
1317 fjac(i,4) = -x[i]*b[2]*exp(-b[4]*x[i]);
1318 }
1319 return 0;
1320 }
1321};
1322const double MGH17_functor::x[33] = { 0.000000E+00, 1.000000E+01, 2.000000E+01, 3.000000E+01, 4.000000E+01, 5.000000E+01, 6.000000E+01, 7.000000E+01, 8.000000E+01, 9.000000E+01, 1.000000E+02, 1.100000E+02, 1.200000E+02, 1.300000E+02, 1.400000E+02, 1.500000E+02, 1.600000E+02, 1.700000E+02, 1.800000E+02, 1.900000E+02, 2.000000E+02, 2.100000E+02, 2.200000E+02, 2.300000E+02, 2.400000E+02, 2.500000E+02, 2.600000E+02, 2.700000E+02, 2.800000E+02, 2.900000E+02, 3.000000E+02, 3.100000E+02, 3.200000E+02 };
1323const double MGH17_functor::y[33] = { 8.440000E-01, 9.080000E-01, 9.320000E-01, 9.360000E-01, 9.250000E-01, 9.080000E-01, 8.810000E-01, 8.500000E-01, 8.180000E-01, 7.840000E-01, 7.510000E-01, 7.180000E-01, 6.850000E-01, 6.580000E-01, 6.280000E-01, 6.030000E-01, 5.800000E-01, 5.580000E-01, 5.380000E-01, 5.220000E-01, 5.060000E-01, 4.900000E-01, 4.780000E-01, 4.670000E-01, 4.570000E-01, 4.480000E-01, 4.380000E-01, 4.310000E-01, 4.240000E-01, 4.200000E-01, 4.140000E-01, 4.110000E-01, 4.060000E-01 };
1324
1325// http://www.itl.nist.gov/div898/strd/nls/data/mgh17.shtml
1326void testNistMGH17(void)
1327{
1328 const int n=5;
1329 int info;
1330
1331 VectorXd x(n);
1332
1333 /*
1334 * First try
1335 */
1336 x<< 50., 150., -100., 1., 2.;
1337 // do the computation
1338 MGH17_functor functor;
1339 LevenbergMarquardt<MGH17_functor> lm(functor);
1340 lm.parameters.ftol = NumTraits<double>::epsilon();
1341 lm.parameters.xtol = NumTraits<double>::epsilon();
1342 lm.parameters.maxfev = 1000;
1343 info = lm.minimize(x);
1344
1345 // check return value
1346 VERIFY_IS_EQUAL(info, 2);
1347 VERIFY_IS_EQUAL(lm.nfev, 602 );
1348 VERIFY_IS_EQUAL(lm.njev, 545 );
1349 // check norm^2
1350 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.4648946975E-05);
1351 // check x
1352 VERIFY_IS_APPROX(x[0], 3.7541005211E-01);
1353 VERIFY_IS_APPROX(x[1], 1.9358469127E+00);
1354 VERIFY_IS_APPROX(x[2], -1.4646871366E+00);
1355 VERIFY_IS_APPROX(x[3], 1.2867534640E-02);
1356 VERIFY_IS_APPROX(x[4], 2.2122699662E-02);
1357
1358 /*
1359 * Second try
1360 */
1361 x<< 0.5 ,1.5 ,-1 ,0.01 ,0.02;
1362 // do the computation
1363 lm.resetParameters();
1364 info = lm.minimize(x);
1365
1366 // check return value
1367 VERIFY_IS_EQUAL(info, 1);
1368 VERIFY_IS_EQUAL(lm.nfev, 18);
1369 VERIFY_IS_EQUAL(lm.njev, 15);
1370 // check norm^2
1371 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.4648946975E-05);
1372 // check x
1373 VERIFY_IS_APPROX(x[0], 3.7541005211E-01);
1374 VERIFY_IS_APPROX(x[1], 1.9358469127E+00);
1375 VERIFY_IS_APPROX(x[2], -1.4646871366E+00);
1376 VERIFY_IS_APPROX(x[3], 1.2867534640E-02);
1377 VERIFY_IS_APPROX(x[4], 2.2122699662E-02);
1378}
1379
1380struct MGH09_functor : Functor<double>
1381{
1382 MGH09_functor(void) : Functor<double>(4,11) {}
1383 static const double _x[11];
1384 static const double y[11];
1385 int operator()(const VectorXd &b, VectorXd &fvec)
1386 {
1387 assert(b.size()==4);
1388 assert(fvec.size()==11);
1389 for(int i=0; i<11; i++) {
1390 double x = _x[i], xx=x*x;
1391 fvec[i] = b[0]*(xx+x*b[1])/(xx+x*b[2]+b[3]) - y[i];
1392 }
1393 return 0;
1394 }
1395 int df(const VectorXd &b, MatrixXd &fjac)
1396 {
1397 assert(b.size()==4);
1398 assert(fjac.rows()==11);
1399 assert(fjac.cols()==4);
1400 for(int i=0; i<11; i++) {
1401 double x = _x[i], xx=x*x;
1402 double factor = 1./(xx+x*b[2]+b[3]);
1403 fjac(i,0) = (xx+x*b[1]) * factor;
1404 fjac(i,1) = b[0]*x* factor;
1405 fjac(i,2) = - b[0]*(xx+x*b[1]) * x * factor * factor;
1406 fjac(i,3) = - b[0]*(xx+x*b[1]) * factor * factor;
1407 }
1408 return 0;
1409 }
1410};
1411const double MGH09_functor::_x[11] = { 4., 2., 1., 5.E-1 , 2.5E-01, 1.670000E-01, 1.250000E-01, 1.E-01, 8.330000E-02, 7.140000E-02, 6.250000E-02 };
1412const double MGH09_functor::y[11] = { 1.957000E-01, 1.947000E-01, 1.735000E-01, 1.600000E-01, 8.440000E-02, 6.270000E-02, 4.560000E-02, 3.420000E-02, 3.230000E-02, 2.350000E-02, 2.460000E-02 };
1413
1414// http://www.itl.nist.gov/div898/strd/nls/data/mgh09.shtml
1415void testNistMGH09(void)
1416{
1417 const int n=4;
1418 int info;
1419
1420 VectorXd x(n);
1421
1422 /*
1423 * First try
1424 */
1425 x<< 25., 39, 41.5, 39.;
1426 // do the computation
1427 MGH09_functor functor;
1428 LevenbergMarquardt<MGH09_functor> lm(functor);
1429 lm.parameters.maxfev = 1000;
1430 info = lm.minimize(x);
1431
1432 // check return value
1433 VERIFY_IS_EQUAL(info, 1);
1434 VERIFY_IS_EQUAL(lm.nfev, 490 );
1435 VERIFY_IS_EQUAL(lm.njev, 376 );
1436 // check norm^2
1437 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 3.0750560385E-04);
1438 // check x
1439 VERIFY_IS_APPROX(x[0], 0.1928077089); // should be 1.9280693458E-01
1440 VERIFY_IS_APPROX(x[1], 0.19126423573); // should be 1.9128232873E-01
1441 VERIFY_IS_APPROX(x[2], 0.12305309914); // should be 1.2305650693E-01
1442 VERIFY_IS_APPROX(x[3], 0.13605395375); // should be 1.3606233068E-01
1443
1444 /*
1445 * Second try
1446 */
1447 x<< 0.25, 0.39, 0.415, 0.39;
1448 // do the computation
1449 lm.resetParameters();
1450 info = lm.minimize(x);
1451
1452 // check return value
1453 VERIFY_IS_EQUAL(info, 1);
1454 VERIFY_IS_EQUAL(lm.nfev, 18);
1455 VERIFY_IS_EQUAL(lm.njev, 16);
1456 // check norm^2
1457 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 3.0750560385E-04);
1458 // check x
1459 VERIFY_IS_APPROX(x[0], 0.19280781); // should be 1.9280693458E-01
1460 VERIFY_IS_APPROX(x[1], 0.19126265); // should be 1.9128232873E-01
1461 VERIFY_IS_APPROX(x[2], 0.12305280); // should be 1.2305650693E-01
1462 VERIFY_IS_APPROX(x[3], 0.13605322); // should be 1.3606233068E-01
1463}
1464
1465
1466
1467struct Bennett5_functor : Functor<double>
1468{
1469 Bennett5_functor(void) : Functor<double>(3,154) {}
1470 static const double x[154];
1471 static const double y[154];
1472 int operator()(const VectorXd &b, VectorXd &fvec)
1473 {
1474 assert(b.size()==3);
1475 assert(fvec.size()==154);
1476 for(int i=0; i<154; i++)
1477 fvec[i] = b[0]* pow(b[1]+x[i],-1./b[2]) - y[i];
1478 return 0;
1479 }
1480 int df(const VectorXd &b, MatrixXd &fjac)
1481 {
1482 assert(b.size()==3);
1483 assert(fjac.rows()==154);
1484 assert(fjac.cols()==3);
1485 for(int i=0; i<154; i++) {
1486 double e = pow(b[1]+x[i],-1./b[2]);
1487 fjac(i,0) = e;
1488 fjac(i,1) = - b[0]*e/b[2]/(b[1]+x[i]);
1489 fjac(i,2) = b[0]*e*log(b[1]+x[i])/b[2]/b[2];
1490 }
1491 return 0;
1492 }
1493};
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -07001494const double Bennett5_functor::x[154] = { 7.447168E0, 8.102586E0, 8.452547E0, 8.711278E0, 8.916774E0, 9.087155E0, 9.232590E0, 9.359535E0, 9.472166E0, 9.573384E0, 9.665293E0, 9.749461E0, 9.827092E0, 9.899128E0, 9.966321E0, 10.029280E0, 10.088510E0, 10.144430E0, 10.197380E0, 10.247670E0, 10.295560E0, 10.341250E0, 10.384950E0, 10.426820E0, 10.467000E0, 10.505640E0, 10.542830E0, 10.578690E0, 10.613310E0, 10.646780E0, 10.679150E0, 10.710520E0, 10.740920E0, 10.770440E0, 10.799100E0, 10.826970E0, 10.854080E0, 10.880470E0, 10.906190E0, 10.931260E0, 10.955720E0, 10.979590E0, 11.002910E0, 11.025700E0, 11.047980E0, 11.069770E0, 11.091100E0, 11.111980E0, 11.132440E0, 11.152480E0, 11.172130E0, 11.191410E0, 11.210310E0, 11.228870E0, 11.247090E0, 11.264980E0, 11.282560E0, 11.299840E0, 11.316820E0, 11.333520E0, 11.349940E0, 11.366100E0, 11.382000E0, 11.397660E0, 11.413070E0, 11.428240E0, 11.443200E0, 11.457930E0, 11.472440E0, 11.486750E0, 11.500860E0, 11.514770E0, 11.528490E0, 11.542020E0, 11.555380E0, 11.568550E0,
149511.581560E0, 11.594420E0, 11.607121E0, 11.619640E0, 11.632000E0, 11.644210E0, 11.656280E0, 11.668200E0, 11.679980E0, 11.691620E0, 11.703130E0, 11.714510E0, 11.725760E0, 11.736880E0, 11.747890E0, 11.758780E0, 11.769550E0, 11.780200E0, 11.790730E0, 11.801160E0, 11.811480E0, 11.821700E0, 11.831810E0, 11.841820E0, 11.851730E0, 11.861550E0, 11.871270E0, 11.880890E0, 11.890420E0, 11.899870E0, 11.909220E0, 11.918490E0, 11.927680E0, 11.936780E0, 11.945790E0, 11.954730E0, 11.963590E0, 11.972370E0, 11.981070E0, 11.989700E0, 11.998260E0, 12.006740E0, 12.015150E0, 12.023490E0, 12.031760E0, 12.039970E0, 12.048100E0, 12.056170E0, 12.064180E0, 12.072120E0, 12.080010E0, 12.087820E0, 12.095580E0, 12.103280E0, 12.110920E0, 12.118500E0, 12.126030E0, 12.133500E0, 12.140910E0, 12.148270E0, 12.155570E0, 12.162830E0, 12.170030E0, 12.177170E0, 12.184270E0, 12.191320E0, 12.198320E0, 12.205270E0, 12.212170E0, 12.219030E0, 12.225840E0, 12.232600E0, 12.239320E0, 12.245990E0, 12.252620E0, 12.259200E0, 12.265750E0, 12.272240E0 };
1496const double Bennett5_functor::y[154] = { -34.834702E0 ,-34.393200E0 ,-34.152901E0 ,-33.979099E0 ,-33.845901E0 ,-33.732899E0 ,-33.640301E0 ,-33.559200E0 ,-33.486801E0 ,-33.423100E0 ,-33.365101E0 ,-33.313000E0 ,-33.260899E0 ,-33.217400E0 ,-33.176899E0 ,-33.139198E0 ,-33.101601E0 ,-33.066799E0 ,-33.035000E0 ,-33.003101E0 ,-32.971298E0 ,-32.942299E0 ,-32.916302E0 ,-32.890202E0 ,-32.864101E0 ,-32.841000E0 ,-32.817799E0 ,-32.797501E0 ,-32.774300E0 ,-32.757000E0 ,-32.733799E0 ,-32.716400E0 ,-32.699100E0 ,-32.678799E0 ,-32.661400E0 ,-32.644001E0 ,-32.626701E0 ,-32.612202E0 ,-32.597698E0 ,-32.583199E0 ,-32.568699E0 ,-32.554298E0 ,-32.539799E0 ,-32.525299E0 ,-32.510799E0 ,-32.499199E0 ,-32.487598E0 ,-32.473202E0 ,-32.461601E0 ,-32.435501E0 ,-32.435501E0 ,-32.426800E0 ,-32.412300E0 ,-32.400799E0 ,-32.392101E0 ,-32.380501E0 ,-32.366001E0 ,-32.357300E0 ,-32.348598E0 ,-32.339901E0 ,-32.328400E0 ,-32.319698E0 ,-32.311001E0 ,-32.299400E0 ,-32.290699E0 ,-32.282001E0 ,-32.273300E0 ,-32.264599E0 ,-32.256001E0 ,-32.247299E0
1497,-32.238602E0 ,-32.229900E0 ,-32.224098E0 ,-32.215401E0 ,-32.203800E0 ,-32.198002E0 ,-32.189400E0 ,-32.183601E0 ,-32.174900E0 ,-32.169102E0 ,-32.163300E0 ,-32.154598E0 ,-32.145901E0 ,-32.140099E0 ,-32.131401E0 ,-32.125599E0 ,-32.119801E0 ,-32.111198E0 ,-32.105400E0 ,-32.096699E0 ,-32.090900E0 ,-32.088001E0 ,-32.079300E0 ,-32.073502E0 ,-32.067699E0 ,-32.061901E0 ,-32.056099E0 ,-32.050301E0 ,-32.044498E0 ,-32.038799E0 ,-32.033001E0 ,-32.027199E0 ,-32.024300E0 ,-32.018501E0 ,-32.012699E0 ,-32.004002E0 ,-32.001099E0 ,-31.995300E0 ,-31.989500E0 ,-31.983700E0 ,-31.977900E0 ,-31.972099E0 ,-31.969299E0 ,-31.963501E0 ,-31.957701E0 ,-31.951900E0 ,-31.946100E0 ,-31.940300E0 ,-31.937401E0 ,-31.931601E0 ,-31.925800E0 ,-31.922899E0 ,-31.917101E0 ,-31.911301E0 ,-31.908400E0 ,-31.902599E0 ,-31.896900E0 ,-31.893999E0 ,-31.888201E0 ,-31.885300E0 ,-31.882401E0 ,-31.876600E0 ,-31.873699E0 ,-31.867901E0 ,-31.862101E0 ,-31.859200E0 ,-31.856300E0 ,-31.850500E0 ,-31.844700E0 ,-31.841801E0 ,-31.838900E0 ,-31.833099E0 ,-31.830200E0 ,
1498-31.827299E0 ,-31.821600E0 ,-31.818701E0 ,-31.812901E0 ,-31.809999E0 ,-31.807100E0 ,-31.801300E0 ,-31.798401E0 ,-31.795500E0 ,-31.789700E0 ,-31.786800E0 };
Narayan Kamathc981c482012-11-02 10:59:05 +00001499
1500// http://www.itl.nist.gov/div898/strd/nls/data/bennett5.shtml
1501void testNistBennett5(void)
1502{
1503 const int n=3;
1504 int info;
1505
1506 VectorXd x(n);
1507
1508 /*
1509 * First try
1510 */
1511 x<< -2000., 50., 0.8;
1512 // do the computation
1513 Bennett5_functor functor;
1514 LevenbergMarquardt<Bennett5_functor> lm(functor);
1515 lm.parameters.maxfev = 1000;
1516 info = lm.minimize(x);
1517
1518 // check return value
1519 VERIFY_IS_EQUAL(info, 1);
1520 VERIFY_IS_EQUAL(lm.nfev, 758);
1521 VERIFY_IS_EQUAL(lm.njev, 744);
1522 // check norm^2
1523 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.2404744073E-04);
1524 // check x
1525 VERIFY_IS_APPROX(x[0], -2.5235058043E+03);
1526 VERIFY_IS_APPROX(x[1], 4.6736564644E+01);
1527 VERIFY_IS_APPROX(x[2], 9.3218483193E-01);
1528 /*
1529 * Second try
1530 */
1531 x<< -1500., 45., 0.85;
1532 // do the computation
1533 lm.resetParameters();
1534 info = lm.minimize(x);
1535
1536 // check return value
1537 VERIFY_IS_EQUAL(info, 1);
1538 VERIFY_IS_EQUAL(lm.nfev, 203);
1539 VERIFY_IS_EQUAL(lm.njev, 192);
1540 // check norm^2
1541 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.2404744073E-04);
1542 // check x
1543 VERIFY_IS_APPROX(x[0], -2523.3007865); // should be -2.5235058043E+03
1544 VERIFY_IS_APPROX(x[1], 46.735705771); // should be 4.6736564644E+01);
1545 VERIFY_IS_APPROX(x[2], 0.93219881891); // should be 9.3218483193E-01);
1546}
1547
1548struct thurber_functor : Functor<double>
1549{
1550 thurber_functor(void) : Functor<double>(7,37) {}
1551 static const double _x[37];
1552 static const double _y[37];
1553 int operator()(const VectorXd &b, VectorXd &fvec)
1554 {
1555 // int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;
1556 assert(b.size()==7);
1557 assert(fvec.size()==37);
1558 for(int i=0; i<37; i++) {
1559 double x=_x[i], xx=x*x, xxx=xx*x;
1560 fvec[i] = (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) / (1.+b[4]*x+b[5]*xx+b[6]*xxx) - _y[i];
1561 }
1562 return 0;
1563 }
1564 int df(const VectorXd &b, MatrixXd &fjac)
1565 {
1566 assert(b.size()==7);
1567 assert(fjac.rows()==37);
1568 assert(fjac.cols()==7);
1569 for(int i=0; i<37; i++) {
1570 double x=_x[i], xx=x*x, xxx=xx*x;
1571 double fact = 1./(1.+b[4]*x+b[5]*xx+b[6]*xxx);
1572 fjac(i,0) = 1.*fact;
1573 fjac(i,1) = x*fact;
1574 fjac(i,2) = xx*fact;
1575 fjac(i,3) = xxx*fact;
1576 fact = - (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) * fact * fact;
1577 fjac(i,4) = x*fact;
1578 fjac(i,5) = xx*fact;
1579 fjac(i,6) = xxx*fact;
1580 }
1581 return 0;
1582 }
1583};
1584const double thurber_functor::_x[37] = { -3.067E0, -2.981E0, -2.921E0, -2.912E0, -2.840E0, -2.797E0, -2.702E0, -2.699E0, -2.633E0, -2.481E0, -2.363E0, -2.322E0, -1.501E0, -1.460E0, -1.274E0, -1.212E0, -1.100E0, -1.046E0, -0.915E0, -0.714E0, -0.566E0, -0.545E0, -0.400E0, -0.309E0, -0.109E0, -0.103E0, 0.010E0, 0.119E0, 0.377E0, 0.790E0, 0.963E0, 1.006E0, 1.115E0, 1.572E0, 1.841E0, 2.047E0, 2.200E0 };
1585const double thurber_functor::_y[37] = { 80.574E0, 84.248E0, 87.264E0, 87.195E0, 89.076E0, 89.608E0, 89.868E0, 90.101E0, 92.405E0, 95.854E0, 100.696E0, 101.060E0, 401.672E0, 390.724E0, 567.534E0, 635.316E0, 733.054E0, 759.087E0, 894.206E0, 990.785E0, 1090.109E0, 1080.914E0, 1122.643E0, 1178.351E0, 1260.531E0, 1273.514E0, 1288.339E0, 1327.543E0, 1353.863E0, 1414.509E0, 1425.208E0, 1421.384E0, 1442.962E0, 1464.350E0, 1468.705E0, 1447.894E0, 1457.628E0};
1586
1587// http://www.itl.nist.gov/div898/strd/nls/data/thurber.shtml
1588void testNistThurber(void)
1589{
1590 const int n=7;
1591 int info;
1592
1593 VectorXd x(n);
1594
1595 /*
1596 * First try
1597 */
1598 x<< 1000 ,1000 ,400 ,40 ,0.7,0.3,0.0 ;
1599 // do the computation
1600 thurber_functor functor;
1601 LevenbergMarquardt<thurber_functor> lm(functor);
1602 lm.parameters.ftol = 1.E4*NumTraits<double>::epsilon();
1603 lm.parameters.xtol = 1.E4*NumTraits<double>::epsilon();
1604 info = lm.minimize(x);
1605
1606 // check return value
1607 VERIFY_IS_EQUAL(info, 1);
1608 VERIFY_IS_EQUAL(lm.nfev, 39);
1609 VERIFY_IS_EQUAL(lm.njev, 36);
1610 // check norm^2
1611 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6427082397E+03);
1612 // check x
1613 VERIFY_IS_APPROX(x[0], 1.2881396800E+03);
1614 VERIFY_IS_APPROX(x[1], 1.4910792535E+03);
1615 VERIFY_IS_APPROX(x[2], 5.8323836877E+02);
1616 VERIFY_IS_APPROX(x[3], 7.5416644291E+01);
1617 VERIFY_IS_APPROX(x[4], 9.6629502864E-01);
1618 VERIFY_IS_APPROX(x[5], 3.9797285797E-01);
1619 VERIFY_IS_APPROX(x[6], 4.9727297349E-02);
1620
1621 /*
1622 * Second try
1623 */
1624 x<< 1300 ,1500 ,500 ,75 ,1 ,0.4 ,0.05 ;
1625 // do the computation
1626 lm.resetParameters();
1627 lm.parameters.ftol = 1.E4*NumTraits<double>::epsilon();
1628 lm.parameters.xtol = 1.E4*NumTraits<double>::epsilon();
1629 info = lm.minimize(x);
1630
1631 // check return value
1632 VERIFY_IS_EQUAL(info, 1);
1633 VERIFY_IS_EQUAL(lm.nfev, 29);
1634 VERIFY_IS_EQUAL(lm.njev, 28);
1635 // check norm^2
1636 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6427082397E+03);
1637 // check x
1638 VERIFY_IS_APPROX(x[0], 1.2881396800E+03);
1639 VERIFY_IS_APPROX(x[1], 1.4910792535E+03);
1640 VERIFY_IS_APPROX(x[2], 5.8323836877E+02);
1641 VERIFY_IS_APPROX(x[3], 7.5416644291E+01);
1642 VERIFY_IS_APPROX(x[4], 9.6629502864E-01);
1643 VERIFY_IS_APPROX(x[5], 3.9797285797E-01);
1644 VERIFY_IS_APPROX(x[6], 4.9727297349E-02);
1645}
1646
1647struct rat43_functor : Functor<double>
1648{
1649 rat43_functor(void) : Functor<double>(4,15) {}
1650 static const double x[15];
1651 static const double y[15];
1652 int operator()(const VectorXd &b, VectorXd &fvec)
1653 {
1654 assert(b.size()==4);
1655 assert(fvec.size()==15);
1656 for(int i=0; i<15; i++)
1657 fvec[i] = b[0] * pow(1.+exp(b[1]-b[2]*x[i]),-1./b[3]) - y[i];
1658 return 0;
1659 }
1660 int df(const VectorXd &b, MatrixXd &fjac)
1661 {
1662 assert(b.size()==4);
1663 assert(fjac.rows()==15);
1664 assert(fjac.cols()==4);
1665 for(int i=0; i<15; i++) {
1666 double e = exp(b[1]-b[2]*x[i]);
1667 double power = -1./b[3];
1668 fjac(i,0) = pow(1.+e, power);
1669 fjac(i,1) = power*b[0]*e*pow(1.+e, power-1.);
1670 fjac(i,2) = -power*b[0]*e*x[i]*pow(1.+e, power-1.);
1671 fjac(i,3) = b[0]*power*power*log(1.+e)*pow(1.+e, power);
1672 }
1673 return 0;
1674 }
1675};
1676const double rat43_functor::x[15] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15. };
1677const double rat43_functor::y[15] = { 16.08, 33.83, 65.80, 97.20, 191.55, 326.20, 386.87, 520.53, 590.03, 651.92, 724.93, 699.56, 689.96, 637.56, 717.41 };
1678
1679// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky3.shtml
1680void testNistRat43(void)
1681{
1682 const int n=4;
1683 int info;
1684
1685 VectorXd x(n);
1686
1687 /*
1688 * First try
1689 */
1690 x<< 100., 10., 1., 1.;
1691 // do the computation
1692 rat43_functor functor;
1693 LevenbergMarquardt<rat43_functor> lm(functor);
1694 lm.parameters.ftol = 1.E6*NumTraits<double>::epsilon();
1695 lm.parameters.xtol = 1.E6*NumTraits<double>::epsilon();
1696 info = lm.minimize(x);
1697
1698 // check return value
1699 VERIFY_IS_EQUAL(info, 1);
1700 VERIFY_IS_EQUAL(lm.nfev, 27);
1701 VERIFY_IS_EQUAL(lm.njev, 20);
1702 // check norm^2
1703 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7864049080E+03);
1704 // check x
1705 VERIFY_IS_APPROX(x[0], 6.9964151270E+02);
1706 VERIFY_IS_APPROX(x[1], 5.2771253025E+00);
1707 VERIFY_IS_APPROX(x[2], 7.5962938329E-01);
1708 VERIFY_IS_APPROX(x[3], 1.2792483859E+00);
1709
1710 /*
1711 * Second try
1712 */
1713 x<< 700., 5., 0.75, 1.3;
1714 // do the computation
1715 lm.resetParameters();
1716 lm.parameters.ftol = 1.E5*NumTraits<double>::epsilon();
1717 lm.parameters.xtol = 1.E5*NumTraits<double>::epsilon();
1718 info = lm.minimize(x);
1719
1720 // check return value
1721 VERIFY_IS_EQUAL(info, 1);
1722 VERIFY_IS_EQUAL(lm.nfev, 9);
1723 VERIFY_IS_EQUAL(lm.njev, 8);
1724 // check norm^2
1725 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7864049080E+03);
1726 // check x
1727 VERIFY_IS_APPROX(x[0], 6.9964151270E+02);
1728 VERIFY_IS_APPROX(x[1], 5.2771253025E+00);
1729 VERIFY_IS_APPROX(x[2], 7.5962938329E-01);
1730 VERIFY_IS_APPROX(x[3], 1.2792483859E+00);
1731}
1732
1733
1734
1735struct eckerle4_functor : Functor<double>
1736{
1737 eckerle4_functor(void) : Functor<double>(3,35) {}
1738 static const double x[35];
1739 static const double y[35];
1740 int operator()(const VectorXd &b, VectorXd &fvec)
1741 {
1742 assert(b.size()==3);
1743 assert(fvec.size()==35);
1744 for(int i=0; i<35; i++)
1745 fvec[i] = b[0]/b[1] * exp(-0.5*(x[i]-b[2])*(x[i]-b[2])/(b[1]*b[1])) - y[i];
1746 return 0;
1747 }
1748 int df(const VectorXd &b, MatrixXd &fjac)
1749 {
1750 assert(b.size()==3);
1751 assert(fjac.rows()==35);
1752 assert(fjac.cols()==3);
1753 for(int i=0; i<35; i++) {
1754 double b12 = b[1]*b[1];
1755 double e = exp(-0.5*(x[i]-b[2])*(x[i]-b[2])/b12);
1756 fjac(i,0) = e / b[1];
1757 fjac(i,1) = ((x[i]-b[2])*(x[i]-b[2])/b12-1.) * b[0]*e/b12;
1758 fjac(i,2) = (x[i]-b[2])*e*b[0]/b[1]/b12;
1759 }
1760 return 0;
1761 }
1762};
1763const double eckerle4_functor::x[35] = { 400.0, 405.0, 410.0, 415.0, 420.0, 425.0, 430.0, 435.0, 436.5, 438.0, 439.5, 441.0, 442.5, 444.0, 445.5, 447.0, 448.5, 450.0, 451.5, 453.0, 454.5, 456.0, 457.5, 459.0, 460.5, 462.0, 463.5, 465.0, 470.0, 475.0, 480.0, 485.0, 490.0, 495.0, 500.0};
1764const double eckerle4_functor::y[35] = { 0.0001575, 0.0001699, 0.0002350, 0.0003102, 0.0004917, 0.0008710, 0.0017418, 0.0046400, 0.0065895, 0.0097302, 0.0149002, 0.0237310, 0.0401683, 0.0712559, 0.1264458, 0.2073413, 0.2902366, 0.3445623, 0.3698049, 0.3668534, 0.3106727, 0.2078154, 0.1164354, 0.0616764, 0.0337200, 0.0194023, 0.0117831, 0.0074357, 0.0022732, 0.0008800, 0.0004579, 0.0002345, 0.0001586, 0.0001143, 0.0000710 };
1765
1766// http://www.itl.nist.gov/div898/strd/nls/data/eckerle4.shtml
1767void testNistEckerle4(void)
1768{
1769 const int n=3;
1770 int info;
1771
1772 VectorXd x(n);
1773
1774 /*
1775 * First try
1776 */
1777 x<< 1., 10., 500.;
1778 // do the computation
1779 eckerle4_functor functor;
1780 LevenbergMarquardt<eckerle4_functor> lm(functor);
1781 info = lm.minimize(x);
1782
1783 // check return value
1784 VERIFY_IS_EQUAL(info, 1);
1785 VERIFY_IS_EQUAL(lm.nfev, 18);
1786 VERIFY_IS_EQUAL(lm.njev, 15);
1787 // check norm^2
1788 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.4635887487E-03);
1789 // check x
1790 VERIFY_IS_APPROX(x[0], 1.5543827178);
1791 VERIFY_IS_APPROX(x[1], 4.0888321754);
1792 VERIFY_IS_APPROX(x[2], 4.5154121844E+02);
1793
1794 /*
1795 * Second try
1796 */
1797 x<< 1.5, 5., 450.;
1798 // do the computation
1799 info = lm.minimize(x);
1800
1801 // check return value
1802 VERIFY_IS_EQUAL(info, 1);
1803 VERIFY_IS_EQUAL(lm.nfev, 7);
1804 VERIFY_IS_EQUAL(lm.njev, 6);
1805 // check norm^2
1806 VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.4635887487E-03);
1807 // check x
1808 VERIFY_IS_APPROX(x[0], 1.5543827178);
1809 VERIFY_IS_APPROX(x[1], 4.0888321754);
1810 VERIFY_IS_APPROX(x[2], 4.5154121844E+02);
1811}
1812
1813void test_NonLinearOptimization()
1814{
1815 // Tests using the examples provided by (c)minpack
1816 CALL_SUBTEST/*_1*/(testChkder());
1817 CALL_SUBTEST/*_1*/(testLmder1());
1818 CALL_SUBTEST/*_1*/(testLmder());
1819 CALL_SUBTEST/*_2*/(testHybrj1());
1820 CALL_SUBTEST/*_2*/(testHybrj());
1821 CALL_SUBTEST/*_2*/(testHybrd1());
1822 CALL_SUBTEST/*_2*/(testHybrd());
1823 CALL_SUBTEST/*_3*/(testLmstr1());
1824 CALL_SUBTEST/*_3*/(testLmstr());
1825 CALL_SUBTEST/*_3*/(testLmdif1());
1826 CALL_SUBTEST/*_3*/(testLmdif());
1827
1828 // NIST tests, level of difficulty = "Lower"
1829 CALL_SUBTEST/*_4*/(testNistMisra1a());
1830 CALL_SUBTEST/*_4*/(testNistChwirut2());
1831
1832 // NIST tests, level of difficulty = "Average"
1833 CALL_SUBTEST/*_5*/(testNistHahn1());
1834 CALL_SUBTEST/*_6*/(testNistMisra1d());
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -07001835// CALL_SUBTEST/*_7*/(testNistMGH17());
1836// CALL_SUBTEST/*_8*/(testNistLanczos1());
Narayan Kamathc981c482012-11-02 10:59:05 +00001837
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -07001838// // NIST tests, level of difficulty = "Higher"
Narayan Kamathc981c482012-11-02 10:59:05 +00001839 CALL_SUBTEST/*_9*/(testNistRat42());
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -07001840// CALL_SUBTEST/*_10*/(testNistMGH10());
Narayan Kamathc981c482012-11-02 10:59:05 +00001841 CALL_SUBTEST/*_11*/(testNistBoxBOD());
Carlos Hernandez7faaa9f2014-08-05 17:53:32 -07001842// CALL_SUBTEST/*_12*/(testNistMGH09());
Narayan Kamathc981c482012-11-02 10:59:05 +00001843 CALL_SUBTEST/*_13*/(testNistBennett5());
1844 CALL_SUBTEST/*_14*/(testNistThurber());
1845 CALL_SUBTEST/*_15*/(testNistRat43());
1846 CALL_SUBTEST/*_16*/(testNistEckerle4());
1847}
1848
1849/*
1850 * Can be useful for debugging...
1851 printf("info, nfev : %d, %d\n", info, lm.nfev);
1852 printf("info, nfev, njev : %d, %d, %d\n", info, solver.nfev, solver.njev);
1853 printf("info, nfev : %d, %d\n", info, solver.nfev);
1854 printf("x[0] : %.32g\n", x[0]);
1855 printf("x[1] : %.32g\n", x[1]);
1856 printf("x[2] : %.32g\n", x[2]);
1857 printf("x[3] : %.32g\n", x[3]);
1858 printf("fvec.blueNorm() : %.32g\n", solver.fvec.blueNorm());
1859 printf("fvec.blueNorm() : %.32g\n", lm.fvec.blueNorm());
1860
1861 printf("info, nfev, njev : %d, %d, %d\n", info, lm.nfev, lm.njev);
1862 printf("fvec.squaredNorm() : %.13g\n", lm.fvec.squaredNorm());
1863 std::cout << x << std::endl;
1864 std::cout.precision(9);
1865 std::cout << x[0] << std::endl;
1866 std::cout << x[1] << std::endl;
1867 std::cout << x[2] << std::endl;
1868 std::cout << x[3] << std::endl;
1869*/
1870