Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VectorContainer.cc
Go to the documentation of this file.
1 ///
2 /// @file VectorContainer.cc
3 /// @brief Non-sparse tensor data container
4 ///
5 
6 //**** This file is a part of the HAMMER library
7 //**** Copyright (C) 2016 - 2020 The HAMMER Collaboration
8 //**** HAMMER is licensed under version 3 of the GPL; see COPYING for details
9 //**** Please note the MCnet academic guidelines; see GUIDELINES for details
10 
11 // -*- C++ -*-
12 #include <numeric>
13 #include <functional>
14 
15 #include <boost/fusion/adapted/std_pair.hpp>
16 
18 #include "Hammer/Exceptions.hh"
19 #include "Hammer/Tools/Utils.hh"
20 #include "Hammer/Math/Utils.hh"
22 #include "Hammer/Tools/Logging.hh"
23 
24 using namespace std;
25 
26 namespace Hammer {
27 
28  namespace MultiDimensional {
29 
30  VectorContainer::VectorContainer(const IndexList& dimensions, const LabelsList& labels) :
31  _indexing{dimensions, labels} {
32  clear();
33  }
34 
36  clear();
37  }
38 
39  VectorContainer::VectorContainer(const Serial::FBSingleTensor* input) {
40  if (input != nullptr) {
41  auto serialvals = input->vals();
42  auto serialpos = input->pos();
43  auto serialdims = input->dims();
44  auto seriallabels = input->labels();
45  if (serialdims != nullptr && seriallabels != nullptr) {
46  vector<IndexLabel> tmplabels;
47  tmplabels.reserve(seriallabels->size());
48  vector<IndexType> tmpdims;
49  tmpdims.reserve(serialdims->size());
50  for (unsigned int i = 0; i < serialdims->size(); ++i) {
51  tmplabels.push_back(static_cast<IndexLabel>(seriallabels->Get(i)));
52  tmpdims.push_back(serialdims->Get(i));
53  }
54  _indexing = LabeledIndexing<SequentialIndexing>{tmpdims, tmplabels};
55  }
56  clear();
57  if (serialvals != nullptr && serialpos != nullptr) {
58  for (unsigned int i = 0; i < serialvals->size(); ++i) {
59  _data[serialpos->Get(i)] = complex<double>{serialvals->Get(i)->re(), serialvals->Get(i)->im()};
60  }
61  }
62  }
63  }
64 
66  ASSERT(_indexing.checkValidIndices(indices));
67  PositionType pos = _indexing.indicesToPos(indices);
68  return _data[pos];
69  }
70 
71  VectorContainer::ElementType VectorContainer::value(IndexList::const_iterator first, IndexList::const_iterator last) const {
72  PositionType pos = _indexing.indicesToPos(first, last);
73  return _data[pos];
74  }
75 
76  void VectorContainer::setValue(const IndexList& indices, ElementType value) {
77  ASSERT(_indexing.checkValidIndices(indices));
78  PositionType pos = _indexing.indicesToPos(indices);
79  _data[pos] = value;
80  }
81 
82  void VectorContainer::setValue(IndexList::const_iterator first, IndexList::const_iterator last,
83  ElementType value) {
84  ASSERT(_indexing.checkValidIndices(first, last));
85  PositionType pos = _indexing.indicesToPos(first, last);
86  _data[pos] = value;
87  }
88 
90  _data.clear();
91  DataType(_indexing.numValues()).swap(_data);
92  }
93 
95  return _data.begin();
96  }
97 
99  return _data.begin();
100  }
101 
103  return _data.end();
104  }
105 
107  return _data.end();
108  }
109 
111  return _data[pos];
112  }
113 
115  return _data[pos];
116  }
117 
118  size_t VectorContainer::rank() const {
119  return _indexing.rank();
120  }
121 
123  return _indexing.dims();
124  }
125 
127  return _indexing.labels();
128  }
129 
130  size_t VectorContainer::numValues() const {
131  return _indexing.numValues();
132  }
133 
134  size_t VectorContainer::dataSize() const {
135  return (count_if(_data.begin(), _data.end(), [](complex<double> val) -> bool { return !isZero(val); })
136  * sizeof(complex<double>));
137  }
138 
139  size_t VectorContainer::entrySize() const {
140  return sizeof(complex<double>);
141  }
142 
144  return _indexing.labelIndex(label);
145  }
146 
147 
149  const UniqueLabelsList& indices) const {
150  return _indexing.getSameLabelPairs(other.labels(), indices);
151  }
152 
154  return _indexing.getOppositeLabelPairs(_indexing.spinIndices());
155  }
156 
157  bool VectorContainer::isSameShape(const IContainer& other) const {
158  return _indexing.isSameLabelShape(other.labels(), other.dims());
159  }
160 
161  bool VectorContainer::canAddAt(const IContainer& subContainer, IndexLabel coord,
162  IndexType position) const {
163  return _indexing.canAddAt(subContainer.labels(), subContainer.dims(), coord, position);
164  }
165 
167  ASSERT(_indexing.checkValidIndices(coords));
168  PositionType pos = _indexing.indicesToPos(coords);
169  return _data[pos];
170  }
171 
173  return value(coords);
174  }
175 
176 
177  VectorContainer::reference VectorContainer::element(IndexList::const_iterator start, IndexList::const_iterator end) {
178  ASSERT(_indexing.checkValidIndices(start, end));
179  PositionType pos = _indexing.indicesToPos(start, end);
180  return _data[pos];
181  }
182 
183  VectorContainer::ElementType VectorContainer::element(IndexList::const_iterator start, IndexList::const_iterator end) const {
184  return value(start, end);
185  }
186 
187  bool VectorContainer::compare(const IContainer& other) const {
188  const VectorContainer* tmp = dynamic_cast<const VectorContainer*>(&other);
189  if (tmp == nullptr)
190  return false;
191  bool dimcheck = _indexing.isSameLabelShape(tmp->_indexing);
192  if (!dimcheck)
193  return false;
194  if (_data.size() != tmp->_data.size())
195  return false;
196  return equal(
197  _data.begin(), _data.end(), tmp->_data.begin(),
198  [](ElementType a, ElementType b) -> bool {
199  return isZero(a - b);
200  });
201  }
202 
204  VectorContainer* t = new VectorContainer{*this};
205  return TensorData{static_cast<IContainer*>(t)};
206  }
207 
209  auto it = NonZeroIt{new ItSequential{_data.begin(), _data.size()}};
210  return it;
211  }
212 
214  return NonZeroIt{new ItSequential{_data.end(), _data.size(), _data.size(),
215  static_cast<PositionType>(dataSize() / sizeof(complex<double>))}};
216  }
217 
219  for (auto& elem : _data) {
220  elem *= value;
221  }
222  return static_cast<IContainer&>(*this);
223  }
224 
226  for (auto& elem : _data) {
227  elem *= value;
228  }
229  return static_cast<IContainer&>(*this);
230  }
231 
233  for (auto& elem : _data) {
234  elem = conj(elem);
235  }
236  _indexing.flipLabels();
237  return *this;
238  }
239 
240  VectorContainer::SerialType VectorContainer::write(flatbuffers::FlatBufferBuilder* msgwriter) const {
241  vector<Serial::FBComplex> datalist;
242  vector<uint32_t> poslist;
243  datalist.reserve(_data.size());
244  poslist.reserve(_data.size());
245  if (_data.size() > 4294967295ul) {
246  MSG_ERROR("Error saving binary tensor: too many entries!");
247  }
248  // size_t count = 0ul;
249  // size_t count2 = 0ul;
250  for (size_t i = 0; i < _data.size(); ++i) {
251  if (!isZero(_data[i])) {
252  // if (!isZero(_data[i].real())) count++;
253  // if (!isZero(_data[i].imag())) count++;
254  // count2++;
255  auto resc = Serial::FBComplex{_data[i].real(), _data[i].imag()};
256  datalist.push_back(resc);
257  poslist.push_back(static_cast<uint32_t>(i));
258  }
259  }
260  // cout << numValues() << ": " << 1.-(count*(8+4) + 4*4)/(16.*numValues()+4)
261  // << " vs " << 1.-(count2*(16+4)+4*2)/(16.*numValues()+4) << endl;
262  auto serialdata = msgwriter->CreateVectorOfStructs(datalist.data(), datalist.size());
263  auto serialpos = msgwriter->CreateVector(poslist);
264  vector<uint16_t> dims;
265  for (auto elem : _indexing.dims()) {
266  dims.push_back(static_cast<uint16_t>(elem));
267  }
268  vector<int16_t> labels;
269  for (auto elem : _indexing.labels()) {
270  labels.push_back(static_cast<int16_t>(elem));
271  }
272  auto serialdims = msgwriter->CreateVector(dims);
273  auto seriallabels = msgwriter->CreateVector(labels);
274  Serial::FBSingleTensorBuilder serialtensor{*msgwriter};
275  serialtensor.add_sparse(false);
276  serialtensor.add_vals(serialdata);
277  serialtensor.add_pos(serialpos);
278  serialtensor.add_labels(seriallabels);
279  serialtensor.add_dims(serialdims);
280  auto out = serialtensor.Finish();
281  return make_pair(out.Union(), Serial::FBTensorTypes::FBSingleTensor);
282  }
283 
285  return Log::getLog("Hammer.VectorContainer");
286  }
287 
289  return _indexing;
290  }
291 
292  void VectorContainer::swap(vector<complex<double>>& values) {
293  ASSERT(_data.size() == values.size());
294  values.swap(_data);
295  }
296 
297  TensorData makeEmptyVector(const IndexList& dimensions, const LabelsList& labels) {
298  auto result = new VectorContainer{dimensions, labels};
299  return TensorData{static_cast<IContainer*>(result)};
300  }
301 
303  auto result = new VectorContainer{indexing};
304  return TensorData{static_cast<IContainer*>(result)};
305  }
306 
307  TensorData makeVector(IndexList dimensions, LabelsList labels, vector<complex<double>> values) {
308  auto result = new VectorContainer{dimensions, labels};
309  result->swap(values);
310  return TensorData{static_cast<IContainer*>(result)};
311  }
312 
313  VectorContainer::ItSequential::ItSequential(DataType::const_iterator it, PositionType maxPos,
314  PositionType pos,
315  PositionType nonZeroPos)
316  : _it{it}, _maxPosition{maxPos}, _nonZeroPos{nonZeroPos}, _position{pos} {
317  if(_position == 0 && _nonZeroPos == 0 && _maxPosition > 0 && isZero(*_it)) {
318  while (_position < _maxPosition && isZero(*_it)) {
319  ++_it;
320  ++_position;
321  }
322  }
323  }
324 
326  return *_it;
327  }
328 
330  return _position;
331  }
332 
334  if(n > 0) {
335  for (size_t i = 0; i < static_cast<size_t>(n) && _position < _maxPosition; ++i) {
336  ++_it;
337  ++_position;
338  while (_position < _maxPosition && isZero(*_it)) {
339  ++_it;
340  ++_position;
341  }
342  ++_nonZeroPos;
343  }
344  }
345  else if(n < 0) {
346  for (size_t i = 0; i < static_cast<size_t>(-n) && _nonZeroPos > 0; ++i) {
347  --_it;
348  --_position;
349  while (isZero(*_it)) {
350  --_it;
351  --_position;
352  }
353  --_nonZeroPos;
354  }
355  }
356  }
357 
359  return _it == static_cast<const ItSequential&>(other)._it;
360  }
361 
363  return false;
364  }
365 
366  ptrdiff_t VectorContainer::ItSequential::distanceFrom(const ItBase& other) const {
367  return _nonZeroPos - static_cast<const ItSequential&>(other)._nonZeroPos;
368  }
369 
370 
371  } // namespace MultiDimensional
372 
373 } // namespace Hammer
std::pair< flatbuffers::Offset< void >, Serial::FBTensorTypes > SerialType
Definition: IContainer.hh:68
friend TensorData makeVector(IndexList, LabelsList, std::vector< std::complex< double >>)
LabeledIndexing< SequentialIndexing > _indexing
const LabeledIndexing< SequentialIndexing > & getIndexing() const
bool compare(const IContainer &other) const override
Log & getLog() const
logging facility
reference operator[](PositionType pos)
virtual LabelsList labels() const =0
std::vector< IndexPair > IndexPairList
ItSequential(DataType::const_iterator it, PositionType maxPosition, PositionType pos=0, PositionType nonZeroPos=0)
IContainer & operator*=(double value) override
size_t PositionType
#define ASSERT(x)
Definition: Exceptions.hh:95
Non-sparse tensor data container.
VectorContainer(const IndexList &dimensions, const LabelsList &labels)
void swap(std::vector< std::complex< double >> &values)
Message logging routines.
std::complex< double > ElementType
Definition: IContainer.hh:34
uint16_t IndexType
std::unique_ptr< IContainer > TensorData
bool isSame(const ItBase &other) const override
const ElementType & const_reference
Definition: IContainer.hh:36
static Log & getLog(const std::string &name)
Get a logger with the given name.
Definition: Logging.cc:139
void setValue(const IndexList &indices, ElementType value=0.)
Hammer exception definitions.
std::vector< IndexType > IndexList
SerialType write(flatbuffers::FlatBufferBuilder *msgwriter) const override
Logging class.
Definition: Logging.hh:33
ptrdiff_t distanceFrom(const ItBase &other) const override
ElementType value(const IndexList &indices) const
IndexLabel
label identifiers of tensor indices they are used to determine which indices can be contracted togeth...
Definition: IndexLabels.hh:27
virtual IndexList dims() const =0
bool isZero(const std::complex< double > val)
Definition: Math/Utils.hh:25
bool isSameShape(const IContainer &other) const override
IndexPairList getSpinLabelPairs() const override
IndexType labelToIndex(IndexLabel label) const override
reference element(const IndexList &coords={}) override
bool canAddAt(const IContainer &subContainer, IndexLabel coord, IndexType position) const override
std::vector< IndexLabel > LabelsList
std::set< IndexLabel > UniqueLabelsList
TensorData makeEmptyVector(const IndexList &dimensions, const LabelsList &labels)
#define MSG_ERROR(x)
Definition: Logging.hh:367
IndexPairList getSameLabelPairs(const IContainer &other, const UniqueLabelsList &indices) const override
auto end(reversion_wrapper< T > w)
Definition: Tools/Utils.hh:84
Serialization related typedefs and includes.