diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-08-16 10:55:10 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-08-16 10:55:10 +0200 |
commit | fc9480cbb38db2c7585e3ac5d14719237a85d2d7 (patch) | |
tree | 5de889a7cc9294b791f3bf06c4987360fa86dce7 /Eigen/src/Core/NoAlias.h | |
parent | ee982709d37e219e9d67beaf777a5bf2131e835e (diff) |
bugfix in compute_matrix_flags, optimization in LU,
improve doc, and workaround aliasing detection in MatrixBase_eval snippet
(not very nice but I don't know how to do it in a better way)
Diffstat (limited to 'Eigen/src/Core/NoAlias.h')
-rw-r--r-- | Eigen/src/Core/NoAlias.h | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h index 5c2b6e3ca..a45493ddc 100644 --- a/Eigen/src/Core/NoAlias.h +++ b/Eigen/src/Core/NoAlias.h @@ -31,8 +31,9 @@ * * \param ExpressionType the type of the object on which to do the lazy assignment * - * This class represents an expression with a special assignment operator (operator=) + * This class represents an expression with special assignment operators * assuming no aliasing between the target expression and the source expression. + * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression. * It is the return type of MatrixBase::noalias() * and most of the time this is the only way it is used. * @@ -44,44 +45,61 @@ class NoAlias public: NoAlias(ExpressionType& expression) : m_expression(expression) {} - /** Behaves like MatrixBase::lazyAssign() */ + /** Behaves like MatrixBase::lazyAssign(other) + * \sa MatrixBase::lazyAssign() */ template<typename OtherDerived> ExpressionType& operator=(const MatrixBase<OtherDerived>& other) - { - return m_expression.lazyAssign(other.derived()); - } + { return m_expression.lazyAssign(other.derived()); } - // TODO could be removed if we decide that += is noalias by default + /** \sa MatrixBase::operator+= */ template<typename OtherDerived> ExpressionType& operator+=(const MatrixBase<OtherDerived>& other) - { - return m_expression.lazyAssign(m_expression + other.derived()); - } + { return m_expression.lazyAssign(m_expression + other.derived()); } - // TODO could be removed if we decide that += is noalias by default + /** \sa MatrixBase::operator-= */ template<typename OtherDerived> ExpressionType& operator-=(const MatrixBase<OtherDerived>& other) - { - return m_expression.lazyAssign(m_expression - other.derived()); - } + { return m_expression.lazyAssign(m_expression - other.derived()); } - // TODO could be removed if we decide that += is noalias by default +#ifndef EIGEN_PARSED_BY_DOXYGEN template<typename ProductDerived, typename Lhs, typename Rhs> ExpressionType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other) { other.derived().addTo(m_expression); return m_expression; } - // TODO could be removed if we decide that += is noalias by default template<typename ProductDerived, typename Lhs, typename Rhs> ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other) { other.derived().subTo(m_expression); return m_expression; } +#endif protected: ExpressionType& m_expression; }; - /** \returns a pseudo expression of \c *this with an operator= assuming - * no aliasing between \c *this and the source expression + * no aliasing between \c *this and the source expression. + * + * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. + * Currently, even though several expressions may alias, only product + * expressions have this flag. Therefore, noalias() is only usefull when + * the source expression contains a matrix product. + * + * Here are some examples where noalias is usefull: + * \code + * D.noalias() = A * B; + * D.noalias() += A.transpose() * B; + * D.noalias() -= 2 * A * B.adjoint(); + * \endcode + * + * On the other hand the following example will lead to a \b wrong result: + * \code + * A.noalias() = A * B; + * \endcode + * because the result matrix A is also an operand of the matrix product. Therefore, + * there is no alternative than evaluating A * B in a temporary, that is the default + * behavior when you write: + * \code + * A = A * B; + * \endcode * * \sa class NoAlias */ |