1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_NOALIAS_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_NOALIAS_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \class NoAlias
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \ingroup Core_Module
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \brief Pseudo expression providing an operator = assuming no aliasing
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \param ExpressionType the type of the object on which to do the lazy assignment
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * This class represents an expression with special assignment operators
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * assuming no aliasing between the target expression and the source expression.
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression.
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * It is the return type of MatrixBase::noalias()
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * and most of the time this is the only way it is used.
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \sa MatrixBase::noalias()
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, template <typename> class StorageBase>
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass NoAlias
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ExpressionType::Scalar Scalar;
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    NoAlias(ExpressionType& expression) : m_expression(expression) {}
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Behaves like MatrixBase::lazyAssign(other)
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa MatrixBase::lazyAssign() */
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return internal::assign_selector<ExpressionType,OtherDerived,false>::run(m_expression,other.derived()); }
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::operator+= */
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      SelfAdder tmp(m_expression);
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_expression;
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::operator-= */
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      SelfAdder tmp(m_expression);
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_expression;
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_PARSED_BY_DOXYGEN
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived, typename Lhs, typename Rhs>
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { other.derived().addTo(m_expression); return m_expression; }
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived, typename Lhs, typename Rhs>
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { other.derived().subTo(m_expression); return m_expression; }
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Lhs, typename Rhs, int NestingFlags>
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Lhs, typename Rhs, int NestingFlags>
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    template<typename OtherDerived>
857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    { return m_expression = func; }
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    ExpressionType& expression() const
907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    {
917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return m_expression;
927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ExpressionType& m_expression;
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns a pseudo expression of \c *this with an operator= assuming
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * no aliasing between \c *this and the source expression.
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Currently, even though several expressions may alias, only product
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * expressions have this flag. Therefore, noalias() is only usefull when
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * the source expression contains a matrix product.
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Here are some examples where noalias is usefull:
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \code
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * D.noalias()  = A * B;
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * D.noalias() += A.transpose() * B;
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * D.noalias() -= 2 * A * B.adjoint();
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \endcode
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * On the other hand the following example will lead to a \b wrong result:
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \code
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * A.noalias() = A * B;
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \endcode
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * because the result matrix A is also an operand of the matrix product. Therefore,
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * there is no alternative than evaluating A * B in a temporary, that is the default
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * behavior when you write:
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \code
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * A = A * B;
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \endcode
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \sa class NoAlias
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathNoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return derived();
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_NOALIAS_H
135