Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:56:15

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0009 
0010 #ifndef EIGEN_NOALIAS_H
0011 #define EIGEN_NOALIAS_H
0012 
0013 namespace Eigen {
0014 
0015 /** \class NoAlias
0016   * \ingroup Core_Module
0017   *
0018   * \brief Pseudo expression providing an operator = assuming no aliasing
0019   *
0020   * \tparam ExpressionType the type of the object on which to do the lazy assignment
0021   *
0022   * This class represents an expression with special assignment operators
0023   * assuming no aliasing between the target expression and the source expression.
0024   * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression.
0025   * It is the return type of MatrixBase::noalias()
0026   * and most of the time this is the only way it is used.
0027   *
0028   * \sa MatrixBase::noalias()
0029   */
0030 template<typename ExpressionType, template <typename> class StorageBase>
0031 class NoAlias
0032 {
0033   public:
0034     typedef typename ExpressionType::Scalar Scalar;
0035     
0036     EIGEN_DEVICE_FUNC
0037     explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
0038     
0039     template<typename OtherDerived>
0040     EIGEN_DEVICE_FUNC
0041     EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
0042     {
0043       call_assignment_no_alias(m_expression, other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
0044       return m_expression;
0045     }
0046     
0047     template<typename OtherDerived>
0048     EIGEN_DEVICE_FUNC
0049     EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
0050     {
0051       call_assignment_no_alias(m_expression, other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
0052       return m_expression;
0053     }
0054     
0055     template<typename OtherDerived>
0056     EIGEN_DEVICE_FUNC
0057     EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
0058     {
0059       call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
0060       return m_expression;
0061     }
0062 
0063     EIGEN_DEVICE_FUNC
0064     ExpressionType& expression() const
0065     {
0066       return m_expression;
0067     }
0068 
0069   protected:
0070     ExpressionType& m_expression;
0071 };
0072 
0073 /** \returns a pseudo expression of \c *this with an operator= assuming
0074   * no aliasing between \c *this and the source expression.
0075   *
0076   * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
0077   * Currently, even though several expressions may alias, only product
0078   * expressions have this flag. Therefore, noalias() is only useful when
0079   * the source expression contains a matrix product.
0080   *
0081   * Here are some examples where noalias is useful:
0082   * \code
0083   * D.noalias()  = A * B;
0084   * D.noalias() += A.transpose() * B;
0085   * D.noalias() -= 2 * A * B.adjoint();
0086   * \endcode
0087   *
0088   * On the other hand the following example will lead to a \b wrong result:
0089   * \code
0090   * A.noalias() = A * B;
0091   * \endcode
0092   * because the result matrix A is also an operand of the matrix product. Therefore,
0093   * there is no alternative than evaluating A * B in a temporary, that is the default
0094   * behavior when you write:
0095   * \code
0096   * A = A * B;
0097   * \endcode
0098   *
0099   * \sa class NoAlias
0100   */
0101 template<typename Derived>
0102 NoAlias<Derived,MatrixBase> EIGEN_DEVICE_FUNC MatrixBase<Derived>::noalias()
0103 {
0104   return NoAlias<Derived, Eigen::MatrixBase >(derived());
0105 }
0106 
0107 } // end namespace Eigen
0108 
0109 #endif // EIGEN_NOALIAS_H