mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
fix: issue 2481: LDLT produce wrong results with AutoDiffScalar
This commit is contained in:
parent
477eb7f630
commit
e99163e732
@ -78,7 +78,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
|
|||||||
if (k>0)
|
if (k>0)
|
||||||
rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map<const Matrix<RhsScalar,Dynamic,1> >(rhs+s,k))).sum();
|
rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map<const Matrix<RhsScalar,Dynamic,1> >(rhs+s,k))).sum();
|
||||||
|
|
||||||
if((!(Mode & UnitDiag)) && numext::not_equal_strict(rhs[i],RhsScalar(0)))
|
if((!(Mode & UnitDiag)) && !is_identically_zero(rhs[i]))
|
||||||
rhs[i] /= cjLhs(i,i);
|
rhs[i] /= cjLhs(i,i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
|
|||||||
for(Index k=0; k<actualPanelWidth; ++k)
|
for(Index k=0; k<actualPanelWidth; ++k)
|
||||||
{
|
{
|
||||||
Index i = IsLower ? pi+k : pi-k-1;
|
Index i = IsLower ? pi+k : pi-k-1;
|
||||||
if(numext::not_equal_strict(rhs[i],RhsScalar(0)))
|
if(!is_identically_zero(rhs[i]))
|
||||||
{
|
{
|
||||||
if(!(Mode & UnitDiag))
|
if(!(Mode & UnitDiag))
|
||||||
rhs[i] /= cjLhs.coeff(i,i);
|
rhs[i] /= cjLhs.coeff(i,i);
|
||||||
|
@ -441,6 +441,17 @@ bool not_equal_strict(const double& x,const double& y) { return std::not_equal_t
|
|||||||
} // end namespace numext
|
} // end namespace numext
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename Scalar>
|
||||||
|
struct is_identically_zero_impl {
|
||||||
|
static inline bool run(const Scalar& s) {
|
||||||
|
return numext::is_exactly_zero(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Scalar> EIGEN_STRONG_INLINE
|
||||||
|
bool is_identically_zero(const Scalar& s) { return is_identically_zero_impl<Scalar>::run(s); }
|
||||||
|
|
||||||
/// \internal Returns true if its argument is of integer or enum type.
|
/// \internal Returns true if its argument is of integer or enum type.
|
||||||
/// FIXME this has the same purpose as `is_valid_index_type` in XprHelper.h
|
/// FIXME this has the same purpose as `is_valid_index_type` in XprHelper.h
|
||||||
template<typename A>
|
template<typename A>
|
||||||
|
@ -715,6 +715,23 @@ template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
template<typename DerivativeType>
|
||||||
|
struct is_identically_zero_impl<AutoDiffScalar<DerivativeType>> {
|
||||||
|
static inline bool run(const AutoDiffScalar<DerivativeType>& s)
|
||||||
|
{
|
||||||
|
const DerivativeType& derivatives = s.derivatives();
|
||||||
|
for(int i=0; i<derivatives.size(); ++i)
|
||||||
|
{
|
||||||
|
if(!numext::is_exactly_zero(derivatives[i]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numext::is_exactly_zero(s.value());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user