1 #pragma clang diagnostic push
2 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
7 #pragma clang diagnostic pop
24 namespace MultiDimensional {
26 template <
class BasicIndexing>
31 template <
class BasicIndexing>
35 _hasUnderOverFlow{hasUnderOverFlow} {
37 throw RangeError(
"Length of list of bin edges is incompatible with length of dimensions: " +
38 std::to_string(edges.size()) +
" vs " + std::to_string(dimensions.size()) +
39 " -> all your base are belong to us.");
43 template <
class BasicIndexing>
46 _hasUnderOverFlow{hasUnderOverFlow} {
50 template <
class BasicIndexing>
54 _hasUnderOverFlow{hasUnderOverFlow} {
57 template <
class BasicIndexing>
62 template <
class BasicIndexing>
64 ASSERT(pos < _edges.size());
68 template <
class BasicIndexing>
70 auto itv = point.begin();
71 auto itb = _edges.begin();
73 int delta = _hasUnderOverFlow ? 0 : -1;
74 for (; itb != _edges.end(); ++itv, ++itb) {
75 auto itp = lower_bound(itb->begin(), itb->end(), *itv);
76 result.push_back(static_cast<IndexType>(distance(itb->begin(), itp) + delta));
81 template <
class BasicIndexing>
83 return (_hasUnderOverFlow ||
84 this->checkValidIndices(valueToPos(point)));
87 template <
class BasicIndexing>
89 ASSERT(this->checkValidIndices(position));
91 result.reserve(position.size());
92 auto itp = position.begin();
93 auto itd = this->dims().begin();
94 auto ite = _edges.begin();
95 int delta = _hasUnderOverFlow ? -1 : 0;
96 for(; itp != position.end(); ++itp, ++ite, ++itd) {
97 if (_hasUnderOverFlow && *itp == 0) {
98 result.push_back({-std::numeric_limits<double>::max(),(*ite)[0]});
100 else if (_hasUnderOverFlow && *itp == ((*itd) - 1)) {
101 result.push_back({ite->back(), std::numeric_limits<double>::max()});
104 result.push_back({(*ite)[*itp + delta], (*ite)[*itp + delta + 1]});
110 template <
class BasicIndexing>
112 ASSERT(coord < this->rank());
113 ASSERT(position < this->dims(coord));
114 auto& binnings = _edges[coord];
115 int delta = _hasUnderOverFlow ? -1 : 0;
116 if (_hasUnderOverFlow && position == 0) {
117 return {-std::numeric_limits<double>::max(), binnings[0]};
119 else if (_hasUnderOverFlow && position == (this->dims(coord) - 1)) {
120 return {binnings.back(), std::numeric_limits<double>::max()};
123 return {binnings[position + delta], binnings[position + delta + 1]};
128 template <
class BasicIndexing>
130 bool otherUnderOverFlow)
const {
131 bool result = (_hasUnderOverFlow == otherUnderOverFlow);
134 result = this->isSameShape(otherIndices);
137 result &= equal(_edges.begin(), _edges.end(), otherEdges.begin());
141 template <
class BasicIndexing>
144 bool otherUnderOverFlow)
const {
145 bool result = (_hasUnderOverFlow == otherUnderOverFlow);
148 result = this->isSameShape(otherIndices);
149 if(!result)
return false;
150 auto ite = _edges.begin();
151 auto itr = otherRanges.begin();
152 for(; ite != _edges.end() && itr != otherRanges.end(); ++ite, ++itr) {
153 result &=
isZero(ite->front() - itr->first) &&
isZero(ite->back() - itr->second);
159 template <
class BasicIndexing>
160 template <
typename S>
165 result = this->isSameShape(other);
166 if(!result)
return false;
167 result &= equal(_edges.begin(), _edges.end(), other.
_edges.begin());
171 template <
class BasicIndexing>
173 bool valid = (_edges.size() == this->rank());
174 for (
IndexType i = 0; i < _edges.size(); ++i) {
175 valid &= ((_hasUnderOverFlow && (_edges[i].size() + 1u == dim(i))) ||
176 (!_hasUnderOverFlow && (_edges[i].size() == dim(i) + 1u)));
181 template <
class BasicIndexing>
183 int deltaIdx = _hasUnderOverFlow ? -1 : 1;
184 if (ranges.size() > 0) {
185 ASSERT(ranges.size() == this->rank());
186 auto itr = ranges.begin();
187 auto itn = this->dims().begin();
188 for (; itn != this->dims().end(); ++itr, ++itn) {
189 std::vector<double> tmpvec(static_cast<size_t>(*itn + deltaIdx));
190 const double delta = (itr->second - itr->first) / (1. * (*itn + deltaIdx - 1));
191 generate(tmpvec.begin(), tmpvec.end(), [&, n = itr->first]()
mutable {
196 _edges.push_back(tmpvec);
199 for (
auto itn = this->dims().
begin(); itn != this->dims().end(); ++itn) {
200 std::vector<double> tmpvec(static_cast<size_t>(*itn + deltaIdx));
201 generate(tmpvec.begin(), tmpvec.end(), [n = 0]()
mutable {
return n++; });
202 _edges.push_back(tmpvec);
207 template <
class BasicIndexing>
210 result.reserve(edges.size());
211 int delta = hasUnderOverFlow ? 1 : -1;
212 for (
auto& elem : edges) {
213 ASSERT(static_cast<int>(elem.size()) + delta > 0);
214 result.push_back(static_cast<IndexType>(static_cast<int>(elem.size()) + delta));
219 template <
class BasicIndexing>
222 result.reserve(dimensions.size());
223 int delta = hasUnderOverFlow ? 2 : 0;
224 for (
auto& elem : dimensions) {
226 result.push_back(static_cast<IndexType>(elem + delta));
232 template <
class BasicIndexing>
234 return _hasUnderOverFlow;
237 template <
class BasicIndexing>
239 std::map<IndexType, long> innerStrides;
240 for(
auto& elem: positions) {
241 innerStrides.insert({elem, 0});
243 return this->buildStrideMap(innerStrides);
BasicIndexing::StrideMap getBinStrides(const UniqueIndexList &positions) const
const BinEdgeList & edges() const
get the labels of all the indices at once
std::vector< std::vector< double >> BinEdgeList
bool isSameBinShape(const BinEdgeList &otherEdges, const IndexList &otherIndices, bool otherUnderOverFlow) const
BinRangeList binEdges(IndexList position) const
bool hasUnderOverFlow() const
auto begin(reversion_wrapper< T > w)
Hammer exception definitions.
IndexList valueToPos(const BinValue &point) const
Interface class for tensor container data structure.
std::vector< IndexType > IndexList
const BinValue & edge(IndexType pos) const
BinEdgeList _edges
the labels of each tensor index
bool isZero(const std::complex< double > val)
std::set< IndexType > UniqueIndexList
static IndexList processEdges(const BinEdgeList &edges, bool hasUnderOverFlow)
void fillEdges(const BinRangeList &ranges)
std::vector< BinRange > BinRangeList
BinRange binEdge(IndexType position, IndexType coord) const
std::pair< double, double > BinRange
std::vector< double > BinValue
static IndexList processRanges(const IndexList &dimensions, bool hasUnderOverFlow)