CwiseBinaryOp.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
  5. // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
  6. //
  7. // This Source Code Form is subject to the terms of the Mozilla
  8. // Public License v. 2.0. If a copy of the MPL was not distributed
  9. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  10. #ifndef EIGEN_CWISE_BINARY_OP_H
  11. #define EIGEN_CWISE_BINARY_OP_H
  12. namespace Eigen {
  13. namespace internal {
  14. template<typename BinaryOp, typename Lhs, typename Rhs>
  15. struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
  16. {
  17. // we must not inherit from traits<Lhs> since it has
  18. // the potential to cause problems with MSVC
  19. typedef typename remove_all<Lhs>::type Ancestor;
  20. typedef typename traits<Ancestor>::XprKind XprKind;
  21. enum {
  22. RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
  23. ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
  24. MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
  25. MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
  26. };
  27. // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor),
  28. // we still want to handle the case when the result type is different.
  29. typedef typename result_of<
  30. BinaryOp(
  31. const typename Lhs::Scalar&,
  32. const typename Rhs::Scalar&
  33. )
  34. >::type Scalar;
  35. typedef typename cwise_promote_storage_type<typename traits<Lhs>::StorageKind,
  36. typename traits<Rhs>::StorageKind,
  37. BinaryOp>::ret StorageKind;
  38. typedef typename promote_index_type<typename traits<Lhs>::StorageIndex,
  39. typename traits<Rhs>::StorageIndex>::type StorageIndex;
  40. typedef typename Lhs::Nested LhsNested;
  41. typedef typename Rhs::Nested RhsNested;
  42. typedef typename remove_reference<LhsNested>::type _LhsNested;
  43. typedef typename remove_reference<RhsNested>::type _RhsNested;
  44. enum {
  45. Flags = cwise_promote_storage_order<typename traits<Lhs>::StorageKind,typename traits<Rhs>::StorageKind,_LhsNested::Flags & RowMajorBit,_RhsNested::Flags & RowMajorBit>::value
  46. };
  47. };
  48. } // end namespace internal
  49. template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
  50. class CwiseBinaryOpImpl;
  51. /** \class CwiseBinaryOp
  52. * \ingroup Core_Module
  53. *
  54. * \brief Generic expression where a coefficient-wise binary operator is applied to two expressions
  55. *
  56. * \tparam BinaryOp template functor implementing the operator
  57. * \tparam LhsType the type of the left-hand side
  58. * \tparam RhsType the type of the right-hand side
  59. *
  60. * This class represents an expression where a coefficient-wise binary operator is applied to two expressions.
  61. * It is the return type of binary operators, by which we mean only those binary operators where
  62. * both the left-hand side and the right-hand side are Eigen expressions.
  63. * For example, the return type of matrix1+matrix2 is a CwiseBinaryOp.
  64. *
  65. * Most of the time, this is the only way that it is used, so you typically don't have to name
  66. * CwiseBinaryOp types explicitly.
  67. *
  68. * \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp
  69. */
  70. template<typename BinaryOp, typename LhsType, typename RhsType>
  71. class CwiseBinaryOp :
  72. public CwiseBinaryOpImpl<
  73. BinaryOp, LhsType, RhsType,
  74. typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
  75. typename internal::traits<RhsType>::StorageKind,
  76. BinaryOp>::ret>,
  77. internal::no_assignment_operator
  78. {
  79. public:
  80. typedef typename internal::remove_all<BinaryOp>::type Functor;
  81. typedef typename internal::remove_all<LhsType>::type Lhs;
  82. typedef typename internal::remove_all<RhsType>::type Rhs;
  83. typedef typename CwiseBinaryOpImpl<
  84. BinaryOp, LhsType, RhsType,
  85. typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
  86. typename internal::traits<Rhs>::StorageKind,
  87. BinaryOp>::ret>::Base Base;
  88. EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
  89. typedef typename internal::ref_selector<LhsType>::type LhsNested;
  90. typedef typename internal::ref_selector<RhsType>::type RhsNested;
  91. typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
  92. typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
  93. EIGEN_DEVICE_FUNC
  94. EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
  95. : m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
  96. {
  97. EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
  98. // require the sizes to match
  99. EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
  100. eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
  101. }
  102. EIGEN_DEVICE_FUNC
  103. EIGEN_STRONG_INLINE Index rows() const {
  104. // return the fixed size type if available to enable compile time optimizations
  105. if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
  106. return m_rhs.rows();
  107. else
  108. return m_lhs.rows();
  109. }
  110. EIGEN_DEVICE_FUNC
  111. EIGEN_STRONG_INLINE Index cols() const {
  112. // return the fixed size type if available to enable compile time optimizations
  113. if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
  114. return m_rhs.cols();
  115. else
  116. return m_lhs.cols();
  117. }
  118. /** \returns the left hand side nested expression */
  119. EIGEN_DEVICE_FUNC
  120. const _LhsNested& lhs() const { return m_lhs; }
  121. /** \returns the right hand side nested expression */
  122. EIGEN_DEVICE_FUNC
  123. const _RhsNested& rhs() const { return m_rhs; }
  124. /** \returns the functor representing the binary operation */
  125. EIGEN_DEVICE_FUNC
  126. const BinaryOp& functor() const { return m_functor; }
  127. protected:
  128. LhsNested m_lhs;
  129. RhsNested m_rhs;
  130. const BinaryOp m_functor;
  131. };
  132. // Generic API dispatcher
  133. template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
  134. class CwiseBinaryOpImpl
  135. : public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
  136. {
  137. public:
  138. typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
  139. };
  140. /** replaces \c *this by \c *this - \a other.
  141. *
  142. * \returns a reference to \c *this
  143. */
  144. template<typename Derived>
  145. template<typename OtherDerived>
  146. EIGEN_STRONG_INLINE Derived &
  147. MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
  148. {
  149. call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
  150. return derived();
  151. }
  152. /** replaces \c *this by \c *this + \a other.
  153. *
  154. * \returns a reference to \c *this
  155. */
  156. template<typename Derived>
  157. template<typename OtherDerived>
  158. EIGEN_STRONG_INLINE Derived &
  159. MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
  160. {
  161. call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
  162. return derived();
  163. }
  164. } // end namespace Eigen
  165. #endif // EIGEN_CWISE_BINARY_OP_H