aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-06-01 09:17:50 -0400
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-06-01 09:17:50 -0400
commite54faba198a67a6177ca3743a3b884a77aa92512 (patch)
treeb7902687bbbbfec13b14383b0dd363bc4c38748a /Eigen/src
parent09a1b7f7e1ec09f96dd0f58bb6bc22881e0c76b6 (diff)
parent3e95609cd4f036ccb647f9a590062cdb250e9760 (diff)
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()
Diffstat (limited to 'Eigen/src')
-rw-r--r--Eigen/src/Core/NoAlias.h10
-rw-r--r--Eigen/src/Core/ReturnByValue.h11
-rw-r--r--Eigen/src/LU/Inverse.h12
3 files changed, 16 insertions, 17 deletions
diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h
index 0542571e2..30ddbeb3c 100644
--- a/Eigen/src/Core/NoAlias.h
+++ b/Eigen/src/Core/NoAlias.h
@@ -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)
diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h
index 665d48031..90887356c 100644
--- a/Eigen/src/Core/ReturnByValue.h
+++ b/Eigen/src/Core/ReturnByValue.h
@@ -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
diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h
index ed1724dda..9e4e1dccf 100644
--- a/Eigen/src/LU/Inverse.h
+++ b/Eigen/src/LU/Inverse.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);
}