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