mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Fix default rank-detection threshold in QR and LU decompositions
libeigen/eigen!2232 Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
@@ -321,9 +321,10 @@ class FullPivLU : public SolverBase<FullPivLU<MatrixType_, PermutationIndex_> >
|
||||
RealScalar threshold() const {
|
||||
eigen_assert(m_isInitialized || m_usePrescribedThreshold);
|
||||
return m_usePrescribedThreshold ? m_prescribedThreshold
|
||||
// this formula comes from experimenting (see "LU precision tuning" thread on the
|
||||
// list) and turns out to be identical to Higham's formula used already in LDLt.
|
||||
: NumTraits<Scalar>::epsilon() * RealScalar(m_lu.diagonalSize());
|
||||
// Higham's backward error bound for Gaussian elimination with
|
||||
// complete pivoting (Theorem 9.4) is ||ΔA||₂ ≤ c·min(m,n)·u·||A||₂.
|
||||
// The factor of 4 covers the constant c.
|
||||
: NumTraits<Scalar>::epsilon() * RealScalar(4 * m_lu.diagonalSize());
|
||||
}
|
||||
|
||||
/** \returns the rank of the matrix of which *this is the LU decomposition.
|
||||
|
||||
@@ -375,9 +375,10 @@ class ColPivHouseholderQR : public SolverBase<ColPivHouseholderQR<MatrixType_, P
|
||||
RealScalar threshold() const {
|
||||
eigen_assert(m_isInitialized || m_usePrescribedThreshold);
|
||||
return m_usePrescribedThreshold ? m_prescribedThreshold
|
||||
// this formula comes from experimenting (see "LU precision tuning" thread on the
|
||||
// list) and turns out to be identical to Higham's formula used already in LDLt.
|
||||
: NumTraits<Scalar>::epsilon() * RealScalar(m_qr.diagonalSize());
|
||||
// Higham's backward error bound for Householder QR (Theorem 19.4) is
|
||||
// ||ΔA||₂ ≤ c·min(m,n)·u·||A||₂. The factor of 4 covers the
|
||||
// constant c (typically 3–6 worst-case, ~1 probabilistically).
|
||||
: NumTraits<Scalar>::epsilon() * RealScalar(4 * m_qr.diagonalSize());
|
||||
}
|
||||
|
||||
/** \returns the number of nonzero pivots in the QR decomposition.
|
||||
|
||||
@@ -97,7 +97,9 @@ struct ColPivHouseholderQR_LAPACKE_impl {
|
||||
|
||||
maxpivot = qr.diagonal().cwiseAbs().maxCoeff();
|
||||
hCoeffs.adjointInPlace();
|
||||
RealScalar defaultThreshold = NumTraits<RealScalar>::epsilon() * RealScalar(qr.diagonalSize());
|
||||
// Higham's backward error bound (Theorem 19.4): ||ΔA||₂ ≤ c·min(m,n)·u·||A||₂.
|
||||
// The factor of 4 covers the constant c (typically 3–6 worst-case).
|
||||
RealScalar defaultThreshold = NumTraits<RealScalar>::epsilon() * RealScalar(4 * qr.diagonalSize());
|
||||
RealScalar threshold = usePrescribedThreshold ? prescribedThreshold : defaultThreshold;
|
||||
RealScalar premultiplied_threshold = maxpivot * threshold;
|
||||
nonzero_pivots = (qr.diagonal().cwiseAbs().array() > premultiplied_threshold).count();
|
||||
|
||||
@@ -396,9 +396,10 @@ class FullPivHouseholderQR : public SolverBase<FullPivHouseholderQR<MatrixType_,
|
||||
RealScalar threshold() const {
|
||||
eigen_assert(m_isInitialized || m_usePrescribedThreshold);
|
||||
return m_usePrescribedThreshold ? m_prescribedThreshold
|
||||
// this formula comes from experimenting (see "LU precision tuning" thread on the
|
||||
// list) and turns out to be identical to Higham's formula used already in LDLt.
|
||||
: NumTraits<Scalar>::epsilon() * RealScalar(m_qr.diagonalSize());
|
||||
// Higham's backward error bound for Householder QR (Theorem 19.4) is
|
||||
// ||ΔA||₂ ≤ c·min(m,n)·u·||A||₂. The factor of 4 covers the
|
||||
// constant c (typically 3–6 worst-case, ~1 probabilistically).
|
||||
: NumTraits<Scalar>::epsilon() * RealScalar(4 * m_qr.diagonalSize());
|
||||
}
|
||||
|
||||
/** \returns the number of nonzero pivots in the QR decomposition.
|
||||
|
||||
Reference in New Issue
Block a user