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