| 193 | } |
| 194 | |
| 195 | void testLmder() |
| 196 | { |
| 197 | const int m=15, n=3; |
| 198 | int info; |
| 199 | double fnorm, covfac; |
| 200 | VectorXd x; |
| 201 | |
| 202 | /* the following starting values provide a rough fit. */ |
| 203 | x.setConstant(n, 1.); |
| 204 | |
| 205 | // do the computation |
| 206 | lmder_functor functor; |
| 207 | LevenbergMarquardt<lmder_functor> lm(functor); |
| 208 | info = lm.minimize(x); |
| 209 | |
| 210 | // check return values |
| 211 | VERIFY_IS_EQUAL(info, 1); |
| 212 | VERIFY_IS_EQUAL(lm.nfev, 6); |
| 213 | VERIFY_IS_EQUAL(lm.njev, 5); |
| 214 | |
| 215 | // check norm |
| 216 | fnorm = lm.fvec.blueNorm(); |
| 217 | VERIFY_IS_APPROX(fnorm, 0.09063596); |
| 218 | |
| 219 | // check x |
| 220 | VectorXd x_ref(n); |
| 221 | x_ref << 0.08241058, 1.133037, 2.343695; |
| 222 | VERIFY_IS_APPROX(x, x_ref); |
| 223 | |
| 224 | // check covariance |
| 225 | covfac = fnorm*fnorm/(m-n); |
| 226 | internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm |
| 227 | |
| 228 | MatrixXd cov_ref(n,n); |
| 229 | cov_ref << |
| 230 | 0.0001531202, 0.002869941, -0.002656662, |
| 231 | 0.002869941, 0.09480935, -0.09098995, |
| 232 | -0.002656662, -0.09098995, 0.08778727; |
| 233 | |
| 234 | // std::cout << fjac*covfac << std::endl; |
| 235 | |
| 236 | MatrixXd cov; |
| 237 | cov = covfac*lm.fjac.topLeftCorner<n,n>(); |
| 238 | VERIFY_IS_APPROX( cov, cov_ref); |
| 239 | // TODO: why isn't this allowed ? : |
| 240 | // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref); |
| 241 | } |
| 242 | |
| 243 | struct hybrj_functor : Functor<double> |
| 244 | { |
no test coverage detected