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 
45  template< std::size_t RANK >
46  inline static std::size_t OffsetFromRowMajorIndex(const std::size_t* DimSize, const std::size_t* Index)
47  {
48  std::size_t val = Index[0];
49  for(std::size_t i = 1; i < RANK; i++)
50  {
51  val *= DimSize[i];
52  val += Index[i];
53  }
54  return val;
55  }
56 
68  template< std::size_t RANK >
69  inline static std::size_t OffsetFromStrideIndex(const std::size_t* Strides, const std::size_t* Index)
70  {
71  std::size_t val = 0;
72  for(std::size_t i = 0; i < RANK; i++)
73  {
74  val += Index[i] * Strides[i];
75  }
76  return val;
77  }
78 
91  template< std::size_t RANK >
92  inline static std::size_t StrideFromRowMajorIndex(std::size_t selected_dim, const std::size_t* DimSize)
93  {
94  std::size_t val = 1;
95  for(std::size_t i = 0; i < RANK; i++)
96  {
97  if(i > selected_dim)
98  {
99  val *= DimSize[i];
100  };
101  }
102  return val;
103  }
104 
116  template< std::size_t RANK >
117  inline static void RowMajorIndexFromOffset(std::size_t offset, const std::size_t* DimSize, std::size_t* Index)
118  {
119  std::size_t div[RANK];
120 
121  //in row major format the last index varies the fastest
122  std::size_t i;
123  for(std::size_t d = 0; d < RANK; d++)
124  {
125  i = RANK - d - 1;
126 
127  if(d == 0)
128  {
129  Index[i] = MHO_NDArrayMath::Modulus(offset, DimSize[i]);
130  div[i] = (offset - Index[i]) / DimSize[i];
131  }
132  else
133  {
134  Index[i] = MHO_NDArrayMath::Modulus(div[i + 1], DimSize[i]);
135  div[i] = (div[i + 1] - Index[i]) / DimSize[i];
136  }
137  }
138  }
139 
140  //checks if all the indices in Index are in the valid range
149  template< std::size_t RANK > inline static bool CheckIndexValidity(const std::size_t* DimSize, const std::size_t* Index)
150  {
151  for(std::size_t i = 0; i < RANK; i++)
152  {
153  if(Index[i] >= DimSize[i])
154  {
155  return false;
156  };
157  }
158  return true;
159  };
160 
161  //given the dimensions of an array, computes its total size, assuming all dimensions are non-zero
169  template< std::size_t RANK > inline static std::size_t TotalArraySize(const std::size_t* DimSize)
170  {
171  std::size_t val = 1;
172  for(std::size_t i = 0; i < RANK; i++)
173  {
174  val *= DimSize[i];
175  }
176  return val;
177  }
178 
182  template< std::size_t N > struct PowerOfTwo
183  {
184  enum
185  {
186  value = 2 * PowerOfTwo< N - 1 >::value
187  };
188  };
189 
193  template< int numerator, int denominator > struct Divide
194  {
195  enum
196  {
198  };
199  };
200 
209  template< std::size_t RANK >
210  static void OffsetsForReversedIndices(const std::size_t* DimSize, std::size_t* ReversedIndex)
211  {
212  std::size_t total_array_size = MHO_NDArrayMath::TotalArraySize< RANK >(DimSize);
213  std::size_t index[RANK];
214  for(std::size_t i = 0; i < total_array_size; i++)
215  {
216  MHO_NDArrayMath::RowMajorIndexFromOffset< RANK >(i, DimSize, index);
217  for(std::size_t j = 0; j < RANK; j++)
218  {
219  index[j] = (DimSize[j] - index[j]) % DimSize[j];
220  };
221  ReversedIndex[i] = MHO_NDArrayMath::OffsetFromRowMajorIndex< RANK >(DimSize, index);
222  }
223  }
224 
233  template< std::size_t RANK > static bool IncrementIndices(const std::size_t* DimSize, std::size_t* Index)
234  {
235  for(std::size_t i = 1; i <= RANK; i++)
236  {
237  if(++Index[RANK - i] < DimSize[RANK - i])
238  {
239  return true;
240  }
241  else
242  {
243  Index[RANK - i] = 0;
244  }
245  }
246  //if we have reached here we have overflowed the 0-th dimension
247  return false;
248  }
249 
260  template< std::size_t RANK >
261  static bool IncrementIndices(const std::size_t* DimSize, std::size_t* Index, std::size_t diff)
262  {
263  std::size_t offset = OffsetFromRowMajorIndex< RANK >(DimSize, Index);
264  offset += diff;
265  if(offset < TotalArraySize< RANK >(DimSize))
266  {
267  RowMajorIndexFromOffset< RANK >(offset, DimSize, Index);
268  return true;
269  }
270  //cannot increment past the end
271  return false;
272  }
273 
282  template< std::size_t RANK > static bool DecrementIndices(const std::size_t* DimSize, std::size_t* Index)
283  {
284  for(std::size_t i = 1; i <= RANK; i++)
285  {
286  if(Index[RANK - i] > 0)
287  {
288  --Index[RANK - i];
289  return true;
290  }
291  else
292  {
293  Index[RANK - i] = DimSize[RANK - i] - 1;
294  }
295  }
296  //if we reach here we have underflowed the 0-th dimension
297  return false;
298  }
299 
310  template< std::size_t RANK >
311  static bool DecrementIndices(const std::size_t* DimSize, std::size_t* Index, std::size_t diff)
312  {
313  std::size_t offset = OffsetFromRowMajorIndex< RANK >(DimSize, Index);
314  if(diff < offset)
315  {
316  offset -= diff;
317  RowMajorIndexFromOffset< RANK >(offset, DimSize, Index);
318  return true;
319  }
320  //cannot decrement more than the offset from start
321  return false;
322  }
323 };
324 
328 template<> struct MHO_NDArrayMath::PowerOfTwo< 0 >
329 {
330  enum
331  {
332  value = 1
333  };
334 };
335 
339 template< int numerator > struct MHO_NDArrayMath::Divide< numerator, 1 >
340 {
341  enum
342  {
343  value = numerator
344  };
345 };
346 
347 } // namespace hops
348 
349 #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:282
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:117
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:149
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:92
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:233
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:46
static void OffsetsForReversedIndices(const std::size_t *DimSize, std::size_t *ReversedIndex)
Calculates reversed indices offsets for the given dimensions.
Definition: MHO_NDArrayMath.hh:210
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:69
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:311
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:261
static std::size_t TotalArraySize(const std::size_t *DimSize)
Calculates total size of an array given its dimensions.
Definition: MHO_NDArrayMath.hh:169
Definition: MHO_AdhocFlagging.hh:18
enum Divide - compute integer division at compile time
Definition: MHO_NDArrayMath.hh:194
enum PowerOfTwo - compute 2^N at compile time
Definition: MHO_NDArrayMath.hh:183
Definition: vex.h:175