multi_index.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. //
  2. // Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // The authors gratefully acknowledge the support of
  9. // Fraunhofer IOSB, Ettlingen, Germany
  10. //
  11. #ifndef BOOST_UBLAS_TENSOR_MULTI_INDEX_HPP
  12. #define BOOST_UBLAS_TENSOR_MULTI_INDEX_HPP
  13. #include <cstddef>
  14. #include <array>
  15. #include <vector>
  16. #include "multi_index_utility.hpp"
  17. namespace boost {
  18. namespace numeric {
  19. namespace ublas {
  20. namespace index {
  21. template<std::size_t I>
  22. struct index_type;
  23. } // namespace indices
  24. }
  25. }
  26. }
  27. namespace boost {
  28. namespace numeric {
  29. namespace ublas {
  30. /** @brief Proxy class for the einstein summation notation
  31. *
  32. * Denotes an array of index_type types ::_a for 0<=K<=16 is used in tensor::operator()
  33. */
  34. template<std::size_t N>
  35. class multi_index
  36. {
  37. public:
  38. multi_index() = delete;
  39. template<std::size_t I, class ... indexes>
  40. constexpr multi_index(index::index_type<I> const& i, indexes ... is )
  41. : _base{i(), is()... }
  42. {
  43. static_assert( sizeof...(is)+1 == N,
  44. "Static assert in boost::numeric::ublas::multi_index: number of constructor arguments is not equal to the template parameter." );
  45. static_assert( valid_multi_index<std::tuple<index::index_type<I>, indexes ...> >::value,
  46. "Static assert in boost::numeric::ublas::multi_index: indexes occur twice in multi-index." );
  47. }
  48. multi_index(multi_index const& other)
  49. : _base(other._base)
  50. {
  51. }
  52. multi_index& operator=(multi_index const& other)
  53. {
  54. this->_base = other._base;
  55. return *this;
  56. }
  57. ~multi_index() = default;
  58. auto const& base() const { return _base; }
  59. constexpr auto size() const { return _base.size(); }
  60. constexpr auto at(std::size_t i) const { return _base.at(i); }
  61. constexpr auto operator[](std::size_t i) const { return _base.at(i); }
  62. private:
  63. std::array<std::size_t, N> _base;
  64. };
  65. template<std::size_t K, std::size_t N>
  66. constexpr auto get(multi_index<N> const& m) { return std::get<K>(m.base()); }
  67. template<std::size_t M, std::size_t N>
  68. auto array_to_vector(multi_index<M> const& lhs, multi_index<N> const& rhs)
  69. {
  70. using vtype = std::vector<std::size_t>;
  71. auto pair_of_vector = std::make_pair( vtype {}, vtype{} );
  72. for(auto i = 0u; i < N; ++i)
  73. for(auto j = 0u; j < M; ++j)
  74. if ( lhs.at(i) == rhs.at(j) && lhs.at(i) != boost::numeric::ublas::index::_())
  75. pair_of_vector.first .push_back( i+1 ),
  76. pair_of_vector.second.push_back( j+1 );
  77. return pair_of_vector;
  78. }
  79. } // namespace ublas
  80. } // namespace numeric
  81. } // namespace boost
  82. #endif // MULTI_INDEX_HPP