| // |
| // 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 |