mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-01 18:26:24 +08:00
merge the backing-out of the stupid RetByVal change, and implement a simple
aliasing check in inverse, that catches simple cases like x = x.inverse()
This commit is contained in:
commit
e54faba198
@ -45,18 +45,12 @@ class NoAlias
|
||||
public:
|
||||
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||
|
||||
/* \sa MatrixBase::lazyAssign() */
|
||||
/** Behaves like MatrixBase::lazyAssign(other)
|
||||
* \sa MatrixBase::lazyAssign() */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
||||
{ return m_expression.lazyAssign(other.derived()); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
other.evalTo(m_expression);
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
/** \sa MatrixBase::operator+= */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
|
||||
|
@ -36,9 +36,9 @@ struct ei_traits<ReturnByValue<Derived> >
|
||||
enum {
|
||||
// We're disabling the DirectAccess because e.g. the constructor of
|
||||
// the Block-with-DirectAccess expression requires to have a coeffRef method.
|
||||
// FIXME this should be fixed so we can have DirectAccessBit here.
|
||||
// Also, we don't want to have to implement the stride stuff.
|
||||
Flags = (ei_traits<typename ei_traits<Derived>::ReturnType>::Flags
|
||||
| EvalBeforeNestingBit | EvalBeforeAssigningBit) & ~DirectAccessBit
|
||||
| EvalBeforeNestingBit) & ~DirectAccessBit
|
||||
};
|
||||
};
|
||||
|
||||
@ -84,11 +84,8 @@ template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
// since we're by-passing the mechanisms in Assign.h, we implement here the EvalBeforeAssigningBit.
|
||||
// override by using .noalias(), see corresponding operator= in NoAlias.
|
||||
typename Derived::PlainObject result(rows(), cols());
|
||||
other.evalTo(result);
|
||||
return (derived() = result);
|
||||
other.evalTo(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
#endif // EIGEN_RETURNBYVALUE_H
|
||||
|
@ -284,7 +284,6 @@ struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename ei_eval<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ei_cleantype<MatrixTypeNested>::type MatrixTypeNestedCleaned;
|
||||
|
||||
const MatrixTypeNested m_matrix;
|
||||
|
||||
ei_inverse_impl(const MatrixType& matrix)
|
||||
@ -296,6 +295,8 @@ struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
// FIXME this is a naive aliasing check that could be improved. It only catches x = x.inverse();
|
||||
ei_assert(&dst != &m_matrix && "Aliasing problem detected in inverse(), you need to do inverse().eval() here.");
|
||||
ei_compute_inverse<MatrixTypeNestedCleaned, Dest>::run(m_matrix, dst);
|
||||
}
|
||||
};
|
||||
@ -354,7 +355,14 @@ inline void MatrixBase<Derived>::computeInverseAndDetWithCheck(
|
||||
{
|
||||
// i'd love to put some static assertions there, but SFINAE means that they have no effect...
|
||||
ei_assert(rows() == cols());
|
||||
ei_compute_inverse_and_det_with_check<PlainObject, ResultType>::run
|
||||
// for 2x2, it's worth giving a chance to avoid evaluating.
|
||||
// for larger sizes, evaluating has negligible cost and limits code size.
|
||||
typedef typename ei_meta_if<
|
||||
RowsAtCompileTime == 2,
|
||||
typename ei_cleantype<typename ei_nested<Derived, 2>::type>::type,
|
||||
PlainObject
|
||||
>::ret MatrixType;
|
||||
ei_compute_inverse_and_det_with_check<MatrixType, ResultType>::run
|
||||
(derived(), absDeterminantThreshold, inverse, determinant, invertible);
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,7 @@ template<typename MatrixType> void inverse_general_4x4(int repeat)
|
||||
double error_avg = error_sum / repeat;
|
||||
EIGEN_DEBUG_VAR(error_avg);
|
||||
EIGEN_DEBUG_VAR(error_max);
|
||||
// FIXME that 1.3 used to be a 1.0 until the NumTraits changes on 28 April 2010, and then a 1.2 until the ReturnByValue/Inverse changes
|
||||
// on 30 May 2010, what's going wrong (if anything) ??
|
||||
VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.3));
|
||||
VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.2)); // FIXME that 1.2 used to be a 1.0 until the NumTraits changes on 28 April 2010, what's going wrong??
|
||||
VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user