1 //
2 // Copyright (c) 2018-2019, Cem Bassoy, [email protected]
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
12 #ifndef BOOST_UBLAS_TENSOR_MULTI_INDEX_HPP
13 #define BOOST_UBLAS_TENSOR_MULTI_INDEX_HPP
14
15
16 #include <cstddef>
17 #include <array>
18 #include <vector>
19
20 #include "multi_index_utility.hpp"
21
22 namespace boost {
23 namespace numeric {
24 namespace ublas {
25 namespace index {
26
27 template<std::size_t I>
28 struct index_type;
29
30 } // namespace indices
31 }
32 }
33 }
34
35
36 namespace boost {
37 namespace numeric {
38 namespace ublas {
39
40 /** @brief Proxy class for the einstein summation notation
41 *
42 * Denotes an array of index_type types ::_a for 0<=K<=16 is used in tensor::operator()
43 */
44 template<std::size_t N>
45 class multi_index
46 {
47 public:
48 multi_index() = delete;
49
50 template<std::size_t I, class ... indexes>
multi_index(index::index_type<I> const & i,indexes...is)51 constexpr multi_index(index::index_type<I> const& i, indexes ... is )
52 : _base{i(), is()... }
53 {
54 static_assert( sizeof...(is)+1 == N,
55 "Static assert in boost::numeric::ublas::multi_index: number of constructor arguments is not equal to the template parameter." );
56
57 static_assert( valid_multi_index<std::tuple<index::index_type<I>, indexes ...> >::value,
58 "Static assert in boost::numeric::ublas::multi_index: indexes occur twice in multi-index." );
59 }
60
multi_index(multi_index const & other)61 multi_index(multi_index const& other)
62 : _base(other._base)
63 {
64 }
65
operator =(multi_index const & other)66 multi_index& operator=(multi_index const& other)
67 {
68 this->_base = other._base;
69 return *this;
70 }
71
72 ~multi_index() = default;
73
base() const74 auto const& base() const { return _base; }
size() const75 constexpr auto size() const { return _base.size(); }
at(std::size_t i) const76 constexpr auto at(std::size_t i) const { return _base.at(i); }
operator [](std::size_t i) const77 constexpr auto operator[](std::size_t i) const { return _base.at(i); }
78
79 private:
80 std::array<std::size_t, N> _base;
81 };
82
83 template<std::size_t K, std::size_t N>
get(multi_index<N> const & m)84 constexpr auto get(multi_index<N> const& m) { return std::get<K>(m.base()); }
85
86 template<std::size_t M, std::size_t N>
array_to_vector(multi_index<M> const & lhs,multi_index<N> const & rhs)87 auto array_to_vector(multi_index<M> const& lhs, multi_index<N> const& rhs)
88 {
89 using vtype = std::vector<std::size_t>;
90
91 auto pair_of_vector = std::make_pair( vtype {}, vtype{} );
92
93 for(auto i = 0u; i < N; ++i)
94 for(auto j = 0u; j < M; ++j)
95 if ( lhs.at(i) == rhs.at(j) && lhs.at(i) != boost::numeric::ublas::index::_())
96 pair_of_vector.first .push_back( i+1 ),
97 pair_of_vector.second.push_back( j+1 );
98
99 return pair_of_vector;
100 }
101
102
103
104
105
106 } // namespace ublas
107 } // namespace numeric
108 } // namespace boost
109
110 #endif // MULTI_INDEX_HPP
111