Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
718
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.60 KB | None | 0 0
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2017 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.  
  10. #ifndef EIGEN_ARITHMETIC_SEQUENCE_H
  11. #define EIGEN_ARITHMETIC_SEQUENCE_H
  12.  
  13. namespace Eigen {
  14.  
  15. namespace internal {
  16.  
  17. // Helper to cleanup the type of the increment:
  18. template<typename T> struct cleanup_seq_incr {
  19. typedef typename cleanup_index_type<T,DynamicIndex>::type type;
  20. };
  21.  
  22. }
  23.  
  24. //--------------------------------------------------------------------------------
  25. // seq(first,last,incr) and seqN(first,size,incr)
  26. //--------------------------------------------------------------------------------
  27.  
  28. template<typename FirstType=Index,typename SizeType=Index,typename IncrType=internal::FixedInt<1> >
  29. class ArithmeticSequence;
  30.  
  31. /** \class ArithmeticSequence
  32. * \ingroup Core_Module
  33. *
  34. * This class represents an arithmetic progression \f$ a_0, a_1, a_2, ..., a_{n-1}\f$ defined by
  35. * its \em first value \f$ a_0 \f$, its \em size (aka length) \em n, and the \em increment (aka stride)
  36. * that is equal to \f$ a_{i+1}-a_{i}\f$ for any \em i.
  37. *
  38. * It is internally used as the return type of the Eigen::seq and Eigen::seqN functions, and as the input arguments
  39. * of DenseBase::operator()(const RowIndices&, const ColIndices&), and most of the time this is the
  40. * only way it is used.
  41. *
  42. * \tparam FirstType type of the first element, usually an Index,
  43. * but internally it can be a symbolic expression
  44. * \tparam SizeType type representing the size of the sequence, usually an Index
  45. * or a compile time integral constant. Internally, it can also be a symbolic expression
  46. * \tparam IncrType type of the increment, can be a runtime Index, or a compile time integral constant (default is compile-time 1)
  47. *
  48. * \sa Eigen::seq, Eigen::seqN, DenseBase::operator()(const RowIndices&, const ColIndices&), class IndexedView
  49. */
  50. template<typename FirstType,typename SizeType,typename IncrType>
  51. class ArithmeticSequence
  52. {
  53. public:
  54. ArithmeticSequence(FirstType first, SizeType size) : m_first(first), m_size(size) {}
  55. ArithmeticSequence(FirstType first, SizeType size, IncrType incr) : m_first(first), m_size(size), m_incr(incr) {}
  56.  
  57. enum {
  58. SizeAtCompileTime = internal::get_fixed_value<SizeType>::value,
  59. IncrAtCompileTime = internal::get_fixed_value<IncrType,DynamicIndex>::value
  60. };
  61.  
  62. /** \returns the size, i.e., number of elements, of the sequence */
  63. Index size() const { return m_size; }
  64.  
  65. /** \returns the first element \f$ a_0 \f$ in the sequence */
  66. Index first() const { return m_first; }
  67.  
  68. /** \returns the value \f$ a_i \f$ at index \a i in the sequence. */
  69. Index operator[](Index i) const { return m_first + i * m_incr; }
  70.  
  71. const FirstType& firstObject() const { return m_first; }
  72. const SizeType& sizeObject() const { return m_size; }
  73. const IncrType& incrObject() const { return m_incr; }
  74.  
  75. protected:
  76. FirstType m_first;
  77. SizeType m_size;
  78. IncrType m_incr;
  79.  
  80. public:
  81.  
  82. auto reverse() const {
  83. return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
  84. }
  85.  
  86. };
  87.  
  88. /** \returns an ArithmeticSequence starting at \a first, of length \a size, and increment \a incr
  89. *
  90. * \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
  91. template<typename FirstType,typename SizeType,typename IncrType>
  92. auto seqN(FirstType first, SizeType size, IncrType incr) {
  93. return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type>(first,size,incr);
  94. }
  95.  
  96. /** \returns an ArithmeticSequence starting at \a first, of length \a size, and unit increment
  97. *
  98. * \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType) */
  99. template<typename FirstType,typename SizeType>
  100. auto seqN(FirstType first, SizeType size) {
  101. return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type>(first,size);
  102. }
  103.  
  104. /** \returns an ArithmeticSequence starting at \a f, up (or down) to \a l, and unit increment
  105. *
  106. * It is essentially an alias to:
  107. * \code
  108. * seqN(f,l-f+1);
  109. * \endcode
  110. *
  111. * \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType)
  112. */
  113. template<typename FirstType,typename LastType>
  114. auto seq(FirstType f, LastType l)
  115. {
  116. return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
  117. (typename internal::cleanup_index_type<LastType>::type(l)
  118. -typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>()));
  119. }
  120.  
  121. /** \returns an ArithmeticSequence starting at \a f, up (or down) to \a l, and with positive (or negative) increment \a incr
  122. *
  123. * It is essentially an alias to:
  124. * \code
  125. * seqN(f, (l-f+incr)/incr, incr);
  126. * \endcode
  127. *
  128. * \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType)
  129. */
  130. template<typename FirstType,typename LastType, typename IncrType>
  131. auto seq(FirstType f, LastType l, IncrType incr)
  132. {
  133. typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
  134. return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
  135. ( typename internal::cleanup_index_type<LastType>::type(l)
  136. -typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr)) / CleanedIncrType(incr),
  137. CleanedIncrType(incr));
  138. }
  139.  
  140. /** \cpp11
  141. * \returns a symbolic ArithmeticSequence representing the last \a size elements with increment \a incr.
  142. *
  143. * It is a shortcut for: \code seqN(last-(size-fix<1>)*incr, size, incr) \endcode
  144. *
  145. * \sa lastN(SizeType), seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
  146. template<typename SizeType,typename IncrType>
  147. auto lastN(SizeType size, IncrType incr)
  148. {
  149. return seqN(Eigen::last-(size-fix<1>())*incr, size, incr);
  150. }
  151.  
  152. /** \cpp11
  153. * \returns a symbolic ArithmeticSequence representing the last \a size elements with a unit increment.
  154. *
  155. * It is a shortcut for: \code seq(last+fix<1>-size, last) \endcode
  156. *
  157. * \sa lastN(SizeType,IncrType, seqN(FirstType,SizeType), seq(FirstType,LastType) */
  158. template<typename SizeType>
  159. auto lastN(SizeType size)
  160. {
  161. return seqN(Eigen::last+fix<1>()-size, size);
  162. }
  163.  
  164. namespace internal {
  165.  
  166. // Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
  167. template<typename T>
  168. struct make_size_type {
  169. typedef typename internal::conditional<symbolic::is_symbolic<T>::value, Index, T>::type type;
  170. };
  171.  
  172. template<typename FirstType,typename SizeType,typename IncrType,int XprSize>
  173. struct IndexedViewCompatibleType<ArithmeticSequence<FirstType,SizeType,IncrType>, XprSize> {
  174. typedef ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType> type;
  175. };
  176.  
  177. template<typename FirstType,typename SizeType,typename IncrType>
  178. auto
  179. makeIndexedViewCompatible(const ArithmeticSequence<FirstType,SizeType,IncrType>& ids, Index size,SpecializedType) {
  180. return ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>(
  181. eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.sizeObject(),size),ids.incrObject());
  182. }
  183.  
  184. template<typename FirstType,typename SizeType,typename IncrType>
  185. struct get_compile_time_incr<ArithmeticSequence<FirstType,SizeType,IncrType> > {
  186. enum { value = get_fixed_value<IncrType,DynamicIndex>::value };
  187. };
  188.  
  189. } // end namespace internal
  190.  
  191. /** \namespace Eigen::indexing
  192. * \ingroup Core_Module
  193. *
  194. * The sole purpose of this namespace is to be able to import all functions
  195. * and symbols that are expected to be used within operator() for indexing
  196. * and slicing. If you already imported the whole Eigen namespace:
  197. * \code using namespace Eigen; \endcode
  198. * then you are already all set. Otherwise, if you don't want/cannot import
  199. * the whole Eigen namespace, the following line:
  200. * \code using namespace Eigen::indexing; \endcode
  201. * is equivalent to:
  202. * \code
  203. using Eigen::all;
  204. using Eigen::seq;
  205. using Eigen::seqN;
  206. using Eigen::lastN; // c++11 only
  207. using Eigen::last;
  208. using Eigen::lastp1;
  209. using Eigen::fix;
  210. \endcode
  211. */
  212. namespace indexing {
  213. using Eigen::all;
  214. using Eigen::seq;
  215. using Eigen::seqN;
  216. #if EIGEN_HAS_CXX11
  217. using Eigen::lastN;
  218. #endif
  219. using Eigen::last;
  220. using Eigen::lastp1;
  221. using Eigen::fix;
  222. }
  223.  
  224. } // end namespace Eigen
  225.  
  226. #endif // EIGEN_ARITHMETIC_SEQUENCE_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement