Jaesung Oh / Eigen

Dependents:   MPC_current_control HydraulicControlBoard_SW AHRS Test_ekf ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NoAlias.h Source File

NoAlias.h

00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_NOALIAS_H
00011 #define EIGEN_NOALIAS_H
00012 
00013 namespace Eigen {
00014 
00015 /** \class NoAlias
00016   * \ingroup Core_Module
00017   *
00018   * \brief Pseudo expression providing an operator = assuming no aliasing
00019   *
00020   * \param ExpressionType the type of the object on which to do the lazy assignment
00021   *
00022   * This class represents an expression with special assignment operators
00023   * assuming no aliasing between the target expression and the source expression.
00024   * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression.
00025   * It is the return type of MatrixBase::noalias()
00026   * and most of the time this is the only way it is used.
00027   *
00028   * \sa MatrixBase::noalias()
00029   */
00030 template<typename ExpressionType, template <typename> class StorageBase>
00031 class NoAlias
00032 {
00033     typedef typename ExpressionType::Scalar Scalar;
00034   public:
00035     NoAlias(ExpressionType& expression) : m_expression(expression) {}
00036 
00037     /** Behaves like MatrixBase::lazyAssign(other)
00038       * \sa MatrixBase::lazyAssign() */
00039     template<typename OtherDerived>
00040     EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
00041     { return internal::assign_selector<ExpressionType,OtherDerived,false>::run(m_expression,other.derived()); }
00042 
00043     /** \sa MatrixBase::operator+= */
00044     template<typename OtherDerived>
00045     EIGEN_STRONG_INLINE ExpressionType& operator+= (const StorageBase<OtherDerived>& other)
00046     {
00047       typedef SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
00048       SelfAdder tmp(m_expression);
00049       typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
00050       typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
00051       internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
00052       return m_expression;
00053     }
00054 
00055     /** \sa MatrixBase::operator-= */
00056     template<typename OtherDerived>
00057     EIGEN_STRONG_INLINE ExpressionType& operator-= (const StorageBase<OtherDerived>& other)
00058     {
00059       typedef SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
00060       SelfAdder tmp(m_expression);
00061       typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
00062       typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
00063       internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
00064       return m_expression;
00065     }
00066 
00067 #ifndef EIGEN_PARSED_BY_DOXYGEN
00068     template<typename ProductDerived, typename Lhs, typename Rhs>
00069     EIGEN_STRONG_INLINE ExpressionType& operator+= (const ProductBase<ProductDerived, Lhs,Rhs>& other)
00070     { other.derived().addTo(m_expression); return m_expression; }
00071 
00072     template<typename ProductDerived, typename Lhs, typename Rhs>
00073     EIGEN_STRONG_INLINE ExpressionType& operator-= (const ProductBase<ProductDerived, Lhs,Rhs>& other)
00074     { other.derived().subTo(m_expression); return m_expression; }
00075 
00076     template<typename Lhs, typename Rhs, int NestingFlags>
00077     EIGEN_STRONG_INLINE ExpressionType& operator+= (const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
00078     { return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
00079 
00080     template<typename Lhs, typename Rhs, int NestingFlags>
00081     EIGEN_STRONG_INLINE ExpressionType& operator-= (const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
00082     { return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
00083     
00084     template<typename OtherDerived>
00085     ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
00086     { return m_expression = func; }
00087 #endif
00088 
00089     ExpressionType& expression() const
00090     {
00091       return m_expression;
00092     }
00093 
00094   protected:
00095     ExpressionType& m_expression;
00096 };
00097 
00098 /** \returns a pseudo expression of \c *this with an operator= assuming
00099   * no aliasing between \c *this and the source expression.
00100   *
00101   * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
00102   * Currently, even though several expressions may alias, only product
00103   * expressions have this flag. Therefore, noalias() is only usefull when
00104   * the source expression contains a matrix product.
00105   *
00106   * Here are some examples where noalias is usefull:
00107   * \code
00108   * D.noalias()  = A * B;
00109   * D.noalias() += A.transpose() * B;
00110   * D.noalias() -= 2 * A * B.adjoint();
00111   * \endcode
00112   *
00113   * On the other hand the following example will lead to a \b wrong result:
00114   * \code
00115   * A.noalias() = A * B;
00116   * \endcode
00117   * because the result matrix A is also an operand of the matrix product. Therefore,
00118   * there is no alternative than evaluating A * B in a temporary, that is the default
00119   * behavior when you write:
00120   * \code
00121   * A = A * B;
00122   * \endcode
00123   *
00124   * \sa class NoAlias
00125   */
00126 template<typename Derived>
00127 NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias ()
00128 {
00129   return derived();
00130 }
00131 
00132 } // end namespace Eigen
00133 
00134 #endif // EIGEN_NOALIAS_H