| 584 | } |
| 585 | |
| 586 | void testLmdif() |
| 587 | { |
| 588 | const int m=15, n=3; |
| 589 | int info; |
| 590 | double fnorm, covfac; |
| 591 | VectorXd x(n); |
| 592 | |
| 593 | /* the following starting values provide a rough fit. */ |
| 594 | x.setConstant(n, 1.); |
| 595 | |
| 596 | // do the computation |
| 597 | lmdif_functor functor; |
| 598 | NumericalDiff<lmdif_functor> numDiff(functor); |
| 599 | LevenbergMarquardt<NumericalDiff<lmdif_functor> > lm(numDiff); |
| 600 | info = lm.minimize(x); |
| 601 | |
| 602 | // check return values |
| 603 | VERIFY_IS_EQUAL(info, 1); |
| 604 | VERIFY_IS_EQUAL(lm.nfev, 26); |
| 605 | |
| 606 | // check norm |
| 607 | fnorm = lm.fvec.blueNorm(); |
| 608 | VERIFY_IS_APPROX(fnorm, 0.09063596); |
| 609 | |
| 610 | // check x |
| 611 | VectorXd x_ref(n); |
| 612 | x_ref << 0.08241058, 1.133037, 2.343695; |
| 613 | VERIFY_IS_APPROX(x, x_ref); |
| 614 | |
| 615 | // check covariance |
| 616 | covfac = fnorm*fnorm/(m-n); |
| 617 | internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm |
| 618 | |
| 619 | MatrixXd cov_ref(n,n); |
| 620 | cov_ref << |
| 621 | 0.0001531202, 0.002869942, -0.002656662, |
| 622 | 0.002869942, 0.09480937, -0.09098997, |
| 623 | -0.002656662, -0.09098997, 0.08778729; |
| 624 | |
| 625 | // std::cout << fjac*covfac << std::endl; |
| 626 | |
| 627 | MatrixXd cov; |
| 628 | cov = covfac*lm.fjac.topLeftCorner<n,n>(); |
| 629 | VERIFY_IS_APPROX( cov, cov_ref); |
| 630 | // TODO: why isn't this allowed ? : |
| 631 | // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref); |
| 632 | } |
| 633 | |
| 634 | struct chwirut2_functor : Functor<double> |
| 635 | { |
no test coverage detected