13 #ifndef EIGEN_LEVENBERGMARQUARDT__H 14 #define EIGEN_LEVENBERGMARQUARDT__H 18 namespace LevenbergMarquardtSpace {
45 template<
typename FunctorType,
typename Scalar=
double>
56 : functor(_functor) { nfev = njev =
iter = 0; fnorm = gnorm = 0.; useExternalScaling=
false; }
64 , ftol(sqrt_epsilon())
65 , xtol(sqrt_epsilon())
122 FVectorType wa1, wa2, wa3,
wa4;
133 template<
typename FunctorType,
typename Scalar>
141 m = functor.values();
144 if (
n <= 0 ||
m <
n || tol < 0.)
156 template<
typename FunctorType,
typename Scalar>
164 status = minimizeOneStep(x);
169 template<
typename FunctorType,
typename Scalar>
174 m = functor.values();
176 wa1.resize(
n); wa2.resize(
n); wa3.resize(
n);
180 if (!useExternalScaling)
182 eigen_assert( (!useExternalScaling ||
diag.size()==
n) &&
"When useExternalScaling is set, the caller must provide a valid 'diag'");
193 if (useExternalScaling)
194 for (Index
j = 0;
j <
n; ++
j)
201 if ( functor(x, fvec) < 0)
203 fnorm = fvec.stableNorm();
212 template<
typename FunctorType,
typename Scalar>
222 Index df_ret = functor.df(x, fjac);
231 wa2 = fjac.colwise().blueNorm();
233 fjac = qrfac.matrixQR();
234 permutation = qrfac.colsPermutation();
239 if (!useExternalScaling)
240 for (Index
j = 0;
j <
n; ++
j)
241 diag[
j] = (wa2[
j]==0.)? 1. : wa2[
j];
245 xnorm =
diag.cwiseProduct(x).stableNorm();
254 wa4.applyOnTheLeft(qrfac.householderQ().adjoint());
260 for (Index
j = 0;
j <
n; ++
j)
261 if (wa2[permutation.indices()[
j]] != 0.)
262 gnorm = (
std::max)(gnorm,
abs( fjac.col(
j).head(
j+1).dot(qtf.head(
j+1)/fnorm) / wa2[permutation.indices()[
j]]));
269 if (!useExternalScaling)
275 internal::lmpar2<Scalar>(qrfac,
diag, qtf,
delta, par, wa1);
280 pnorm = diag.cwiseProduct(wa1).stableNorm();
287 if ( functor(wa2, wa4) < 0)
290 fnorm1 = wa4.stableNorm();
294 if (
Scalar(.1) * fnorm1 < fnorm)
299 wa3 = fjac.template triangularView<Upper>() * (qrfac.colsPermutation().inverse() *wa1);
302 prered = temp1 + temp2 /
Scalar(.5);
303 dirder = -(temp1 + temp2);
309 ratio = actred / prered;
316 temp =
Scalar(.5) * dirder / (dirder +
Scalar(.5) * actred);
323 delta = pnorm /
Scalar(.5);
331 wa2 = diag.cwiseProduct(x);
333 xnorm = wa2.stableNorm();
361 template<
typename FunctorType,
typename Scalar>
369 m = functor.values();
372 if (n <= 0 ||
m < n || tol < 0.)
380 return minimizeOptimumStorage(x);
383 template<
typename FunctorType,
typename Scalar>
388 m = functor.values();
390 wa1.resize(n); wa2.resize(n); wa3.resize(n);
399 if (!useExternalScaling)
401 eigen_assert( (!useExternalScaling || diag.size()==
n) &&
"When useExternalScaling is set, the caller must provide a valid 'diag'");
412 if (useExternalScaling)
413 for (Index
j = 0;
j <
n; ++
j)
420 if ( functor(x, fvec) < 0)
422 fnorm = fvec.stableNorm();
432 template<
typename FunctorType,
typename Scalar>
451 for (i = 0; i <
m; ++
i) {
453 internal::rwupdt<Scalar>(fjac, wa3, qtf, fvec[
i]);
461 for (j = 0; j <
n; ++
j) {
464 wa2[
j] = fjac.col(j).head(j).stableNorm();
466 permutation.setIdentity(n);
468 wa2 = fjac.colwise().blueNorm();
473 wa1 = fjac.diagonal();
474 fjac.diagonal() = qrfac.
hCoeffs();
477 for(Index ii=0; ii< fjac.cols(); ii++) fjac.col(ii).segment(ii+1, fjac.rows()-ii-1) *= fjac(ii,ii);
479 for (j = 0; j <
n; ++
j) {
480 if (fjac(j,j) != 0.) {
482 for (i = j; i <
n; ++
i)
483 sum += fjac(i,j) * qtf[
i];
484 temp = -sum / fjac(j,j);
485 for (i = j; i <
n; ++
i)
486 qtf[i] += fjac(i,j) * temp;
495 if (!useExternalScaling)
496 for (j = 0; j <
n; ++
j)
497 diag[j] = (wa2[j]==0.)? 1. : wa2[
j];
501 xnorm = diag.cwiseProduct(x).stableNorm();
510 for (j = 0; j <
n; ++
j)
511 if (wa2[permutation.indices()[
j]] != 0.)
512 gnorm = (
std::max)(gnorm,
abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[
j]]));
519 if (!useExternalScaling)
520 diag = diag.cwiseMax(wa2);
525 internal::lmpar<Scalar>(fjac, permutation.indices(),
diag, qtf,
delta, par, wa1);
530 pnorm = diag.cwiseProduct(wa1).stableNorm();
537 if ( functor(wa2, wa4) < 0)
540 fnorm1 = wa4.stableNorm();
544 if (
Scalar(.1) * fnorm1 < fnorm)
549 wa3 = fjac.topLeftCorner(n,n).template triangularView<Upper>() * (permutation.inverse() * wa1);
552 prered = temp1 + temp2 /
Scalar(.5);
553 dirder = -(temp1 + temp2);
559 ratio = actred / prered;
566 temp =
Scalar(.5) * dirder / (dirder +
Scalar(.5) * actred);
573 delta = pnorm /
Scalar(.5);
581 wa2 = diag.cwiseProduct(x);
583 xnorm = wa2.stableNorm();
611 template<
typename FunctorType,
typename Scalar>
619 status = minimizeOptimumStorageOneStep(x);
624 template<
typename FunctorType,
typename Scalar>
634 Index
m = functor.values();
637 if (n <= 0 || m < n || tol < 0.)
655 #endif // EIGEN_LEVENBERGMARQUARDT__H
LevenbergMarquardtSpace::Status minimize(FVectorType &x)
Matrix< Scalar, Dynamic, Dynamic > JacobianType
static LevenbergMarquardtSpace::Status lmdif1(FunctorType &functor, FVectorType &x, Index *nfev, const Scalar tol=std::sqrt(NumTraits< Scalar >::epsilon()))
LevenbergMarquardtSpace::Status minimizeOneStep(FVectorType &x)
static Scalar sqrt_epsilon()
Matrix< Scalar, Dynamic, 1 > FVectorType
Performs non linear optimization over a non-linear function, using a variant of the Levenberg Marquar...
Matrix diag(const std::vector< Matrix > &Hs)
const HCoeffsType & hCoeffs() const
PermutationMatrix< Dynamic, Dynamic > permutation
JacobianType::Scalar Scalar
LevenbergMarquardtSpace::Status minimizeOptimumStorageInit(FVectorType &x)
Namespace containing all symbols from the Eigen library.
iterator iter(handle obj)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
void resetParameters(void)
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size ratio
LevenbergMarquardtSpace::Status lmstr1(FVectorType &x, const Scalar tol=sqrt_epsilon())
Householder rank-revealing QR decomposition of a matrix with column-pivoting.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
static ConjugateGradientParameters parameters
LevenbergMarquardtSpace::Status minimizeOptimumStorageOneStep(FVectorType &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex
LevenbergMarquardt(FunctorType &_functor)
LevenbergMarquardtSpace::Status minimizeInit(FVectorType &x)
LevenbergMarquardtSpace::Status minimizeOptimumStorage(FVectorType &x)
Jet< T, N > sqrt(const Jet< T, N > &f)
LevenbergMarquardtSpace::Status lmder1(FVectorType &x, const Scalar tol=std::sqrt(NumTraits< Scalar >::epsilon()))
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
const MatrixType & matrixQR() const
const PermutationType & colsPermutation() const
EIGEN_DEVICE_FUNC bool abs2(bool x)