CMS 3D CMS Logo

BoxNDScanner.h
Go to the documentation of this file.
1 #ifndef NPSTAT_BOXNDSCANNER_HH_
2 #define NPSTAT_BOXNDSCANNER_HH_
3 
16 
17 namespace npstat {
37  template <typename Numeric>
39  {
40  public:
42 
46  inline BoxNDScanner(const BoxND<Numeric>& box,
47  const std::vector<unsigned>& shape)
48  : box_(box), state_(0UL)
49  {initialize(shape.empty() ? static_cast<unsigned*>(0) :
50  &shape[0], shape.size());}
51 
52  inline BoxNDScanner(const BoxND<Numeric>& box,
53  const unsigned* shape, const unsigned lenShape)
54  : box_(box), state_(0UL) {initialize(shape, lenShape);}
56 
58  inline unsigned dim() const {return box_.dim();}
59 
61  inline unsigned long state() const {return state_;}
62 
64  inline unsigned long maxState() const {return maxState_;}
65 
67  inline bool isValid() const {return state_ < maxState_;}
68 
70  void getCoords(Numeric* x, unsigned nx) const;
71 
73  void getIndex(unsigned* index, unsigned indexBufferLen) const;
74 
76  inline void reset() {state_ = 0UL;}
77 
80  {if (state_ < maxState_) ++state_; return *this;}
81 
83  inline void operator++(int) {if (state_ < maxState_) ++state_;}
84 
86  inline void setState(const unsigned long state)
87  {state_ = state <= maxState_ ? state : maxState_;}
88 
89  private:
90  BoxNDScanner();
91 
92  void initialize(const unsigned* shape, unsigned lenShape);
93 
95  std::vector<unsigned long> strides_;
96  std::vector<double> bw_;
97  unsigned long state_;
98  unsigned long maxState_;
99  };
100 }
101 
102 #include <cassert>
104 
105 namespace npstat {
106  template <typename Numeric>
107  void BoxNDScanner<Numeric>::initialize(const unsigned* shape,
108  const unsigned dim)
109  {
110  if (!(dim && box_.dim() == dim)) throw npstat::NpstatInvalidArgument(
111  "In npstat::BoxNDScanner::initialize: incompatible scan shape");
112  assert(shape);
113  for (unsigned j=0; j<dim; ++j)
114  if (!shape[j]) throw npstat::NpstatInvalidArgument(
115  "In npstat::BoxNDScanner::initialize: "
116  "number of scans must be positive in each dimension");
117 
118  strides_.resize(dim);
119  strides_[dim - 1] = 1UL;
120  for (unsigned j=dim - 1; j>0; --j)
121  strides_[j - 1] = strides_[j]*shape[j];
122  maxState_ = strides_[0]*shape[0];
123 
124  bw_.reserve(dim);
125  for (unsigned j=0; j<dim; ++j)
126  bw_.push_back(box_[j].length()*1.0/shape[j]);
127  }
128 
129  template <typename Numeric>
130  void BoxNDScanner<Numeric>::getCoords(Numeric* x, const unsigned nx) const
131  {
132  const unsigned dim = strides_.size();
133  if (nx < dim) throw npstat::NpstatInvalidArgument(
134  "In npstat::BoxNDScanner::getCoords: "
135  "insufficient length of the output buffer");
137  "In npstat::BoxNDScanner::getCoords: invalid scanner state");
138  assert(x);
139 
140  unsigned long l = state_;
141  for (unsigned i=0; i<dim; ++i)
142  {
143  unsigned long idx = l / strides_[i];
144  x[i] = box_[i].min() + (idx + 0.5)*bw_[i];
145  l -= (idx * strides_[i]);
146  }
147  }
148 
149  template <typename Numeric>
150  void BoxNDScanner<Numeric>::getIndex(unsigned* ix, const unsigned nx) const
151  {
152  const unsigned dim = strides_.size();
153  if (nx < dim) throw npstat::NpstatInvalidArgument(
154  "In npstat::BoxNDScanner::getIndex: "
155  "insufficient length of the output buffer");
157  "In npstat::BoxNDScanner::getIndex: invalid scanner state");
158  assert(ix);
159 
160  unsigned long l = state_;
161  for (unsigned i=0; i<dim; ++i)
162  {
163  unsigned long idx = l / strides_[i];
164  ix[i] = static_cast<unsigned>(idx);
165  l -= (idx * strides_[i]);
166  }
167  }
168 }
169 
170 
171 #endif // NPSTAT_BOXNDSCANNER_HH_
172 
void setState(const unsigned long state)
Definition: BoxNDScanner.h:86
void getCoords(Numeric *x, unsigned nx) const
Definition: BoxNDScanner.h:130
unsigned long maxState_
Definition: BoxNDScanner.h:98
BoxNDScanner(const BoxND< Numeric > &box, const std::vector< unsigned > &shape)
Definition: BoxNDScanner.h:46
BoxNDScanner(const BoxND< Numeric > &box, const unsigned *shape, const unsigned lenShape)
Definition: BoxNDScanner.h:52
T x() const
Cartesian x coordinate.
Exceptions for the npstat namespace.
void getIndex(unsigned *index, unsigned indexBufferLen) const
Definition: BoxNDScanner.h:150
void initialize(const unsigned *shape, unsigned lenShape)
Definition: BoxNDScanner.h:107
BoxNDScanner & operator++()
Definition: BoxNDScanner.h:79
BoxND< Numeric > box_
Definition: BoxNDScanner.h:94
unsigned long state_
Definition: BoxNDScanner.h:97
std::vector< unsigned long > strides_
Definition: BoxNDScanner.h:95
bool isValid() const
Definition: BoxNDScanner.h:67
unsigned dim() const
Definition: BoxNDScanner.h:58
std::vector< double > bw_
Definition: BoxNDScanner.h:96
unsigned long state() const
Definition: BoxNDScanner.h:61
unsigned long maxState() const
Definition: BoxNDScanner.h:64
Template to represent rectangles, boxes, and hyperboxes.