Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BruteForceIterator.cc
Go to the documentation of this file.
1 ///
2 /// @file BruteForceIterator.cc
3 /// @brief Generic tensor indexing iterator
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 <cstdlib>
13 #include <iostream>
14 
16  #include "Hammer/Exceptions.hh"
17 
18 using namespace std;
19 
20 namespace Hammer {
21 
22  namespace MultiDimensional {
23 
24  BruteForceIterator::BruteForceIterator() : _dimensions{}, _fixedMask{}, _state{} {
25  setInitialState();
26  }
27 
28  BruteForceIterator::BruteForceIterator(IndexList dimensions, IndexList fixed) : _dimensions{dimensions}, _fixedMask{fixed} {
29  ASSERT(_fixedMask.size() == 0 || equal(_dimensions.begin(), _dimensions.end(), _fixedMask.begin(), _fixedMask.end(),
30  [](IndexType a, IndexType b) -> bool { return a >= b; }));
31  setInitialState();
32  }
33 
35  BruteForceIterator b{*this};
36  b.setInitialState();
37  return b;
38  }
39 
41  BruteForceIterator b{*this};
42  b._state = _dimensions;
43  return b;
44  }
45 
47  incrementEntry(_dimensions.size(), 1);
48  return *this;
49  }
50 
52  BruteForceIterator b{*this};
53  incrementEntry(_dimensions.size(), n);
54  return b;
55  }
56 
57  void BruteForceIterator::incrementEntry(size_t position, int n) {
58  if (position == _dimensions.size()) {
59  if (_dimensions == _state) {
60  throw RangeError("Invalid increment");
61  }
62  long newpos = static_cast<long>(position) - 1;
63  if (_fixedMask.size() > 0) {
64  auto itd = _dimensions.rbegin();
65  auto itm = _fixedMask.rbegin();
66  while (newpos >= 0 && *itd != *itm) {
67  ++itd;
68  ++itm;
69  --newpos;
70  }
71  if(newpos < 0) {
73  return;
74  }
75  }
76  incrementEntry(static_cast<size_t>(newpos), n);
77  return;
78  }
79  if (position == 0) {
80  if (n + _state[0] >= _dimensions[0]) {
82  return;
83  }
84  }
85  auto res = div(_state[position] + n, _dimensions[position]);
86  _state[position] = static_cast<IndexType>(res.rem);
87  if(res.quot != 0) {
88  long newpos = static_cast<long>(position) - 1;
89  if (_fixedMask.size() > 0) {
90  while(newpos >= 0 && _fixedMask[static_cast<size_t>(newpos)] != _dimensions[static_cast<size_t>(newpos)]) {
91  --newpos;
92  }
93  }
94  if(newpos < 0) {
96  return;
97  }
98  incrementEntry(static_cast<size_t>(newpos), res.quot);
99  }
100  return;
101  }
102 
104  return _state;
105  }
106 
108  _state.clear();
109  if(_fixedMask.size() == 0) {
110  _state = IndexList(_dimensions.size(), 0);
111  }
112  else {
113  _state.reserve(_dimensions.size());
114  auto itd = _dimensions.begin();
115  auto itm = _fixedMask.begin();
116  for(; itd != _dimensions.end(); ++itd, ++itm) {
117  if(*itd == *itm) {
118  _state.push_back(0);
119  }
120  else {
121  _state.push_back(*itm);
122  }
123  }
124  }
125  }
126 
128  return _state == other._state;
129  }
130 
131 
132  } // namespace MultiDimensional
133 
134 } // namespace Hammer
#define ASSERT(x)
Definition: Exceptions.hh:95
IndexList _fixedMask
the strides for each tensor index (necessary to convert coordinates to position in _data) ...
uint16_t IndexType
Hammer exception definitions.
std::vector< IndexType > IndexList
bool isSame(const BruteForceIterator &other) const
Generic tensor indexing iterator.
Out-of-range error class.
Definition: Exceptions.hh:49