20#ifndef EIGEN_LEVENBERGMARQUARDT_H
21#define EIGEN_LEVENBERGMARQUARDT_H
24#include "./InternalHeaderCheck.h"
27namespace LevenbergMarquardtSpace {
31 ImproperInputParameters = 0,
32 RelativeReductionTooSmall = 1,
33 RelativeErrorTooSmall = 2,
34 RelativeErrorAndReductionTooSmall = 3,
36 TooManyFunctionEvaluation = 5,
44template <
typename Scalar_,
int NX = Dynamic,
int NY = Dynamic>
46 typedef Scalar_ Scalar;
47 enum { InputsAtCompileTime = NX, ValuesAtCompileTime = NY };
48 typedef Matrix<Scalar, InputsAtCompileTime, 1> InputType;
49 typedef Matrix<Scalar, ValuesAtCompileTime, 1> ValueType;
50 typedef Matrix<Scalar, ValuesAtCompileTime, InputsAtCompileTime> JacobianType;
51 typedef ColPivHouseholderQR<JacobianType> QRSolver;
52 const int m_inputs = InputsAtCompileTime;
53 const int m_values = ValuesAtCompileTime;
55 DenseFunctor() =
default;
56 DenseFunctor(
int inputs,
int values) : m_inputs(inputs), m_values(values) {}
58 int inputs()
const {
return m_inputs; }
59 int values()
const {
return m_values; }
68template <
typename Scalar_,
typename Index_>
70 typedef Scalar_ Scalar;
72 typedef Matrix<Scalar, Dynamic, 1> InputType;
73 typedef Matrix<Scalar, Dynamic, 1> ValueType;
74 typedef SparseMatrix<Scalar, ColMajor, Index> JacobianType;
75 typedef SparseQR<JacobianType, COLAMDOrdering<int> > QRSolver;
76 enum { InputsAtCompileTime = Dynamic, ValuesAtCompileTime = Dynamic };
78 SparseFunctor(
int inputs,
int values) : m_inputs(inputs), m_values(values) {}
80 int inputs()
const {
return m_inputs; }
81 int values()
const {
return m_values; }
83 const int m_inputs, m_values;
91template <
typename QRSolver,
typename VectorType>
92void lmpar2(
const QRSolver &qr,
const VectorType &diag,
const VectorType &qtb,
typename VectorType::Scalar m_delta,
93 typename VectorType::Scalar &par, VectorType &x);
103template <
typename FunctorType_>
104class LevenbergMarquardt : internal::no_assignment_operator {
106 typedef FunctorType_ FunctorType;
107 typedef typename FunctorType::QRSolver QRSolver;
108 typedef typename FunctorType::JacobianType JacobianType;
109 typedef typename JacobianType::Scalar Scalar;
110 typedef typename JacobianType::RealScalar RealScalar;
111 typedef typename QRSolver::StorageIndex PermIndex;
116 LevenbergMarquardt(FunctorType &functor)
117 : m_functor(functor),
122 m_isInitialized(
false),
125 m_useExternalScaling =
false;
128 LevenbergMarquardtSpace::Status minimize(FVectorType &x);
129 LevenbergMarquardtSpace::Status minimizeInit(FVectorType &x);
130 LevenbergMarquardtSpace::Status minimizeOneStep(FVectorType &x);
132 static LevenbergMarquardtSpace::Status lmdif1(FunctorType &functor, FVectorType &x, Index *nfev,
169 RealScalar
xtol()
const {
return m_xtol; }
172 RealScalar
ftol()
const {
return m_ftol; }
175 RealScalar
gtol()
const {
return m_gtol; }
178 RealScalar
factor()
const {
return m_factor; }
181 RealScalar
epsilon()
const {
return m_epsfcn; }
184 Index
maxfev()
const {
return m_maxfev; }
187 FVectorType &
diag() {
return m_diag; }
193 Index
nfev()
const {
return m_nfev; }
196 Index
njev()
const {
return m_njev; }
199 RealScalar
fnorm()
const {
return m_fnorm; }
202 RealScalar
gnorm()
const {
return m_gnorm; }
209 FVectorType &
fvec() {
return m_fvec; }
237 JacobianType m_rfactor;
238 FunctorType &m_functor;
239 FVectorType m_fvec, m_qtf, m_diag;
254 bool m_useExternalScaling;
255 PermutationType m_permutation;
256 FVectorType m_wa1, m_wa2, m_wa3, m_wa4;
258 bool m_isInitialized;
262template <
typename FunctorType>
263LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::minimize(FVectorType &x) {
264 LevenbergMarquardtSpace::Status status = minimizeInit(x);
265 if (status == LevenbergMarquardtSpace::ImproperInputParameters) {
266 m_isInitialized =
true;
270 status = minimizeOneStep(x);
271 }
while (status == LevenbergMarquardtSpace::Running);
272 m_isInitialized =
true;
276template <
typename FunctorType>
277LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::minimizeInit(FVectorType &x) {
279 m = m_functor.values();
288 if (!m_useExternalScaling) m_diag.resize(n);
289 eigen_assert((!m_useExternalScaling || m_diag.size() == n) &&
290 "When m_useExternalScaling is set, the caller must provide a valid 'm_diag'");
298 if (n <= 0 || m < n || m_ftol < 0. || m_xtol < 0. || m_gtol < 0. || m_maxfev <= 0 || m_factor <= 0.) {
300 return LevenbergMarquardtSpace::ImproperInputParameters;
303 if (m_useExternalScaling)
304 for (Index j = 0; j < n; ++j)
305 if (m_diag[j] <= 0.) {
307 return LevenbergMarquardtSpace::ImproperInputParameters;
313 if (m_functor(x, m_fvec) < 0)
return LevenbergMarquardtSpace::UserAsked;
314 m_fnorm = m_fvec.stableNorm();
320 return LevenbergMarquardtSpace::NotStarted;
323template <
typename FunctorType>
324LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::lmder1(FVectorType &x,
const Scalar tol) {
326 m = m_functor.values();
329 if (n <= 0 || m < n || tol < 0.)
return LevenbergMarquardtSpace::ImproperInputParameters;
334 m_maxfev = 100 * (n + 1);
339template <
typename FunctorType>
340LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::lmdif1(FunctorType &functor, FVectorType &x,
341 Index *nfev,
const Scalar tol) {
343 Index m = functor.values();
346 if (n <= 0 || m < n || tol < 0.)
return LevenbergMarquardtSpace::ImproperInputParameters;
353 lm.setMaxfev(200 * (n + 1));
355 LevenbergMarquardtSpace::Status info = LevenbergMarquardtSpace::Status(lm.minimize(x));
356 if (nfev) *nfev = lm.nfev();
Performs non linear optimization over a non-linear function, using a variant of the Levenberg Marquar...
Definition LevenbergMarquardt.h:104
RealScalar epsilon() const
Definition LevenbergMarquardt.h:181
ComputationInfo info() const
Reports whether the minimization was successful.
Definition LevenbergMarquardt.h:233
void setFtol(RealScalar ftol)
Definition LevenbergMarquardt.h:151
RealScalar gtol() const
Definition LevenbergMarquardt.h:175
void resetParameters()
Definition LevenbergMarquardt.h:136
RealScalar ftol() const
Definition LevenbergMarquardt.h:172
FVectorType & diag()
Definition LevenbergMarquardt.h:187
RealScalar gnorm() const
Definition LevenbergMarquardt.h:202
RealScalar fnorm() const
Definition LevenbergMarquardt.h:199
Index maxfev() const
Definition LevenbergMarquardt.h:184
void setExternalScaling(bool value)
Definition LevenbergMarquardt.h:166
RealScalar xtol() const
Definition LevenbergMarquardt.h:169
RealScalar lm_param(void) const
Definition LevenbergMarquardt.h:205
JacobianType & matrixR()
Definition LevenbergMarquardt.h:218
PermutationType permutation() const
Definition LevenbergMarquardt.h:222
void setGtol(RealScalar gtol)
Definition LevenbergMarquardt.h:154
void setEpsilon(RealScalar epsfcn)
Definition LevenbergMarquardt.h:160
void setXtol(RealScalar xtol)
Definition LevenbergMarquardt.h:148
FVectorType & fvec()
Definition LevenbergMarquardt.h:209
void setFactor(RealScalar factor)
Definition LevenbergMarquardt.h:157
RealScalar factor() const
Definition LevenbergMarquardt.h:178
Index nfev() const
Definition LevenbergMarquardt.h:193
void setMaxfev(Index maxfev)
Definition LevenbergMarquardt.h:163
Index njev() const
Definition LevenbergMarquardt.h:196
Index iterations() const
Definition LevenbergMarquardt.h:190
JacobianType & jacobian()
Definition LevenbergMarquardt.h:213
Definition NumericalDiff.h:51
Namespace containing all symbols from the Eigen library.