Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LabeledIndexingDefs.hh
Go to the documentation of this file.
1 #pragma clang diagnostic push
2 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
3 ///
4 /// @file LabeledIndexingDefs.hh
5 /// @brief Tensor labeled indexer template methods definitions
6 ///
7 #pragma clang diagnostic pop
8 
9 //**** This file is a part of the HAMMER library
10 //**** Copyright (C) 2016 - 2020 The HAMMER Collaboration
11 //**** HAMMER is licensed under version 3 of the GPL; see COPYING for details
12 //**** Please note the MCnet academic guidelines; see GUIDELINES for details
13 
14 // -*- C++ -*-
15 
16 #include <utility>
17 #include <algorithm>
18 
19 #include "Hammer/Exceptions.hh"
20 #include "Hammer/IndexLabels.hh"
22 
23 namespace Hammer {
24 
25  namespace MultiDimensional {
26 
27  template<class BasicIndexing>
29  ptrdiff_t pos = - distance(find(_labels.begin(), _labels.end(), label), _labels.begin());
30  ptrdiff_t dim = static_cast<ptrdiff_t>(this->rank());
31  if (pos < dim && pos >= 0) {
32  return this->dim(static_cast<IndexType>(pos));
33  }
34  throw IndexLabelError("Label " + std::to_string(label) + " not found for multidimensional object" +
35  "': all your base are belong to us.");
36  }
37 
38  template<class BasicIndexing>
40  return _labels;
41  }
42 
43  template<class BasicIndexing>
45  UniqueLabelsList result;
46  for(auto elem: _labels) {
47  if(abs(elem) > IndexLabel::SPIN_INDEX_START && abs(elem) < IndexLabel::SPIN_INDEX_END) {
48  result.insert(elem);
49  }
50  }
51  return result;
52  }
53 
54  template <class BasicIndexing>
56 
57  }
58 
59  template <class BasicIndexing>
60  LabeledIndexing<BasicIndexing>::LabeledIndexing(IndexList dimensions, LabelsList labels) : BasicIndexing{dimensions}, _labels{labels} {
61  if (labels.size() != dimensions.size()) {
62  throw IndexLabelError("Length of list of labels is different than length of dimensions: " +
63  std::to_string(labels.size()) + " vs " + std::to_string(dimensions.size()) +
64  " -> all your base are belong to us.");
65  }
66  }
67 
68  template <class BasicIndexing>
70  LabelsList tmp1 = _labels;
71  LabelsList tmp2 = otherLabels;
72  std::sort(tmp1.begin(), tmp1.end());
73  std::sort(tmp2.begin(), tmp2.end());
74  UniqueLabelsList result;
75  std::set_intersection(tmp1.begin(), tmp1.end(), tmp2.begin(), tmp2.end(), inserter(result, result.begin()));
76  return result;
77  }
78 
79  template<class BasicIndexing>
81  UniqueLabelsList tmp;
82  for (auto elem : _labels) {
83  tmp.insert(elem);
84  }
85  auto res = getOppositeLabelPairs(tmp);
86  LabelPairsSet out;
87  for (auto elem : res) {
88  out.insert({_labels[elem.first], _labels[elem.second]});
89  }
90  return out;
91  }
92 
93  template <class BasicIndexing>
95  const UniqueLabelsList& indices,
96  bool sortedBySecond) const {
97  IndexPairList result;
98  for (auto elem : indices) {
99  ptrdiff_t dim = static_cast<ptrdiff_t>(_labels.size());
100  ptrdiff_t otherdim = static_cast<ptrdiff_t>(otherLabels.size());
101  auto it = _labels.begin();
102  auto ito = otherLabels.begin();
103  while(it != _labels.end() && ito != otherLabels.end()) {
104  auto it2 = find(it, _labels.end(), elem);
105  auto ito2 = find(ito, otherLabels.end(), elem);
106  ptrdiff_t pos1 = distance(_labels.begin(), it2);
107  ptrdiff_t pos2 = distance(otherLabels.begin(), ito2);
108  if (pos1 < dim && pos2 < otherdim) {
109  result.push_back(std::make_pair(pos1, pos2));
110  }
111  it = it2;
112  ito = ito2;
113  if(it != _labels.end()) {
114  ++it;
115  }
116  if (ito != otherLabels.end()) {
117  ++ito;
118  }
119  }
120  }
121  if(sortedBySecond) {
122  std::sort(result.begin(), result.end(), [](const IndexPair& a, const IndexPair& b) -> bool { return a.second < b.second; });
123  }
124  return result;
125  }
126 
127  template<class BasicIndexing>
129  IndexPairList result;
130  for (auto elem : indices) {
131  if (elem > 0) {
132  IndexLabel other_elem = static_cast<IndexLabel>(-elem);
133  ptrdiff_t pos1 = - distance(find(_labels.begin(), _labels.end(), elem), _labels.begin());
134  ptrdiff_t pos2 = - distance(find(_labels.begin(), _labels.end(), other_elem), _labels.begin());
135  ptrdiff_t dim = static_cast<ptrdiff_t>(_labels.size());
136  if (pos1 < dim && pos2 < dim) {
137  result.push_back(std::make_pair(pos1, pos2));
138  }
139  }
140  }
141  return result;
142  }
143 
144  template <class BasicIndexing>
146  const IndexList& otherIndices) const {
147  bool result = this->isSameShape(otherIndices);
148  if(!result) return false;
149  result &= equal(_labels.begin(), _labels.end(), otherLabels.begin());
150  return result;
151  }
152 
153  template <class BasicIndexing>
154  template <typename S>
156  bool result = this->isSameShape(other);
157  if(!result) return false;
158  result &= equal(_labels.begin(), _labels.end(), other._labels.begin());
159  return result;
160  }
161 
162  template <class BasicIndexing>
164  auto itfind = find(_labels.begin(), _labels.end(), label);
165  return static_cast<IndexType>(distance(_labels.begin(), itfind));
166  }
167 
168 
169  template <class BasicIndexing>
170  bool LabeledIndexing<BasicIndexing>::canAddAt(const LabelsList& otherLabels, const IndexList& otherIndices,
171  IndexLabel coord, IndexType position) const {
172  auto pos = labelIndex(coord);
173  if (pos >= this->rank())
174  return false;
175  if (this->dims()[pos] <= position)
176  return false;
177  auto tmpLabs = _labels;
178  tmpLabs.erase(tmpLabs.begin() + pos);
179  if(!(tmpLabs == otherLabels)) return false;
180  auto tmpDims = this->dims();
181  tmpDims.erase(tmpDims.begin() + pos);
182  return (tmpDims == otherIndices);
183  }
184 
185  template <class BasicIndexing>
187  _labels = flipListOfLabels(_labels);
188  }
189 
191  transform(labels.begin(), labels.end(), labels.begin(),
192  [](IndexLabel l) -> IndexLabel { return static_cast<IndexLabel>(-l); });
193  return labels;
194  }
195 
196  } // namespace MultiDimensional
197 
198 } // namespace Hammer
IndexType dim(IndexLabel label) const
dimension of a specific component by label.
std::pair< IndexType, IndexType > IndexPair
std::vector< IndexPair > IndexPairList
UniqueLabelsList sameIndices(const LabelsList &otherLabels) const
returns the set of indices of this tensor that can be contracted using dot with those of another give...
Tensor indices label definitions.
UniqueLabelsList spinIndices() const
returns only the labels corresponding to spin indices
bool isSameLabelShape(const LabelsList &otherLabels, const IndexList &otherIndices) const
uint16_t IndexType
LabelPairsSet oppositeIndices() const
returns the pairs of indices that can be traced over.
const LabelsList & labels() const
get the labels of all the indices at once
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...
Hammer exception definitions.
Interface class for tensor container data structure.
std::vector< IndexType > IndexList
Invalid index label error class.
Definition: Exceptions.hh:39
IndexLabel
label identifiers of tensor indices they are used to determine which indices can be contracted togeth...
Definition: IndexLabels.hh:27
IndexType labelIndex(IndexLabel label) const
bool canAddAt(const LabelsList &otherLabels, const IndexList &otherIndices, IndexLabel coord, IndexType position) const
std::vector< IndexLabel > LabelsList
std::set< IndexLabel > UniqueLabelsList
IndexPairList getOppositeLabelPairs(const UniqueLabelsList &indices) const
returns the position of the indices that can be traced together, given a set of allowed index labels ...
std::set< LabelPair > LabelPairsSet
LabelsList flipListOfLabels(LabelsList labels)
LabelsList _labels
the labels of each tensor index