HOPS
HOPS class reference
MHO_NDArrayWrapper_1.hh
Go to the documentation of this file.
1 #ifndef MHO_NDArrayWrapper_1_HH__
2 #define MHO_NDArrayWrapper_1_HH__
3 
4 //this include file should not be used directly
5 #ifndef MHO_NDArrayWrapper_HH__
6  #error "Do not include MHO_NDArrayWrapper_1.hh directly; use MHO_NDArrayWrapper.hh instead."
7 #endif
8 
9 namespace hops
10 {
11 
15 template< typename XValueType > class MHO_NDArrayWrapper< XValueType, 1 >: public MHO_ExtensibleElement
16 {
17  public:
18  using value_type = XValueType;
19  using index_type = std::array< std::size_t, 1 >;
20  typedef std::integral_constant< std::size_t, 1 > rank;
21 
22  //constructors
23  MHO_NDArrayWrapper() { Construct(nullptr, nullptr); }; //empty constructor, to be configured later
24 
25  MHO_NDArrayWrapper(const std::size_t* dim) { Construct(nullptr, dim); }; //data is internally allocated
26 
27  MHO_NDArrayWrapper(XValueType* ptr, const std::size_t* dim)
28  {
29  Construct(ptr, dim);
30  }; //data is externally allocated/managed
31 
32  MHO_NDArrayWrapper(std::size_t dim) { Construct(nullptr, &dim); }; //data is internally allocated
33 
34  MHO_NDArrayWrapper(XValueType* ptr, std::size_t dim) { Construct(ptr, &dim); }; //data is externally allocated/managed
35 
37  {
38  Construct(nullptr, &(obj.fDims[0]));
39  std::copy(obj.fData.begin(), obj.fData.end(), fData.begin());
40  }
41 
42  //destructor
43  virtual ~MHO_NDArrayWrapper(){};
44 
45  //resize functions
52  virtual void Resize(const std::size_t* dim) { Construct(nullptr, dim); }
53 
60  void Resize(std::size_t dim) { Resize(&dim); }
61 
62  //set pointer to externally managed array with associated dimension
69  void SetExternalData(XValueType* ptr, const std::size_t* dim) { Construct(ptr, dim); }
70 
77  void SetExternalData(XValueType* ptr, std::size_t dim) { Construct(ptr, &dim); }
78 
79  //access to underlying raw array pointer
85  XValueType* GetData() { return fData.data(); };
86 
92  const XValueType* GetData() const { return fData.data(); };
93 
94  //get the total size of the array
100  std::size_t GetRank() const { return 1; }
101 
107  std::size_t GetSize() const { return fDims[0]; };
108 
109  //get the dimensions/shape of the array
115  const std::size_t* GetDimensions() const { return &(fDims[0]); }
116 
122  void GetDimensions(std::size_t* dim) const { dim[0] = fDims[0]; }
123 
129  index_type GetDimensionArray() const { return fDims; }
130 
131  std::size_t GetDimension(std::size_t idx) const
132  {
133  if(idx == 0)
134  {
135  return fDims[0];
136  }
137  else
138  {
139  throw std::out_of_range("MHO_NDArrayWrapper_1::GetDimension() index out of range.");
140  }
141  }
142 
143  //get element strides
144  const std::size_t* GetStrides() const { return &(fStrides[0]); }
145 
146  void GetStrides(std::size_t* strd) const { strd[0] = fStrides[0]; }
147 
148  index_type GetStrideArray() const { return fStrides; }
149 
150  std::size_t GetStride(std::size_t idx) const { return fStrides[0]; }
151 
152  //access operators
153 
154  //access operator () -- no bounds checking
155  inline XValueType& operator()(std::size_t idx) { return fData[idx]; }
156 
157  inline const XValueType& operator()(std::size_t idx) const { return fData[idx]; }
158 
159  //access via at() -- same as operator() but with bounds checking
160  inline XValueType& at(std::size_t idx) { return fData.at(idx); }
161 
162  inline const XValueType& at(std::size_t idx) const { return fData.at(idx); }
163 
164  //in 1-d case, operator[] is same as operator()
165  XValueType& operator[](std::size_t i) { return fData[i]; }
166 
167  const XValueType& operator[](std::size_t i) const { return fData[i]; }
168 
169  //assignment operator
171  {
172  if(this != &rhs)
173  {
174  Construct(nullptr, &(rhs.fDims[0]));
175  std::copy(rhs.fData.begin(), rhs.fData.end(), this->fData.begin());
176  }
177  return *this;
178  }
179 
180  //convenience functions
181  void SetArray(const XValueType& obj)
182  {
183  for(std::size_t i = 0; i < fDims[0]; i++)
184  {
185  fData[i] = obj;
186  }
187  }
188 
189  void ZeroArray() { std::memset(&(fData[0]), 0, fData.size() * sizeof(XValueType)); };
190 
191  //expensive copy (as opposed to the assignment operator,
192  //pointers to exernally managed memory are not transferred)
193  //but copied instead, inteally managed memory is also copied
194  virtual void Copy(const MHO_NDArrayWrapper& rhs)
195  {
196  if(this != &rhs)
197  {
198  Construct(nullptr, &(rhs.fDims[0]));
199  std::copy(rhs.fData.begin(), rhs.fData.end(), this->fData.begin());
200  }
201  }
202 
203  // //append the contents of the addition to the end of vector container
204  // virtual int Append(const MHO_NDArrayWrapper& addition)
205  // {
206  // if(this == &addition)
207  // {
208  // msg_error("containers", "cannot append 1d-array to itself." << eom);
209  // return 1;
210  // }
211  //
212  // XValueType* &(fData[0]);
213  // bool fExternallyManaged;
214  // std::vector< XValueType > fData; //used for internally managed data
215  // index_type fDims; //size of each dimension
216  // index_type fStrides; //strides between elements in each dimension
217  // mutable index_type fTmp; //temp index workspace
218  // std::size_t fDims[0]; //total size of array
219  //
220  // fData.reserve( fDims[0] + addition.fDims[0]);
221  // //in-case our re-allocation has triggered a move, we need to update the &(fData[0])
222  //
223  // if(addition.fExternallyManaged)
224  // {
225  // fData.insert(addition.end(), addition.begin(), addition.end());
226  //
227  // &(fData[0]) = &(fData[0]);
228  // fDims[0] = fData.size();
229  // fDims[0] = fDims[0];
230  // fStrides = 1;
231  // }
232  //
233  // Construct(nullptr, &(rhs.fDims[0]));
234  // if(fDims[0] != 0){std::copy(rhs.fData.begin(), rhs.fData.end(), this->fData.begin() );}
235  // return 0;
236  //
237  // }
238 
239  //linear offset into the array -- no real utility in 1-d case
240  std::size_t GetOffsetForIndices(const std::size_t* index) { return index[0]; }
241 
242  index_type GetIndicesForOffset(std::size_t offset)
243  {
244  index_type val;
245  val[0] = offset;
246  return val;
247  }
248 
249  //here mainly so table containers with rank 1 still work, in this case a sub-view just gets you a scalar
250  template< typename... XIndexTypeS >
251  typename std::enable_if< (sizeof...(XIndexTypeS) < 1),
252  MHO_NDArrayWrapper< XValueType, 1 - (sizeof...(XIndexTypeS)) > >::type
253  SubView(XIndexTypeS... idx)
254  {
255  std::array< std::size_t, sizeof...(XIndexTypeS) > leading_idx = {{static_cast< size_t >(idx)...}};
256  for(std::size_t i = 0; i < 1; i++)
257  {
258  fTmp[i] = 0;
259  }
260  for(std::size_t i = 0; i < leading_idx.size(); i++)
261  {
262  fTmp[i] = leading_idx[i];
263  }
264  std::size_t offset = MHO_NDArrayMath::OffsetFromRowMajorIndex< 1 >(&(fDims[0]), &(fTmp[0]));
265  std::array< std::size_t, 1 - (sizeof...(XIndexTypeS)) > dim;
266  for(std::size_t i = 0; i < dim.size(); i++)
267  {
268  dim[i] = fDims[i + (sizeof...(XIndexTypeS))];
269  }
270  return MHO_NDArrayWrapper< XValueType, 1 - (sizeof...(XIndexTypeS)) >(VPTR_AT(fData, offset), &(dim[0]));
271  }
272 
273  //this function is mainly here to allow for 1-d table containers, there's not much utility
274  //of a 'slice view' of a 1-d array (you just get the same array back...)
276  {
277  //just return a 1d array view of this 1-d array
278  return MHO_NDArrayView< XValueType, 1 >(&(fData[0]), &(fDims[0]), &(fStrides[0]));
279  }
280 
281  XValueType& ValueAt(const index_type& idx) { return fData[idx[0]]; }
282 
283  const XValueType& ValueAt(const index_type& idx) const { return fData[idx[0]]; }
284 
285  //in place multiplication by a scalar factor
286  template< typename T >
287  typename std::enable_if< std::is_same< XValueType, T >::value or std::is_integral< T >::value or
288  std::is_floating_point< T >::value,
289  MHO_NDArrayWrapper& >::type inline
290  operator*=(T aScalar)
291  {
292  std::size_t length = fData.size();
293  for(std::size_t i = 0; i < length; i++)
294  {
295  fData[i] *= aScalar;
296  }
297  return *this;
298  }
299 
300  //in place addition by a scalar amount
301  template< typename T >
302  typename std::enable_if< std::is_same< XValueType, T >::value or std::is_integral< T >::value or
303  std::is_floating_point< T >::value,
304  MHO_NDArrayWrapper& >::type inline
305  operator+=(T aScalar)
306  {
307  std::size_t length = fData.size();
308  for(std::size_t i = 0; i < length; i++)
309  {
310  fData[i] += aScalar;
311  }
312  return *this;
313  }
314 
315  //in place subraction by a scalar amount
316  template< typename T >
317  typename std::enable_if< std::is_same< XValueType, T >::value or std::is_integral< T >::value or
318  std::is_floating_point< T >::value,
319  MHO_NDArrayWrapper& >::type inline
320  operator-=(T aScalar)
321  {
322  std::size_t length = fData.size();
323  for(std::size_t i = 0; i < length; i++)
324  {
325  fData[i] -= aScalar;
326  }
327  return *this;
328  }
329 
330  //in place point-wise multiplication by another array
332  {
333  if(!HaveSameNumberOfElements(this, &anArray))
334  {
335  throw std::out_of_range("MHO_NDArrayWrapper::*= size mismatch.");
336  }
337  std::size_t length = fData.size();
338  for(std::size_t i = 0; i < length; i++)
339  {
340  fData[i] *= anArray.fData[i];
341  }
342  return *this;
343  }
344 
345  //in place point-wise addition by another array of the same type
347  {
348  if(!HaveSameNumberOfElements(this, &anArray))
349  {
350  throw std::out_of_range("MHO_NDArrayWrapper::+= size mismatch.");
351  }
352  std::size_t length = fData.size();
353  for(std::size_t i = 0; i < length; i++)
354  {
355  fData[i] += anArray.fData[i];
356  }
357  return *this;
358  }
359 
360  //in place point-wise subtraction of another array
362  {
363  if(!HaveSameNumberOfElements(this, &anArray))
364  {
365  throw std::out_of_range("MHO_NDArrayWrapper::-= size mismatch.");
366  }
367  std::size_t length = fData.size();
368  for(std::size_t i = 0; i < length; i++)
369  {
370  fData[i] -= anArray.fData[i];
371  }
372  return *this;
373  }
374 
375  private:
376  std::vector< XValueType > fData; //used for internally managed data
377  index_type fDims; //size of each dimension
378  index_type fStrides; //strides between elements in each dimension
379  mutable index_type fTmp; //temp index workspace
380 
381  void Construct(XValueType* ptr, const std::size_t* dim)
382  {
383  //default construction (empty)
384  fDims[0] = 0;
385  fStrides[0] = 0;
386  if(ptr == nullptr && dim == nullptr)
387  {
388  return;
389  }
390 
391  //dimensions known
392  if(dim != nullptr)
393  {
394  fDims[0] = dim[0];
395  }
396  fStrides[0] = 1;
397 
398  fData.resize(fDims[0]);
399  if(ptr != nullptr) //if given a ptr, copy in data from this location
400  {
401  std::memcpy(&(fData[0]), ptr, fData.size() * sizeof(XValueType));
402  }
403  }
404 
405  //the iterator definitions //////////////////////////////////////////////////
406  public:
409 
412 
413  iterator begin() { return iterator(&(fData[0]), &(fData[0]), fData.size()); }
414 
415  iterator end() { return iterator(&(fData[0]), &(fData[0]) + fData.size(), fData.size()); }
416 
417  iterator iterator_at(std::size_t offset)
418  {
419  return iterator(&(fData[0]), &(fData[0]) + std::min(offset, fData.size()), fData.size());
420  }
421 
422  const_iterator cbegin() const { return const_iterator(&(fData[0]), &(fData[0]), fData.size()); }
423 
424  const_iterator cend() const { return const_iterator(&(fData[0]), &(fData[0]) + fData.size(), fData.size()); }
425 
426  const_iterator citerator_at(std::size_t offset) const
427  {
428  return const_iterator(&(fData[0]), &(fData[0]) + std::min(offset, fData.size()), fData.size());
429  }
430 
431  stride_iterator stride_begin(std::size_t stride)
432  {
433  return stride_iterator(&(fData[0]), &(fData[0]), fData.size(), stride);
434  }
435 
436  stride_iterator stride_end(std::size_t stride)
437  {
438  return stride_iterator(&(fData[0]), &(fData[0]) + fData.size(), fData.size(), stride);
439  }
440 
441  stride_iterator stride_iterator_at(std::size_t offset, std::size_t stride)
442  {
443  return stride_iterator(&(fData[0]), &(fData[0]) + std::min(offset, fData.size()), fData.size(), stride);
444  }
445 
446  const_stride_iterator cstride_begin(std::size_t stride) const
447  {
448  return const_stride_iterator(&(fData[0]), &(fData[0]), fData.size(), stride);
449  }
450 
451  const_stride_iterator cstride_end(std::size_t stride) const
452  {
453  return const_stride_iterator(&(fData[0]), &(fData[0]) + fData.size(), fData.size(), stride);
454  }
455 
456  const_stride_iterator cstride_iterator_at(std::size_t offset, std::size_t stride) const
457  {
458  return const_stride_iterator(&(fData[0]), &(fData[0]) + std::min(offset, fData.size()), fData.size(), stride);
459  }
460 };
461 
462 } // namespace hops
463 
464 #endif
Class MHO_BidirectionalConstIterator.
Definition: MHO_BidirectionalIterator.hh:144
Class MHO_BidirectionalConstStrideIterator.
Definition: MHO_BidirectionalStrideIterator.hh:139
Class MHO_BidirectionalIterator.
Definition: MHO_BidirectionalIterator.hh:22
Class MHO_BidirectionalStrideIterator.
Definition: MHO_BidirectionalStrideIterator.hh:22
Class MHO_ExtensibleElement.
Definition: MHO_ExtensibleElement.hh:60
MHO_NDArrayView is a class to represent a view (slice) of a n-dimensional array Thu 13 Aug 2020 02:53...
Definition: MHO_NDArrayView.hh:33
XValueType & at(std::size_t idx)
Definition: MHO_NDArrayWrapper_1.hh:160
std::enable_if< std::is_same< XValueType, T >::value or std::is_integral< T >::value or std::is_floating_point< T >::value, MHO_NDArrayWrapper & >::type operator-=(T aScalar)
Definition: MHO_NDArrayWrapper_1.hh:320
MHO_NDArrayWrapper & operator=(const MHO_NDArrayWrapper &rhs)
Definition: MHO_NDArrayWrapper_1.hh:170
XValueType & ValueAt(const index_type &idx)
Definition: MHO_NDArrayWrapper_1.hh:281
virtual ~MHO_NDArrayWrapper()
Definition: MHO_NDArrayWrapper_1.hh:43
MHO_NDArrayWrapper(std::size_t dim)
Definition: MHO_NDArrayWrapper_1.hh:32
XValueType & operator()(std::size_t idx)
Definition: MHO_NDArrayWrapper_1.hh:155
std::size_t GetStride(std::size_t idx) const
Definition: MHO_NDArrayWrapper_1.hh:150
const_stride_iterator cstride_end(std::size_t stride) const
Definition: MHO_NDArrayWrapper_1.hh:451
MHO_NDArrayWrapper(const std::size_t *dim)
Definition: MHO_NDArrayWrapper_1.hh:25
MHO_NDArrayWrapper & operator*=(const MHO_NDArrayWrapper &anArray)
Definition: MHO_NDArrayWrapper_1.hh:331
void ZeroArray()
Definition: MHO_NDArrayWrapper_1.hh:189
MHO_NDArrayWrapper(XValueType *ptr, std::size_t dim)
Definition: MHO_NDArrayWrapper_1.hh:34
MHO_NDArrayWrapper & operator-=(const MHO_NDArrayWrapper &anArray)
Definition: MHO_NDArrayWrapper_1.hh:361
XValueType * GetData()
Getter for data.
Definition: MHO_NDArrayWrapper_1.hh:85
index_type GetIndicesForOffset(std::size_t offset)
Definition: MHO_NDArrayWrapper_1.hh:242
stride_iterator stride_begin(std::size_t stride)
Definition: MHO_NDArrayWrapper_1.hh:431
void SetArray(const XValueType &obj)
Definition: MHO_NDArrayWrapper_1.hh:181
std::enable_if< std::is_same< XValueType, T >::value or std::is_integral< T >::value or std::is_floating_point< T >::value, MHO_NDArrayWrapper & >::type operator+=(T aScalar)
Definition: MHO_NDArrayWrapper_1.hh:305
std::size_t GetRank() const
Getter for rank.
Definition: MHO_NDArrayWrapper_1.hh:100
const XValueType & operator[](std::size_t i) const
Definition: MHO_NDArrayWrapper_1.hh:167
const_stride_iterator cstride_begin(std::size_t stride) const
Definition: MHO_NDArrayWrapper_1.hh:446
std::array< std::size_t, 1 > index_type
Definition: MHO_NDArrayWrapper_1.hh:19
const std::size_t * GetDimensions() const
Getter for dimensions.
Definition: MHO_NDArrayWrapper_1.hh:115
index_type GetDimensionArray() const
Getter for dimension array.
Definition: MHO_NDArrayWrapper_1.hh:129
virtual void Copy(const MHO_NDArrayWrapper &rhs)
Definition: MHO_NDArrayWrapper_1.hh:194
const std::size_t * GetStrides() const
Definition: MHO_NDArrayWrapper_1.hh:144
std::enable_if< std::is_same< XValueType, T >::value or std::is_integral< T >::value or std::is_floating_point< T >::value, MHO_NDArrayWrapper & >::type operator*=(T aScalar)
Definition: MHO_NDArrayWrapper_1.hh:290
const_stride_iterator cstride_iterator_at(std::size_t offset, std::size_t stride) const
Definition: MHO_NDArrayWrapper_1.hh:456
const XValueType & ValueAt(const index_type &idx) const
Definition: MHO_NDArrayWrapper_1.hh:283
MHO_NDArrayWrapper()
Definition: MHO_NDArrayWrapper_1.hh:23
const_iterator cend() const
Definition: MHO_NDArrayWrapper_1.hh:424
void SetExternalData(XValueType *ptr, const std::size_t *dim)
Setter for external data.
Definition: MHO_NDArrayWrapper_1.hh:69
std::enable_if<(sizeof...(XIndexTypeS)< 1), MHO_NDArrayWrapper< XValueType, 1 -(sizeof...(XIndexTypeS)) > >::type SubView(XIndexTypeS... idx)
Definition: MHO_NDArrayWrapper_1.hh:253
const_iterator cbegin() const
Definition: MHO_NDArrayWrapper_1.hh:422
index_type GetStrideArray() const
Definition: MHO_NDArrayWrapper_1.hh:148
MHO_NDArrayWrapper(XValueType *ptr, const std::size_t *dim)
Definition: MHO_NDArrayWrapper_1.hh:27
MHO_NDArrayView< XValueType, 1 > SliceView(const char *)
Definition: MHO_NDArrayWrapper_1.hh:275
std::size_t GetDimension(std::size_t idx) const
Definition: MHO_NDArrayWrapper_1.hh:131
iterator end()
Definition: MHO_NDArrayWrapper_1.hh:415
stride_iterator stride_end(std::size_t stride)
Definition: MHO_NDArrayWrapper_1.hh:436
const XValueType * GetData() const
Getter for data.
Definition: MHO_NDArrayWrapper_1.hh:92
iterator begin()
Definition: MHO_NDArrayWrapper_1.hh:413
const XValueType & operator()(std::size_t idx) const
Definition: MHO_NDArrayWrapper_1.hh:157
std::size_t GetOffsetForIndices(const std::size_t *index)
Definition: MHO_NDArrayWrapper_1.hh:240
std::integral_constant< std::size_t, 1 > rank
Definition: MHO_NDArrayWrapper_1.hh:20
virtual void Resize(const std::size_t *dim)
Resize an externally managed array using provided dimensions.
Definition: MHO_NDArrayWrapper_1.hh:52
void Resize(std::size_t dim)
Sets dimensions for externally managed array.
Definition: MHO_NDArrayWrapper_1.hh:60
std::size_t GetSize() const
Getter for size.
Definition: MHO_NDArrayWrapper_1.hh:107
void GetStrides(std::size_t *strd) const
Definition: MHO_NDArrayWrapper_1.hh:146
XValueType value_type
Definition: MHO_NDArrayWrapper_1.hh:18
stride_iterator stride_iterator_at(std::size_t offset, std::size_t stride)
Definition: MHO_NDArrayWrapper_1.hh:441
void SetExternalData(XValueType *ptr, std::size_t dim)
Setter for external data.
Definition: MHO_NDArrayWrapper_1.hh:77
XValueType & operator[](std::size_t i)
Definition: MHO_NDArrayWrapper_1.hh:165
iterator iterator_at(std::size_t offset)
Definition: MHO_NDArrayWrapper_1.hh:417
MHO_NDArrayWrapper(const MHO_NDArrayWrapper &obj)
Definition: MHO_NDArrayWrapper_1.hh:36
void GetDimensions(std::size_t *dim) const
Getter for dimensions.
Definition: MHO_NDArrayWrapper_1.hh:122
const_iterator citerator_at(std::size_t offset) const
Definition: MHO_NDArrayWrapper_1.hh:426
const XValueType & at(std::size_t idx) const
Definition: MHO_NDArrayWrapper_1.hh:162
MHO_NDArrayWrapper & operator+=(const MHO_NDArrayWrapper &anArray)
Definition: MHO_NDArrayWrapper_1.hh:346
Class MHO_NDArrayWrapper.
Definition: MHO_NDArrayWrapper.hh:42
MHO_BidirectionalConstIterator< XValueType > const_iterator
Definition: MHO_NDArrayWrapper.hh:625
MHO_BidirectionalStrideIterator< XValueType > stride_iterator
Definition: MHO_NDArrayWrapper.hh:623
MHO_BidirectionalIterator< XValueType > iterator
Definition: MHO_NDArrayWrapper.hh:622
MHO_BidirectionalConstStrideIterator< XValueType > const_stride_iterator
Definition: MHO_NDArrayWrapper.hh:626
std::array< std::size_t, RANK > index_type
Definition: MHO_NDArrayWrapper.hh:45
#define min(a, b)
Definition: max555.c:9
Definition: MHO_ChannelLabeler.hh:17