NoAlias.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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@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. #ifndef EIGEN_NOALIAS_H
  10. #define EIGEN_NOALIAS_H
  11. namespace Eigen {
  12. /** \class NoAlias
  13. * \ingroup Core_Module
  14. *
  15. * \brief Pseudo expression providing an operator = assuming no aliasing
  16. *
  17. * \tparam ExpressionType the type of the object on which to do the lazy assignment
  18. *
  19. * This class represents an expression with special assignment operators
  20. * assuming no aliasing between the target expression and the source expression.
  21. * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression.
  22. * It is the return type of MatrixBase::noalias()
  23. * and most of the time this is the only way it is used.
  24. *
  25. * \sa MatrixBase::noalias()
  26. */
  27. template<typename ExpressionType, template <typename> class StorageBase>
  28. class NoAlias
  29. {
  30. public:
  31. typedef typename ExpressionType::Scalar Scalar;
  32. explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
  33. template<typename OtherDerived>
  34. EIGEN_DEVICE_FUNC
  35. EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
  36. {
  37. call_assignment_no_alias(m_expression, other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
  38. return m_expression;
  39. }
  40. template<typename OtherDerived>
  41. EIGEN_DEVICE_FUNC
  42. EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
  43. {
  44. call_assignment_no_alias(m_expression, other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
  45. return m_expression;
  46. }
  47. template<typename OtherDerived>
  48. EIGEN_DEVICE_FUNC
  49. EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
  50. {
  51. call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
  52. return m_expression;
  53. }
  54. EIGEN_DEVICE_FUNC
  55. ExpressionType& expression() const
  56. {
  57. return m_expression;
  58. }
  59. protected:
  60. ExpressionType& m_expression;
  61. };
  62. /** \returns a pseudo expression of \c *this with an operator= assuming
  63. * no aliasing between \c *this and the source expression.
  64. *
  65. * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
  66. * Currently, even though several expressions may alias, only product
  67. * expressions have this flag. Therefore, noalias() is only usefull when
  68. * the source expression contains a matrix product.
  69. *
  70. * Here are some examples where noalias is usefull:
  71. * \code
  72. * D.noalias() = A * B;
  73. * D.noalias() += A.transpose() * B;
  74. * D.noalias() -= 2 * A * B.adjoint();
  75. * \endcode
  76. *
  77. * On the other hand the following example will lead to a \b wrong result:
  78. * \code
  79. * A.noalias() = A * B;
  80. * \endcode
  81. * because the result matrix A is also an operand of the matrix product. Therefore,
  82. * there is no alternative than evaluating A * B in a temporary, that is the default
  83. * behavior when you write:
  84. * \code
  85. * A = A * B;
  86. * \endcode
  87. *
  88. * \sa class NoAlias
  89. */
  90. template<typename Derived>
  91. NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
  92. {
  93. return NoAlias<Derived, Eigen::MatrixBase >(derived());
  94. }
  95. } // end namespace Eigen
  96. #endif // EIGEN_NOALIAS_H