aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-08-16 10:55:10 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-08-16 10:55:10 +0200
commitfc9480cbb38db2c7585e3ac5d14719237a85d2d7 (patch)
tree5de889a7cc9294b791f3bf06c4987360fa86dce7 /Eigen/src/Core
parentee982709d37e219e9d67beaf777a5bf2131e835e (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')
-rw-r--r--Eigen/src/Core/NoAlias.h52
-rw-r--r--Eigen/src/Core/ProductBase.h6
-rw-r--r--Eigen/src/Core/util/XprHelper.h2
3 files changed, 38 insertions, 22 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
*/
diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h
index 5e259b7f7..b2c4cd989 100644
--- a/Eigen/src/Core/ProductBase.h
+++ b/Eigen/src/Core/ProductBase.h
@@ -119,10 +119,8 @@ class ProductBase : public MatrixBase<Derived>
return res;
}
- const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const
- {
- return *this;
- }
+ EIGEN_DEPRECATED const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const
+ { return *this; }
const _LhsNested& lhs() const { return m_lhs; }
const _RhsNested& rhs() const { return m_rhs; }
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index d392e27ba..871259b08 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -90,7 +90,7 @@ class ei_compute_matrix_flags
: MaxRows==1 ? MaxCols
: row_major_bit ? MaxCols : MaxRows,
is_big = inner_max_size == Dynamic,
- is_packet_size_multiple = Rows==Dynamic || Cols==Dynamic || ((Cols*Rows) % ei_packet_traits<Scalar>::size) == 0,
+ is_packet_size_multiple = MaxRows==Dynamic || MaxCols==Dynamic || ((MaxCols*MaxRows) % ei_packet_traits<Scalar>::size) == 0,
aligned_bit = (((Options&DontAlign)==0) && (is_big || is_packet_size_multiple)) ? AlignedBit : 0,
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
};