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