Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_NOALIAS_H
     11 #define EIGEN_NOALIAS_H
     12 
     13 namespace Eigen {
     14 
     15 /** \class NoAlias
     16   * \ingroup Core_Module
     17   *
     18   * \brief Pseudo expression providing an operator = assuming no aliasing
     19   *
     20   * \tparam ExpressionType the type of the object on which to do the lazy assignment
     21   *
     22   * This class represents an expression with special assignment operators
     23   * assuming no aliasing between the target expression and the source expression.
     24   * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression.
     25   * It is the return type of MatrixBase::noalias()
     26   * and most of the time this is the only way it is used.
     27   *
     28   * \sa MatrixBase::noalias()
     29   */
     30 template<typename ExpressionType, template <typename> class StorageBase>
     31 class NoAlias
     32 {
     33   public:
     34     typedef typename ExpressionType::Scalar Scalar;
     35 
     36     explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
     37 
     38     template<typename OtherDerived>
     39     EIGEN_DEVICE_FUNC
     40     EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
     41     {
     42       call_assignment_no_alias(m_expression, other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
     43       return m_expression;
     44     }
     45 
     46     template<typename OtherDerived>
     47     EIGEN_DEVICE_FUNC
     48     EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
     49     {
     50       call_assignment_no_alias(m_expression, other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
     51       return m_expression;
     52     }
     53 
     54     template<typename OtherDerived>
     55     EIGEN_DEVICE_FUNC
     56     EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
     57     {
     58       call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
     59       return m_expression;
     60     }
     61 
     62     EIGEN_DEVICE_FUNC
     63     ExpressionType& expression() const
     64     {
     65       return m_expression;
     66     }
     67 
     68   protected:
     69     ExpressionType& m_expression;
     70 };
     71 
     72 /** \returns a pseudo expression of \c *this with an operator= assuming
     73   * no aliasing between \c *this and the source expression.
     74   *
     75   * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
     76   * Currently, even though several expressions may alias, only product
     77   * expressions have this flag. Therefore, noalias() is only usefull when
     78   * the source expression contains a matrix product.
     79   *
     80   * Here are some examples where noalias is usefull:
     81   * \code
     82   * D.noalias()  = A * B;
     83   * D.noalias() += A.transpose() * B;
     84   * D.noalias() -= 2 * A * B.adjoint();
     85   * \endcode
     86   *
     87   * On the other hand the following example will lead to a \b wrong result:
     88   * \code
     89   * A.noalias() = A * B;
     90   * \endcode
     91   * because the result matrix A is also an operand of the matrix product. Therefore,
     92   * there is no alternative than evaluating A * B in a temporary, that is the default
     93   * behavior when you write:
     94   * \code
     95   * A = A * B;
     96   * \endcode
     97   *
     98   * \sa class NoAlias
     99   */
    100 template<typename Derived>
    101 NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
    102 {
    103   return NoAlias<Derived, Eigen::MatrixBase >(derived());
    104 }
    105 
    106 } // end namespace Eigen
    107 
    108 #endif // EIGEN_NOALIAS_H
    109