blob: 3cc86e2fdffc9fcc8737a661a3903f8652300924 [file] [log] [blame]
//
// 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