aboutsummaryrefslogtreecommitdiffhomepage
path: root/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
diff options
context:
space:
mode:
Diffstat (limited to 'unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h')
-rw-r--r--unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h66
1 files changed, 45 insertions, 21 deletions
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h b/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
index 51ade866c..351c28c2c 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
@@ -40,13 +40,14 @@ LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)
/* compute the qr factorization of the jacobian. */
for (int j = 0; j < x.size(); ++j)
- m_wa2(j) = m_fjac.col(j).norm();
- //FIXME Implement bluenorm for sparse vectors
-// m_wa2 = m_fjac.colwise().blueNorm();
- QRSolver qrfac(m_fjac); //FIXME Check if the QR decomposition succeed
+ m_wa2(j) = m_fjac.col(j).blueNorm();
+ QRSolver qrfac(m_fjac);
+ if(qrfac.info() != Success) {
+ m_info = NumericalIssue;
+ return LevenbergMarquardtSpace::ImproperInputParameters;
+ }
// Make a copy of the first factor with the associated permutation
- JacobianType rfactor;
- rfactor = qrfac.matrixQR();
+ m_rfactor = qrfac.matrixR();
m_permutation = (qrfac.colsPermutation());
/* on the first iteration and if external scaling is not used, scale according */
@@ -75,11 +76,13 @@ LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)
if (m_fnorm != 0.)
for (Index j = 0; j < n; ++j)
if (m_wa2[m_permutation.indices()[j]] != 0.)
- m_gnorm = (std::max)(m_gnorm, abs( rfactor.col(j).head(j+1).dot(m_qtf.head(j+1)/m_fnorm) / m_wa2[m_permutation.indices()[j]]));
+ m_gnorm = (std::max)(m_gnorm, abs( m_rfactor.col(j).head(j+1).dot(m_qtf.head(j+1)/m_fnorm) / m_wa2[m_permutation.indices()[j]]));
/* test for convergence of the gradient norm. */
- if (m_gnorm <= m_gtol)
- return LevenbergMarquardtSpace::CosinusTooSmall;
+ if (m_gnorm <= m_gtol) {
+ m_info = Success;
+ return LevenbergMarquardtSpace::CosinusTooSmall;
+ }
/* rescale if necessary. */
if (!m_useExternalScaling)
@@ -111,7 +114,7 @@ LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)
/* compute the scaled predicted reduction and */
/* the scaled directional derivative. */
- m_wa3 = rfactor.template triangularView<Upper>() * (m_permutation.inverse() *m_wa1);
+ m_wa3 = m_rfactor.template triangularView<Upper>() * (m_permutation.inverse() *m_wa1);
temp1 = internal::abs2(m_wa3.stableNorm() / m_fnorm);
temp2 = internal::abs2(sqrt(m_par) * pnorm / m_fnorm);
prered = temp1 + temp2 / Scalar(.5);
@@ -152,21 +155,42 @@ LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)
/* tests for convergence. */
if (abs(actred) <= m_ftol && prered <= m_ftol && Scalar(.5) * ratio <= 1. && m_delta <= m_xtol * xnorm)
- return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;
- if (abs(actred) <= m_ftol && prered <= m_ftol && Scalar(.5) * ratio <= 1.)
- return LevenbergMarquardtSpace::RelativeReductionTooSmall;
+ {
+ m_info = Success;
+ return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;
+ }
+ if (abs(actred) <= m_ftol && prered <= m_ftol && Scalar(.5) * ratio <= 1.)
+ {
+ m_info = Success;
+ return LevenbergMarquardtSpace::RelativeReductionTooSmall;
+ }
if (m_delta <= m_xtol * xnorm)
- return LevenbergMarquardtSpace::RelativeErrorTooSmall;
+ {
+ m_info = Success;
+ return LevenbergMarquardtSpace::RelativeErrorTooSmall;
+ }
/* tests for termination and stringent tolerances. */
- if (m_nfev >= m_maxfev)
- return LevenbergMarquardtSpace::TooManyFunctionEvaluation;
+ if (m_nfev >= m_maxfev)
+ {
+ m_info = NoConvergence;
+ return LevenbergMarquardtSpace::TooManyFunctionEvaluation;
+ }
if (abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)
- return LevenbergMarquardtSpace::FtolTooSmall;
- if (m_delta <= NumTraits<Scalar>::epsilon() * xnorm)
- return LevenbergMarquardtSpace::XtolTooSmall;
+ {
+ m_info = Success;
+ return LevenbergMarquardtSpace::FtolTooSmall;
+ }
+ if (m_delta <= NumTraits<Scalar>::epsilon() * xnorm)
+ {
+ m_info = Success;
+ return LevenbergMarquardtSpace::XtolTooSmall;
+ }
if (m_gnorm <= NumTraits<Scalar>::epsilon())
- return LevenbergMarquardtSpace::GtolTooSmall;
+ {
+ m_info = Success;
+ return LevenbergMarquardtSpace::GtolTooSmall;
+ }
} while (ratio < Scalar(1e-4));
@@ -176,4 +200,4 @@ LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)
} // end namespace Eigen
-#endif // EIGEN_LMONESTEP_H
+#endif // EIGEN_LMONESTEP_H \ No newline at end of file