15 #include <type_traits>
26 namespace MultiDimensional {
28 BlockIndexing::BlockIndexing()
29 : _subIndexing{}, _splitIndices{0}, _splitPads{0} {
33 auto itd = dims.begin();
34 auto itl = labels.begin();
35 for (; itd != dims.end(); ++itd, ++itl) {
56 ": all your base are belong to us.");
65 to_string(
rank()) +
": all your base are belong to us.");
95 auto its = splits.begin();
98 result &= it->checkValidIndices(*its);
104 vector<IndexList> result;
106 auto ite= indices.begin();
110 advance(ite, static_cast<ptrdiff_t>(it->rank()));
111 result.emplace_back(
IndexList{itb, ite});
117 IndexList::const_iterator last)
const {
118 vector<IndexList::const_iterator> result;
122 result.push_back(itv);
123 advance(itv, static_cast<ptrdiff_t>(elem.rank()));
125 result.push_back(last);
130 bool sortedBySecond)
const {
131 return _globalIndexing.getSameLabelPairs(otherLabels, indices, sortedBySecond);
153 if(includeBlockShapes) {
159 for (; it1 !=
_subIndexing.end() && res; ++it1, ++it2) {
160 res &= it1->isSameLabelShape(*it2);
172 return make_pair(idx, res);
196 tmpLabs.insert(tmpLabs.end(), elem.labels().begin(), elem.labels().end());
197 tmpIdxs.insert(tmpIdxs.end(), elem.dims().begin(), elem.dims().end());
198 baseIdx =
static_cast<IndexType>(baseIdx + elem.rank());
201 transform(_subIndexing.rbegin(), _subIndexing.rend(), back_inserter(tmpPads),
205 partial_sum(tmpPads.begin(), tmpPads.end(), back_inserter(
_splitPads));
220 vector<tuple<IndexList, vector<bool>,
PositionType>> result;
221 result.reserve(pairs.size() - 1);
222 for(
IndexType i=1; i<pairs.size(); ++i) {
227 vector<bool>& outerchecks = get<1>(tmp);
233 for(
IndexType j = static_cast<IndexType>(shifts.size()); j-- > 0;) {
234 if(!outerchecks[j])
continue;
236 bool isUsed = (find(used.begin(), used.end(), subPos.first) != used.end());
238 currentPadSubtract =
static_cast<IndexType>(currentPadSubtract + shifts[j] - previousPad);
242 previousPad = shifts[j];
247 shifts[j] =
static_cast<IndexType>(shifts[j] - currentPadSubtract);
251 currentPadSubtract =
static_cast<IndexType>(currentPadSubtract + maxPad - previousPad);
253 get<2>(tmp) = ((get<2>(tmp)) / (1 << currentPadSubtract)) ;
254 result.push_back(tmp);
260 const IndexList& outerShiftsInnerPositions,
261 const vector<bool>& isOuter,
IndexList& innerList,
262 vector<bool>& innerAdded,
bool shouldCompare)
const {
263 const IndexList& chunkIndices = shouldCompare ? get<1>(chunk) : get<0>(chunk);
265 return _globalIndexing.splitPosition(fullPos, outerShiftsInnerPositions, isOuter, innerList, innerAdded, shouldCompare);
271 for (
IndexType i = 0; i < chunkIndices.size(); ++i) {
283 : _entry{entry}, _containers(entry.size()), _dimensions(entry.size()) {
284 for (
size_t i = 0; i < _entry.size(); ++i) {
286 if (pTry !=
nullptr) {
287 _containers[i] = pTry;
288 _dimensions[i] =
static_cast<IndexType>(pTry->dataSize()/pTry->entrySize());
291 throw Error(
"Invalid contained type");
322 for (
size_t i = 0; i <
_entry.size(); ++i) {
323 result *=
_entry[i].second ? conj(
_it[i]->value()) :
_it[i]->value();
329 return _it[idx]->position();
333 return _it[idx]->isAligned();
339 for (
size_t i = 0; i <
_it.size() && result; ++i) {
340 result &= (*(
_it[i]) == *(other.
_it[i]));
360 if (position ==
_it.size()) {
364 long newpos =
static_cast<long>(
position) - 1;
370 for(
size_t i = 0; i<
_it.size(); ++i) {
377 auto res = div(d1 + n, static_cast<long>(
_dimensions[position]));
378 _it[
position]->next(static_cast<int>(res.rem - d1));
380 long newpos =
static_cast<long>(
position) - 1;
382 for (
size_t i = 0; i <
_it.size(); ++i) {
387 incrementEntry(static_cast<size_t>(newpos), static_cast<int>(res.quot));
IndexType labelIndex(IndexLabel label) const
OuterElemIterator(const EntryType &entry)
std::pair< IndexType, IndexType > IndexPair
bool isSame(const OuterElemIterator &other) const
bool checkValidIndices(const IndexList &indices) const
check that the indices are within range for each component
std::tuple< IndexList, IndexList, IndexPairList > DotGroupType
IndexPairList getSameLabelPairs(const LabelsList &otherLabels, const UniqueLabelsList &indices, bool sortedBySecond=true) const
returns the position of the indices in the two tensor (this and another) that can be contracted toget...
std::vector< IndexList > splitIndices(const IndexList &indices) const
std::vector< IndexPair > IndexPairList
IndexType dim(IndexType index) const
dimension of a specific component
IndexList dims() const
get the dimensions of all the indices at once
PositionType position(IndexType idx) const
UniqueLabelsList spinIndices() const
returns only the labels corresponding to spin indices
bool isSameLabelShape(const LabelsList &otherLabels, const IndexList &otherIndices) const
OuterElemIterator begin() const
void incrementEntry(size_t position, int n)
std::vector< std::pair< SharedTensorData, bool >> EntryType
std::complex< double > ElementType
PositionType splitPosition(const OuterElemIterator ¤tPosition, const DotGroupType &chunk, const IndexList &outerShiftsInnerPositions, const std::vector< bool > &isOuter, IndexList &innerList, std::vector< bool > &innerAdded, bool shouldCompare=false) const
ContainerList _containers
size_t numSubIndexing() const
PositionType buildFullPosition(const OuterElemIterator ¤t, const IndexList &chunkIndices) const
Hammer exception definitions.
std::vector< LabeledIndexing< AlignedIndexing > > _subIndexing
OuterElemIterator end() const
std::vector< DotGroupType > DotGroupList
std::vector< IndexType > IndexList
IndexPairList getOppositeLabelPairs(const UniqueLabelsList &indices) const
returns the position of the indices that can be traced together, given a set of allowed index labels ...
Invalid index label error class.
std::vector< PositionType > _splitPads
IndexLabel
label identifiers of tensor indices they are used to determine which indices can be contracted togeth...
LabeledIndexing< AlignedIndexing > _globalIndexing
Outer product tensor indexer.
std::vector< std::tuple< IndexList, std::vector< bool >, PositionType > > processShifts(const DotGroupList &chunks, IndexPairMember which) const
std::vector< IndexType > _splitIndices
IContainer::ElementType operator*()
size_t rank() const
rank of the tensor
const LabeledIndexing< AlignedIndexing > & getSubIndexing(IndexType position) const
std::vector< IndexLabel > LabelsList
PositionType numValues() const
the number of elements (product of all the dimensions)
std::set< IndexLabel > UniqueLabelsList
LabelsList labels() const
get the labels of all the indices at once
std::enable_if< std::is_unsigned< T >::value &&std::is_integral< T >::value, T >::type minPadding(T value)
bool isAligned(IndexType idx) const
size_t maxSubRank() const
Out-of-range error class.
IndexPair getElementIndex(IndexType position) const
OuterElemIterator & operator++()