VectorwiseOp.h 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008-2019 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_PARTIAL_REDUX_H
  11. #define EIGEN_PARTIAL_REDUX_H
  12. namespace Eigen {
  13. /** \class PartialReduxExpr
  14. * \ingroup Core_Module
  15. *
  16. * \brief Generic expression of a partially reduxed matrix
  17. *
  18. * \tparam MatrixType the type of the matrix we are applying the redux operation
  19. * \tparam MemberOp type of the member functor
  20. * \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal)
  21. *
  22. * This class represents an expression of a partial redux operator of a matrix.
  23. * It is the return type of some VectorwiseOp functions,
  24. * and most of the time this is the only way it is used.
  25. *
  26. * \sa class VectorwiseOp
  27. */
  28. template< typename MatrixType, typename MemberOp, int Direction>
  29. class PartialReduxExpr;
  30. namespace internal {
  31. template<typename MatrixType, typename MemberOp, int Direction>
  32. struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
  33. : traits<MatrixType>
  34. {
  35. typedef typename MemberOp::result_type Scalar;
  36. typedef typename traits<MatrixType>::StorageKind StorageKind;
  37. typedef typename traits<MatrixType>::XprKind XprKind;
  38. typedef typename MatrixType::Scalar InputScalar;
  39. enum {
  40. RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
  41. ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
  42. MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
  43. MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
  44. Flags = RowsAtCompileTime == 1 ? RowMajorBit : 0,
  45. TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
  46. };
  47. };
  48. }
  49. template< typename MatrixType, typename MemberOp, int Direction>
  50. class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<MatrixType, MemberOp, Direction> >::type,
  51. internal::no_assignment_operator
  52. {
  53. public:
  54. typedef typename internal::dense_xpr_base<PartialReduxExpr>::type Base;
  55. EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr)
  56. EIGEN_DEVICE_FUNC
  57. explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
  58. : m_matrix(mat), m_functor(func) {}
  59. EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
  60. Index rows() const EIGEN_NOEXCEPT { return (Direction==Vertical ? 1 : m_matrix.rows()); }
  61. EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
  62. Index cols() const EIGEN_NOEXCEPT { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
  63. EIGEN_DEVICE_FUNC
  64. typename MatrixType::Nested nestedExpression() const { return m_matrix; }
  65. EIGEN_DEVICE_FUNC
  66. const MemberOp& functor() const { return m_functor; }
  67. protected:
  68. typename MatrixType::Nested m_matrix;
  69. const MemberOp m_functor;
  70. };
  71. template<typename A,typename B> struct partial_redux_dummy_func;
  72. #define EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER,COST,VECTORIZABLE,BINARYOP) \
  73. template <typename ResultType,typename Scalar> \
  74. struct member_##MEMBER { \
  75. EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
  76. typedef ResultType result_type; \
  77. typedef BINARYOP<Scalar,Scalar> BinaryOp; \
  78. template<int Size> struct Cost { enum { value = COST }; }; \
  79. enum { Vectorizable = VECTORIZABLE }; \
  80. template<typename XprType> \
  81. EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
  82. ResultType operator()(const XprType& mat) const \
  83. { return mat.MEMBER(); } \
  84. BinaryOp binaryFunc() const { return BinaryOp(); } \
  85. }
  86. #define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
  87. EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER,COST,0,partial_redux_dummy_func)
  88. namespace internal {
  89. EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
  90. EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
  91. EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
  92. EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
  93. EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
  94. EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
  95. EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
  96. EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_sum_op);
  97. EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_min_op);
  98. EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_max_op);
  99. EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost, 1, internal::scalar_product_op);
  100. template <int p, typename ResultType,typename Scalar>
  101. struct member_lpnorm {
  102. typedef ResultType result_type;
  103. enum { Vectorizable = 0 };
  104. template<int Size> struct Cost
  105. { enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; };
  106. EIGEN_DEVICE_FUNC member_lpnorm() {}
  107. template<typename XprType>
  108. EIGEN_DEVICE_FUNC inline ResultType operator()(const XprType& mat) const
  109. { return mat.template lpNorm<p>(); }
  110. };
  111. template <typename BinaryOpT, typename Scalar>
  112. struct member_redux {
  113. typedef BinaryOpT BinaryOp;
  114. typedef typename result_of<
  115. BinaryOp(const Scalar&,const Scalar&)
  116. >::type result_type;
  117. enum { Vectorizable = functor_traits<BinaryOp>::PacketAccess };
  118. template<int Size> struct Cost { enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
  119. EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
  120. template<typename Derived>
  121. EIGEN_DEVICE_FUNC inline result_type operator()(const DenseBase<Derived>& mat) const
  122. { return mat.redux(m_functor); }
  123. const BinaryOp& binaryFunc() const { return m_functor; }
  124. const BinaryOp m_functor;
  125. };
  126. }
  127. /** \class VectorwiseOp
  128. * \ingroup Core_Module
  129. *
  130. * \brief Pseudo expression providing broadcasting and partial reduction operations
  131. *
  132. * \tparam ExpressionType the type of the object on which to do partial reductions
  133. * \tparam Direction indicates whether to operate on columns (#Vertical) or rows (#Horizontal)
  134. *
  135. * This class represents a pseudo expression with broadcasting and partial reduction features.
  136. * It is the return type of DenseBase::colwise() and DenseBase::rowwise()
  137. * and most of the time this is the only way it is explicitly used.
  138. *
  139. * To understand the logic of rowwise/colwise expression, let's consider a generic case `A.colwise().foo()`
  140. * where `foo` is any method of `VectorwiseOp`. This expression is equivalent to applying `foo()` to each
  141. * column of `A` and then re-assemble the outputs in a matrix expression:
  142. * \code [A.col(0).foo(), A.col(1).foo(), ..., A.col(A.cols()-1).foo()] \endcode
  143. *
  144. * Example: \include MatrixBase_colwise.cpp
  145. * Output: \verbinclude MatrixBase_colwise.out
  146. *
  147. * The begin() and end() methods are obviously exceptions to the previous rule as they
  148. * return STL-compatible begin/end iterators to the rows or columns of the nested expression.
  149. * Typical use cases include for-range-loop and calls to STL algorithms:
  150. *
  151. * Example: \include MatrixBase_colwise_iterator_cxx11.cpp
  152. * Output: \verbinclude MatrixBase_colwise_iterator_cxx11.out
  153. *
  154. * For a partial reduction on an empty input, some rules apply.
  155. * For the sake of clarity, let's consider a vertical reduction:
  156. * - If the number of columns is zero, then a 1x0 row-major vector expression is returned.
  157. * - Otherwise, if the number of rows is zero, then
  158. * - a row vector of zeros is returned for sum-like reductions (sum, squaredNorm, norm, etc.)
  159. * - a row vector of ones is returned for a product reduction (e.g., <code>MatrixXd(n,0).colwise().prod()</code>)
  160. * - an assert is triggered for all other reductions (minCoeff,maxCoeff,redux(bin_op))
  161. *
  162. * \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr
  163. */
  164. template<typename ExpressionType, int Direction> class VectorwiseOp
  165. {
  166. public:
  167. typedef typename ExpressionType::Scalar Scalar;
  168. typedef typename ExpressionType::RealScalar RealScalar;
  169. typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
  170. typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
  171. typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
  172. template<template<typename OutScalar,typename InputScalar> class Functor,
  173. typename ReturnScalar=Scalar> struct ReturnType
  174. {
  175. typedef PartialReduxExpr<ExpressionType,
  176. Functor<ReturnScalar,Scalar>,
  177. Direction
  178. > Type;
  179. };
  180. template<typename BinaryOp> struct ReduxReturnType
  181. {
  182. typedef PartialReduxExpr<ExpressionType,
  183. internal::member_redux<BinaryOp,Scalar>,
  184. Direction
  185. > Type;
  186. };
  187. enum {
  188. isVertical = (Direction==Vertical) ? 1 : 0,
  189. isHorizontal = (Direction==Horizontal) ? 1 : 0
  190. };
  191. protected:
  192. template<typename OtherDerived> struct ExtendedType {
  193. typedef Replicate<OtherDerived,
  194. isVertical ? 1 : ExpressionType::RowsAtCompileTime,
  195. isHorizontal ? 1 : ExpressionType::ColsAtCompileTime> Type;
  196. };
  197. /** \internal
  198. * Replicates a vector to match the size of \c *this */
  199. template<typename OtherDerived>
  200. EIGEN_DEVICE_FUNC
  201. typename ExtendedType<OtherDerived>::Type
  202. extendedTo(const DenseBase<OtherDerived>& other) const
  203. {
  204. EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isVertical, OtherDerived::MaxColsAtCompileTime==1),
  205. YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
  206. EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isHorizontal, OtherDerived::MaxRowsAtCompileTime==1),
  207. YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
  208. return typename ExtendedType<OtherDerived>::Type
  209. (other.derived(),
  210. isVertical ? 1 : m_matrix.rows(),
  211. isHorizontal ? 1 : m_matrix.cols());
  212. }
  213. template<typename OtherDerived> struct OppositeExtendedType {
  214. typedef Replicate<OtherDerived,
  215. isHorizontal ? 1 : ExpressionType::RowsAtCompileTime,
  216. isVertical ? 1 : ExpressionType::ColsAtCompileTime> Type;
  217. };
  218. /** \internal
  219. * Replicates a vector in the opposite direction to match the size of \c *this */
  220. template<typename OtherDerived>
  221. EIGEN_DEVICE_FUNC
  222. typename OppositeExtendedType<OtherDerived>::Type
  223. extendedToOpposite(const DenseBase<OtherDerived>& other) const
  224. {
  225. EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isHorizontal, OtherDerived::MaxColsAtCompileTime==1),
  226. YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
  227. EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isVertical, OtherDerived::MaxRowsAtCompileTime==1),
  228. YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
  229. return typename OppositeExtendedType<OtherDerived>::Type
  230. (other.derived(),
  231. isHorizontal ? 1 : m_matrix.rows(),
  232. isVertical ? 1 : m_matrix.cols());
  233. }
  234. public:
  235. EIGEN_DEVICE_FUNC
  236. explicit inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
  237. /** \internal */
  238. EIGEN_DEVICE_FUNC
  239. inline const ExpressionType& _expression() const { return m_matrix; }
  240. #ifdef EIGEN_PARSED_BY_DOXYGEN
  241. /** STL-like <a href="https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator">RandomAccessIterator</a>
  242. * iterator type over the columns or rows as returned by the begin() and end() methods.
  243. */
  244. random_access_iterator_type iterator;
  245. /** This is the const version of iterator (aka read-only) */
  246. random_access_iterator_type const_iterator;
  247. #else
  248. typedef internal::subvector_stl_iterator<ExpressionType, DirectionType(Direction)> iterator;
  249. typedef internal::subvector_stl_iterator<const ExpressionType, DirectionType(Direction)> const_iterator;
  250. typedef internal::subvector_stl_reverse_iterator<ExpressionType, DirectionType(Direction)> reverse_iterator;
  251. typedef internal::subvector_stl_reverse_iterator<const ExpressionType, DirectionType(Direction)> const_reverse_iterator;
  252. #endif
  253. /** returns an iterator to the first row (rowwise) or column (colwise) of the nested expression.
  254. * \sa end(), cbegin()
  255. */
  256. iterator begin() { return iterator (m_matrix, 0); }
  257. /** const version of begin() */
  258. const_iterator begin() const { return const_iterator(m_matrix, 0); }
  259. /** const version of begin() */
  260. const_iterator cbegin() const { return const_iterator(m_matrix, 0); }
  261. /** returns a reverse iterator to the last row (rowwise) or column (colwise) of the nested expression.
  262. * \sa rend(), crbegin()
  263. */
  264. reverse_iterator rbegin() { return reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
  265. /** const version of rbegin() */
  266. const_reverse_iterator rbegin() const { return const_reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
  267. /** const version of rbegin() */
  268. const_reverse_iterator crbegin() const { return const_reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
  269. /** returns an iterator to the row (resp. column) following the last row (resp. column) of the nested expression
  270. * \sa begin(), cend()
  271. */
  272. iterator end() { return iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
  273. /** const version of end() */
  274. const_iterator end() const { return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
  275. /** const version of end() */
  276. const_iterator cend() const { return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
  277. /** returns a reverse iterator to the row (resp. column) before the first row (resp. column) of the nested expression
  278. * \sa begin(), cend()
  279. */
  280. reverse_iterator rend() { return reverse_iterator (m_matrix, -1); }
  281. /** const version of rend() */
  282. const_reverse_iterator rend() const { return const_reverse_iterator (m_matrix, -1); }
  283. /** const version of rend() */
  284. const_reverse_iterator crend() const { return const_reverse_iterator (m_matrix, -1); }
  285. /** \returns a row or column vector expression of \c *this reduxed by \a func
  286. *
  287. * The template parameter \a BinaryOp is the type of the functor
  288. * of the custom redux operator. Note that func must be an associative operator.
  289. *
  290. * \warning the size along the reduction direction must be strictly positive,
  291. * otherwise an assertion is triggered.
  292. *
  293. * \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
  294. */
  295. template<typename BinaryOp>
  296. EIGEN_DEVICE_FUNC
  297. const typename ReduxReturnType<BinaryOp>::Type
  298. redux(const BinaryOp& func = BinaryOp()) const
  299. {
  300. eigen_assert(redux_length()>0 && "you are using an empty matrix");
  301. return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp,Scalar>(func));
  302. }
  303. typedef typename ReturnType<internal::member_minCoeff>::Type MinCoeffReturnType;
  304. typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
  305. typedef PartialReduxExpr<const CwiseUnaryOp<internal::scalar_abs2_op<Scalar>, const ExpressionTypeNestedCleaned>,internal::member_sum<RealScalar,RealScalar>,Direction> SquaredNormReturnType;
  306. typedef CwiseUnaryOp<internal::scalar_sqrt_op<RealScalar>, const SquaredNormReturnType> NormReturnType;
  307. typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
  308. typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
  309. typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
  310. typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
  311. typedef EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(SumReturnType,Scalar,quotient) MeanReturnType;
  312. typedef typename ReturnType<internal::member_all>::Type AllReturnType;
  313. typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
  314. typedef PartialReduxExpr<ExpressionType, internal::member_count<Index,Scalar>, Direction> CountReturnType;
  315. typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
  316. typedef Reverse<const ExpressionType, Direction> ConstReverseReturnType;
  317. typedef Reverse<ExpressionType, Direction> ReverseReturnType;
  318. template<int p> struct LpNormReturnType {
  319. typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar,Scalar>,Direction> Type;
  320. };
  321. /** \returns a row (or column) vector expression of the smallest coefficient
  322. * of each column (or row) of the referenced expression.
  323. *
  324. * \warning the size along the reduction direction must be strictly positive,
  325. * otherwise an assertion is triggered.
  326. *
  327. * \warning the result is undefined if \c *this contains NaN.
  328. *
  329. * Example: \include PartialRedux_minCoeff.cpp
  330. * Output: \verbinclude PartialRedux_minCoeff.out
  331. *
  332. * \sa DenseBase::minCoeff() */
  333. EIGEN_DEVICE_FUNC
  334. const MinCoeffReturnType minCoeff() const
  335. {
  336. eigen_assert(redux_length()>0 && "you are using an empty matrix");
  337. return MinCoeffReturnType(_expression());
  338. }
  339. /** \returns a row (or column) vector expression of the largest coefficient
  340. * of each column (or row) of the referenced expression.
  341. *
  342. * \warning the size along the reduction direction must be strictly positive,
  343. * otherwise an assertion is triggered.
  344. *
  345. * \warning the result is undefined if \c *this contains NaN.
  346. *
  347. * Example: \include PartialRedux_maxCoeff.cpp
  348. * Output: \verbinclude PartialRedux_maxCoeff.out
  349. *
  350. * \sa DenseBase::maxCoeff() */
  351. EIGEN_DEVICE_FUNC
  352. const MaxCoeffReturnType maxCoeff() const
  353. {
  354. eigen_assert(redux_length()>0 && "you are using an empty matrix");
  355. return MaxCoeffReturnType(_expression());
  356. }
  357. /** \returns a row (or column) vector expression of the squared norm
  358. * of each column (or row) of the referenced expression.
  359. * This is a vector with real entries, even if the original matrix has complex entries.
  360. *
  361. * Example: \include PartialRedux_squaredNorm.cpp
  362. * Output: \verbinclude PartialRedux_squaredNorm.out
  363. *
  364. * \sa DenseBase::squaredNorm() */
  365. EIGEN_DEVICE_FUNC
  366. const SquaredNormReturnType squaredNorm() const
  367. { return SquaredNormReturnType(m_matrix.cwiseAbs2()); }
  368. /** \returns a row (or column) vector expression of the norm
  369. * of each column (or row) of the referenced expression.
  370. * This is a vector with real entries, even if the original matrix has complex entries.
  371. *
  372. * Example: \include PartialRedux_norm.cpp
  373. * Output: \verbinclude PartialRedux_norm.out
  374. *
  375. * \sa DenseBase::norm() */
  376. EIGEN_DEVICE_FUNC
  377. const NormReturnType norm() const
  378. { return NormReturnType(squaredNorm()); }
  379. /** \returns a row (or column) vector expression of the norm
  380. * of each column (or row) of the referenced expression.
  381. * This is a vector with real entries, even if the original matrix has complex entries.
  382. *
  383. * Example: \include PartialRedux_norm.cpp
  384. * Output: \verbinclude PartialRedux_norm.out
  385. *
  386. * \sa DenseBase::norm() */
  387. template<int p>
  388. EIGEN_DEVICE_FUNC
  389. const typename LpNormReturnType<p>::Type lpNorm() const
  390. { return typename LpNormReturnType<p>::Type(_expression()); }
  391. /** \returns a row (or column) vector expression of the norm
  392. * of each column (or row) of the referenced expression, using
  393. * Blue's algorithm.
  394. * This is a vector with real entries, even if the original matrix has complex entries.
  395. *
  396. * \sa DenseBase::blueNorm() */
  397. EIGEN_DEVICE_FUNC
  398. const BlueNormReturnType blueNorm() const
  399. { return BlueNormReturnType(_expression()); }
  400. /** \returns a row (or column) vector expression of the norm
  401. * of each column (or row) of the referenced expression, avoiding
  402. * underflow and overflow.
  403. * This is a vector with real entries, even if the original matrix has complex entries.
  404. *
  405. * \sa DenseBase::stableNorm() */
  406. EIGEN_DEVICE_FUNC
  407. const StableNormReturnType stableNorm() const
  408. { return StableNormReturnType(_expression()); }
  409. /** \returns a row (or column) vector expression of the norm
  410. * of each column (or row) of the referenced expression, avoiding
  411. * underflow and overflow using a concatenation of hypot() calls.
  412. * This is a vector with real entries, even if the original matrix has complex entries.
  413. *
  414. * \sa DenseBase::hypotNorm() */
  415. EIGEN_DEVICE_FUNC
  416. const HypotNormReturnType hypotNorm() const
  417. { return HypotNormReturnType(_expression()); }
  418. /** \returns a row (or column) vector expression of the sum
  419. * of each column (or row) of the referenced expression.
  420. *
  421. * Example: \include PartialRedux_sum.cpp
  422. * Output: \verbinclude PartialRedux_sum.out
  423. *
  424. * \sa DenseBase::sum() */
  425. EIGEN_DEVICE_FUNC
  426. const SumReturnType sum() const
  427. { return SumReturnType(_expression()); }
  428. /** \returns a row (or column) vector expression of the mean
  429. * of each column (or row) of the referenced expression.
  430. *
  431. * \sa DenseBase::mean() */
  432. EIGEN_DEVICE_FUNC
  433. const MeanReturnType mean() const
  434. { return sum() / Scalar(Direction==Vertical?m_matrix.rows():m_matrix.cols()); }
  435. /** \returns a row (or column) vector expression representing
  436. * whether \b all coefficients of each respective column (or row) are \c true.
  437. * This expression can be assigned to a vector with entries of type \c bool.
  438. *
  439. * \sa DenseBase::all() */
  440. EIGEN_DEVICE_FUNC
  441. const AllReturnType all() const
  442. { return AllReturnType(_expression()); }
  443. /** \returns a row (or column) vector expression representing
  444. * whether \b at \b least one coefficient of each respective column (or row) is \c true.
  445. * This expression can be assigned to a vector with entries of type \c bool.
  446. *
  447. * \sa DenseBase::any() */
  448. EIGEN_DEVICE_FUNC
  449. const AnyReturnType any() const
  450. { return AnyReturnType(_expression()); }
  451. /** \returns a row (or column) vector expression representing
  452. * the number of \c true coefficients of each respective column (or row).
  453. * This expression can be assigned to a vector whose entries have the same type as is used to
  454. * index entries of the original matrix; for dense matrices, this is \c std::ptrdiff_t .
  455. *
  456. * Example: \include PartialRedux_count.cpp
  457. * Output: \verbinclude PartialRedux_count.out
  458. *
  459. * \sa DenseBase::count() */
  460. EIGEN_DEVICE_FUNC
  461. const CountReturnType count() const
  462. { return CountReturnType(_expression()); }
  463. /** \returns a row (or column) vector expression of the product
  464. * of each column (or row) of the referenced expression.
  465. *
  466. * Example: \include PartialRedux_prod.cpp
  467. * Output: \verbinclude PartialRedux_prod.out
  468. *
  469. * \sa DenseBase::prod() */
  470. EIGEN_DEVICE_FUNC
  471. const ProdReturnType prod() const
  472. { return ProdReturnType(_expression()); }
  473. /** \returns a matrix expression
  474. * where each column (or row) are reversed.
  475. *
  476. * Example: \include Vectorwise_reverse.cpp
  477. * Output: \verbinclude Vectorwise_reverse.out
  478. *
  479. * \sa DenseBase::reverse() */
  480. EIGEN_DEVICE_FUNC
  481. const ConstReverseReturnType reverse() const
  482. { return ConstReverseReturnType( _expression() ); }
  483. /** \returns a writable matrix expression
  484. * where each column (or row) are reversed.
  485. *
  486. * \sa reverse() const */
  487. EIGEN_DEVICE_FUNC
  488. ReverseReturnType reverse()
  489. { return ReverseReturnType( _expression() ); }
  490. typedef Replicate<ExpressionType,(isVertical?Dynamic:1),(isHorizontal?Dynamic:1)> ReplicateReturnType;
  491. EIGEN_DEVICE_FUNC
  492. const ReplicateReturnType replicate(Index factor) const;
  493. /**
  494. * \return an expression of the replication of each column (or row) of \c *this
  495. *
  496. * Example: \include DirectionWise_replicate.cpp
  497. * Output: \verbinclude DirectionWise_replicate.out
  498. *
  499. * \sa VectorwiseOp::replicate(Index), DenseBase::replicate(), class Replicate
  500. */
  501. // NOTE implemented here because of sunstudio's compilation errors
  502. // isVertical*Factor+isHorizontal instead of (isVertical?Factor:1) to handle CUDA bug with ternary operator
  503. template<int Factor> const Replicate<ExpressionType,isVertical*Factor+isHorizontal,isHorizontal*Factor+isVertical>
  504. EIGEN_DEVICE_FUNC
  505. replicate(Index factor = Factor) const
  506. {
  507. return Replicate<ExpressionType,(isVertical?Factor:1),(isHorizontal?Factor:1)>
  508. (_expression(),isVertical?factor:1,isHorizontal?factor:1);
  509. }
  510. /////////// Artithmetic operators ///////////
  511. /** Copies the vector \a other to each subvector of \c *this */
  512. template<typename OtherDerived>
  513. EIGEN_DEVICE_FUNC
  514. ExpressionType& operator=(const DenseBase<OtherDerived>& other)
  515. {
  516. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  517. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  518. //eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
  519. return m_matrix = extendedTo(other.derived());
  520. }
  521. /** Adds the vector \a other to each subvector of \c *this */
  522. template<typename OtherDerived>
  523. EIGEN_DEVICE_FUNC
  524. ExpressionType& operator+=(const DenseBase<OtherDerived>& other)
  525. {
  526. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  527. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  528. return m_matrix += extendedTo(other.derived());
  529. }
  530. /** Substracts the vector \a other to each subvector of \c *this */
  531. template<typename OtherDerived>
  532. EIGEN_DEVICE_FUNC
  533. ExpressionType& operator-=(const DenseBase<OtherDerived>& other)
  534. {
  535. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  536. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  537. return m_matrix -= extendedTo(other.derived());
  538. }
  539. /** Multiples each subvector of \c *this by the vector \a other */
  540. template<typename OtherDerived>
  541. EIGEN_DEVICE_FUNC
  542. ExpressionType& operator*=(const DenseBase<OtherDerived>& other)
  543. {
  544. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  545. EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
  546. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  547. m_matrix *= extendedTo(other.derived());
  548. return m_matrix;
  549. }
  550. /** Divides each subvector of \c *this by the vector \a other */
  551. template<typename OtherDerived>
  552. EIGEN_DEVICE_FUNC
  553. ExpressionType& operator/=(const DenseBase<OtherDerived>& other)
  554. {
  555. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  556. EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
  557. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  558. m_matrix /= extendedTo(other.derived());
  559. return m_matrix;
  560. }
  561. /** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
  562. template<typename OtherDerived> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
  563. CwiseBinaryOp<internal::scalar_sum_op<Scalar,typename OtherDerived::Scalar>,
  564. const ExpressionTypeNestedCleaned,
  565. const typename ExtendedType<OtherDerived>::Type>
  566. operator+(const DenseBase<OtherDerived>& other) const
  567. {
  568. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  569. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  570. return m_matrix + extendedTo(other.derived());
  571. }
  572. /** Returns the expression of the difference between each subvector of \c *this and the vector \a other */
  573. template<typename OtherDerived>
  574. EIGEN_DEVICE_FUNC
  575. CwiseBinaryOp<internal::scalar_difference_op<Scalar,typename OtherDerived::Scalar>,
  576. const ExpressionTypeNestedCleaned,
  577. const typename ExtendedType<OtherDerived>::Type>
  578. operator-(const DenseBase<OtherDerived>& other) const
  579. {
  580. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  581. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  582. return m_matrix - extendedTo(other.derived());
  583. }
  584. /** Returns the expression where each subvector is the product of the vector \a other
  585. * by the corresponding subvector of \c *this */
  586. template<typename OtherDerived> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
  587. CwiseBinaryOp<internal::scalar_product_op<Scalar>,
  588. const ExpressionTypeNestedCleaned,
  589. const typename ExtendedType<OtherDerived>::Type>
  590. EIGEN_DEVICE_FUNC
  591. operator*(const DenseBase<OtherDerived>& other) const
  592. {
  593. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  594. EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
  595. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  596. return m_matrix * extendedTo(other.derived());
  597. }
  598. /** Returns the expression where each subvector is the quotient of the corresponding
  599. * subvector of \c *this by the vector \a other */
  600. template<typename OtherDerived>
  601. EIGEN_DEVICE_FUNC
  602. CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
  603. const ExpressionTypeNestedCleaned,
  604. const typename ExtendedType<OtherDerived>::Type>
  605. operator/(const DenseBase<OtherDerived>& other) const
  606. {
  607. EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  608. EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
  609. EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
  610. return m_matrix / extendedTo(other.derived());
  611. }
  612. /** \returns an expression where each column (or row) of the referenced matrix are normalized.
  613. * The referenced matrix is \b not modified.
  614. * \sa MatrixBase::normalized(), normalize()
  615. */
  616. EIGEN_DEVICE_FUNC
  617. CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
  618. const ExpressionTypeNestedCleaned,
  619. const typename OppositeExtendedType<NormReturnType>::Type>
  620. normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
  621. /** Normalize in-place each row or columns of the referenced matrix.
  622. * \sa MatrixBase::normalize(), normalized()
  623. */
  624. EIGEN_DEVICE_FUNC void normalize() {
  625. m_matrix = this->normalized();
  626. }
  627. EIGEN_DEVICE_FUNC inline void reverseInPlace();
  628. /////////// Geometry module ///////////
  629. typedef Homogeneous<ExpressionType,Direction> HomogeneousReturnType;
  630. EIGEN_DEVICE_FUNC
  631. HomogeneousReturnType homogeneous() const;
  632. typedef typename ExpressionType::PlainObject CrossReturnType;
  633. template<typename OtherDerived>
  634. EIGEN_DEVICE_FUNC
  635. const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const;
  636. enum {
  637. HNormalized_Size = Direction==Vertical ? internal::traits<ExpressionType>::RowsAtCompileTime
  638. : internal::traits<ExpressionType>::ColsAtCompileTime,
  639. HNormalized_SizeMinusOne = HNormalized_Size==Dynamic ? Dynamic : HNormalized_Size-1
  640. };
  641. typedef Block<const ExpressionType,
  642. Direction==Vertical ? int(HNormalized_SizeMinusOne)
  643. : int(internal::traits<ExpressionType>::RowsAtCompileTime),
  644. Direction==Horizontal ? int(HNormalized_SizeMinusOne)
  645. : int(internal::traits<ExpressionType>::ColsAtCompileTime)>
  646. HNormalized_Block;
  647. typedef Block<const ExpressionType,
  648. Direction==Vertical ? 1 : int(internal::traits<ExpressionType>::RowsAtCompileTime),
  649. Direction==Horizontal ? 1 : int(internal::traits<ExpressionType>::ColsAtCompileTime)>
  650. HNormalized_Factors;
  651. typedef CwiseBinaryOp<internal::scalar_quotient_op<typename internal::traits<ExpressionType>::Scalar>,
  652. const HNormalized_Block,
  653. const Replicate<HNormalized_Factors,
  654. Direction==Vertical ? HNormalized_SizeMinusOne : 1,
  655. Direction==Horizontal ? HNormalized_SizeMinusOne : 1> >
  656. HNormalizedReturnType;
  657. EIGEN_DEVICE_FUNC
  658. const HNormalizedReturnType hnormalized() const;
  659. # ifdef EIGEN_VECTORWISEOP_PLUGIN
  660. # include EIGEN_VECTORWISEOP_PLUGIN
  661. # endif
  662. protected:
  663. Index redux_length() const
  664. {
  665. return Direction==Vertical ? m_matrix.rows() : m_matrix.cols();
  666. }
  667. ExpressionTypeNested m_matrix;
  668. };
  669. //const colwise moved to DenseBase.h due to CUDA compiler bug
  670. /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations
  671. *
  672. * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
  673. */
  674. template<typename Derived>
  675. EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ColwiseReturnType
  676. DenseBase<Derived>::colwise()
  677. {
  678. return ColwiseReturnType(derived());
  679. }
  680. //const rowwise moved to DenseBase.h due to CUDA compiler bug
  681. /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations
  682. *
  683. * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
  684. */
  685. template<typename Derived>
  686. EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::RowwiseReturnType
  687. DenseBase<Derived>::rowwise()
  688. {
  689. return RowwiseReturnType(derived());
  690. }
  691. } // end namespace Eigen
  692. #endif // EIGEN_PARTIAL_REDUX_H