NumCpp  2.3.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
DataCube.hpp
Go to the documentation of this file.
1 #pragma once
29 
32 #include "NumCpp/Core/Shape.hpp"
33 #include "NumCpp/Core/Slice.hpp"
34 #include "NumCpp/Core/Types.hpp"
35 #include "NumCpp/NdArray.hpp"
36 
37 #include <limits>
38 #include <string>
39 #include <vector>
40 
41 namespace nc
42 {
43  //================================================================================
45  template<typename dtype>
46  class DataCube
47  {
48  public:
49  //================================Typedefs==================================
50  using iterator = typename std::deque<NdArray<dtype> >::iterator;
51  using const_iterator = typename std::deque<NdArray<dtype> >::const_iterator;
52 
53  //============================================================================
56  DataCube() = default;
57 
58  //============================================================================
63  explicit DataCube(uint32 inSize)
64  {
65  cube_.reserve(inSize);
66  }
67 
68  //============================================================================
76  {
77  return cube_.at(inIndex);
78  }
79 
80  //============================================================================
87  const NdArray<dtype>& at(uint32 inIndex) const
88  {
89  return cube_.at(inIndex);
90  }
91 
92  //============================================================================
97  NdArray<dtype>& back() noexcept
98  {
99  return cube_.back();
100  }
101 
102  //============================================================================
107  iterator begin() noexcept
108  {
109  return cube_.begin();
110  }
111 
112  //============================================================================
117  const_iterator cbegin() const noexcept
118  {
119  return cube_.cbegin();
120  }
121 
122  //============================================================================
127  void dump(const std::string& inFilename) const
128  {
129  filesystem::File f(inFilename);
130  if (!f.hasExt())
131  {
132  f.withExt("bin");
133  }
134 
135  std::ofstream ofile(f.fullName().c_str(), std::ios::binary);
136  if (!ofile.good())
137  {
138  THROW_RUNTIME_ERROR("Could not open the input file:\n\t" + inFilename);
139  }
140 
141  for (auto& ndarray : cube_)
142  {
143  ofile.write(reinterpret_cast<const char*>(ndarray.data()), ndarray.size() * sizeof(dtype));
144  }
145 
146  ofile.close();
147  }
148 
149  //============================================================================
154  bool isempty() noexcept
155  {
156  return cube_.empty();
157  }
158 
159  //============================================================================
164  iterator end() noexcept
165  {
166  return cube_.end();
167  }
168 
169  //============================================================================
174  const_iterator cend() const noexcept
175  {
176  return cube_.cend();
177  }
178 
179  //============================================================================
184  NdArray<dtype>& front() noexcept
185  {
186  return cube_.front();
187  }
188 
189  //============================================================================
194  const Shape& shape() const noexcept
195  {
196  return elementShape_;
197  }
198 
199  //============================================================================
204  uint32 sizeZ() const noexcept
205  {
206  return static_cast<uint32>(cube_.size());
207  }
208 
209  //============================================================================
212  void pop_back() noexcept
213  {
214  cube_.pop_back();
215  }
216 
217  //============================================================================
222  void push_back(const NdArray<dtype>& inArray)
223  {
224  const Shape inputShape = inArray.shape();
225 
226  if (elementShape_.rows == 0 && elementShape_.cols == 0)
227  {
228  // initialize to the first input array size
229  elementShape_.rows = inputShape.rows;
230  elementShape_.cols = inputShape.cols;
231  }
232 
233  if (inputShape != elementShape_)
234  {
235  THROW_INVALID_ARGUMENT_ERROR("element arrays must all be the same shape");
236  }
237 
238  cube_.push_back(inArray);
239  }
240 
241  //============================================================================
248  {
249  if (inIndex < 0)
250  {
251  inIndex += elementShape_.size();
252  }
253 
254  NdArray<dtype> returnArray(1, sizeZ());
255 
256  for (uint32 i = 0; i < sizeZ(); ++i)
257  {
258  returnArray[i] = cube_[i][inIndex];
259  }
260 
261  return returnArray;
262  }
263 
264  //============================================================================
271  NdArray<dtype> sliceZ(int32 inIndex, Slice inSliceZ) const
272  {
273  if (inIndex < 0)
274  {
275  inIndex += elementShape_.size();
276  }
277 
278  NdArray<dtype> returnArray(1, inSliceZ.numElements(sizeZ()));
279 
280  uint32 idx = 0;
281  for (int32 i = inSliceZ.start; i < inSliceZ.stop; i+=inSliceZ.step)
282  {
283  returnArray[idx++] = cube_[i][inIndex];
284  }
285 
286  return returnArray;
287  }
288 
289  //============================================================================
296  NdArray<dtype> sliceZAll(int32 inRow, int32 inCol) const
297  {
298  if (inRow < 0)
299  {
300  inRow += elementShape_.rows;
301  }
302 
303  if (inCol < 0)
304  {
305  inCol += elementShape_.cols;
306  }
307 
308  NdArray<dtype> returnArray(1, sizeZ());
309 
310  for (uint32 i = 0; i < sizeZ(); ++i)
311  {
312  returnArray[i] = cube_[i](inRow, inCol);
313  }
314 
315  return returnArray;
316  }
317 
318  //============================================================================
326  NdArray<dtype> sliceZ(int32 inRow, int32 inCol, Slice inSliceZ) const
327  {
328  if (inRow < 0)
329  {
330  inRow += elementShape_.rows;
331  }
332 
333  if (inCol < 0)
334  {
335  inCol += elementShape_.cols;
336  }
337 
338  NdArray<dtype> returnArray(1, inSliceZ.numElements(sizeZ()));
339 
340  uint32 idx = 0;
341  for (int32 i = inSliceZ.start; i < inSliceZ.stop; i+=inSliceZ.step)
342  {
343  returnArray[idx++] = cube_[i](inRow, inCol);
344  }
345 
346  return returnArray;
347  }
348 
349  //============================================================================
356  NdArray<dtype> sliceZAll(Slice inRow, int32 inCol) const
357  {
358  if (inCol < 0)
359  {
360  inCol += elementShape_.cols;
361  }
362 
363  NdArray<dtype> returnArray(inRow.numElements(elementShape_.rows), sizeZ());
364  for (uint32 i = 0; i < sizeZ(); ++i)
365  {
366  returnArray.put(returnArray.rSlice(), i, cube_[i](inRow, inCol));
367  }
368 
369  return returnArray;
370  }
371 
372  //============================================================================
380  NdArray<dtype> sliceZ(Slice inRow, int32 inCol, Slice inSliceZ) const
381  {
382  if (inCol < 0)
383  {
384  inCol += elementShape_.cols;
385  }
386 
387  NdArray<dtype> returnArray(inRow.numElements(elementShape_.rows), inSliceZ.numElements(sizeZ()));
388  uint32 idx = 0;
389  for (int32 i = inSliceZ.start; i < inSliceZ.stop; i+=inSliceZ.step)
390  {
391  returnArray.put(returnArray.rSlice(), idx++, cube_[i](inRow, inCol));
392  }
393 
394  return returnArray;
395  }
396 
397  //============================================================================
404  NdArray<dtype> sliceZAll(int32 inRow, Slice inCol) const
405  {
406  if (inRow < 0)
407  {
408  inRow += elementShape_.rows;
409  }
410 
411  NdArray<dtype> returnArray(inCol.numElements(elementShape_.cols), sizeZ());
412  for (uint32 i = 0; i < sizeZ(); ++i)
413  {
414  returnArray.put(returnArray.rSlice(), i, cube_[i](inRow, inCol));
415  }
416 
417  return returnArray;
418  }
419 
420  //============================================================================
428  NdArray<dtype> sliceZ(int32 inRow, Slice inCol, Slice inSliceZ) const
429  {
430  if (inRow < 0)
431  {
432  inRow += elementShape_.rows;
433  }
434 
435  NdArray<dtype> returnArray(inCol.numElements(elementShape_.cols), inSliceZ.numElements(sizeZ()));
436  uint32 idx = 0;
437  for (int32 i = inSliceZ.start; i < inSliceZ.stop; i+=inSliceZ.step)
438  {
439  returnArray.put(returnArray.rSlice(), idx++, cube_[i](inRow, inCol));
440  }
441 
442  return returnArray;
443  }
444 
445  //============================================================================
452  DataCube<dtype> sliceZAll(Slice inRow, Slice inCol) const
453  {
454  DataCube<dtype> returnCube(sizeZ());
455  for (uint32 i = 0; i < sizeZ(); ++i)
456  {
457  returnCube.push_back(cube_[i](inRow, inCol));
458  }
459 
460  return returnCube;
461  }
462 
463  //============================================================================
471  DataCube<dtype> sliceZ(Slice inRow, Slice inCol, Slice inSliceZ) const
472  {
473  DataCube<dtype> returnCube(inSliceZ.numElements(sizeZ()));
474  for (int32 i = inSliceZ.start; i < inSliceZ.stop; i+=inSliceZ.step)
475  {
476  returnCube.push_back(cube_[i](inRow, inCol));
477  }
478 
479  return returnCube;
480  }
481 
482  //============================================================================
489  {
490  if (inIndex < 0)
491  {
492  inIndex += elementShape_.size();
493  }
494 
495  if (static_cast<uint32>(inIndex) >= elementShape_.size())
496  {
497  THROW_INVALID_ARGUMENT_ERROR("inIndex exceeds matrix dimensions.");
498  }
499 
500  return sliceZAll(inIndex);
501  }
502 
503  //============================================================================
510  NdArray<dtype> sliceZat(int32 inIndex, Slice inSliceZ) const
511  {
512  if (inIndex < 0)
513  {
514  inIndex += elementShape_.size();
515  }
516 
517  if (static_cast<uint32>(inIndex) >= elementShape_.size())
518  {
519  THROW_INVALID_ARGUMENT_ERROR("inIndex exceeds matrix dimensions.");
520  }
521 
522  auto numElements = inSliceZ.numElements(sizeZ());
523  if (numElements > sizeZ())
524  {
525  THROW_INVALID_ARGUMENT_ERROR("inIndex exceeds matrix dimensions.");
526  }
527 
528  return sliceZ(inIndex, inSliceZ);
529  }
530 
531  //============================================================================
539  NdArray<dtype> sliceZAllat(int32 inRow, int32 inCol) const
540  {
541  if (inRow < 0)
542  {
543  inRow += elementShape_.rows;
544  }
545 
546  if (inCol < 0)
547  {
548  inCol += elementShape_.cols;
549  }
550 
551  if (static_cast<uint32>(inRow) >= elementShape_.rows)
552  {
553  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
554  }
555 
556  if (static_cast<uint32>(inCol) >= elementShape_.cols)
557  {
558  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
559  }
560 
561  return sliceZAll(inRow, inCol);
562  }
563 
564  //============================================================================
572  NdArray<dtype> sliceZat(int32 inRow, int32 inCol, Slice inSliceZ) const
573  {
574  if (inRow < 0)
575  {
576  inRow += elementShape_.rows;
577  }
578 
579  if (inCol < 0)
580  {
581  inCol += elementShape_.cols;
582  }
583 
584  if (static_cast<uint32>(inRow) >= elementShape_.rows)
585  {
586  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
587  }
588  if (static_cast<uint32>(inCol) >= elementShape_.cols)
589  {
590  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
591  }
592 
593  auto numElements = inSliceZ.numElements(sizeZ());
594  if (numElements > sizeZ())
595  {
596  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
597  }
598 
599  return sliceZ(inRow, inCol, inSliceZ);
600  }
601 
602  //============================================================================
609  NdArray<dtype> sliceZAllat(Slice inRow, int32 inCol) const
610  {
611  auto numRows = inRow.numElements(elementShape_.rows);
612  if (numRows > elementShape_.rows)
613  {
614  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
615  }
616 
617  if (inCol < 0)
618  {
619  inCol += elementShape_.cols;
620  }
621 
622  if (static_cast<uint32>(inCol) >= elementShape_.cols)
623  {
624  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
625  }
626 
627  return sliceZAll(inRow, inCol);
628  }
629 
630  //============================================================================
638  NdArray<dtype> sliceZat(Slice inRow, int32 inCol, Slice inSliceZ) const
639  {
640  auto numRows = inRow.numElements(elementShape_.rows);
641  if (numRows > elementShape_.rows)
642  {
643  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
644  }
645 
646  if (inCol < 0)
647  {
648  inCol += elementShape_.cols;
649  }
650 
651  if (static_cast<uint32>(inCol) >= elementShape_.cols)
652  {
653  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
654  }
655 
656  auto numElements = inSliceZ.numElements(sizeZ());
657  if (numElements > sizeZ())
658  {
659  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
660  }
661 
662  return sliceZ(inRow, inCol, inSliceZ);
663  }
664 
665  //============================================================================
672  NdArray<dtype> sliceZAllat(int32 inRow, Slice inCol) const
673  {
674  auto numCols = inCol.numElements(elementShape_.cols);
675  if (numCols > elementShape_.cols)
676  {
677  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
678  }
679 
680  if (inRow < 0)
681  {
682  inRow += elementShape_.rows;
683  }
684 
685  if (static_cast<uint32>(inRow) >= elementShape_.rows)
686  {
687  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
688  }
689 
690  return sliceZAll(inRow, inCol);
691  }
692 
693  //============================================================================
701  NdArray<dtype> sliceZat(int32 inRow, Slice inCol, Slice inSliceZ) const
702  {
703  auto numCols = inCol.numElements(elementShape_.cols);
704  if (numCols > elementShape_.cols)
705  {
706  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
707  }
708 
709  if (inRow < 0)
710  {
711  inRow += elementShape_.rows;
712  }
713 
714  if (static_cast<uint32>(inRow) >= elementShape_.rows)
715  {
716  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
717  }
718 
719  auto numElements = inSliceZ.numElements(sizeZ());
720  if (numElements > sizeZ())
721  {
722  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
723  }
724 
725  return sliceZ(inRow, inCol, inSliceZ);
726  }
727 
728  //============================================================================
736  {
737  if (inRow.numElements(elementShape_.rows) > elementShape_.rows)
738  {
739  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
740  }
741 
742  if (inCol.numElements(elementShape_.cols) > elementShape_.cols)
743  {
744  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
745  }
746 
747  return sliceZAll(inRow, inCol);
748  }
749 
750  //============================================================================
758  DataCube<dtype> sliceZat(Slice inRow, Slice inCol, Slice inSliceZ) const
759  {
760  if (inRow.numElements(elementShape_.rows) > elementShape_.rows)
761  {
762  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
763  }
764 
765  if (inCol.numElements(elementShape_.cols) > elementShape_.cols)
766  {
767  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
768  }
769 
770  auto numElements = inSliceZ.numElements(sizeZ());
771  if (numElements > sizeZ())
772  {
773  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
774  }
775 
776  return sliceZ(inRow, inCol, inSliceZ);
777  }
778 
779  //============================================================================
786  NdArray<dtype>& operator[](uint32 inIndex) noexcept
787  {
788  return cube_[inIndex];
789  }
790 
791  //============================================================================
798  const NdArray<dtype>& operator[](uint32 inIndex) const noexcept
799  {
800  return cube_[inIndex];
801  }
802 
803  private:
804  //================================Attributes==================================
805  std::vector<NdArray<dtype> > cube_{};
806  Shape elementShape_{ 0, 0 };
807  };
808 } // namespace nc
nc::Slice::stop
int32 stop
Definition: Slice.hpp:48
nc::NdArray::shape
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4311
nc::int32
std::int32_t int32
Definition: Types.hpp:36
Error.hpp
nc::DataCube::DataCube
DataCube(uint32 inSize)
Definition: DataCube.hpp:63
nc::DataCube::sliceZAllat
DataCube< dtype > sliceZAllat(Slice inRow, Slice inCol) const
Definition: DataCube.hpp:735
nc::DataCube::DataCube
DataCube()=default
nc::DataCube::sliceZat
NdArray< dtype > sliceZat(int32 inIndex, Slice inSliceZ) const
Definition: DataCube.hpp:510
nc::DataCube::end
iterator end() noexcept
Definition: DataCube.hpp:164
nc::DataCube::sliceZ
NdArray< dtype > sliceZ(int32 inRow, Slice inCol, Slice inSliceZ) const
Definition: DataCube.hpp:428
nc::NdArray< dtype >
nc::uint32
std::uint32_t uint32
Definition: Types.hpp:40
nc::NdArray::rSlice
Slice rSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:905
nc::DataCube::sizeZ
uint32 sizeZ() const noexcept
Definition: DataCube.hpp:204
nc::DataCube::back
NdArray< dtype > & back() noexcept
Definition: DataCube.hpp:97
nc::DataCube::isempty
bool isempty() noexcept
Definition: DataCube.hpp:154
NdArray.hpp
nc::DataCube::dump
void dump(const std::string &inFilename) const
Definition: DataCube.hpp:127
nc::Shape
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:40
nc::NdArray::put
NdArray< dtype > & put(int32 inIndex, value_type inValue)
Definition: NdArrayCore.hpp:3684
nc::Slice::start
int32 start
Definition: Slice.hpp:47
nc::DataCube::front
NdArray< dtype > & front() noexcept
Definition: DataCube.hpp:184
nc::DataCube::sliceZ
NdArray< dtype > sliceZ(Slice inRow, int32 inCol, Slice inSliceZ) const
Definition: DataCube.hpp:380
nc::DataCube::const_iterator
typename std::deque< NdArray< dtype > >::const_iterator const_iterator
Definition: DataCube.hpp:51
nc::DataCube::operator[]
const NdArray< dtype > & operator[](uint32 inIndex) const noexcept
Definition: DataCube.hpp:798
nc::DataCube
Convenience container for holding a uniform array of NdArrays.
Definition: DataCube.hpp:46
nc::Shape::cols
uint32 cols
Definition: Core/Shape.hpp:45
nc::DataCube::at
const NdArray< dtype > & at(uint32 inIndex) const
Definition: DataCube.hpp:87
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(int32 inRow, int32 inCol) const
Definition: DataCube.hpp:539
nc::Slice::numElements
uint32 numElements(uint32 inArraySize)
Definition: Slice.hpp:164
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(int32 inRow, Slice inCol) const
Definition: DataCube.hpp:672
nc::DataCube::cend
const_iterator cend() const noexcept
Definition: DataCube.hpp:174
THROW_RUNTIME_ERROR
#define THROW_RUNTIME_ERROR(msg)
Definition: Error.hpp:37
nc::Slice::step
int32 step
Definition: Slice.hpp:49
Shape.hpp
Filesystem.hpp
nc::DataCube::shape
const Shape & shape() const noexcept
Definition: DataCube.hpp:194
nc
Definition: Coordinate.hpp:44
nc::DataCube::sliceZat
NdArray< dtype > sliceZat(Slice inRow, int32 inCol, Slice inSliceZ) const
Definition: DataCube.hpp:638
nc::DataCube::push_back
void push_back(const NdArray< dtype > &inArray)
Definition: DataCube.hpp:222
nc::DataCube::sliceZAll
NdArray< dtype > sliceZAll(int32 inIndex) const
Definition: DataCube.hpp:247
nc::DataCube::sliceZat
DataCube< dtype > sliceZat(Slice inRow, Slice inCol, Slice inSliceZ) const
Definition: DataCube.hpp:758
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(Slice inRow, int32 inCol) const
Definition: DataCube.hpp:609
nc::Shape::rows
uint32 rows
Definition: Core/Shape.hpp:44
nc::DataCube::sliceZ
DataCube< dtype > sliceZ(Slice inRow, Slice inCol, Slice inSliceZ) const
Definition: DataCube.hpp:471
nc::DataCube::operator[]
NdArray< dtype > & operator[](uint32 inIndex) noexcept
Definition: DataCube.hpp:786
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
nc::Shape::size
constexpr uint32 size() const noexcept
Definition: Core/Shape.hpp:102
nc::DataCube::sliceZat
NdArray< dtype > sliceZat(int32 inRow, int32 inCol, Slice inSliceZ) const
Definition: DataCube.hpp:572
nc::DataCube::sliceZAll
NdArray< dtype > sliceZAll(Slice inRow, int32 inCol) const
Definition: DataCube.hpp:356
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(int32 inIndex) const
Definition: DataCube.hpp:488
nc::DataCube::sliceZ
NdArray< dtype > sliceZ(int32 inRow, int32 inCol, Slice inSliceZ) const
Definition: DataCube.hpp:326
nc::DataCube::sliceZat
NdArray< dtype > sliceZat(int32 inRow, Slice inCol, Slice inSliceZ) const
Definition: DataCube.hpp:701
nc::DataCube::iterator
typename std::deque< NdArray< dtype > >::iterator iterator
Definition: DataCube.hpp:50
Types.hpp
nc::random::f
dtype f(dtype inDofN, dtype inDofD)
Definition: f.hpp:57
nc::Slice
A Class for slicing into NdArrays.
Definition: Slice.hpp:43
nc::DataCube::sliceZAll
DataCube< dtype > sliceZAll(Slice inRow, Slice inCol) const
Definition: DataCube.hpp:452
nc::DataCube::cbegin
const_iterator cbegin() const noexcept
Definition: DataCube.hpp:117
nc::DataCube::at
NdArray< dtype > & at(uint32 inIndex)
Definition: DataCube.hpp:75
nc::DataCube::sliceZAll
NdArray< dtype > sliceZAll(int32 inRow, int32 inCol) const
Definition: DataCube.hpp:296
Slice.hpp
nc::filesystem::File
Provides simple filesystem functions.
Definition: Filesystem.hpp:39
nc::DataCube::sliceZ
NdArray< dtype > sliceZ(int32 inIndex, Slice inSliceZ) const
Definition: DataCube.hpp:271
nc::DataCube::begin
iterator begin() noexcept
Definition: DataCube.hpp:107
nc::DataCube::pop_back
void pop_back() noexcept
Definition: DataCube.hpp:212
nc::DataCube::sliceZAll
NdArray< dtype > sliceZAll(int32 inRow, Slice inCol) const
Definition: DataCube.hpp:404