26 namespace MultiDimensional {
28 SequentialIndexing::SequentialIndexing() : _dimensions{}, _strides{}, _maxIndex{0} {
44 to_string(
_dimensions.size()) +
": all your base are belong to us.");
56 bool valid = (indices.size() ==
_dimensions.size());
59 valid = inner_product(indices.begin(), indices.end(),
_dimensions.begin(), valid, logical_and<bool>(),
65 IndexList::const_iterator last)
const {
66 bool valid = (distance(first, last) ==
static_cast<ptrdiff_t
>(
_dimensions.size()));
69 valid = inner_product(first, last,
_dimensions.begin(), valid, logical_and<bool>(), less<IndexType>());
81 IndexList::const_iterator last)
const {
89 index = inner_product(first, last,
_strides.begin(), index, plus<PositionType>(), opCombine);
95 result[0] =
static_cast<IndexType>(position);
97 pair<IndexType, PositionType> current{
'\0', position};
100 auto itr = result.begin();
101 for (; its !=
_strides.end(); ++its, ++itd, ++itr) {
102 current = {
static_cast<IndexType>(current.second / (*its)), current.second % (*its)};
103 if (static_cast<PositionType>(current.first) < *itd) {
104 *itr = current.first;
107 " for multidimensional object "
109 to_string(
_dimensions.size()) +
" out of range (" + to_string(current.first) +
110 " vs " + to_string(*itd) +
"): all your base are belong to us.");
116 if (indexPosition ==
'\0') {
127 auto res = div(static_cast<long>(position), static_cast<long>(stride));
128 return (static_cast<PositionType>(res.quot) *
_dimensions[indexPosition] + indexValue) * stride +
static_cast<PositionType>(res.rem);
136 for (
auto& elem : conversion) {
137 auto res = div(static_cast<long>(tmp), static_cast<long>(elem.first));
138 out +=
static_cast<PositionType>(res.quot) * elem.second;
139 tmp = static_cast<PositionType>(res.rem);
141 return out + innerPosition;
146 auto tmp = accumulate(indices.begin(), indices.end(), 1ul,
148 return current *
dims[elem.second];
157 for(
auto& elem: conversion) {
158 if(!get<2>(elem) && get<0>(elem) == 0) {
161 auto res = div(static_cast<long>(tmp), static_cast<long>(get<0>(elem)));
163 in += res.quot * get<1>(elem);
166 out +=
static_cast<PositionType>(res.quot * get<1>(elem));
170 return make_pair(out, in);
175 ASSERT(is_sorted(positions.begin(), positions.end(), [](
const pair<IndexType, IndexType>& a,
176 const pair<IndexType, IndexType>& b) ->
bool {
return a.second < b.second;}));
177 map<IndexType, long> innerStrides;
178 for (
auto& elem : positions) {
179 innerStrides.insert({elem.first, secondStrides[elem.second]});
181 innerStrides.insert({elem.second, -1 *
static_cast<long>(secondStrides[elem.second])});
188 auto it = innerMap.end();
192 bool done = (it == innerMap.begin());
197 if (!done && i == it->first) {
198 results.push_back(make_tuple(
_strides[i], it->second,
true));
199 if(it == innerMap.begin()) {
206 results.push_back(make_tuple(
_strides[i], outerStride,
false));
210 reverse(results.begin(), results.end());
211 for(
size_t i=0; i< results.size()-1; ++i) {
212 if (!get<2>(results[i + 1]) && !get<2>(results[i])) {
213 results[i] = make_tuple(0,0,
false);
221 ASSERT(is_sorted(positions.begin(), positions.end(),
223 return a.second < b.second;
225 auto it = positions.end();
228 results.reserve(
_dimensions.size()-positions.size());
229 bool done = (it == positions.begin());
234 if (!done && i == it->second) {
235 if (it == positions.begin()) {
241 results.push_back(make_pair(outerStride,
_strides[i]));
245 reverse(results.begin(), results.end());
269 if (
rank() != indices.size())
PositionPairList getOuterStrides2nd(const IndexPairList &positions) const
Get the Outer Strides2nd object.
std::pair< IndexType, IndexType > IndexPair
StrideMap buildStrideMap(const std::map< IndexType, long > innerMap) const
std::vector< IndexPair > IndexPairList
PositionList _strides
the strides for each tensor index (necessary to convert coordinates to position in _data) ...
const IndexList & dims() const
get the dimensions of all the indices at once
std::pair< PositionType, PositionType > PositionPair
Non-sparse tensor indexer.
PositionType extendPosition(PositionType position, IndexType indexPosition, IndexType indexValue) const
extends an absolute position from a rank N-1 tensor to the corresponding position for this rank N ten...
std::vector< std::tuple< PositionType, long, bool >> StrideMap
PositionPair splitPosition(PositionType position, const StrideMap &conversion) const
PositionType indicesToPos(const IndexList &indices) const
convert the indices into the position indicizing a sparse tensor container organized as row-major ...
void posToIndices(PositionType position, IndexList &result) const
convert the absolute position (in row-major convention) into the list of indices
Hammer exception definitions.
size_t rank() const
rank of the tensor
bool isSameShape(const BasicIndexing &other) const
PositionType reducedNumValues(const IndexPairList &indices) const
std::vector< IndexType > IndexList
IndexType ithIndexInPos(PositionType position, IndexType indexPosition) const
extract the value of the i-th index from an absolute position
IndexType dim(IndexType index) const
dimension of a specific component
PositionType numValues() const
the number of elements (product of all the dimensions)
std::vector< PositionPair > PositionPairList
const PositionList & strides() const
list of strides, i.e.
StrideMap getInnerOuterStrides(const IndexPairList &positions, const PositionList &secondStrides, bool flipSecond=false) const
Get the Inner Outer Strides object.
bool checkValidIndices(const IndexList &indices) const
check that the indices are within range for each component
PositionType build2ndPosition(PositionType reducedPosition, PositionType innerPosition, const PositionPairList &conversion) const
Out-of-range error class.
PositionType stride(IndexType index) const
stride of a specific component, i.e.
IndexList _dimensions
the dimensions of each tensor index
std::vector< PositionType > PositionList