16#include "./InternalHeaderCheck.h"
22template <
typename QRSolver,
typename VectorType>
23void lmpar2(
const QRSolver &qr,
const VectorType &diag,
const VectorType &qtb,
typename VectorType::Scalar m_delta,
24 typename VectorType::Scalar &par, VectorType &x)
29 typedef typename QRSolver::MatrixType MatrixType;
30 typedef typename QRSolver::Scalar Scalar;
48 const Scalar dwarf = (std::numeric_limits<Scalar>::min)();
49 const Index n = qr.matrixR().cols();
50 eigen_assert(n == diag.size());
51 eigen_assert(n == qtb.size());
59 const Index rank = qr.rank();
61 wa1.tail(n - rank).setZero();
63 wa1.head(rank) = s.topLeftCorner(rank, rank).template triangularView<Upper>().solve(qtb.head(rank));
65 x = qr.colsPermutation() * wa1;
71 wa2 = diag.cwiseProduct(x);
72 dxnorm = wa2.blueNorm();
73 fp = dxnorm - m_delta;
74 if (fp <= Scalar(0.1) * m_delta) {
84 wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2) / dxnorm;
85 s.topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
86 temp = wa1.blueNorm();
87 parl = fp / m_delta / temp / temp;
91 for (j = 0; j < n; ++j) wa1[j] = s.col(j).head(j + 1).dot(qtb.head(j + 1)) / diag[qr.colsPermutation().indices()(j)];
93 gnorm = wa1.stableNorm();
94 paru = gnorm / m_delta;
95 if (paru == 0.) paru = dwarf / (std::min)(m_delta, Scalar(0.1));
99 par = (std::max)(par, parl);
100 par = (std::min)(par, paru);
101 if (par == 0.) par = gnorm / dxnorm;
108 if (par == 0.) par = (std::max)(dwarf, Scalar(.001) * paru);
109 wa1 =
sqrt(par) * diag;
112 lmqrsolv(s, qr.colsPermutation(), wa1, qtb, x, sdiag);
114 wa2 = diag.cwiseProduct(x);
115 dxnorm = wa2.blueNorm();
117 fp = dxnorm - m_delta;
122 if (
abs(fp) <= Scalar(0.1) * m_delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10)
break;
125 wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2 / dxnorm);
127 for (j = 0; j < n; ++j) {
130 for (
Index i = j + 1; i < n; ++i) wa1[i] -= s.coeff(i, j) * temp;
132 temp = wa1.blueNorm();
133 parc = fp / m_delta / temp / temp;
136 if (fp > 0.) parl = (std::max)(parl, par);
137 if (fp < 0.) paru = (std::min)(paru, par);
140 par = (std::max)(parl, par + parc);
142 if (iter == 0) par = 0.;
Namespace containing all symbols from the Eigen library.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index