NumCpp  2.9.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
NdArrayCore.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <array>
31 #include <cmath>
32 #include <deque>
33 #include <forward_list>
34 #include <fstream>
35 #include <initializer_list>
36 #include <iostream>
37 #include <iterator>
38 #include <list>
39 #include <memory>
40 #include <numeric>
41 #include <set>
42 #include <string>
43 #include <type_traits>
44 #include <utility>
45 #include <vector>
46 
56 #include "NumCpp/Core/Shape.hpp"
57 #include "NumCpp/Core/Slice.hpp"
58 #include "NumCpp/Core/Types.hpp"
60 #include "NumCpp/Utils/num2str.hpp"
61 #include "NumCpp/Utils/power.hpp"
62 #include "NumCpp/Utils/sqr.hpp"
64 
65 namespace nc
66 {
67  //================================================================================
68  // Class Description:
70  template<typename dtype, class Allocator = std::allocator<dtype>>
71  class NdArray
72  {
73  private:
74  STATIC_ASSERT_VALID_DTYPE(dtype);
75  static_assert(is_same_v<dtype, typename Allocator::value_type>,
76  "value_type and Allocator::value_type must match");
77 
78  using AllocType = typename std::allocator_traits<Allocator>::template rebind_alloc<dtype>;
79  using AllocTraits = std::allocator_traits<AllocType>;
80 
81  public:
82  using value_type = dtype;
83  using allocator_type = Allocator;
84  using pointer = typename AllocTraits::pointer;
85  using const_pointer = typename AllocTraits::const_pointer;
86  using reference = dtype&;
87  using const_reference = const dtype&;
88  using size_type = uint32;
89  using difference_type = typename AllocTraits::difference_type;
90 
93  using reverse_iterator = std::reverse_iterator<iterator>;
94  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
95 
98  using reverse_column_iterator = std::reverse_iterator<column_iterator>;
99  using const_reverse_column_iterator = std::reverse_iterator<const_column_iterator>;
100 
101  //============================================================================
102  // Method Description:
105  NdArray() = default;
106 
107  //============================================================================
108  // Method Description:
113  explicit NdArray(size_type inSquareSize) :
114  shape_(inSquareSize, inSquareSize),
115  size_(inSquareSize * inSquareSize)
116  {
117  newArray();
118  }
119 
120  //============================================================================
121  // Method Description:
127  NdArray(size_type inNumRows, size_type inNumCols) :
128  shape_(inNumRows, inNumCols),
129  size_(inNumRows * inNumCols)
130  {
131  newArray();
132  }
133 
134  //============================================================================
135  // Method Description:
140  explicit NdArray(const Shape& inShape) :
141  shape_(inShape),
142  size_(shape_.size())
143  {
144  newArray();
145  }
146 
147  //============================================================================
148  // Method Description:
153  NdArray(std::initializer_list<dtype> inList) :
154  shape_(1, static_cast<uint32>(inList.size())),
155  size_(shape_.size())
156  {
157  newArray();
158  if (size_ > 0)
159  {
160  stl_algorithms::copy(inList.begin(), inList.end(), begin());
161  }
162  }
163 
164  //============================================================================
165  // Method Description:
170  NdArray(const std::initializer_list<std::initializer_list<dtype>>& inList) :
171  shape_(static_cast<uint32>(inList.size()), 0)
172  {
173  for (const auto& list : inList)
174  {
175  if (shape_.cols == 0)
176  {
177  shape_.cols = static_cast<uint32>(list.size());
178  }
179  else if (list.size() != shape_.cols)
180  {
182  "All rows of the initializer list needs to have the same number of elements");
183  }
184  }
185 
186  size_ = shape_.size();
187  newArray();
188  uint32 row = 0;
189  for (const auto& list : inList)
190  {
191  const auto ptr = begin() += row * shape_.cols;
192  stl_algorithms::copy(list.begin(), list.end(), ptr);
193  ++row;
194  }
195  }
196 
197  //============================================================================
198  // Method Description:
205  template<size_t ArraySize, std::enable_if_t<is_valid_dtype_v<dtype>, int> = 0>
206  NdArray(std::array<dtype, ArraySize>& inArray, bool copy = true) :
207  shape_(1, static_cast<uint32>(ArraySize)),
208  size_(shape_.size())
209  {
210  if (copy)
211  {
212  newArray();
213  if (size_ > 0)
214  {
215  stl_algorithms::copy(inArray.begin(), inArray.end(), begin());
216  }
217  }
218  else
219  {
220  array_ = inArray.data();
221  ownsPtr_ = false;
222  }
223  }
224 
225  //============================================================================
226  // Method Description:
233  template<size_t Dim0Size, size_t Dim1Size>
234  NdArray(std::array<std::array<dtype, Dim1Size>, Dim0Size>& in2dArray, bool copy = true) :
235  shape_(static_cast<uint32>(Dim0Size), static_cast<uint32>(Dim1Size)),
236  size_(shape_.size())
237  {
238  if (copy)
239  {
240  newArray();
241  if (size_ > 0)
242  {
243  const auto start = in2dArray.front().begin();
244  stl_algorithms::copy(start, start + size_, begin());
245  }
246  }
247  else
248  {
249  array_ = in2dArray.front().data();
250  ownsPtr_ = false;
251  }
252  }
253 
254  //============================================================================
255  // Method Description:
262  template<std::enable_if_t<is_valid_dtype_v<dtype>, int> = 0>
263  NdArray(std::vector<dtype>& inVector, bool copy = true) :
264  shape_(1, static_cast<uint32>(inVector.size())),
265  size_(shape_.size())
266  {
267  if (copy)
268  {
269  newArray();
270  if (size_ > 0)
271  {
272  stl_algorithms::copy(inVector.begin(), inVector.end(), begin());
273  }
274  }
275  else
276  {
277  array_ = inVector.data();
278  ownsPtr_ = false;
279  }
280  }
281 
282  //============================================================================
283  // Method Description:
288  explicit NdArray(const std::vector<std::vector<dtype>>& in2dVector) :
289  shape_(static_cast<uint32>(in2dVector.size()), 0)
290  {
291  for (const auto& row : in2dVector)
292  {
293  if (shape_.cols == 0)
294  {
295  shape_.cols = static_cast<uint32>(row.size());
296  }
297  else if (row.size() != shape_.cols)
298  {
299  THROW_INVALID_ARGUMENT_ERROR("All rows of the 2d vector need to have the same number of elements");
300  }
301  }
302 
303  size_ = shape_.size();
304 
305  newArray();
306  auto currentPosition = begin();
307  for (const auto& row : in2dVector)
308  {
309  stl_algorithms::copy(row.begin(), row.end(), currentPosition);
310  currentPosition += shape_.cols;
311  }
312  }
313 
314  //============================================================================
315  // Method Description:
322  template<size_t Dim1Size>
323  NdArray(std::vector<std::array<dtype, Dim1Size>>& in2dArray, bool copy = true) :
324  shape_(static_cast<uint32>(in2dArray.size()), static_cast<uint32>(Dim1Size)),
325  size_(shape_.size())
326  {
327  if (copy)
328  {
329  newArray();
330  if (size_ > 0)
331  {
332  const auto start = in2dArray.front().begin();
333  stl_algorithms::copy(start, start + size_, begin());
334  }
335  }
336  else
337  {
338  array_ = in2dArray.front().data();
339  ownsPtr_ = false;
340  }
341  }
342 
343  //============================================================================
344  // Method Description:
349  template<std::enable_if_t<is_valid_dtype_v<dtype>, int> = 0>
350  explicit NdArray(const std::deque<dtype>& inDeque) :
351  shape_(1, static_cast<uint32>(inDeque.size())),
352  size_(shape_.size())
353  {
354  newArray();
355  if (size_ > 0)
356  {
357  stl_algorithms::copy(inDeque.begin(), inDeque.end(), begin());
358  }
359  }
360 
361  //============================================================================
362  // Method Description:
367  explicit NdArray(const std::deque<std::deque<dtype>>& in2dDeque) :
368  shape_(static_cast<uint32>(in2dDeque.size()), 0)
369  {
370  for (const auto& row : in2dDeque)
371  {
372  if (shape_.cols == 0)
373  {
374  shape_.cols = static_cast<uint32>(row.size());
375  }
376  else if (row.size() != shape_.cols)
377  {
378  THROW_INVALID_ARGUMENT_ERROR("All rows of the 2d vector need to have the same number of elements");
379  }
380  }
381 
382  size_ = shape_.size();
383 
384  newArray();
385  auto currentPosition = begin();
386  for (const auto& row : in2dDeque)
387  {
388  stl_algorithms::copy(row.begin(), row.end(), currentPosition);
389  currentPosition += shape_.cols;
390  }
391  }
392 
393  //============================================================================
394  // Method Description:
399  explicit NdArray(const std::list<dtype>& inList) :
400  shape_(1, static_cast<uint32>(inList.size())),
401  size_(shape_.size())
402  {
403  newArray();
404  if (size_ > 0)
405  {
406  stl_algorithms::copy(inList.begin(), inList.end(), begin());
407  }
408  }
409 
410  //============================================================================
411  // Method Description:
417  template<typename Iterator,
418  std::enable_if_t<is_same_v<typename std::iterator_traits<Iterator>::value_type, dtype>, int> = 0>
419  NdArray(Iterator inFirst, Iterator inLast) :
420  shape_(1, static_cast<uint32>(std::distance(inFirst, inLast))),
421  size_(shape_.size())
422  {
423  newArray();
424  if (size_ > 0)
425  {
426  stl_algorithms::copy(inFirst, inLast, begin());
427  }
428  }
429 
430  //============================================================================
431  // Method Description:
439  shape_(1, size),
440  size_(size)
441  {
442  newArray();
443  if (inPtr != nullptr && size_ > 0)
444  {
445  stl_algorithms::copy(inPtr, inPtr + size_, begin());
446  }
447  }
448 
449  //============================================================================
450  // Method Description:
458  template<typename UIntType1,
459  typename UIntType2,
460  std::enable_if_t<!is_same_v<UIntType1, bool>, int> = 0,
461  std::enable_if_t<!is_same_v<UIntType2, bool>, int> = 0>
462  NdArray(const_pointer inPtr, UIntType1 numRows, UIntType2 numCols) :
463  shape_(numRows, numCols),
464  size_(shape_.size())
465  {
466  newArray();
467  if (inPtr != nullptr && size_ > 0)
468  {
469  stl_algorithms::copy(inPtr, inPtr + size_, begin());
470  }
471  }
472 
473  //============================================================================
474  // Method Description:
483  template<typename BoolType, std::enable_if_t<is_same_v<BoolType, bool>, int> = 0>
484  NdArray(pointer inPtr, size_type size, BoolType takeOwnership) noexcept :
485  shape_(1, size),
486  size_(size),
487  array_(inPtr),
488  ownsPtr_(takeOwnership)
489  {
490  }
491 
492  //============================================================================
493  // Method Description:
503  template<typename BoolType, std::enable_if_t<is_same_v<BoolType, bool>, int> = 0>
504  NdArray(pointer inPtr, uint32 numRows, uint32 numCols, BoolType takeOwnership) noexcept :
505  shape_(numRows, numCols),
506  size_(numRows * numCols),
507  array_(inPtr),
508  ownsPtr_(takeOwnership)
509  {
510  }
511 
512  //============================================================================
513  // Method Description:
518  NdArray(const NdArray<dtype>& inOtherArray) :
519  shape_(inOtherArray.shape_),
520  size_(inOtherArray.size_),
521  endianess_(inOtherArray.endianess_)
522  {
523  newArray();
524  if (size_ > 0)
525  {
526  stl_algorithms::copy(inOtherArray.cbegin(), inOtherArray.cend(), begin());
527  }
528  }
529 
530  //============================================================================
531  // Method Description:
536  NdArray(NdArray<dtype>&& inOtherArray) noexcept :
537  shape_(inOtherArray.shape_),
538  size_(inOtherArray.size_),
539  endianess_(inOtherArray.endianess_),
540  array_(inOtherArray.array_),
541  ownsPtr_(inOtherArray.ownsPtr_)
542  {
543  inOtherArray.shape_.rows = inOtherArray.shape_.cols = 0;
544  inOtherArray.size_ = 0;
545  inOtherArray.ownsPtr_ = false;
546  inOtherArray.array_ = nullptr;
547  }
548 
549  //============================================================================
550  // Method Description:
553  ~NdArray() noexcept
554  {
555  deleteArray();
556  }
557 
558  //============================================================================
559  // Method Description:
566  {
567  if (&rhs != this)
568  {
569  if (rhs.size_ > 0)
570  {
571  newArray(rhs.shape_);
572  endianess_ = rhs.endianess_;
573 
574  stl_algorithms::copy(rhs.cbegin(), rhs.cend(), begin());
575  }
576  }
577 
578  return *this;
579  }
580 
581  //============================================================================
582  // Method Description:
590  {
591  if (array_ != nullptr)
592  {
593  stl_algorithms::fill(begin(), end(), inValue);
594  }
595 
596  return *this;
597  }
598 
599  //============================================================================
600  // Method Description:
607  {
608  if (&rhs != this)
609  {
610  deleteArray();
611  shape_ = rhs.shape_;
612  size_ = rhs.size_;
613  endianess_ = rhs.endianess_;
614  array_ = rhs.array_;
615  ownsPtr_ = rhs.ownsPtr_;
616 
617  rhs.shape_.rows = rhs.shape_.cols = rhs.size_ = 0;
618  rhs.array_ = nullptr;
619  rhs.ownsPtr_ = false;
620  }
621 
622  return *this;
623  }
624 
625  //============================================================================
626  // Method Description:
632  reference operator[](int32 inIndex) noexcept
633  {
634  if (inIndex < 0)
635  {
636  inIndex += size_;
637  }
638 
639  return array_[inIndex];
640  }
641 
642  //============================================================================
643  // Method Description:
649  const_reference operator[](int32 inIndex) const noexcept
650  {
651  if (inIndex < 0)
652  {
653  inIndex += size_;
654  }
655 
656  return array_[inIndex];
657  }
658 
659  //============================================================================
660  // Method Description:
667  reference operator()(int32 inRowIndex, int32 inColIndex) noexcept
668  {
669  if (inRowIndex < 0)
670  {
671  inRowIndex += shape_.rows;
672  }
673 
674  if (inColIndex < 0)
675  {
676  inColIndex += shape_.cols;
677  }
678 
679  return array_[inRowIndex * shape_.cols + inColIndex];
680  }
681 
682  //============================================================================
683  // Method Description:
690  const_reference operator()(int32 inRowIndex, int32 inColIndex) const noexcept
691  {
692  if (inRowIndex < 0)
693  {
694  inRowIndex += shape_.rows;
695  }
696 
697  if (inColIndex < 0)
698  {
699  inColIndex += shape_.cols;
700  }
701 
702  return array_[inRowIndex * shape_.cols + inColIndex];
703  }
704 
705  //============================================================================
706  // Method Description:
713  NdArray<dtype> operator[](const Slice& inSlice) const
714  {
715  Slice inSliceCopy(inSlice);
716 
717  uint32 counter = 0;
718  NdArray<dtype> returnArray(1, inSliceCopy.numElements(size_));
719  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
720  {
721  returnArray[counter++] = at(i);
722  }
723 
724  return returnArray;
725  }
726 
727  //============================================================================
728  // Method Description:
735  {
736  if (inMask.shape() != shape_)
737  {
739  "input inMask must have the same shape as the NdArray it will be masking.");
740  }
741 
742  auto indices = inMask.flatnonzero();
743  auto outArray = NdArray<dtype>(1, indices.size());
744  for (size_type i = 0; i < indices.size(); ++i)
745  {
746  outArray[i] = operator[](indices[i]);
747  }
748 
749  return outArray;
750  }
751 
752  //============================================================================
753  // Method Description:
760  template<typename Indices, enable_if_t<is_same_v<Indices, NdArray<size_type>>, int> = 0>
761  NdArray<dtype> operator[](const Indices& inIndices) const
762  {
763  if (inIndices.max().item() > size_ - 1)
764  {
765  THROW_INVALID_ARGUMENT_ERROR("input indices must be less than the array size.");
766  }
767 
768  auto outArray = NdArray<dtype>(1, static_cast<size_type>(inIndices.size()));
769  size_type i = 0;
770  for (auto& index : inIndices)
771  {
772  outArray[i++] = operator[](index);
773  }
774 
775  return outArray;
776  }
777 
778  //============================================================================
779  // Method Description:
787  NdArray<dtype> operator()(Slice inRowSlice, Slice inColSlice) const
788  {
789  NdArray<dtype> returnArray(inRowSlice.numElements(shape_.rows), inColSlice.numElements(shape_.cols));
790 
791  uint32 rowCounter = 0;
792  uint32 colCounter = 0;
793  for (int32 row = inRowSlice.start; row < inRowSlice.stop; row += inRowSlice.step)
794  {
795  for (int32 col = inColSlice.start; col < inColSlice.stop; col += inColSlice.step)
796  {
797  returnArray(rowCounter, colCounter++) = at(row, col);
798  }
799  colCounter = 0;
800  ++rowCounter;
801  }
802 
803  return returnArray;
804  }
805 
806  //============================================================================
807  // Method Description:
815  NdArray<dtype> operator()(Slice inRowSlice, int32 inColIndex) const
816  {
817  NdArray<dtype> returnArray(inRowSlice.numElements(shape_.rows), 1);
818 
819  uint32 rowCounter = 0;
820  for (int32 row = inRowSlice.start; row < inRowSlice.stop; row += inRowSlice.step)
821  {
822  returnArray(rowCounter++, 0) = at(row, inColIndex);
823  }
824 
825  return returnArray;
826  }
827 
828  //============================================================================
829  // Method Description:
837  NdArray<dtype> operator()(int32 inRowIndex, Slice inColSlice) const
838  {
839  NdArray<dtype> returnArray(1, inColSlice.numElements(shape_.cols));
840 
841  uint32 colCounter = 0;
842  for (int32 col = inColSlice.start; col < inColSlice.stop; col += inColSlice.step)
843  {
844  returnArray(0, colCounter++) = at(inRowIndex, col);
845  }
846 
847  return returnArray;
848  }
849 
850  //============================================================================
851  // Method Description:
859  template<typename Indices,
860  enable_if_t<is_same_v<Indices, NdArray<int32>> || is_same_v<Indices, NdArray<uint32>>, int> = 0>
861  NdArray<dtype> operator()(const Indices& rowIndices, int32 colIndex) const
862  {
863  const NdArray<int32> colIndices = { colIndex };
864  return operator()(rowIndices, colIndices);
865  }
866 
867  //============================================================================
868  // Method Description:
876  template<typename Indices,
877  enable_if_t<is_same_v<Indices, NdArray<int32>> || is_same_v<Indices, NdArray<uint32>>, int> = 0>
878  NdArray<dtype> operator()(const Indices& rowIndices, Slice colSlice) const
879  {
880  return operator()(rowIndices, toIndices(colSlice, Axis::COL));
881  }
882 
883  //============================================================================
884  // Method Description:
892  template<typename Indices,
893  enable_if_t<is_same_v<Indices, NdArray<int32>> || is_same_v<Indices, NdArray<uint32>>, int> = 0>
894  NdArray<dtype> operator()(int32 rowIndex, const Indices& colIndices) const
895  {
896  const NdArray<int32> rowIndices = { rowIndex };
897  return operator()(rowIndices, colIndices);
898  }
899 
900  //============================================================================
901  // Method Description:
909  template<typename Indices,
910  enable_if_t<is_same_v<Indices, NdArray<int32>> || is_same_v<Indices, NdArray<uint32>>, int> = 0>
911  NdArray<dtype> operator()(Slice rowSlice, const Indices& colIndices) const
912  {
913  return operator()(toIndices(rowSlice, Axis::ROW), colIndices);
914  }
915 
916  //============================================================================
917  // Method Description:
925  template<typename RowIndices,
926  typename ColIndices,
927  enable_if_t<is_same_v<RowIndices, NdArray<int32>> || is_same_v<RowIndices, NdArray<uint32>>, int> = 0,
928  enable_if_t<is_same_v<ColIndices, NdArray<int32>> || is_same_v<ColIndices, NdArray<uint32>>, int> = 0>
929  NdArray<dtype> operator()(RowIndices rowIndices, ColIndices colIndices) const
930  {
931  rowIndices.sort();
932  colIndices.sort();
933 
934  std::vector<int32> rowIndicesUnique(rowIndices.size());
935  std::vector<int32> colIndicesUnique(colIndices.size());
936 
937  const auto lastRow =
938  stl_algorithms::unique_copy(rowIndices.begin(), rowIndices.end(), rowIndicesUnique.begin());
939  const auto lastCol =
940  stl_algorithms::unique_copy(colIndices.begin(), colIndices.end(), colIndicesUnique.begin());
941 
942  NdArray<dtype> returnArray(static_cast<uint32>(lastRow - rowIndicesUnique.begin()),
943  static_cast<uint32>(lastCol - colIndicesUnique.begin()));
944 
945  uint32 rowCounter = 0;
946  for (auto rowIter = rowIndicesUnique.begin(); rowIter != lastRow; ++rowIter)
947  {
948  uint32 colCounter = 0;
949  for (auto colIter = colIndicesUnique.begin(); colIter != lastCol; ++colIter)
950  {
951  returnArray(rowCounter, colCounter++) = at(*rowIter, *colIter);
952  }
953 
954  ++rowCounter;
955  }
956 
957  return returnArray;
958  }
959 
960  //============================================================================
961  // Method Description:
969  Slice cSlice(int32 inStartIdx = 0, uint32 inStepSize = 1) const noexcept
970  {
971  return Slice(inStartIdx, shape_.cols, inStepSize);
972  }
973 
974  //============================================================================
975  // Method Description:
983  Slice rSlice(int32 inStartIdx = 0, uint32 inStepSize = 1) const noexcept
984  {
985  return Slice(inStartIdx, shape_.rows, inStepSize);
986  }
987 
988  //============================================================================
989  // Method Description:
995  reference at(int32 inIndex)
996  {
997  // this doesn't allow for calling the first element as -size_...
998  // but why would you really want to do that anyway?
999  if (std::abs(inIndex) > static_cast<int64>(size_ - 1))
1000  {
1001  std::string errStr = "Input index " + utils::num2str(inIndex);
1002  errStr += " is out of bounds for array of size " + utils::num2str(size_) + ".";
1004  }
1005 
1006  return operator[](inIndex);
1007  }
1008 
1009  //============================================================================
1010  // Method Description:
1016  const_reference at(int32 inIndex) const
1017  {
1018  // this doesn't allow for calling the first element as -size_...
1019  // but why would you really want to do that anyway?
1020  if (std::abs(inIndex) > static_cast<int64>(size_ - 1))
1021  {
1022  std::string errStr = "Input index " + utils::num2str(inIndex);
1023  errStr += " is out of bounds for array of size " + utils::num2str(size_) + ".";
1025  }
1026 
1027  return operator[](inIndex);
1028  }
1029 
1030  //============================================================================
1031  // Method Description:
1038  reference at(int32 inRowIndex, int32 inColIndex)
1039  {
1040  // this doesn't allow for calling the first element as -size_...
1041  // but why would you really want to do that anyway?
1042  if (std::abs(inRowIndex) > static_cast<int32>(shape_.rows - 1))
1043  {
1044  std::string errStr = "Row index " + utils::num2str(inRowIndex);
1045  errStr += " is out of bounds for array of size " + utils::num2str(shape_.rows) + ".";
1047  }
1048 
1049  // this doesn't allow for calling the first element as -size_...
1050  // but why would you really want to that anyway?
1051  if (std::abs(inColIndex) > static_cast<int32>(shape_.cols - 1))
1052  {
1053  std::string errStr = "Column index " + utils::num2str(inColIndex);
1054  errStr += " is out of bounds for array of size " + utils::num2str(shape_.cols) + ".";
1056  }
1057 
1058  return operator()(inRowIndex, inColIndex);
1059  }
1060 
1061  //============================================================================
1062  // Method Description:
1069  const_reference at(int32 inRowIndex, int32 inColIndex) const
1070  {
1071  // this doesn't allow for calling the first element as -size_...
1072  // but why would you really want to do that anyway?
1073  if (std::abs(inRowIndex) > static_cast<int32>(shape_.rows - 1))
1074  {
1075  std::string errStr = "Row index " + utils::num2str(inRowIndex);
1076  errStr += " is out of bounds for array of size " + utils::num2str(shape_.rows) + ".";
1078  }
1079 
1080  // this doesn't allow for calling the first element as -size_...
1081  // but why would you really want to do that anyway?
1082  if (std::abs(inColIndex) > static_cast<int32>(shape_.cols - 1))
1083  {
1084  std::string errStr = "Column index " + utils::num2str(inColIndex);
1085  errStr += " is out of bounds for array of size " + utils::num2str(shape_.cols) + ".";
1087  }
1088 
1089  return operator()(inRowIndex, inColIndex);
1090  }
1091 
1092  //============================================================================
1093  // Method Description:
1099  NdArray<dtype> at(const Slice& inSlice) const
1100  {
1101  // the slice operator already provides bounds checking. just including
1102  // the at method for completeness
1103  return operator[](inSlice);
1104  }
1105 
1106  //============================================================================
1107  // Method Description:
1114  NdArray<dtype> at(const Slice& inRowSlice, const Slice& inColSlice) const
1115  {
1116  // the slice operator already provides bounds checking. just including
1117  // the at method for completeness
1118  return operator()(inRowSlice, inColSlice);
1119  }
1120 
1121  //============================================================================
1122  // Method Description:
1129  NdArray<dtype> at(const Slice& inRowSlice, int32 inColIndex) const
1130  {
1131  // the slice operator already provides bounds checking. just including
1132  // the at method for completeness
1133  return operator()(inRowSlice, inColIndex);
1134  }
1135 
1136  //============================================================================
1137  // Method Description:
1144  NdArray<dtype> at(int32 inRowIndex, const Slice& inColSlice) const
1145  {
1146  // the slice operator already provides bounds checking. just including
1147  // the at method for completeness
1148  return operator()(inRowIndex, inColSlice);
1149  }
1150 
1151  //============================================================================
1152  // Method Description:
1159  NdArray<dtype> at(const NdArray<int32>& rowIndices, const NdArray<int32>& colIndices) const
1160  {
1161  // the slice operator already provides bounds checking. just including
1162  // the at method for completeness
1163  return operator()(rowIndices, colIndices);
1164  }
1165 
1166  //============================================================================
1167  // Method Description:
1171  iterator begin() noexcept
1172  {
1173  return iterator(array_);
1174  }
1175 
1176  //============================================================================
1177  // Method Description:
1184  {
1185  if (inRow >= shape_.rows)
1186  {
1187  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1188  }
1189 
1190  return begin() += (inRow * shape_.cols);
1191  }
1192 
1193  //============================================================================
1194  // Method Description:
1198  const_iterator begin() const noexcept
1199  {
1200  return cbegin();
1201  }
1202 
1203  //============================================================================
1204  // Method Description:
1211  {
1212  return cbegin(inRow);
1213  }
1214 
1215  //============================================================================
1216  // Method Description:
1221  const_iterator cbegin() const noexcept
1222  {
1223  return const_iterator(array_);
1224  }
1225 
1226  //============================================================================
1227  // Method Description:
1234  {
1235  if (inRow >= shape_.rows)
1236  {
1237  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1238  }
1239 
1240  return cbegin() += (inRow * shape_.cols);
1241  }
1242 
1243  //============================================================================
1244  // Method Description:
1249  {
1250  return column_iterator(array_, shape_.rows, shape_.cols);
1251  }
1252 
1253  //============================================================================
1254  // Method Description:
1261  {
1262  if (inCol >= shape_.cols)
1263  {
1264  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1265  }
1266 
1267  return colbegin() += (inCol * shape_.rows);
1268  }
1269 
1270  //============================================================================
1271  // Method Description:
1276  {
1277  return ccolbegin();
1278  }
1279 
1280  //============================================================================
1281  // Method Description:
1288  {
1289  return ccolbegin(inCol);
1290  }
1291 
1292  //============================================================================
1293  // Method Description:
1299  {
1300  return const_column_iterator(array_, shape_.rows, shape_.cols);
1301  }
1302 
1303  //============================================================================
1304  // Method Description:
1311  {
1312  if (inCol >= shape_.cols)
1313  {
1314  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1315  }
1316 
1317  return ccolbegin() += (inCol * shape_.rows);
1318  }
1319 
1320  //============================================================================
1321  // Method Description:
1326  {
1327  return reverse_iterator(end());
1328  }
1329 
1330  //============================================================================
1331  // Method Description:
1338  {
1339  if (inRow >= shape_.rows)
1340  {
1341  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1342  }
1343 
1344  return rbegin() += (shape_.rows - inRow - 1) * shape_.cols;
1345  }
1346 
1347  //============================================================================
1348  // Method Description:
1353  {
1354  return crbegin();
1355  }
1356 
1357  //============================================================================
1358  // Method Description:
1365  {
1366  return crbegin(inRow);
1367  }
1368 
1369  //============================================================================
1370  // Method Description:
1376  {
1377  return const_reverse_iterator(cend());
1378  }
1379 
1380  //============================================================================
1381  // Method Description:
1388  {
1389  if (inRow >= shape_.rows)
1390  {
1391  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1392  }
1393 
1394  return crbegin() += (shape_.rows - inRow - 1) * shape_.cols;
1395  }
1396 
1397  //============================================================================
1398  // Method Description:
1403  {
1404  return reverse_column_iterator(colend());
1405  }
1406 
1407  //============================================================================
1408  // Method Description:
1415  {
1416  if (inCol >= shape_.cols)
1417  {
1418  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1419  }
1420 
1421  return rcolbegin() += (shape_.cols - inCol - 1) * shape_.rows;
1422  }
1423 
1424  //============================================================================
1425  // Method Description:
1430  {
1431  return crcolbegin();
1432  }
1433 
1434  //============================================================================
1435  // Method Description:
1442  {
1443  return crcolbegin(inCol);
1444  }
1445 
1446  //============================================================================
1447  // Method Description:
1453  {
1455  }
1456 
1457  //============================================================================
1458  // Method Description:
1465  {
1466  if (inCol >= shape_.cols)
1467  {
1468  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1469  }
1470 
1471  return crcolbegin() += (shape_.cols - inCol - 1) * shape_.rows;
1472  }
1473 
1474  //============================================================================
1475  // Method Description:
1479  iterator end() noexcept
1480  {
1481  return begin() += size_;
1482  }
1483 
1484  //============================================================================
1485  // Method Description:
1492  {
1493  if (inRow >= shape_.rows)
1494  {
1495  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1496  }
1497 
1498  return begin(inRow) += shape_.cols;
1499  }
1500 
1501  //============================================================================
1502  // Method Description:
1506  const_iterator end() const noexcept
1507  {
1508  return cend();
1509  }
1510 
1511  //============================================================================
1512  // Method Description:
1519  {
1520  return cend(inRow);
1521  }
1522 
1523  //============================================================================
1524  // Method Description:
1529  const_iterator cend() const noexcept
1530  {
1531  return cbegin() += size_;
1532  }
1533 
1534  //============================================================================
1535  // Method Description:
1542  {
1543  if (inRow >= shape_.rows)
1544  {
1545  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1546  }
1547 
1548  return cbegin(inRow) += shape_.cols;
1549  }
1550 
1551  //============================================================================
1552  // Method Description:
1557  {
1558  return rbegin() += size_;
1559  }
1560 
1561  //============================================================================
1562  // Method Description:
1569  {
1570  if (inRow >= shape_.rows)
1571  {
1572  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1573  }
1574 
1575  return rbegin(inRow) += shape_.cols;
1576  }
1577 
1578  //============================================================================
1579  // Method Description:
1583  const_reverse_iterator rend() const noexcept
1584  {
1585  return crend();
1586  }
1587 
1588  //============================================================================
1589  // Method Description:
1596  {
1597  return crend(inRow);
1598  }
1599 
1600  //============================================================================
1601  // Method Description:
1607  {
1608  return crbegin() += size_;
1609  }
1610 
1611  //============================================================================
1612  // Method Description:
1619  {
1620  if (inRow >= shape_.rows)
1621  {
1622  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1623  }
1624 
1625  return crbegin(inRow) += shape_.cols;
1626  }
1627 
1628  //============================================================================
1629  // Method Description:
1634  {
1635  return colbegin() += size_;
1636  }
1637 
1638  //============================================================================
1639  // Method Description:
1646  {
1647  if (inCol >= shape_.cols)
1648  {
1649  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1650  }
1651 
1652  return colbegin(inCol) += shape_.rows;
1653  }
1654 
1655  //============================================================================
1656  // Method Description:
1661  {
1662  return ccolend();
1663  }
1664 
1665  //============================================================================
1666  // Method Description:
1673  {
1674  return ccolend(inCol);
1675  }
1676 
1677  //============================================================================
1678  // Method Description:
1684  {
1685  return ccolbegin() += size_;
1686  }
1687 
1688  //============================================================================
1689  // Method Description:
1696  {
1697  if (inCol >= shape_.cols)
1698  {
1699  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1700  }
1701 
1702  return ccolbegin(inCol) += shape_.rows;
1703  }
1704 
1705  //============================================================================
1706  // Method Description:
1711  {
1712  return rcolbegin() += size_;
1713  }
1714 
1715  //============================================================================
1716  // Method Description:
1723  {
1724  if (inCol >= shape_.cols)
1725  {
1726  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1727  }
1728 
1729  return rcolbegin(inCol) += shape_.rows;
1730  }
1731 
1732  //============================================================================
1733  // Method Description:
1738  {
1739  return crcolend();
1740  }
1741 
1742  //============================================================================
1743  // Method Description:
1750  {
1751  return crcolend(inCol);
1752  }
1753 
1754  //============================================================================
1755  // Method Description:
1761  {
1762  return crcolbegin() += size_;
1763  }
1764 
1765  //============================================================================
1766  // Method Description:
1773  {
1774  if (inCol >= shape_.cols)
1775  {
1776  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1777  }
1778 
1779  return crcolbegin(inCol) += shape_.rows;
1780  }
1781 
1782  //============================================================================
1783  // Method Description:
1792  {
1794 
1795  const auto function = [](dtype i) -> bool { return i != dtype{ 0 }; };
1796 
1797  switch (inAxis)
1798  {
1799  case Axis::NONE:
1800  {
1801  NdArray<bool> returnArray = { stl_algorithms::all_of(cbegin(), cend(), function) };
1802  return returnArray;
1803  }
1804  case Axis::COL:
1805  {
1806  NdArray<bool> returnArray(1, shape_.rows);
1807  for (uint32 row = 0; row < shape_.rows; ++row)
1808  {
1809  returnArray(0, row) = stl_algorithms::all_of(cbegin(row), cend(row), function);
1810  }
1811 
1812  return returnArray;
1813  }
1814  case Axis::ROW:
1815  {
1816  return transpose().all(Axis::COL);
1817  }
1818  default:
1819  {
1820  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1821  return {}; // get rid of compiler warning
1822  }
1823  }
1824  }
1825 
1826  //============================================================================
1827  // Method Description:
1836  {
1838 
1839  const auto function = [](dtype i) -> bool { return i != dtype{ 0 }; };
1840 
1841  switch (inAxis)
1842  {
1843  case Axis::NONE:
1844  {
1845  NdArray<bool> returnArray = { stl_algorithms::any_of(cbegin(), cend(), function) };
1846  return returnArray;
1847  }
1848  case Axis::COL:
1849  {
1850  NdArray<bool> returnArray(1, shape_.rows);
1851  for (uint32 row = 0; row < shape_.rows; ++row)
1852  {
1853  returnArray(0, row) = stl_algorithms::any_of(cbegin(row), cend(row), function);
1854  }
1855 
1856  return returnArray;
1857  }
1858  case Axis::ROW:
1859  {
1860  return transpose().any(Axis::COL);
1861  }
1862  default:
1863  {
1864  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1865  return {}; // get rid of compiler warning
1866  }
1867  }
1868  }
1869 
1870  //============================================================================
1871  // Method Description:
1881  {
1883 
1884  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
1885 
1886  switch (inAxis)
1887  {
1888  case Axis::NONE:
1889  {
1890  NdArray<uint32> returnArray = { static_cast<uint32>(
1891  stl_algorithms::max_element(cbegin(), cend(), comparitor) - cbegin()) };
1892  return returnArray;
1893  }
1894  case Axis::COL:
1895  {
1896  NdArray<uint32> returnArray(1, shape_.rows);
1897  for (uint32 row = 0; row < shape_.rows; ++row)
1898  {
1899  returnArray(0, row) = static_cast<uint32>(
1900  stl_algorithms::max_element(cbegin(row), cend(row), comparitor) - cbegin(row));
1901  }
1902 
1903  return returnArray;
1904  }
1905  case Axis::ROW:
1906  {
1907  return transpose().argmax(Axis::COL);
1908  }
1909  default:
1910  {
1911  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1912  return {}; // get rid of compiler warning
1913  }
1914  }
1915  }
1916 
1917  //============================================================================
1918  // Method Description:
1928  {
1930 
1931  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
1932 
1933  switch (inAxis)
1934  {
1935  case Axis::NONE:
1936  {
1937  NdArray<uint32> returnArray = { static_cast<uint32>(
1938  stl_algorithms::min_element(cbegin(), cend(), comparitor) - cbegin()) };
1939  return returnArray;
1940  }
1941  case Axis::COL:
1942  {
1943  NdArray<uint32> returnArray(1, shape_.rows);
1944  for (uint32 row = 0; row < shape_.rows; ++row)
1945  {
1946  returnArray(0, row) = static_cast<uint32>(
1947  stl_algorithms::min_element(cbegin(row), cend(row), comparitor) - cbegin(row));
1948  }
1949 
1950  return returnArray;
1951  }
1952  case Axis::ROW:
1953  {
1954  return transpose().argmin(Axis::COL);
1955  }
1956  default:
1957  {
1958  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1959  return {}; // get rid of compiler warning
1960  }
1961  }
1962  }
1963 
1964  //============================================================================
1965  // Method Description:
1974  {
1976 
1977  switch (inAxis)
1978  {
1979  case Axis::NONE:
1980  {
1981  std::vector<uint32> idx(size_);
1982  std::iota(idx.begin(), idx.end(), 0);
1983 
1984  const auto function = [this](uint32 i1, uint32 i2) noexcept -> bool
1985  { return (*this)[i1] < (*this)[i2]; };
1986 
1987  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
1988  return NdArray<uint32>(idx);
1989  }
1990  case Axis::COL:
1991  {
1992  NdArray<uint32> returnArray(shape_);
1993  std::vector<uint32> idx(shape_.cols);
1994 
1995  for (uint32 row = 0; row < shape_.rows; ++row)
1996  {
1997  std::iota(idx.begin(), idx.end(), 0);
1998 
1999  const auto function = [this, row](uint32 i1, uint32 i2) noexcept -> bool
2000  { return operator()(row, i1) < operator()(row, i2); };
2001 
2002  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2003 
2004  for (uint32 col = 0; col < shape_.cols; ++col)
2005  {
2006  returnArray(row, col) = idx[col];
2007  }
2008  }
2009  return returnArray;
2010  }
2011  case Axis::ROW:
2012  {
2013  return transpose().argsort(Axis::COL).transpose();
2014  }
2015  default:
2016  {
2017  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2018  return {}; // get rid of compiler warning
2019  }
2020  }
2021  }
2022 
2023  //============================================================================
2024  // Method Description:
2032  template<typename dtypeOut,
2033  typename dtype_ = dtype,
2038  {
2039  NdArray<dtypeOut> outArray(shape_);
2041  cend(),
2042  outArray.begin(),
2043  [](dtype value) -> dtypeOut { return static_cast<dtypeOut>(value); });
2044 
2045  return outArray;
2046  }
2047 
2048  //============================================================================
2049  // Method Description:
2057  template<typename dtypeOut,
2058  typename dtype_ = dtype,
2063  {
2064  NdArray<dtypeOut> outArray(shape_);
2065 
2066  const auto function = [](const_reference value) -> dtypeOut
2067  { return std::complex<typename dtypeOut::value_type>(value); };
2068 
2069  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2070 
2071  return outArray;
2072  }
2073 
2074  //============================================================================
2075  // Method Description:
2083  template<typename dtypeOut,
2084  typename dtype_ = dtype,
2089  {
2090  NdArray<dtypeOut> outArray(shape_);
2091 
2092  if (is_same_v<dtypeOut, dtype>)
2093  {
2094  std::copy(cbegin(), cend(), outArray.begin());
2095  }
2096  else
2097  {
2098  const auto function = [](const_reference value) noexcept -> dtypeOut
2099  { return complex_cast<typename dtypeOut::value_type>(value); };
2100 
2101  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2102  }
2103 
2104  return outArray;
2105  }
2106 
2107  //============================================================================
2108  // Method Description:
2116  template<typename dtypeOut,
2117  typename dtype_ = dtype,
2122  {
2123  NdArray<dtypeOut> outArray(shape_);
2124 
2125  const auto function = [](const_reference value) -> dtypeOut { return static_cast<dtypeOut>(value.real()); };
2126 
2127  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2128 
2129  return outArray;
2130  }
2131 
2132  //============================================================================
2133  // Method Description:
2138  const_reference back() const noexcept
2139  {
2140  return *(cend() - 1);
2141  }
2142 
2143  //============================================================================
2144  // Method Description:
2149  reference back() noexcept
2150  {
2151  return *(end() - 1);
2152  }
2153 
2154  //============================================================================
2155  // Method Description:
2161  {
2162  return *(cend(row) - 1);
2163  }
2164 
2165  //============================================================================
2166  // Method Description:
2172  {
2173  return *(end(row) - 1);
2174  }
2175 
2176  //============================================================================
2177  // Method Description:
2185  {
2186  STATIC_ASSERT_INTEGER(dtype);
2187 
2189  end(),
2190  [](dtype& value) noexcept -> void { value = endian::byteSwap(value); });
2191 
2192  switch (endianess_)
2193  {
2194  case Endian::NATIVE:
2195  {
2197  break;
2198  }
2199  case Endian::LITTLE:
2200  {
2201  endianess_ = Endian::BIG;
2202  break;
2203  }
2204  case Endian::BIG:
2205  {
2206  endianess_ = Endian::LITTLE;
2207  break;
2208  }
2209  }
2210 
2211  return *this;
2212  }
2213 
2214  //============================================================================
2215  // Method Description:
2225  {
2227 
2228  NdArray<dtype> outArray(shape_);
2230  cend(),
2231  outArray.begin(),
2232  [inMin, inMax](dtype value) noexcept -> dtype
2233  {
2234 #ifdef __cpp_lib_clamp
2235  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
2236  { return lhs < rhs; };
2237 
2238  return std::clamp(value, inMin, inMax, comparitor);
2239 #else
2240  if (value < inMin)
2241  {
2242  return inMin;
2243  }
2244  else if (value > inMax)
2245  {
2246  return inMax;
2247  }
2248 
2249  return value;
2250 #endif
2251  });
2252 
2253  return outArray;
2254  }
2255 
2256  //============================================================================
2257  // Method Description:
2264  {
2265  return operator()(rSlice(), inColumn);
2266  }
2267 
2268  //============================================================================
2269  // Method Description:
2277  {
2279 
2280  switch (inAxis)
2281  {
2282  case Axis::NONE:
2283  {
2284  NdArray<bool> returnArray = { stl_algorithms::find(cbegin(), cend(), inValue) != cend() };
2285  return returnArray;
2286  }
2287  case Axis::COL:
2288  {
2289  NdArray<bool> returnArray(1, shape_.rows);
2290  for (uint32 row = 0; row < shape_.rows; ++row)
2291  {
2292  returnArray(0, row) = stl_algorithms::find(cbegin(row), cend(row), inValue) != cend(row);
2293  }
2294 
2295  return returnArray;
2296  }
2297  case Axis::ROW:
2298  {
2299  return transpose().contains(inValue, Axis::COL);
2300  }
2301  default:
2302  {
2303  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2304  return {}; // get rid of compiler warning
2305  }
2306  }
2307  }
2308 
2309  //============================================================================
2310  // Method Description:
2318  {
2319  return NdArray<dtype>(*this);
2320  }
2321 
2322  //============================================================================
2323  // Method Description:
2332  {
2334 
2335  switch (inAxis)
2336  {
2337  case Axis::NONE:
2338  {
2339  NdArray<dtype> returnArray(1, size_);
2340  returnArray[0] = front();
2341  for (uint32 i = 1; i < size_; ++i)
2342  {
2343  returnArray[i] = returnArray[i - 1] * array_[i];
2344  }
2345 
2346  return returnArray;
2347  }
2348  case Axis::COL:
2349  {
2350  NdArray<dtype> returnArray(shape_);
2351  for (uint32 row = 0; row < shape_.rows; ++row)
2352  {
2353  returnArray(row, 0) = operator()(row, 0);
2354  for (uint32 col = 1; col < shape_.cols; ++col)
2355  {
2356  returnArray(row, col) = returnArray(row, col - 1) * operator()(row, col);
2357  }
2358  }
2359 
2360  return returnArray;
2361  }
2362  case Axis::ROW:
2363  {
2364  return transpose().cumprod(Axis::COL).transpose();
2365  }
2366  default:
2367  {
2368  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2369  return {}; // get rid of compiler warning
2370  }
2371  }
2372  }
2373 
2374  //============================================================================
2375  // Method Description:
2384  {
2386 
2387  switch (inAxis)
2388  {
2389  case Axis::NONE:
2390  {
2391  NdArray<dtype> returnArray(1, size_);
2392  returnArray[0] = front();
2393  for (uint32 i = 1; i < size_; ++i)
2394  {
2395  returnArray[i] = returnArray[i - 1] + array_[i];
2396  }
2397 
2398  return returnArray;
2399  }
2400  case Axis::COL:
2401  {
2402  NdArray<dtype> returnArray(shape_);
2403  for (uint32 row = 0; row < shape_.rows; ++row)
2404  {
2405  returnArray(row, 0) = operator()(row, 0);
2406  for (uint32 col = 1; col < shape_.cols; ++col)
2407  {
2408  returnArray(row, col) = returnArray(row, col - 1) + operator()(row, col);
2409  }
2410  }
2411 
2412  return returnArray;
2413  }
2414  case Axis::ROW:
2415  {
2416  return transpose().cumsum(Axis::COL).transpose();
2417  }
2418  default:
2419  {
2420  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2421  return {}; // get rid of compiler warning
2422  }
2423  }
2424  }
2425 
2426  //============================================================================
2427  // Method Description:
2431  pointer data() noexcept
2432  {
2433  return array_;
2434  }
2435 
2436  //============================================================================
2437  // Method Description:
2441  const_pointer data() const noexcept
2442  {
2443  return array_;
2444  }
2445 
2446  //============================================================================
2447  // Method Description:
2454  {
2455  ownsPtr_ = false;
2456  return data();
2457  }
2458 
2459  //============================================================================
2460  // Method Description:
2470  NdArray<dtype> diagonal(int32 inOffset = 0, Axis inAxis = Axis::ROW) const
2471  {
2472  switch (inAxis)
2473  {
2474  case Axis::COL:
2475  {
2476  std::vector<dtype> diagnolValues;
2477  uint32 col = 0;
2478  for (int32 row = inOffset; row < static_cast<int32>(shape_.rows); ++row)
2479  {
2480  if (row < 0)
2481  {
2482  ++col;
2483  continue;
2484  }
2485  if (col >= shape_.cols)
2486  {
2487  break;
2488  }
2489 
2490  diagnolValues.push_back(operator()(static_cast<uint32>(row), col));
2491  ++col;
2492  }
2493 
2494  return NdArray<dtype>(diagnolValues);
2495  }
2496  case Axis::ROW:
2497  {
2498  return transpose().diagonal(inOffset, Axis::COL);
2499  }
2500  default:
2501  {
2502  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2503  return {}; // get rid of compiler warning
2504  }
2505  }
2506  }
2507 
2508  //============================================================================
2509  // Method Description:
2520  NdArray<dtype> dot(const NdArray<dtype>& inOtherArray) const
2521  {
2523 
2524  if (shape_ == inOtherArray.shape_ && (shape_.rows == 1 || shape_.cols == 1))
2525  {
2526  dtype dotProduct = std::inner_product(cbegin(), cend(), inOtherArray.cbegin(), dtype{ 0 });
2527  NdArray<dtype> returnArray = { dotProduct };
2528  return returnArray;
2529  }
2530  if (shape_.cols == inOtherArray.shape_.rows)
2531  {
2532  // 2D array, use matrix multiplication
2533  NdArray<dtype> returnArray(shape_.rows, inOtherArray.shape_.cols);
2534  auto otherArrayT = inOtherArray.transpose();
2535 
2536  for (uint32 i = 0; i < shape_.rows; ++i)
2537  {
2538  for (uint32 j = 0; j < otherArrayT.shape_.rows; ++j)
2539  {
2540  returnArray(i, j) =
2541  std::inner_product(otherArrayT.cbegin(j), otherArrayT.cend(j), cbegin(i), dtype{ 0 });
2542  }
2543  }
2544 
2545  return returnArray;
2546  }
2547 
2548  std::string errStr = "shapes of [" + utils::num2str(shape_.rows) + ", " + utils::num2str(shape_.cols) + "]";
2549  errStr += " and [" + utils::num2str(inOtherArray.shape_.rows) + ", " +
2550  utils::num2str(inOtherArray.shape_.cols) + "]";
2551  errStr += " are not consistent.";
2553 
2554  return NdArray<dtype>(); // get rid of compiler warning
2555  }
2556 
2557  //============================================================================
2558  // Method Description:
2566  void dump(const std::string& inFilename) const
2567  {
2568  filesystem::File f(inFilename);
2569  if (!f.hasExt())
2570  {
2571  f.withExt(".bin");
2572  }
2573 
2574  std::ofstream ofile(f.fullName().c_str(), std::ios::binary);
2575  if (!ofile.good())
2576  {
2577  THROW_RUNTIME_ERROR("Unable to open the input file:\n\t" + inFilename);
2578  }
2579 
2580  if (array_ != nullptr)
2581  {
2582  ofile.write(reinterpret_cast<const char*>(array_), size_ * sizeof(dtype));
2583  }
2584  ofile.close();
2585  }
2586 
2587  //============================================================================
2588  // Method Description:
2593  Endian endianess() const noexcept
2594  {
2595  STATIC_ASSERT_ARITHMETIC(dtype);
2596 
2597  return endianess_;
2598  }
2599 
2600  //============================================================================
2601  // Method Description:
2609  NdArray<dtype>& fill(value_type inFillValue) noexcept
2610  {
2611  stl_algorithms::fill(begin(), end(), inFillValue);
2612  return *this;
2613  }
2614 
2615  //============================================================================
2616  // Method Description:
2623  {
2625 
2626  std::vector<uint32> indices;
2627  uint32 idx = 0;
2628  for (auto value : *this)
2629  {
2630  if (value != dtype{ 0 })
2631  {
2632  indices.push_back(idx);
2633  }
2634  ++idx;
2635  }
2636 
2637  return NdArray<uint32>(indices);
2638  }
2639 
2640  //============================================================================
2641  // Method Description:
2649  {
2650  NdArray<dtype> outArray(1, size_);
2651  stl_algorithms::copy(cbegin(), cend(), outArray.begin());
2652  return outArray;
2653  }
2654 
2655  //============================================================================
2656  // Method Description:
2661  const_reference front() const noexcept
2662  {
2663  return *cbegin();
2664  }
2665 
2666  //============================================================================
2667  // Method Description:
2672  reference front() noexcept
2673  {
2674  return *begin();
2675  }
2676 
2677  //============================================================================
2678  // Method Description:
2684  {
2685  return *cbegin(row);
2686  }
2687 
2688  //============================================================================
2689  // Method Description:
2695  {
2696  return *begin(row);
2697  }
2698 
2699  //============================================================================
2700  // Method Description:
2707  {
2708  return operator[](inIndices);
2709  }
2710 
2711  //============================================================================
2712  // Method Description:
2721  {
2722  return operator[](inMask);
2723  }
2724 
2725  //============================================================================
2726  // Method Description:
2732  bool isempty() const noexcept
2733  {
2734  return size_ == 0;
2735  }
2736 
2737  //============================================================================
2738  // Method Description:
2744  bool isflat() const noexcept
2745  {
2746  return shape_.rows == 1 || shape_.cols == 1;
2747  }
2748 
2749  //============================================================================
2750  // Method Description:
2757  {
2759 
2760  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
2761 
2762  switch (inAxis)
2763  {
2764  case Axis::NONE:
2765  {
2766  return { stl_algorithms::is_sorted(cbegin(), cend(), comparitor) };
2767  }
2768  case Axis::COL:
2769  {
2770  NdArray<bool> returnArray(1, shape_.rows);
2771  for (uint32 row = 0; row < shape_.rows; ++row)
2772  {
2773  returnArray(0, row) = stl_algorithms::is_sorted(cbegin(row), cend(row), comparitor);
2774  }
2775 
2776  return returnArray;
2777  }
2778  case Axis::ROW:
2779  {
2780  return transpose().issorted(Axis::COL);
2781  }
2782  default:
2783  {
2784  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2785  return {}; // get rid of compiler warning
2786  }
2787  }
2788  }
2789 
2790  //============================================================================
2791  // Method Description:
2796  bool issquare() const noexcept
2797  {
2798  return shape_.issquare();
2799  }
2800 
2801  //============================================================================
2802  // Method Description:
2810  {
2811  if (size_ != 1)
2812  {
2813  THROW_INVALID_ARGUMENT_ERROR("Can only convert an array of size 1 to a C++ scaler");
2814  }
2815 
2816  return front();
2817  }
2818 
2819  //============================================================================
2820  // Method Description:
2829  {
2831 
2832  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
2833 
2834  switch (inAxis)
2835  {
2836  case Axis::NONE:
2837  {
2838  NdArray<dtype> returnArray = { *stl_algorithms::max_element(cbegin(), cend(), comparitor) };
2839  return returnArray;
2840  }
2841  case Axis::COL:
2842  {
2843  NdArray<dtype> returnArray(1, shape_.rows);
2844  for (uint32 row = 0; row < shape_.rows; ++row)
2845  {
2846  returnArray(0, row) = *stl_algorithms::max_element(cbegin(row), cend(row), comparitor);
2847  }
2848 
2849  return returnArray;
2850  }
2851  case Axis::ROW:
2852  {
2853  return transpose().max(Axis::COL);
2854  }
2855  default:
2856  {
2857  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2858  return {}; // get rid of compiler warning
2859  }
2860  }
2861  }
2862 
2863  //============================================================================
2864  // Method Description:
2873  {
2875 
2876  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
2877 
2878  switch (inAxis)
2879  {
2880  case Axis::NONE:
2881  {
2882  NdArray<dtype> returnArray = { *stl_algorithms::min_element(cbegin(), cend(), comparitor) };
2883  return returnArray;
2884  }
2885  case Axis::COL:
2886  {
2887  NdArray<dtype> returnArray(1, shape_.rows);
2888  for (uint32 row = 0; row < shape_.rows; ++row)
2889  {
2890  returnArray(0, row) = *stl_algorithms::min_element(cbegin(row), cend(row), comparitor);
2891  }
2892 
2893  return returnArray;
2894  }
2895  case Axis::ROW:
2896  {
2897  return transpose().min(Axis::COL);
2898  }
2899  default:
2900  {
2901  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2902  return {}; // get rid of compiler warning
2903  }
2904  }
2905  }
2906 
2907  //============================================================================
2908  // Method Description:
2919  {
2921 
2922  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
2923 
2924  if (size_ == 0)
2925  {
2926  THROW_RUNTIME_ERROR("Median is undefined for an array of size = 0.");
2927  }
2928 
2929  switch (inAxis)
2930  {
2931  case Axis::NONE:
2932  {
2933  NdArray<dtype> copyArray(*this);
2934 
2935  const uint32 middleIdx = size_ / 2; // integer division
2936  stl_algorithms::nth_element(copyArray.begin(),
2937  copyArray.begin() + middleIdx,
2938  copyArray.end(),
2939  comparitor);
2940 
2941  dtype medianValue = copyArray.array_[middleIdx];
2942  if (size_ % 2 == 0)
2943  {
2944  const uint32 lhsIndex = middleIdx - 1;
2945  stl_algorithms::nth_element(copyArray.begin(),
2946  copyArray.begin() + lhsIndex,
2947  copyArray.end(),
2948  comparitor);
2949  medianValue =
2950  (medianValue + copyArray.array_[lhsIndex]) / dtype{ 2 }; // potentially integer division, ok
2951  }
2952 
2953  return { medianValue };
2954  }
2955  case Axis::COL:
2956  {
2957  NdArray<dtype> copyArray(*this);
2958  NdArray<dtype> returnArray(1, shape_.rows);
2959 
2960  const bool isEven = shape_.cols % 2 == 0;
2961  for (uint32 row = 0; row < shape_.rows; ++row)
2962  {
2963  const uint32 middleIdx = shape_.cols / 2; // integer division
2964  stl_algorithms::nth_element(copyArray.begin(row),
2965  copyArray.begin(row) + middleIdx,
2966  copyArray.end(row),
2967  comparitor);
2968 
2969  dtype medianValue = copyArray(row, middleIdx);
2970  if (isEven)
2971  {
2972  const uint32 lhsIndex = middleIdx - 1;
2973  stl_algorithms::nth_element(copyArray.begin(row),
2974  copyArray.begin(row) + lhsIndex,
2975  copyArray.end(row),
2976  comparitor);
2977  medianValue = (medianValue + copyArray(row, lhsIndex)) /
2978  dtype{ 2 }; // potentially integer division, ok
2979  }
2980 
2981  returnArray(0, row) = medianValue;
2982  }
2983 
2984  return returnArray;
2985  }
2986  case Axis::ROW:
2987  {
2988  return transpose().median(Axis::COL);
2989  }
2990  default:
2991  {
2992  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2993  return {}; // get rid of compiler warning
2994  }
2995  }
2996  }
2997 
2998  //============================================================================
2999  // Method Description:
3003  NdArray<dtype>& nans() noexcept
3004 
3005  {
3006  STATIC_ASSERT_FLOAT(dtype);
3007 
3009  return *this;
3010  }
3011 
3012  //============================================================================
3013  // Method Description:
3020  uint64 nbytes() const noexcept
3021  {
3022  return static_cast<uint64>(sizeof(dtype) * size_);
3023  }
3024 
3025  //============================================================================
3026  // Method Description:
3036  {
3037  STATIC_ASSERT_INTEGER(dtype);
3038 
3039  const bool nativeIsLittle = endian::isLittleEndian();
3040 
3041  switch (endianess_)
3042  {
3043  case Endian::NATIVE:
3044  {
3045  switch (inEndianess)
3046  {
3047  case Endian::NATIVE:
3048  {
3049  return NdArray(*this);
3050  }
3051  case Endian::BIG:
3052  {
3053  if (nativeIsLittle)
3054  {
3055  NdArray<dtype> outArray(shape_);
3056 
3057  stl_algorithms::transform(cbegin(), end(), outArray.begin(), endian::byteSwap<dtype>);
3058 
3059  outArray.endianess_ = Endian::BIG;
3060  return outArray;
3061  }
3062  else
3063  {
3064  auto outArray = NdArray(*this);
3065  outArray.endianess_ = Endian::BIG;
3066  return outArray;
3067  }
3068  }
3069  case Endian::LITTLE:
3070  {
3071  if (nativeIsLittle)
3072  {
3073  auto outArray = NdArray(*this);
3074  outArray.endianess_ = Endian::LITTLE;
3075  return outArray;
3076  }
3077  else
3078  {
3079  NdArray<dtype> outArray(shape_);
3080 
3081  stl_algorithms::transform(cbegin(), end(), outArray.begin(), endian::byteSwap<dtype>);
3082 
3083  outArray.endianess_ = Endian::LITTLE;
3084  return outArray;
3085  }
3086  }
3087  default:
3088  {
3089  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3090  return {}; // get rid of compiler warning
3091  }
3092  }
3093  break;
3094  }
3095  case Endian::BIG:
3096  {
3097  switch (inEndianess)
3098  {
3099  case Endian::NATIVE:
3100  {
3101  if (nativeIsLittle)
3102  {
3103  NdArray<dtype> outArray(shape_);
3104 
3105  stl_algorithms::transform(cbegin(), end(), outArray.begin(), endian::byteSwap<dtype>);
3106 
3107  outArray.endianess_ = Endian::NATIVE;
3108  return outArray;
3109  }
3110  else
3111  {
3112  auto outArray = NdArray(*this);
3113  outArray.endianess_ = Endian::NATIVE;
3114  return outArray;
3115  }
3116  }
3117  case Endian::BIG:
3118  {
3119  return NdArray(*this);
3120  }
3121  case Endian::LITTLE:
3122  {
3123  NdArray<dtype> outArray(shape_);
3124 
3125  stl_algorithms::transform(cbegin(), end(), outArray.begin(), endian::byteSwap<dtype>);
3126 
3127  outArray.endianess_ = Endian::LITTLE;
3128  return outArray;
3129  }
3130  default:
3131  {
3132  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3133  return {}; // get rid of compiler warning
3134  }
3135  }
3136  break;
3137  }
3138  case Endian::LITTLE:
3139  {
3140  switch (inEndianess)
3141  {
3142  case Endian::NATIVE:
3143  {
3144  if (nativeIsLittle)
3145  {
3146  auto outArray = NdArray(*this);
3147  outArray.endianess_ = Endian::NATIVE;
3148  return outArray;
3149  }
3150  else
3151  {
3152  NdArray<dtype> outArray(shape_);
3153 
3154  stl_algorithms::transform(cbegin(), end(), outArray.begin(), endian::byteSwap<dtype>);
3155 
3156  outArray.endianess_ = Endian::NATIVE;
3157  return outArray;
3158  }
3159  }
3160  case Endian::BIG:
3161  {
3162  NdArray<dtype> outArray(shape_);
3163 
3164  stl_algorithms::transform(cbegin(), end(), outArray.begin(), endian::byteSwap<dtype>);
3165 
3166  outArray.endianess_ = Endian::BIG;
3167  return outArray;
3168  }
3169  case Endian::LITTLE:
3170  {
3171  return NdArray(*this);
3172  }
3173  default:
3174  {
3175  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3176  return {}; // get rid of compiler warning
3177  }
3178  }
3179  break;
3180  }
3181  default:
3182  {
3183  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3184  return {}; // get rid of compiler warning
3185  }
3186  }
3187  }
3188 
3189  //============================================================================
3190  // Method Description:
3199  {
3201 
3202  const auto function = [](dtype i) -> bool { return i != dtype{ 0 }; };
3203 
3204  switch (inAxis)
3205  {
3206  case Axis::NONE:
3207  {
3208  NdArray<bool> returnArray = { stl_algorithms::none_of(cbegin(), cend(), function) };
3209  return returnArray;
3210  }
3211  case Axis::COL:
3212  {
3213  NdArray<bool> returnArray(1, shape_.rows);
3214  for (uint32 row = 0; row < shape_.rows; ++row)
3215  {
3216  returnArray(0, row) = stl_algorithms::none_of(cbegin(row), cend(row), function);
3217  }
3218 
3219  return returnArray;
3220  }
3221  case Axis::ROW:
3222  {
3223  return transpose().none(Axis::COL);
3224  }
3225  default:
3226  {
3227  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3228  return {}; // get rid of compiler warning
3229  }
3230  }
3231  }
3232 
3233  //============================================================================
3234  // Method Description:
3243  std::pair<NdArray<uint32>, NdArray<uint32>> nonzero() const;
3244 
3245  //============================================================================
3246  // Method Description:
3252  uint32 numCols() const noexcept
3253  {
3254  return shape_.cols;
3255  }
3256 
3257  //============================================================================
3258  // Method Description:
3264  uint32 numRows() const noexcept
3265  {
3266  return shape_.rows;
3267  }
3268 
3269  //============================================================================
3270  // Method Description:
3274  NdArray<dtype>& ones() noexcept
3275  {
3277 
3278  fill(dtype{ 1 });
3279  return *this;
3280  }
3281 
3282  //============================================================================
3283  // Method Description:
3288  bool ownsInternalData() noexcept
3289  {
3290  return ownsPtr_;
3291  }
3292 
3293  //============================================================================
3294  // Method Description:
3309  {
3311 
3312  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
3313 
3314  switch (inAxis)
3315  {
3316  case Axis::NONE:
3317  {
3318  if (inKth >= size_)
3319  {
3320  std::string errStr = "kth(=" + utils::num2str(inKth);
3321  errStr += ") out of bounds (" + utils::num2str(size_) + ")";
3323  }
3324 
3325  stl_algorithms::nth_element(begin(), begin() + inKth, end(), comparitor);
3326  break;
3327  }
3328  case Axis::COL:
3329  {
3330  if (inKth >= shape_.cols)
3331  {
3332  std::string errStr = "kth(=" + utils::num2str(inKth);
3333  errStr += ") out of bounds (" + utils::num2str(shape_.cols) + ")";
3335  }
3336 
3337  for (uint32 row = 0; row < shape_.rows; ++row)
3338  {
3339  stl_algorithms::nth_element(begin(row), begin(row) + inKth, end(row), comparitor);
3340  }
3341  break;
3342  }
3343  case Axis::ROW:
3344  {
3345  if (inKth >= shape_.rows)
3346  {
3347  std::string errStr = "kth(=" + utils::num2str(inKth);
3348  errStr += ") out of bounds (" + utils::num2str(shape_.rows) + ")";
3350  }
3351 
3352  NdArray<dtype> transposedArray = transpose();
3353  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3354  {
3355  stl_algorithms::nth_element(transposedArray.begin(row),
3356  transposedArray.begin(row) + inKth,
3357  transposedArray.end(row),
3358  comparitor);
3359  }
3360  *this = transposedArray.transpose();
3361  break;
3362  }
3363  }
3364 
3365  return *this;
3366  }
3367 
3368  //============================================================================
3369  // Method Description:
3373  void print() const
3374  {
3376 
3377  std::cout << *this;
3378  }
3379 
3380  //============================================================================
3381  // Method Description:
3390  {
3392 
3393  switch (inAxis)
3394  {
3395  case Axis::NONE:
3396  {
3397  dtype product = std::accumulate(cbegin(), cend(), dtype{ 1 }, std::multiplies<dtype>());
3398  NdArray<dtype> returnArray = { product };
3399  return returnArray;
3400  }
3401  case Axis::COL:
3402  {
3403  NdArray<dtype> returnArray(1, shape_.rows);
3404  for (uint32 row = 0; row < shape_.rows; ++row)
3405  {
3406  returnArray(0, row) =
3407  std::accumulate(cbegin(row), cend(row), dtype{ 1 }, std::multiplies<dtype>());
3408  }
3409 
3410  return returnArray;
3411  }
3412  case Axis::ROW:
3413  {
3414  return transpose().prod(Axis::COL);
3415  }
3416  default:
3417  {
3418  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3419  return {}; // get rid of compiler warning
3420  }
3421  }
3422  }
3423 
3424  //============================================================================
3425  // Method Description:
3434  {
3436 
3437  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
3438 
3439  switch (inAxis)
3440  {
3441  case Axis::NONE:
3442  {
3443  const auto result = stl_algorithms::minmax_element(cbegin(), cend(), comparitor);
3444  NdArray<dtype> returnArray = { *result.second - *result.first };
3445  return returnArray;
3446  }
3447  case Axis::COL:
3448  {
3449  NdArray<dtype> returnArray(1, shape_.rows);
3450  for (uint32 row = 0; row < shape_.rows; ++row)
3451  {
3452  const auto result = stl_algorithms::minmax_element(cbegin(row), cend(row), comparitor);
3453  returnArray(0, row) = *result.second - *result.first;
3454  }
3455 
3456  return returnArray;
3457  }
3458  case Axis::ROW:
3459  {
3460  return transpose().ptp(Axis::COL);
3461  }
3462  default:
3463  {
3464  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3465  return {}; // get rid of compiler warning
3466  }
3467  }
3468  }
3469 
3470  //============================================================================
3471  // Method Description:
3479  NdArray<dtype>& put(int32 inIndex, value_type inValue)
3480  {
3481  at(inIndex) = inValue;
3482 
3483  return *this;
3484  }
3485 
3486  //============================================================================
3487  // Method Description:
3496  NdArray<dtype>& put(int32 inRow, int32 inCol, value_type inValue)
3497  {
3498  at(inRow, inCol) = inValue;
3499 
3500  return *this;
3501  }
3502 
3503  //============================================================================
3504  // Method Description:
3512  NdArray<dtype>& put(const NdArray<uint32>& inIndices, value_type inValue)
3513  {
3514  for (auto index : inIndices)
3515  {
3516  put(index, inValue);
3517  }
3518 
3519  return *this;
3520  }
3521 
3522  //============================================================================
3523  // Method Description:
3531  NdArray<dtype>& put(const NdArray<uint32>& inIndices, const NdArray<dtype>& inValues)
3532  {
3533  if (inIndices.size() != inValues.size())
3534  {
3535  THROW_INVALID_ARGUMENT_ERROR("Input indices do not match values dimensions.");
3536  }
3537 
3538  uint32 counter = 0;
3539  for (auto index : inIndices)
3540  {
3541  put(index, inValues[counter++]);
3542  }
3543 
3544  return *this;
3545  }
3546 
3547  //============================================================================
3548  // Method Description:
3556  NdArray<dtype>& put(const Slice& inSlice, value_type inValue)
3557  {
3558  Slice inSliceCopy(inSlice);
3559  inSliceCopy.makePositiveAndValidate(size_);
3560 
3561  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
3562  {
3563  put(i, inValue);
3564  }
3565 
3566  return *this;
3567  }
3568 
3569  //============================================================================
3570  // Method Description:
3578  NdArray<dtype>& put(const Slice& inSlice, const NdArray<dtype>& inValues)
3579  {
3580  Slice inSliceCopy(inSlice);
3581  inSliceCopy.makePositiveAndValidate(size_);
3582 
3583  std::vector<uint32> indices;
3584  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
3585  {
3586  indices.push_back(i);
3587  }
3588 
3589  return put(NdArray<uint32>(indices), inValues);
3590  }
3591 
3592  //============================================================================
3593  // Method Description:
3602  NdArray<dtype>& put(const Slice& inRowSlice, const Slice& inColSlice, value_type inValue)
3603  {
3604  Slice inRowSliceCopy(inRowSlice);
3605  Slice inColSliceCopy(inColSlice);
3606 
3607  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3608  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3609 
3610  std::vector<uint32> indices;
3611  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3612  {
3613  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3614  {
3615  put(row, col, inValue);
3616  }
3617  }
3618 
3619  return *this;
3620  }
3621 
3622  //============================================================================
3623  // Method Description:
3632  NdArray<dtype>& put(const Slice& inRowSlice, int32 inColIndex, value_type inValue)
3633  {
3634  Slice inRowSliceCopy(inRowSlice);
3635  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3636 
3637  std::vector<uint32> indices;
3638  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3639  {
3640  put(row, inColIndex, inValue);
3641  }
3642 
3643  return *this;
3644  }
3645 
3646  //============================================================================
3647  // Method Description:
3656  NdArray<dtype>& put(int32 inRowIndex, const Slice& inColSlice, value_type inValue)
3657  {
3658  Slice inColSliceCopy(inColSlice);
3659  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3660 
3661  std::vector<uint32> indices;
3662  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3663  {
3664  put(inRowIndex, col, inValue);
3665  }
3666 
3667  return *this;
3668  }
3669 
3670  //============================================================================
3671  // Method Description:
3680  NdArray<dtype>& put(const Slice& inRowSlice, const Slice& inColSlice, const NdArray<dtype>& inValues)
3681  {
3682  Slice inRowSliceCopy(inRowSlice);
3683  Slice inColSliceCopy(inColSlice);
3684 
3685  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3686  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3687 
3688  std::vector<uint32> indices;
3689  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3690  {
3691  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3692  {
3693  const uint32 index = row * shape_.cols + col;
3694  indices.push_back(index);
3695  }
3696  }
3697 
3698  return put(NdArray<uint32>(indices), inValues);
3699  }
3700 
3701  //============================================================================
3702  // Method Description:
3711  NdArray<dtype>& put(const Slice& inRowSlice, int32 inColIndex, const NdArray<dtype>& inValues)
3712  {
3713  Slice inRowSliceCopy(inRowSlice);
3714  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3715 
3716  std::vector<uint32> indices;
3717  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3718  {
3719  const uint32 index = row * shape_.cols + inColIndex;
3720  indices.push_back(index);
3721  }
3722 
3723  return put(NdArray<uint32>(indices), inValues);
3724  }
3725 
3726  //============================================================================
3727  // Method Description:
3736  NdArray<dtype>& put(int32 inRowIndex, const Slice& inColSlice, const NdArray<dtype>& inValues)
3737  {
3738  Slice inColSliceCopy(inColSlice);
3739  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3740 
3741  std::vector<uint32> indices;
3742  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3743  {
3744  const uint32 index = inRowIndex * shape_.cols + col;
3745  indices.push_back(index);
3746  }
3747 
3748  return put(NdArray<uint32>(indices), inValues);
3749  }
3750 
3751  //============================================================================
3752  // Method Description:
3759  {
3760  if (inMask.shape() != shape_)
3761  {
3762  THROW_INVALID_ARGUMENT_ERROR("input inMask must be the same shape as the array it is masking.");
3763  }
3764 
3765  return put(inMask.flatnonzero(), inValue);
3766  }
3767 
3768  //============================================================================
3769  // Method Description:
3775  NdArray<dtype>& putMask(const NdArray<bool>& inMask, const NdArray<dtype>& inValues)
3776  {
3777  if (inMask.shape() != shape_)
3778  {
3779  THROW_INVALID_ARGUMENT_ERROR("input inMask must be the same shape as the array it is masking.");
3780  }
3781 
3782  return put(inMask.flatnonzero(), inValues);
3783  }
3784 
3785  //============================================================================
3786  // Method Description:
3793  NdArray<dtype>& ravel() noexcept
3794  {
3795  reshape(size_);
3796  return *this;
3797  }
3798 
3799  //============================================================================
3800  // Method Description:
3809  NdArray<dtype> repeat(uint32 inNumRows, uint32 inNumCols) const
3810  {
3811  NdArray<dtype> returnArray(shape_.rows * inNumRows, shape_.cols * inNumCols);
3812 
3813  for (uint32 row = 0; row < inNumRows; ++row)
3814  {
3815  for (uint32 col = 0; col < inNumCols; ++col)
3816  {
3817  std::vector<uint32> indices(shape_.size());
3818 
3819  const uint32 rowStart = row * shape_.rows;
3820  const uint32 colStart = col * shape_.cols;
3821 
3822  const uint32 rowEnd = (row + 1) * shape_.rows;
3823  const uint32 colEnd = (col + 1) * shape_.cols;
3824 
3825  uint32 counter = 0;
3826  for (uint32 rowIdx = rowStart; rowIdx < rowEnd; ++rowIdx)
3827  {
3828  for (uint32 colIdx = colStart; colIdx < colEnd; ++colIdx)
3829  {
3830  indices[counter++] = rowIdx * returnArray.shape_.cols + colIdx;
3831  }
3832  }
3833 
3834  returnArray.put(NdArray<uint32>(indices), *this);
3835  }
3836  }
3837 
3838  return returnArray;
3839  }
3840 
3841  //============================================================================
3842  // Method Description:
3850  NdArray<dtype> repeat(const Shape& inRepeatShape) const
3851  {
3852  return repeat(inRepeatShape.rows, inRepeatShape.cols);
3853  }
3854 
3855  //============================================================================
3856  // Method Description:
3862  void replace(value_type oldValue, value_type newValue)
3863  {
3865 
3866  stl_algorithms::replace(begin(), end(), oldValue, newValue);
3867  }
3868 
3869  //============================================================================
3870  // Method Description:
3881  {
3882  if (inSize != size_)
3883  {
3884  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into shape ";
3885  errStr += "[" + utils::num2str(1) + ", " + utils::num2str(inSize) + "]";
3886  THROW_RUNTIME_ERROR(errStr);
3887  }
3888 
3889  shape_.rows = 1;
3890  shape_.cols = inSize;
3891 
3892  return *this;
3893  }
3894 
3895  //============================================================================
3896  // Method Description:
3907  NdArray<dtype>& reshape(int32 inNumRows, int32 inNumCols)
3908  {
3909  if (inNumRows < 0)
3910  {
3911  if (size_ % inNumCols == 0)
3912  {
3913  return reshape(size_ / inNumCols, inNumCols);
3914  }
3915 
3916  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into a shape ";
3917  errStr += "with " + utils::num2str(inNumCols) + " columns";
3919  }
3920 
3921  if (inNumCols < 0)
3922  {
3923  if (size_ % inNumRows == 0)
3924  {
3925  return reshape(inNumRows, size_ / inNumRows);
3926  }
3927 
3928  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into a shape ";
3929  errStr += "with " + utils::num2str(inNumRows) + " rows";
3931  }
3932 
3933  if (static_cast<uint32>(inNumRows * inNumCols) != size_)
3934  {
3935  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into shape ";
3936  errStr += "[" + utils::num2str(inNumRows) + ", " + utils::num2str(inNumCols) + "]";
3938  }
3939 
3940  shape_.rows = static_cast<uint32>(inNumRows);
3941  shape_.cols = static_cast<uint32>(inNumCols);
3942 
3943  return *this;
3944  }
3945 
3946  //============================================================================
3947  // Method Description:
3957  NdArray<dtype>& reshape(const Shape& inShape)
3958  {
3959  return reshape(inShape.rows, inShape.cols);
3960  }
3961 
3962  //============================================================================
3963  // Method Description:
3972  NdArray<dtype>& resizeFast(uint32 inNumRows, uint32 inNumCols)
3973  {
3974  newArray(Shape(inNumRows, inNumCols));
3975  return *this;
3976  }
3977 
3978  //============================================================================
3979  // Method Description:
3988  {
3989  return resizeFast(inShape.rows, inShape.cols);
3990  }
3991 
3992  //============================================================================
3993  // Method Description:
4004  NdArray<dtype>& resizeSlow(uint32 inNumRows, uint32 inNumCols)
4005  {
4006  std::vector<dtype> oldData(size_);
4007  stl_algorithms::copy(begin(), end(), oldData.begin());
4008 
4009  const Shape inShape(inNumRows, inNumCols);
4010  const Shape oldShape = shape_;
4011 
4012  newArray(inShape);
4013 
4014  for (uint32 row = 0; row < inShape.rows; ++row)
4015  {
4016  for (uint32 col = 0; col < inShape.cols; ++col)
4017  {
4018  if (row >= oldShape.rows || col >= oldShape.cols)
4019  {
4020  operator()(row, col) = dtype{ 0 }; // zero fill
4021  }
4022  else
4023  {
4024  operator()(row, col) = oldData[row * oldShape.cols + col];
4025  }
4026  }
4027  }
4028 
4029  return *this;
4030  }
4031 
4032  //============================================================================
4033  // Method Description:
4044  {
4045  return resizeSlow(inShape.rows, inShape.cols);
4046  }
4047 
4048  //============================================================================
4049  // Method Description:
4058  NdArray<dtype> round(uint8 inNumDecimals = 0) const
4059  {
4060  STATIC_ASSERT_FLOAT(dtype);
4061 
4062  NdArray<dtype> returnArray(shape_);
4063  const double multFactor = utils::power(10., inNumDecimals);
4064  const auto function = [multFactor](dtype value) noexcept -> dtype
4065  { return static_cast<dtype>(std::nearbyint(static_cast<double>(value) * multFactor) / multFactor); };
4066 
4067  stl_algorithms::transform(cbegin(), cend(), returnArray.begin(), function);
4068 
4069  return returnArray;
4070  }
4071 
4072  //============================================================================
4073  // Method Description:
4080  {
4081  return NdArray<dtype>(cbegin(inRow), cend(inRow));
4082  }
4083 
4084  //============================================================================
4085  // Method Description:
4092  Shape shape() const noexcept
4093  {
4094  return shape_;
4095  }
4096 
4097  //============================================================================
4098  // Method Description:
4105  size_type size() const noexcept
4106  {
4107  return size_;
4108  }
4109 
4110  //============================================================================
4111  // Method Description:
4120  {
4122 
4123  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool { return lhs < rhs; };
4124 
4125  switch (inAxis)
4126  {
4127  case Axis::NONE:
4128  {
4129  stl_algorithms::sort(begin(), end(), comparitor);
4130  break;
4131  }
4132  case Axis::COL:
4133  {
4134  for (uint32 row = 0; row < shape_.rows; ++row)
4135  {
4136  stl_algorithms::sort(begin(row), end(row), comparitor);
4137  }
4138  break;
4139  }
4140  case Axis::ROW:
4141  {
4142  NdArray<dtype> transposedArray = transpose();
4143  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
4144  {
4145  stl_algorithms::sort(transposedArray.begin(row), transposedArray.end(row), comparitor);
4146  }
4147 
4148  *this = transposedArray.transpose();
4149  break;
4150  }
4151  }
4152 
4153  return *this;
4154  }
4155 
4156  //============================================================================
4157  // Method Description:
4162  std::string str() const
4163  {
4165 
4166  std::string out;
4167  out += "[";
4168  for (uint32 row = 0; row < shape_.rows; ++row)
4169  {
4170  out += "[";
4171  for (uint32 col = 0; col < shape_.cols; ++col)
4172  {
4173  out += utils::value2str(operator()(row, col)) + ", ";
4174  }
4175 
4176  if (row == shape_.rows - 1)
4177  {
4178  out += "]";
4179  }
4180  else
4181  {
4182  out += "]\n";
4183  }
4184  }
4185  out += "]\n";
4186  return out;
4187  }
4188 
4189  //============================================================================
4190  // Method Description:
4199  {
4201 
4202  switch (inAxis)
4203  {
4204  case Axis::NONE:
4205  {
4206  NdArray<dtype> returnArray = { std::accumulate(cbegin(), cend(), dtype{ 0 }) };
4207  return returnArray;
4208  }
4209  case Axis::COL:
4210  {
4211  NdArray<dtype> returnArray(1, shape_.rows);
4212  for (uint32 row = 0; row < shape_.rows; ++row)
4213  {
4214  returnArray(0, row) = std::accumulate(cbegin(row), cend(row), dtype{ 0 });
4215  }
4216 
4217  return returnArray;
4218  }
4219  case Axis::ROW:
4220  {
4221  return transpose().sum(Axis::COL);
4222  }
4223  default:
4224  {
4225  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
4226  return {}; // get rid of compiler warning
4227  }
4228  }
4229  }
4230 
4231  //============================================================================
4232  // Method Description:
4240  {
4241  return transpose();
4242  }
4243 
4244  //============================================================================
4245  // Method Description:
4251  void swapCols(int32 colIdx1, int32 colIdx2) noexcept
4252  {
4253  for (int32 row = 0; row < static_cast<int32>(shape_.rows); ++row)
4254  {
4255  std::swap(operator()(row, colIdx1), operator()(row, colIdx2));
4256  }
4257  }
4258 
4259  //============================================================================
4260  // Method Description:
4266  void swapRows(int32 rowIdx1, int32 rowIdx2) noexcept
4267  {
4268  for (int32 col = 0; col < static_cast<int32>(shape_.cols); ++col)
4269  {
4270  std::swap(operator()(rowIdx1, col), operator()(rowIdx2, col));
4271  }
4272  }
4273 
4274  //============================================================================
4275  // Method Description:
4285  void tofile(const std::string& inFilename) const
4286  {
4287  dump(inFilename);
4288  }
4289 
4290  //============================================================================
4291  // Method Description:
4302  void tofile(const std::string& inFilename, const char inSep) const
4303  {
4305 
4306  filesystem::File f(inFilename);
4307  if (!f.hasExt())
4308  {
4309  f.withExt("txt");
4310  }
4311 
4312  std::ofstream ofile(f.fullName().c_str());
4313  if (!ofile.good())
4314  {
4315  THROW_RUNTIME_ERROR("Input file could not be opened:\n\t" + inFilename);
4316  }
4317 
4318  uint32 counter = 0;
4319  for (auto value : *this)
4320  {
4321  ofile << value;
4322  if (counter++ != size_ - 1)
4323  {
4324  ofile << inSep;
4325  }
4326  }
4327  ofile.close();
4328  }
4329 
4330  //============================================================================
4331  // Method Description:
4339  NdArray<uint32> toIndices(Slice inSlice, Axis inAxis = Axis::ROW) const
4340  {
4341  uint32 numElements = 0;
4342  switch (inAxis)
4343  {
4344  case Axis::NONE:
4345  {
4346  numElements = inSlice.numElements(size_);
4347  break;
4348  }
4349  case Axis::ROW:
4350  {
4351  numElements = inSlice.numElements(shape_.rows);
4352  break;
4353  }
4354  case Axis::COL:
4355  {
4356  numElements = inSlice.numElements(shape_.cols);
4357  break;
4358  }
4359  default:
4360  {
4361  // not actually possible, getting rid of compiler warning
4362  THROW_INVALID_ARGUMENT_ERROR("Invalid 'inAxis' option");
4363  }
4364  }
4365 
4366  if (numElements == 0)
4367  {
4368  return {};
4369  }
4370 
4371  NdArray<uint32> indices(1, numElements);
4372  indices[0] = inSlice.start;
4373  for (uint32 i = 1; i < indices.size(); ++i)
4374  {
4375  indices[i] = static_cast<uint32>(indices[i - 1] + inSlice.step);
4376  }
4377 
4378  return indices;
4379  }
4380 
4381  //============================================================================
4382  // Method Description:
4387  std::vector<dtype> toStlVector() const
4388  {
4389  return std::vector<dtype>(cbegin(), cend());
4390  }
4391 
4392  //============================================================================
4393  // Method Description:
4404  value_type trace(uint32 inOffset = 0, Axis inAxis = Axis::ROW) const noexcept
4405  {
4407 
4408  uint32 rowStart = 0;
4409  uint32 colStart = 0;
4410  switch (inAxis)
4411  {
4412  case Axis::ROW:
4413  {
4414  rowStart += inOffset;
4415  break;
4416  }
4417  case Axis::COL:
4418  {
4419  colStart += inOffset;
4420  break;
4421  }
4422  default:
4423  {
4424  // if the user input NONE, override back to ROW
4425  inAxis = Axis::ROW;
4426  break;
4427  }
4428  }
4429 
4430  if (rowStart >= shape_.rows || colStart >= shape_.cols)
4431  {
4432  return dtype{ 0 };
4433  }
4434 
4435  uint32 col = colStart;
4436  dtype sum = 0;
4437  for (uint32 row = rowStart; row < shape_.rows; ++row)
4438  {
4439  if (col >= shape_.cols)
4440  {
4441  break;
4442  }
4443  sum += operator()(row, col++);
4444  }
4445 
4446  return sum;
4447  }
4448 
4449  //============================================================================
4450  // Method Description:
4458  {
4459  NdArray<dtype> transArray(shape_.cols, shape_.rows);
4460  for (uint32 row = 0; row < shape_.rows; ++row)
4461  {
4462  for (uint32 col = 0; col < shape_.cols; ++col)
4463  {
4464  transArray(col, row) = operator()(row, col);
4465  }
4466  }
4467  return transArray;
4468  }
4469 
4470  //============================================================================
4471  // Method Description:
4475  NdArray<dtype>& zeros() noexcept
4476  {
4478 
4479  fill(dtype{ 0 });
4480  return *this;
4481  }
4482 
4483  private:
4484  //====================================Attributes==============================
4485  allocator_type allocator_{};
4486  Shape shape_{ 0, 0 };
4487  size_type size_{ 0 };
4488  Endian endianess_{ Endian::NATIVE };
4489  pointer array_{ nullptr };
4490  bool ownsPtr_{ false };
4491 
4492  //============================================================================
4493  // Method Description:
4496  void deleteArray() noexcept
4497  {
4498  if (ownsPtr_ && array_ != nullptr)
4499  {
4500  allocator_.deallocate(array_, size_);
4501  }
4502 
4503  array_ = nullptr;
4504  shape_.rows = shape_.cols = 0;
4505  size_ = 0;
4506  ownsPtr_ = false;
4507  endianess_ = Endian::NATIVE;
4508  }
4509 
4510  //============================================================================
4511  // Method Description:
4514  void newArray()
4515  {
4516  if (size_ > 0)
4517  {
4518  array_ = allocator_.allocate(size_);
4519  ownsPtr_ = true;
4520  }
4521  }
4522 
4523  //============================================================================
4524  // Method Description:
4529  void newArray(const Shape& inShape)
4530  {
4531  deleteArray();
4532 
4533  shape_ = inShape;
4534  size_ = inShape.size();
4535  newArray();
4536  }
4537  };
4538 
4539  // NOTE: this needs to be defined outside of the class to get rid of a compiler
4540  // error in Visual Studio
4541  template<typename dtype, class _Alloc>
4542  std::pair<NdArray<uint32>, NdArray<uint32>> NdArray<dtype, _Alloc>::nonzero() const
4543  {
4545 
4546  std::vector<uint32> rowIndices;
4547  std::vector<uint32> colIndices;
4548 
4549  for (uint32 row = 0; row < shape_.rows; ++row)
4550  {
4551  for (uint32 col = 0; col < shape_.cols; ++col)
4552  {
4553  if (operator()(row, col) != dtype{ 0 })
4554  {
4555  rowIndices.push_back(row);
4556  colIndices.push_back(col);
4557  }
4558  }
4559  }
4560 
4561  return std::make_pair(NdArray<uint32>(rowIndices), NdArray<uint32>(colIndices));
4562  }
4563 } // namespace nc
#define THROW_RUNTIME_ERROR(msg)
Definition: Error.hpp:38
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
#define STATIC_ASSERT_FLOAT(dtype)
Definition: StaticAsserts.hpp:45
#define STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype)
Definition: StaticAsserts.hpp:49
#define STATIC_ASSERT_INTEGER(dtype)
Definition: StaticAsserts.hpp:40
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:37
Custom column iterator for NdArray.
Definition: NdArrayIterators.hpp:818
Custom column const_iterator for NdArray.
Definition: NdArrayIterators.hpp:492
Custom const_iterator for NdArray.
Definition: NdArrayIterators.hpp:42
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:72
uint32 numCols() const noexcept
Definition: NdArrayCore.hpp:3252
NdArray(std::vector< std::array< dtype, Dim1Size >> &in2dArray, bool copy=true)
Definition: NdArrayCore.hpp:323
const_reverse_column_iterator rcolbegin() const noexcept
Definition: NdArrayCore.hpp:1429
NdArray< dtype > at(const NdArray< int32 > &rowIndices, const NdArray< int32 > &colIndices) const
Definition: NdArrayCore.hpp:1159
NdArray< dtypeOut > astype() const
Definition: NdArrayCore.hpp:2037
NdArray< dtype > & put(int32 inIndex, value_type inValue)
Definition: NdArrayCore.hpp:3479
size_type size() const noexcept
Definition: NdArrayCore.hpp:4105
reverse_iterator rbegin() noexcept
Definition: NdArrayCore.hpp:1325
NdArray< dtype > & resizeSlow(uint32 inNumRows, uint32 inNumCols)
Definition: NdArrayCore.hpp:4004
NdArray< dtype > & put(const Slice &inRowSlice, const Slice &inColSlice, value_type inValue)
Definition: NdArrayCore.hpp:3602
NdArray< bool > issorted(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2756
const_iterator cbegin() const noexcept
Definition: NdArrayCore.hpp:1221
NdArray< dtype > operator[](const Indices &inIndices) const
Definition: NdArrayCore.hpp:761
const_reference at(int32 inIndex) const
Definition: NdArrayCore.hpp:1016
const_column_iterator ccolbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1310
NdArrayConstColumnIterator< dtype, size_type, const_pointer, difference_type > const_column_iterator
Definition: NdArrayCore.hpp:97
NdArray< dtype > round(uint8 inNumDecimals=0) const
Definition: NdArrayCore.hpp:4058
NdArray< bool > any(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1835
const_pointer data() const noexcept
Definition: NdArrayCore.hpp:2441
NdArray< uint32 > toIndices(Slice inSlice, Axis inAxis=Axis::ROW) const
Definition: NdArrayCore.hpp:4339
NdArray< dtype > at(const Slice &inRowSlice, int32 inColIndex) const
Definition: NdArrayCore.hpp:1129
iterator end() noexcept
Definition: NdArrayCore.hpp:1479
NdArray< dtype > operator()(Slice inRowSlice, int32 inColIndex) const
Definition: NdArrayCore.hpp:815
NdArray< dtype > & put(const Slice &inRowSlice, const Slice &inColSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3680
NdArray(std::vector< dtype > &inVector, bool copy=true)
Definition: NdArrayCore.hpp:263
NdArray< dtype > prod(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3389
NdArray< dtype > copy() const
Definition: NdArrayCore.hpp:2317
NdArray< dtype > & resizeFast(const Shape &inShape)
Definition: NdArrayCore.hpp:3987
std::vector< dtype > toStlVector() const
Definition: NdArrayCore.hpp:4387
reference back(size_type row)
Definition: NdArrayCore.hpp:2171
iterator end(size_type inRow)
Definition: NdArrayCore.hpp:1491
NdArray< dtype > flatten() const
Definition: NdArrayCore.hpp:2648
NdArray(const std::initializer_list< std::initializer_list< dtype >> &inList)
Definition: NdArrayCore.hpp:170
void tofile(const std::string &inFilename, const char inSep) const
Definition: NdArrayCore.hpp:4302
const_column_iterator ccolbegin() const noexcept
Definition: NdArrayCore.hpp:1298
typename AllocTraits::pointer pointer
Definition: NdArrayCore.hpp:84
Slice cSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:969
reverse_iterator rbegin(size_type inRow)
Definition: NdArrayCore.hpp:1337
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4092
NdArray< dtype > & byteswap() noexcept
Definition: NdArrayCore.hpp:2184
const_reverse_column_iterator rcolend() const noexcept
Definition: NdArrayCore.hpp:1737
uint32 numRows() const noexcept
Definition: NdArrayCore.hpp:3264
const dtype & const_reference
Definition: NdArrayCore.hpp:87
NdArray< dtype > & put(const Slice &inRowSlice, int32 inColIndex, value_type inValue)
Definition: NdArrayCore.hpp:3632
NdArray< dtype > & partition(uint32 inKth, Axis inAxis=Axis::NONE)
Definition: NdArrayCore.hpp:3308
bool issquare() const noexcept
Definition: NdArrayCore.hpp:2796
NdArrayIterator< dtype, pointer, difference_type > iterator
Definition: NdArrayCore.hpp:91
bool isflat() const noexcept
Definition: NdArrayCore.hpp:2744
Endian endianess() const noexcept
Definition: NdArrayCore.hpp:2593
void tofile(const std::string &inFilename) const
Definition: NdArrayCore.hpp:4285
const_reverse_column_iterator crcolbegin() const noexcept
Definition: NdArrayCore.hpp:1452
const_reverse_column_iterator crcolend(size_type inCol) const
Definition: NdArrayCore.hpp:1772
column_iterator colbegin(size_type inCol)
Definition: NdArrayCore.hpp:1260
NdArrayColumnIterator< dtype, size_type, pointer, difference_type > column_iterator
Definition: NdArrayCore.hpp:96
NdArray< bool > none(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3198
NdArray< dtype > at(const Slice &inSlice) const
Definition: NdArrayCore.hpp:1099
reference at(int32 inIndex)
Definition: NdArrayCore.hpp:995
NdArray< dtype > & sort(Axis inAxis=Axis::NONE)
Definition: NdArrayCore.hpp:4119
pointer data() noexcept
Definition: NdArrayCore.hpp:2431
bool isempty() const noexcept
Definition: NdArrayCore.hpp:2732
column_iterator colbegin() noexcept
Definition: NdArrayCore.hpp:1248
const_reference front(size_type row) const
Definition: NdArrayCore.hpp:2683
reverse_column_iterator rcolend(size_type inCol)
Definition: NdArrayCore.hpp:1722
NdArray< dtype > sum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:4198
NdArray(Iterator inFirst, Iterator inLast)
Definition: NdArrayCore.hpp:419
NdArray< dtype > operator[](const Slice &inSlice) const
Definition: NdArrayCore.hpp:713
reverse_column_iterator rcolbegin() noexcept
Definition: NdArrayCore.hpp:1402
NdArrayConstIterator< dtype, const_pointer, difference_type > const_iterator
Definition: NdArrayCore.hpp:92
const_iterator cbegin(size_type inRow) const
Definition: NdArrayCore.hpp:1233
const_column_iterator ccolend(size_type inCol) const
Definition: NdArrayCore.hpp:1695
NdArray< dtype > cumsum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2383
NdArray< dtype > median(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2918
NdArray< dtype > getByMask(const NdArray< bool > &inMask) const
Definition: NdArrayCore.hpp:2720
const_iterator cend(size_type inRow) const
Definition: NdArrayCore.hpp:1541
NdArray< dtype > column(uint32 inColumn)
Definition: NdArrayCore.hpp:2263
const_reverse_column_iterator rcolend(size_type inCol) const
Definition: NdArrayCore.hpp:1749
NdArray< dtype > & putMask(const NdArray< bool > &inMask, value_type inValue)
Definition: NdArrayCore.hpp:3758
const_iterator end(size_type inRow) const
Definition: NdArrayCore.hpp:1518
reference back() noexcept
Definition: NdArrayCore.hpp:2149
const_reverse_column_iterator crcolend() const noexcept
Definition: NdArrayCore.hpp:1760
const_reference back(size_type row) const
Definition: NdArrayCore.hpp:2160
reverse_column_iterator rcolbegin(size_type inCol)
Definition: NdArrayCore.hpp:1414
NdArray(const std::deque< std::deque< dtype >> &in2dDeque)
Definition: NdArrayCore.hpp:367
NdArray< dtype > & put(int32 inRow, int32 inCol, value_type inValue)
Definition: NdArrayCore.hpp:3496
iterator begin(size_type inRow)
Definition: NdArrayCore.hpp:1183
const_reverse_iterator rend() const noexcept
Definition: NdArrayCore.hpp:1583
NdArray< dtype > clip(value_type inMin, value_type inMax) const
Definition: NdArrayCore.hpp:2224
const_reverse_column_iterator rcolbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1441
NdArray< dtype > & operator=(NdArray< dtype > &&rhs) noexcept
Definition: NdArrayCore.hpp:606
typename AllocTraits::difference_type difference_type
Definition: NdArrayCore.hpp:89
NdArray< uint32 > argmin(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1927
const_iterator end() const noexcept
Definition: NdArrayCore.hpp:1506
bool ownsInternalData() noexcept
Definition: NdArrayCore.hpp:3288
NdArray< dtype > & fill(value_type inFillValue) noexcept
Definition: NdArrayCore.hpp:2609
column_iterator colend() noexcept
Definition: NdArrayCore.hpp:1633
NdArray(std::initializer_list< dtype > inList)
Definition: NdArrayCore.hpp:153
NdArray< dtype > operator()(Slice inRowSlice, Slice inColSlice) const
Definition: NdArrayCore.hpp:787
NdArray< dtype > & put(const NdArray< uint32 > &inIndices, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3531
const_reference back() const noexcept
Definition: NdArrayCore.hpp:2138
NdArray< dtype > operator()(int32 inRowIndex, Slice inColSlice) const
Definition: NdArrayCore.hpp:837
std::pair< NdArray< uint32 >, NdArray< uint32 > > nonzero() const
Definition: NdArrayCore.hpp:4542
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: NdArrayCore.hpp:94
NdArray(const_pointer inPtr, UIntType1 numRows, UIntType2 numCols)
Definition: NdArrayCore.hpp:462
NdArray< dtype > cumprod(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2331
uint64 nbytes() const noexcept
Definition: NdArrayCore.hpp:3020
const_reference at(int32 inRowIndex, int32 inColIndex) const
Definition: NdArrayCore.hpp:1069
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4457
NdArray< dtype > swapaxes() const
Definition: NdArrayCore.hpp:4239
NdArray< dtype > & put(int32 inRowIndex, const Slice &inColSlice, value_type inValue)
Definition: NdArrayCore.hpp:3656
NdArray(const std::list< dtype > &inList)
Definition: NdArrayCore.hpp:399
NdArray()=default
NdArray< dtype > at(int32 inRowIndex, const Slice &inColSlice) const
Definition: NdArrayCore.hpp:1144
const_reference front() const noexcept
Definition: NdArrayCore.hpp:2661
NdArray< dtype > repeat(const Shape &inRepeatShape) const
Definition: NdArrayCore.hpp:3850
~NdArray() noexcept
Definition: NdArrayCore.hpp:553
NdArray< dtype > min(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2872
NdArray< dtype > & reshape(const Shape &inShape)
Definition: NdArrayCore.hpp:3957
reference front() noexcept
Definition: NdArrayCore.hpp:2672
NdArray(size_type inNumRows, size_type inNumCols)
Definition: NdArrayCore.hpp:127
Allocator allocator_type
Definition: NdArrayCore.hpp:83
void print() const
Definition: NdArrayCore.hpp:3373
void swapCols(int32 colIdx1, int32 colIdx2) noexcept
Definition: NdArrayCore.hpp:4251
const_reverse_column_iterator crcolbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1464
reverse_iterator rend(size_type inRow)
Definition: NdArrayCore.hpp:1568
NdArray< uint32 > flatnonzero() const
Definition: NdArrayCore.hpp:2622
NdArray(size_type inSquareSize)
Definition: NdArrayCore.hpp:113
NdArray< dtype > operator()(int32 rowIndex, const Indices &colIndices) const
Definition: NdArrayCore.hpp:894
reverse_iterator rend() noexcept
Definition: NdArrayCore.hpp:1556
const_reverse_iterator rend(size_type inRow) const
Definition: NdArrayCore.hpp:1595
NdArray< dtype > getByIndices(const NdArray< uint32 > &inIndices) const
Definition: NdArrayCore.hpp:2706
typename AllocTraits::const_pointer const_pointer
Definition: NdArrayCore.hpp:85
NdArray< dtype > & resizeSlow(const Shape &inShape)
Definition: NdArrayCore.hpp:4043
const_reverse_iterator crbegin() const noexcept
Definition: NdArrayCore.hpp:1375
const_column_iterator colend(size_type inCol) const
Definition: NdArrayCore.hpp:1672
std::reverse_iterator< iterator > reverse_iterator
Definition: NdArrayCore.hpp:93
NdArray< dtype > operator()(const Indices &rowIndices, Slice colSlice) const
Definition: NdArrayCore.hpp:878
NdArray(const std::vector< std::vector< dtype >> &in2dVector)
Definition: NdArrayCore.hpp:288
const_reverse_iterator rbegin(size_type inRow) const
Definition: NdArrayCore.hpp:1364
const_iterator cend() const noexcept
Definition: NdArrayCore.hpp:1529
std::string str() const
Definition: NdArrayCore.hpp:4162
std::reverse_iterator< const_column_iterator > const_reverse_column_iterator
Definition: NdArrayCore.hpp:99
reference operator[](int32 inIndex) noexcept
Definition: NdArrayCore.hpp:632
NdArray< dtype > & reshape(int32 inNumRows, int32 inNumCols)
Definition: NdArrayCore.hpp:3907
NdArray(NdArray< dtype > &&inOtherArray) noexcept
Definition: NdArrayCore.hpp:536
NdArray< dtype > & nans() noexcept
Definition: NdArrayCore.hpp:3003
NdArray< dtype > & put(const NdArray< uint32 > &inIndices, value_type inValue)
Definition: NdArrayCore.hpp:3512
NdArray< dtype > ptp(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3433
const_reference operator()(int32 inRowIndex, int32 inColIndex) const noexcept
Definition: NdArrayCore.hpp:690
reference front(size_type row)
Definition: NdArrayCore.hpp:2694
NdArray< dtype > diagonal(int32 inOffset=0, Axis inAxis=Axis::ROW) const
Definition: NdArrayCore.hpp:2470
NdArray(pointer inPtr, uint32 numRows, uint32 numCols, BoolType takeOwnership) noexcept
Definition: NdArrayCore.hpp:504
NdArray< dtype > & putMask(const NdArray< bool > &inMask, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3775
NdArray< dtype > operator[](const NdArray< bool > &inMask) const
Definition: NdArrayCore.hpp:734
NdArray< dtype > row(uint32 inRow)
Definition: NdArrayCore.hpp:4079
NdArray< dtype > operator()(const Indices &rowIndices, int32 colIndex) const
Definition: NdArrayCore.hpp:861
const_iterator begin(size_type inRow) const
Definition: NdArrayCore.hpp:1210
iterator begin() noexcept
Definition: NdArrayCore.hpp:1171
NdArray< dtype > & put(const Slice &inSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3578
const_column_iterator colbegin() const noexcept
Definition: NdArrayCore.hpp:1275
NdArray< dtype > max(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2828
std::reverse_iterator< column_iterator > reverse_column_iterator
Definition: NdArrayCore.hpp:98
void swapRows(int32 rowIdx1, int32 rowIdx2) noexcept
Definition: NdArrayCore.hpp:4266
NdArray< dtype > & operator=(const NdArray< dtype > &rhs)
Definition: NdArrayCore.hpp:565
value_type item() const
Definition: NdArrayCore.hpp:2809
reference operator()(int32 inRowIndex, int32 inColIndex) noexcept
Definition: NdArrayCore.hpp:667
const_column_iterator colend() const noexcept
Definition: NdArrayCore.hpp:1660
NdArray< dtype > & resizeFast(uint32 inNumRows, uint32 inNumCols)
Definition: NdArrayCore.hpp:3972
const_reverse_iterator crend() const noexcept
Definition: NdArrayCore.hpp:1606
NdArray< dtype > & ones() noexcept
Definition: NdArrayCore.hpp:3274
NdArray< dtype > operator()(RowIndices rowIndices, ColIndices colIndices) const
Definition: NdArrayCore.hpp:929
NdArray< dtype > & zeros() noexcept
Definition: NdArrayCore.hpp:4475
const_column_iterator colbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1287
NdArray< dtype > dot(const NdArray< dtype > &inOtherArray) const
Definition: NdArrayCore.hpp:2520
NdArray< dtype > repeat(uint32 inNumRows, uint32 inNumCols) const
Definition: NdArrayCore.hpp:3809
NdArray< dtype > & reshape(size_type inSize)
Definition: NdArrayCore.hpp:3880
NdArray< bool > contains(value_type inValue, Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2276
const_column_iterator ccolend() const noexcept
Definition: NdArrayCore.hpp:1683
NdArray< uint32 > argmax(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1880
value_type trace(uint32 inOffset=0, Axis inAxis=Axis::ROW) const noexcept
Definition: NdArrayCore.hpp:4404
reverse_column_iterator rcolend() noexcept
Definition: NdArrayCore.hpp:1710
NdArray(std::array< dtype, ArraySize > &inArray, bool copy=true)
Definition: NdArrayCore.hpp:206
NdArray< dtype > & put(int32 inRowIndex, const Slice &inColSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3736
const_reverse_iterator rbegin() const noexcept
Definition: NdArrayCore.hpp:1352
NdArray(const_pointer inPtr, size_type size)
Definition: NdArrayCore.hpp:438
NdArray(const std::deque< dtype > &inDeque)
Definition: NdArrayCore.hpp:350
NdArray(std::array< std::array< dtype, Dim1Size >, Dim0Size > &in2dArray, bool copy=true)
Definition: NdArrayCore.hpp:234
void dump(const std::string &inFilename) const
Definition: NdArrayCore.hpp:2566
dtype & reference
Definition: NdArrayCore.hpp:86
pointer dataRelease() noexcept
Definition: NdArrayCore.hpp:2453
reference at(int32 inRowIndex, int32 inColIndex)
Definition: NdArrayCore.hpp:1038
NdArray< dtype > at(const Slice &inRowSlice, const Slice &inColSlice) const
Definition: NdArrayCore.hpp:1114
NdArray< dtype > operator()(Slice rowSlice, const Indices &colIndices) const
Definition: NdArrayCore.hpp:911
NdArray(const NdArray< dtype > &inOtherArray)
Definition: NdArrayCore.hpp:518
NdArray< uint32 > argsort(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1973
uint32 size_type
Definition: NdArrayCore.hpp:88
const_iterator begin() const noexcept
Definition: NdArrayCore.hpp:1198
NdArray< dtype > & operator=(value_type inValue) noexcept
Definition: NdArrayCore.hpp:589
NdArray< dtype > newbyteorder(Endian inEndianess) const
Definition: NdArrayCore.hpp:3035
column_iterator colend(size_type inCol)
Definition: NdArrayCore.hpp:1645
NdArray< dtype > & put(const Slice &inSlice, value_type inValue)
Definition: NdArrayCore.hpp:3556
const_reference operator[](int32 inIndex) const noexcept
Definition: NdArrayCore.hpp:649
NdArray< dtype > & ravel() noexcept
Definition: NdArrayCore.hpp:3793
dtype value_type
Definition: NdArrayCore.hpp:82
void replace(value_type oldValue, value_type newValue)
Definition: NdArrayCore.hpp:3862
NdArray< dtype > & put(const Slice &inRowSlice, int32 inColIndex, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3711
Slice rSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:983
const_reverse_iterator crend(size_type inRow) const
Definition: NdArrayCore.hpp:1618
const_reverse_iterator crbegin(size_type inRow) const
Definition: NdArrayCore.hpp:1387
NdArray(pointer inPtr, size_type size, BoolType takeOwnership) noexcept
Definition: NdArrayCore.hpp:484
NdArray(const Shape &inShape)
Definition: NdArrayCore.hpp:140
NdArray< bool > all(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1791
Custom iterator for NdArray.
Definition: NdArrayIterators.hpp:318
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:41
uint32 rows
Definition: Core/Shape.hpp:44
uint32 cols
Definition: Core/Shape.hpp:45
uint32 size() const noexcept
Definition: Core/Shape.hpp:104
A Class for slicing into NdArrays.
Definition: Slice.hpp:44
int32 step
Definition: Slice.hpp:49
int32 start
Definition: Slice.hpp:47
void makePositiveAndValidate(uint32 inArraySize)
Definition: Slice.hpp:141
uint32 numElements(uint32 inArraySize)
Definition: Slice.hpp:196
int32 stop
Definition: Slice.hpp:48
Provides simple filesystem functions.
Definition: Filesystem.hpp:40
constexpr auto j
Definition: Constants.hpp:45
const double nan
NaN.
Definition: Constants.hpp:44
bool isLittleEndian() noexcept
Definition: Endian.hpp:44
dtype byteSwap(dtype value) noexcept
Definition: Endian.hpp:63
dtype f(GeneratorType &generator, dtype inDofN, dtype inDofD)
Definition: f.hpp:58
bool any_of(InputIt first, InputIt last, UnaryPredicate p) noexcept
Definition: StlAlgorithms.hpp:78
void sort(RandomIt first, RandomIt last) noexcept
Definition: StlAlgorithms.hpp:705
bool none_of(InputIt first, InputIt last, UnaryPredicate p) noexcept
Definition: StlAlgorithms.hpp:408
ForwardIt max_element(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:287
void stable_sort(RandomIt first, RandomIt last) noexcept
Definition: StlAlgorithms.hpp:743
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:784
bool all_of(InputIt first, InputIt last, UnaryPredicate p) noexcept
Definition: StlAlgorithms.hpp:57
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:227
InputIt find(InputIt first, InputIt last, const T &value) noexcept
Definition: StlAlgorithms.hpp:207
constexpr OutputIt unique_copy(InputIt first, InputIt last, OutputIt destination) noexcept
Definition: StlAlgorithms.hpp:835
std::pair< ForwardIt, ForwardIt > minmax_element(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:366
void replace(ForwardIt first, ForwardIt last, const T &oldValue, const T &newValue) noexcept
Definition: StlAlgorithms.hpp:471
bool is_sorted(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:247
OutputIt copy(InputIt first, InputIt last, OutputIt destination) noexcept
Definition: StlAlgorithms.hpp:99
void nth_element(RandomIt first, RandomIt nth, RandomIt last) noexcept
Definition: StlAlgorithms.hpp:428
ForwardIt min_element(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:326
void fill(ForwardIt first, ForwardIt last, const T &value) noexcept
Definition: StlAlgorithms.hpp:185
std::string num2str(dtype inNumber)
Definition: num2str.hpp:46
dtype power(dtype inValue, uint8 inPower) noexcept
Definition: Utils/power.hpp:48
std::string value2str(dtype inValue)
Definition: value2str.hpp:48
Definition: Coordinate.hpp:45
NdArray< dtype > repeat(const NdArray< dtype > &inArray, uint32 inNumRows, uint32 inNumCols)
Definition: repeat.hpp:49
void swap(NdArray< dtype > &inArray1, NdArray< dtype > &inArray2) noexcept
Definition: swap.hpp:42
std::pair< NdArray< uint32 >, NdArray< uint32 > > nonzero(const NdArray< dtype > &inArray)
Definition: nonzero.hpp:48
NdArray< dtype > & resizeFast(NdArray< dtype > &inArray, uint32 inNumRows, uint32 inNumCols)
Definition: resizeFast.hpp:50
Axis
Enum To describe an axis.
Definition: Types.hpp:47
NdArray< dtype > & reshape(NdArray< dtype > &inArray, uint32 inSize)
Definition: reshape.hpp:51
std::int64_t int64
Definition: Types.hpp:35
auto abs(dtype inValue) noexcept
Definition: abs.hpp:49
std::uint64_t uint64
Definition: Types.hpp:39
NdArray< dtype > & resizeSlow(NdArray< dtype > &inArray, uint32 inNumRows, uint32 inNumCols)
Definition: resizeSlow.hpp:52
Endian
Enum for endianess.
Definition: Types.hpp:56
std::int32_t int32
Definition: Types.hpp:36
std::uint8_t uint8
Definition: Types.hpp:42
NdArray< dtype > sum(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: sum.hpp:46
NdArray< dtype > & put(NdArray< dtype > &inArray, const NdArray< uint32 > &inIndices, dtype inValue)
Definition: put.hpp:48
NdArray< dtype > transpose(const NdArray< dtype > &inArray)
Definition: transpose.hpp:45
typename std::enable_if< B, T >::type enable_if_t
Definition: TypeTraits.hpp:40
std::uint32_t uint32
Definition: Types.hpp:40
void dump(const NdArray< dtype > &inArray, const std::string &inFilename)
Definition: dump.hpp:46