HOPS
HOPS class reference
MHO_NDArrayMath.hh
Go to the documentation of this file.
1 #ifndef MHO_NDArrayMath_HH__
2 #define MHO_NDArrayMath_HH__
3 
4 #include <cmath>
5 #include <cstddef>
6 
7 namespace hops
8 {
9 
19 {
20  public:
22  virtual ~MHO_NDArrayMath(){};
23 
32  static std::size_t Modulus(std::size_t arg, std::size_t n) { return arg % n; }
33 
34 
46  template< std::size_t RANK >
47  inline static std::size_t OffsetFromRowMajorIndex(const std::size_t* DimSize, const std::size_t* Index)
48  {
49  std::size_t val = Index[0];
50  for(std::size_t i = 1; i < RANK; i++)
51  {
52  val *= DimSize[i];
53  val += Index[i];
54  }
55  return val;
56  }
57 
58 
70  template< std::size_t RANK >
71  inline static std::size_t OffsetFromStrideIndex(const std::size_t* Strides, const std::size_t* Index)
72  {
73  std::size_t val = 0;
74  for(std::size_t i = 0; i < RANK; i++)
75  {
76  val += Index[i] * Strides[i];
77  }
78  return val;
79  }
80 
81 
94  template< std::size_t RANK >
95  inline static std::size_t StrideFromRowMajorIndex(std::size_t selected_dim, const std::size_t* DimSize)
96  {
97  std::size_t val = 1;
98  for(std::size_t i = 0; i < RANK; i++)
99  {
100  if(i > selected_dim)
101  {
102  val *= DimSize[i];
103  };
104  }
105  return val;
106  }
107 
108 
120  template< std::size_t RANK >
121  inline static void RowMajorIndexFromOffset(std::size_t offset, const std::size_t* DimSize, std::size_t* Index)
122  {
123  std::size_t div[RANK];
124 
125  //in row major format the last index varies the fastest
126  std::size_t i;
127  for(std::size_t d = 0; d < RANK; d++)
128  {
129  i = RANK - d - 1;
130 
131  if(d == 0)
132  {
133  Index[i] = MHO_NDArrayMath::Modulus(offset, DimSize[i]);
134  div[i] = (offset - Index[i]) / DimSize[i];
135  }
136  else
137  {
138  Index[i] = MHO_NDArrayMath::Modulus(div[i + 1], DimSize[i]);
139  div[i] = (div[i + 1] - Index[i]) / DimSize[i];
140  }
141  }
142  }
143 
144  //checks if all the indices in Index are in the valid range
153  template< std::size_t RANK > inline static bool CheckIndexValidity(const std::size_t* DimSize, const std::size_t* Index)
154  {
155  for(std::size_t i = 0; i < RANK; i++)
156  {
157  if(Index[i] >= DimSize[i])
158  {
159  return false;
160  };
161  }
162  return true;
163  };
164 
165  //given the dimensions of an array, computes its total size, assuming all dimensions are non-zero
173  template< std::size_t RANK > inline static std::size_t TotalArraySize(const std::size_t* DimSize)
174  {
175  std::size_t val = 1;
176  for(std::size_t i = 0; i < RANK; i++)
177  {
178  val *= DimSize[i];
179  }
180  return val;
181  }
182 
186  template< std::size_t N > struct PowerOfTwo
187  {
188  enum
189  {
190  value = 2 * PowerOfTwo< N - 1 >::value
191  };
192  };
193 
197  template< int numerator, int denominator > struct Divide
198  {
199  enum
200  {
202  };
203  };
204 
213  template< std::size_t RANK >
214  static void OffsetsForReversedIndices(const std::size_t* DimSize, std::size_t* ReversedIndex)
215  {
216  std::size_t total_array_size = MHO_NDArrayMath::TotalArraySize< RANK >(DimSize);
217  std::size_t index[RANK];
218  for(std::size_t i = 0; i < total_array_size; i++)
219  {
220  MHO_NDArrayMath::RowMajorIndexFromOffset< RANK >(i, DimSize, index);
221  for(std::size_t j = 0; j < RANK; j++)
222  {
223  index[j] = (DimSize[j] - index[j]) % DimSize[j];
224  };
225  ReversedIndex[i] = MHO_NDArrayMath::OffsetFromRowMajorIndex< RANK >(DimSize, index);
226  }
227  }
228 
237  template< std::size_t RANK > static bool IncrementIndices(const std::size_t* DimSize, std::size_t* Index)
238  {
239  for(std::size_t i = 1; i <= RANK; i++)
240  {
241  if(++Index[RANK - i] < DimSize[RANK - i])
242  {
243  return true;
244  }
245  else
246  {
247  Index[RANK - i] = 0;
248  }
249  }
250  //if we have reached here we have overflowed the 0-th dimension
251  return false;
252  }
253 
264  template< std::size_t RANK >
265  static bool IncrementIndices(const std::size_t* DimSize, std::size_t* Index, std::size_t diff)
266  {
267  std::size_t offset = OffsetFromRowMajorIndex< RANK >(DimSize, Index);
268  offset += diff;
269  if(offset < TotalArraySize< RANK >(DimSize))
270  {
271  RowMajorIndexFromOffset< RANK >(offset, DimSize, Index);
272  return true;
273  }
274  //cannot increment past the end
275  return false;
276  }
277 
286  template< std::size_t RANK > static bool DecrementIndices(const std::size_t* DimSize, std::size_t* Index)
287  {
288  for(std::size_t i = 1; i <= RANK; i++)
289  {
290  if(Index[RANK - i] > 0)
291  {
292  --Index[RANK - i];
293  return true;
294  }
295  else
296  {
297  Index[RANK - i] = DimSize[RANK - i] - 1;
298  }
299  }
300  //if we reach here we have underflowed the 0-th dimension
301  return false;
302  }
303 
314  template< std::size_t RANK >
315  static bool DecrementIndices(const std::size_t* DimSize, std::size_t* Index, std::size_t diff)
316  {
317  std::size_t offset = OffsetFromRowMajorIndex< RANK >(DimSize, Index);
318  if(diff < offset)
319  {
320  offset -= diff;
321  RowMajorIndexFromOffset< RANK >(offset, DimSize, Index);
322  return true;
323  }
324  //cannot decrement more than the offset from start
325  return false;
326  }
327 };
328 
332 template<> struct MHO_NDArrayMath::PowerOfTwo< 0 >
333 {
334  enum
335  {
336  value = 1
337  };
338 };
339 
343 template< int numerator > struct MHO_NDArrayMath::Divide< numerator, 1 >
344 {
345  enum
346  {
347  value = numerator
348  };
349 };
350 
351 } // namespace hops
352 
353 #endif
utility functions for multidimensional array access
Definition: MHO_NDArrayMath.hh:19
static bool DecrementIndices(const std::size_t *DimSize, std::size_t *Index)
Decrements indices in a multidimensional by one, array using row major indexing.
Definition: MHO_NDArrayMath.hh:286
static std::size_t Modulus(std::size_t arg, std::size_t n)
Calculates the modulus of two integers.
Definition: MHO_NDArrayMath.hh:32
static void RowMajorIndexFromOffset(std::size_t offset, const std::size_t *DimSize, std::size_t *Index)
Function RowMajorIndexFromOffset.
Definition: MHO_NDArrayMath.hh:121
static bool CheckIndexValidity(const std::size_t *DimSize, const std::size_t *Index)
Checks if all indices in Index are within valid range for a multidimensional array.
Definition: MHO_NDArrayMath.hh:153
MHO_NDArrayMath()
Definition: MHO_NDArrayMath.hh:21
static std::size_t StrideFromRowMajorIndex(std::size_t selected_dim, const std::size_t *DimSize)
Calculates stride for a given dimension in a row-major indexed multidimensional array.
Definition: MHO_NDArrayMath.hh:95
static bool IncrementIndices(const std::size_t *DimSize, std::size_t *Index)
Increment multi-dimensional indices by one in row-major order, accounting for roll-over.
Definition: MHO_NDArrayMath.hh:237
static std::size_t OffsetFromRowMajorIndex(const std::size_t *DimSize, const std::size_t *Index)
Calculates offset into a multidimensional array using row-major indexing.
Definition: MHO_NDArrayMath.hh:47
static void OffsetsForReversedIndices(const std::size_t *DimSize, std::size_t *ReversedIndex)
Calculates reversed indices offsets for the given dimensions.
Definition: MHO_NDArrayMath.hh:214
static std::size_t OffsetFromStrideIndex(const std::size_t *Strides, const std::size_t *Index)
Calculates offset for a given index into a multidimensional array using row-major indexing/strides.
Definition: MHO_NDArrayMath.hh:71
static bool DecrementIndices(const std::size_t *DimSize, std::size_t *Index, std::size_t diff)
Decrements indices in a multidimensional array by amount specified in diff, or until an underflow is ...
Definition: MHO_NDArrayMath.hh:315
virtual ~MHO_NDArrayMath()
Definition: MHO_NDArrayMath.hh:22
static bool IncrementIndices(const std::size_t *DimSize, std::size_t *Index, std::size_t diff)
Increment multi-dimensional indices by the amount in diff (accounting for roll-over) and return true ...
Definition: MHO_NDArrayMath.hh:265
static std::size_t TotalArraySize(const std::size_t *DimSize)
Calculates total size of an array given its dimensions.
Definition: MHO_NDArrayMath.hh:173
Definition: MHO_ChannelLabeler.hh:17
enum Divide - compute integer division at compile time
Definition: MHO_NDArrayMath.hh:198
enum PowerOfTwo - compute 2^N at compile time
Definition: MHO_NDArrayMath.hh:187
Definition: vex.h:175