NumCpp  2.4.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  //============================================================================
538  NdArray<dtype> sliceZAllat(int32 inRow, int32 inCol) const
539  {
540  if (inRow < 0)
541  {
542  inRow += elementShape_.rows;
543  }
544 
545  if (inCol < 0)
546  {
547  inCol += elementShape_.cols;
548  }
549 
550  if (static_cast<uint32>(inRow) >= elementShape_.rows)
551  {
552  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
553  }
554 
555  if (static_cast<uint32>(inCol) >= elementShape_.cols)
556  {
557  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
558  }
559 
560  return sliceZAll(inRow, inCol);
561  }
562 
563  //============================================================================
571  NdArray<dtype> sliceZat(int32 inRow, int32 inCol, Slice inSliceZ) const
572  {
573  if (inRow < 0)
574  {
575  inRow += elementShape_.rows;
576  }
577 
578  if (inCol < 0)
579  {
580  inCol += elementShape_.cols;
581  }
582 
583  if (static_cast<uint32>(inRow) >= elementShape_.rows)
584  {
585  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
586  }
587  if (static_cast<uint32>(inCol) >= elementShape_.cols)
588  {
589  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
590  }
591 
592  auto numElements = inSliceZ.numElements(sizeZ());
593  if (numElements > sizeZ())
594  {
595  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
596  }
597 
598  return sliceZ(inRow, inCol, inSliceZ);
599  }
600 
601  //============================================================================
608  NdArray<dtype> sliceZAllat(Slice inRow, int32 inCol) const
609  {
610  auto numRows = inRow.numElements(elementShape_.rows);
611  if (numRows > elementShape_.rows)
612  {
613  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
614  }
615 
616  if (inCol < 0)
617  {
618  inCol += elementShape_.cols;
619  }
620 
621  if (static_cast<uint32>(inCol) >= elementShape_.cols)
622  {
623  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
624  }
625 
626  return sliceZAll(inRow, inCol);
627  }
628 
629  //============================================================================
637  NdArray<dtype> sliceZat(Slice inRow, int32 inCol, Slice inSliceZ) const
638  {
639  auto numRows = inRow.numElements(elementShape_.rows);
640  if (numRows > elementShape_.rows)
641  {
642  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
643  }
644 
645  if (inCol < 0)
646  {
647  inCol += elementShape_.cols;
648  }
649 
650  if (static_cast<uint32>(inCol) >= elementShape_.cols)
651  {
652  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
653  }
654 
655  auto numElements = inSliceZ.numElements(sizeZ());
656  if (numElements > sizeZ())
657  {
658  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
659  }
660 
661  return sliceZ(inRow, inCol, inSliceZ);
662  }
663 
664  //============================================================================
671  NdArray<dtype> sliceZAllat(int32 inRow, Slice inCol) const
672  {
673  auto numCols = inCol.numElements(elementShape_.cols);
674  if (numCols > elementShape_.cols)
675  {
676  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
677  }
678 
679  if (inRow < 0)
680  {
681  inRow += elementShape_.rows;
682  }
683 
684  if (static_cast<uint32>(inRow) >= elementShape_.rows)
685  {
686  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
687  }
688 
689  return sliceZAll(inRow, inCol);
690  }
691 
692  //============================================================================
700  NdArray<dtype> sliceZat(int32 inRow, Slice inCol, Slice inSliceZ) const
701  {
702  auto numCols = inCol.numElements(elementShape_.cols);
703  if (numCols > elementShape_.cols)
704  {
705  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
706  }
707 
708  if (inRow < 0)
709  {
710  inRow += elementShape_.rows;
711  }
712 
713  if (static_cast<uint32>(inRow) >= elementShape_.rows)
714  {
715  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
716  }
717 
718  auto numElements = inSliceZ.numElements(sizeZ());
719  if (numElements > sizeZ())
720  {
721  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
722  }
723 
724  return sliceZ(inRow, inCol, inSliceZ);
725  }
726 
727  //============================================================================
735  {
736  if (inRow.numElements(elementShape_.rows) > elementShape_.rows)
737  {
738  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
739  }
740 
741  if (inCol.numElements(elementShape_.cols) > elementShape_.cols)
742  {
743  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
744  }
745 
746  return sliceZAll(inRow, inCol);
747  }
748 
749  //============================================================================
757  DataCube<dtype> sliceZat(Slice inRow, Slice inCol, Slice inSliceZ) const
758  {
759  if (inRow.numElements(elementShape_.rows) > elementShape_.rows)
760  {
761  THROW_INVALID_ARGUMENT_ERROR("inRow exceeds matrix dimensions.");
762  }
763 
764  if (inCol.numElements(elementShape_.cols) > elementShape_.cols)
765  {
766  THROW_INVALID_ARGUMENT_ERROR("inCol exceeds matrix dimensions.");
767  }
768 
769  auto numElements = inSliceZ.numElements(sizeZ());
770  if (numElements > sizeZ())
771  {
772  THROW_INVALID_ARGUMENT_ERROR("Index exceeds matrix dimensions.");
773  }
774 
775  return sliceZ(inRow, inCol, inSliceZ);
776  }
777 
778  //============================================================================
785  NdArray<dtype>& operator[](uint32 inIndex) noexcept
786  {
787  return cube_[inIndex];
788  }
789 
790  //============================================================================
797  const NdArray<dtype>& operator[](uint32 inIndex) const noexcept
798  {
799  return cube_[inIndex];
800  }
801 
802  private:
803  //================================Attributes==================================
804  std::vector<NdArray<dtype> > cube_{};
805  Shape elementShape_{ 0, 0 };
806  };
807 } // namespace nc
nc::Slice::stop
int32 stop
Definition: Slice.hpp:48
nc::NdArray::shape
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4356
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:734
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:902
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:3729
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:797
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::Shape::size
uint32 size() const noexcept
Definition: Core/Shape.hpp:102
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(int32 inRow, int32 inCol) const
Definition: DataCube.hpp:538
nc::Slice::numElements
uint32 numElements(uint32 inArraySize)
Definition: Slice.hpp:188
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(int32 inRow, Slice inCol) const
Definition: DataCube.hpp:671
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:637
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:757
nc::DataCube::sliceZAllat
NdArray< dtype > sliceZAllat(Slice inRow, int32 inCol) const
Definition: DataCube.hpp:608
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:785
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
nc::DataCube::sliceZat
NdArray< dtype > sliceZat(int32 inRow, int32 inCol, Slice inSliceZ) const
Definition: DataCube.hpp:571
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:700
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:56
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