NumCpp  2.1.0
A C++ implementation of the Python Numpy library
NdArrayCore.hpp
Go to the documentation of this file.
1 #pragma once
30 
39 #include "NumCpp/Core/Shape.hpp"
40 #include "NumCpp/Core/Slice.hpp"
41 #include "NumCpp/Core/Types.hpp"
43 #include "NumCpp/Utils/num2str.hpp"
44 #include "NumCpp/Utils/power.hpp"
45 #include "NumCpp/Utils/sqr.hpp"
47 
48 #include <boost/algorithm/clamp.hpp>
49 #include <boost/endian/conversion.hpp>
50 #include <boost/predef/other/endian.h>
51 
52 #include <array>
53 #include <cmath>
54 #include <deque>
55 #include <forward_list>
56 #include <fstream>
57 #include <initializer_list>
58 #include <iostream>
59 #include <iterator>
60 #include <list>
61 #include <memory>
62 #include <numeric>
63 #include <set>
64 #include <string>
65 #include <type_traits>
66 #include <utility>
67 #include <vector>
68 
69 namespace nc
70 {
71  //================================================================================
72  // Class Description:
74  template<typename dtype, class Allocator = std::allocator<dtype>>
75  class NdArray
76  {
77  private:
78  STATIC_ASSERT_VALID_DTYPE(dtype);
79  static_assert(is_same_v<dtype, typename Allocator::value_type>, "value_type and Allocator::value_type must match");
80 
81  using AllocType = typename std::allocator_traits<Allocator>::template rebind_alloc<dtype>;
82  using AllocTraits = std::allocator_traits<AllocType>;
83 
84  public:
85  using value_type = dtype;
86  using allocator_type = Allocator;
87  using pointer = typename AllocTraits::pointer;
88  using const_pointer = typename AllocTraits::const_pointer;
89  using reference = dtype&;
90  using const_reference = const dtype&;
91  using size_type = uint32;
92  using difference_type = typename AllocTraits::difference_type;
93 
96  using reverse_iterator = std::reverse_iterator<iterator>;
97  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
98 
101  using reverse_column_iterator = std::reverse_iterator<column_iterator>;
102  using const_reverse_column_iterator = std::reverse_iterator<const_column_iterator>;
103 
104  //============================================================================
105  // Method Description:
108  NdArray() = default;
109 
110  //============================================================================
111  // Method Description:
117  explicit NdArray(size_type inSquareSize) :
118  shape_(inSquareSize, inSquareSize),
119  size_(inSquareSize * inSquareSize)
120  {
121  newArray();
122  }
123 
124  //============================================================================
125  // Method Description:
131  NdArray(size_type inNumRows, size_type inNumCols) :
132  shape_(inNumRows, inNumCols),
133  size_(inNumRows * inNumCols)
134  {
135  newArray();
136  }
137 
138  //============================================================================
139  // Method Description:
145  explicit NdArray(const Shape& inShape) :
146  shape_(inShape),
147  size_(shape_.size())
148  {
149  newArray();
150  }
151 
152  //============================================================================
153  // Method Description:
159  NdArray(const std::initializer_list<dtype>& inList) :
160  shape_(1, static_cast<uint32>(inList.size())),
161  size_(shape_.size())
162  {
163  newArray();
164  if (size_ > 0)
165  {
166  stl_algorithms::copy(inList.begin(), inList.end(), begin());
167  }
168  }
169 
170  //============================================================================
171  // Method Description:
177  NdArray(const std::initializer_list<std::initializer_list<dtype> >& inList) :
178  shape_(static_cast<uint32>(inList.size()), 0)
179  {
180  for (const auto& list : inList)
181  {
182  if (shape_.cols == 0)
183  {
184  shape_.cols = static_cast<uint32>(list.size());
185  }
186  else if (list.size() != shape_.cols)
187  {
188  THROW_INVALID_ARGUMENT_ERROR("All rows of the initializer list needs to have the same number of elements");
189  }
190  }
191 
192  size_ = shape_.size();
193  newArray();
194  uint32 row = 0;
195  for (const auto& list : inList)
196  {
197  const auto ptr = begin() += row * shape_.cols;
198  stl_algorithms::copy(list.begin(), list.end(), ptr);
199  ++row;
200  }
201  }
202 
203  //============================================================================
204  // Method Description:
211  template<size_t ArraySize,
212  std::enable_if_t<is_valid_dtype_v<dtype>, int> = 0>
213  NdArray(std::array<dtype, ArraySize>& inArray, bool copy = true) :
214  shape_(1, static_cast<uint32>(ArraySize)),
215  size_(shape_.size())
216  {
217  if (copy)
218  {
219  newArray();
220  if (size_ > 0)
221  {
222  stl_algorithms::copy(inArray.begin(), inArray.end(), begin());
223  }
224  }
225  else
226  {
227  array_ = inArray.data();
228  ownsPtr_ = false;
229  }
230  }
231 
232  //============================================================================
233  // Method Description:
240  template<size_t Dim0Size, size_t Dim1Size>
241  NdArray(std::array<std::array<dtype, Dim1Size>, Dim0Size>& in2dArray, bool copy = true) :
242  shape_(static_cast<uint32>(Dim0Size), static_cast<uint32>(Dim1Size)),
243  size_(shape_.size())
244  {
245  if (copy)
246  {
247  newArray();
248  if (size_ > 0)
249  {
250  const auto start = in2dArray.front().begin();
251  stl_algorithms::copy(start, start + size_, begin());
252  }
253  }
254  else
255  {
256  array_ = in2dArray.front().data();
257  ownsPtr_ = false;
258  }
259  }
260 
261  //============================================================================
262  // Method Description:
269  template<std::enable_if_t<is_valid_dtype_v<dtype>, int> = 0>
270  NdArray(std::vector<dtype>& inVector, bool copy = true) :
271  shape_(1, static_cast<uint32>(inVector.size())),
272  size_(shape_.size())
273  {
274  if (copy)
275  {
276  newArray();
277  if (size_ > 0)
278  {
279  stl_algorithms::copy(inVector.begin(), inVector.end(), begin());
280  }
281  }
282  else
283  {
284  array_ = inVector.data();
285  ownsPtr_ = false;
286  }
287  }
288 
289  //============================================================================
290  // Method Description:
295  explicit NdArray(const std::vector<std::vector<dtype>>& in2dVector) :
296  shape_(static_cast<uint32>(in2dVector.size()), 0)
297  {
298  for (const auto& row : in2dVector)
299  {
300  if (shape_.cols == 0)
301  {
302  shape_.cols = static_cast<uint32>(row.size());
303  }
304  else if (row.size() != shape_.cols)
305  {
306  THROW_INVALID_ARGUMENT_ERROR("All rows of the 2d vector need to have the same number of elements");
307  }
308  }
309 
310  size_ = shape_.size();
311 
312  newArray();
313  auto currentPosition = begin();
314  for (const auto& row : in2dVector)
315  {
316  stl_algorithms::copy(row.begin(), row.end(), currentPosition);
317  currentPosition += shape_.cols;
318  }
319  }
320 
321  //============================================================================
322  // Method Description:
329  template<size_t Dim1Size>
330  NdArray(std::vector<std::array<dtype, Dim1Size>>& in2dArray, bool copy = true) :
331  shape_(static_cast<uint32>(in2dArray.size()), static_cast<uint32>(Dim1Size)),
332  size_(shape_.size())
333  {
334  if (copy)
335  {
336  newArray();
337  if (size_ > 0)
338  {
339  const auto start = in2dArray.front().begin();
340  stl_algorithms::copy(start, start + size_, begin());
341  }
342  }
343  else
344  {
345  array_ = in2dArray.front().data();
346  ownsPtr_ = false;
347  }
348  }
349 
350  //============================================================================
351  // Method Description:
356  template<std::enable_if_t<is_valid_dtype_v<dtype>, int> = 0>
357  explicit NdArray(const std::deque<dtype>& inDeque) :
358  shape_(1, static_cast<uint32>(inDeque.size())),
359  size_(shape_.size())
360  {
361  newArray();
362  if (size_ > 0)
363  {
364  stl_algorithms::copy(inDeque.begin(), inDeque.end(), begin());
365  }
366  }
367 
368  //============================================================================
369  // Method Description:
374  explicit NdArray(const std::deque<std::deque<dtype>>& in2dDeque) :
375  shape_(static_cast<uint32>(in2dDeque.size()), 0)
376  {
377  for (const auto& row : in2dDeque)
378  {
379  if (shape_.cols == 0)
380  {
381  shape_.cols = static_cast<uint32>(row.size());
382  }
383  else if (row.size() != shape_.cols)
384  {
385  THROW_INVALID_ARGUMENT_ERROR("All rows of the 2d vector need to have the same number of elements");
386  }
387  }
388 
389  size_ = shape_.size();
390 
391  newArray();
392  auto currentPosition = begin();
393  for (const auto& row : in2dDeque)
394  {
395  stl_algorithms::copy(row.begin(), row.end(), currentPosition);
396  currentPosition += shape_.cols;
397  }
398  }
399 
400  //============================================================================
401  // Method Description:
407  explicit NdArray(const std::list<dtype>& inList) :
408  shape_(1, static_cast<uint32>(inList.size())),
409  size_(shape_.size())
410  {
411  newArray();
412  if (size_ > 0)
413  {
414  stl_algorithms::copy(inList.begin(), inList.end(), begin());
415  }
416  }
417 
418  //============================================================================
419  // Method Description:
425  template<typename Iterator,
426  std::enable_if_t<std::is_same<typename std::iterator_traits<Iterator>::value_type, dtype>::value, int> = 0>
427  NdArray(Iterator inFirst, Iterator inLast) :
428  shape_(1, static_cast<uint32>(std::distance(inFirst, inLast))),
429  size_(shape_.size())
430  {
431  newArray();
432  if (size_ > 0)
433  {
434  stl_algorithms::copy(inFirst, inLast, begin());
435  }
436  }
437 
438  //============================================================================
439  // Method Description:
447  shape_(1, size),
448  size_(size)
449  {
450  newArray();
451  if (inPtr != nullptr && size_ > 0)
452  {
453  stl_algorithms::copy(inPtr, inPtr + size_, begin());
454  }
455  }
456 
457  //============================================================================
458  // Method Description:
467  shape_(numRows, numCols),
468  size_(shape_.size())
469  {
470  newArray();
471  if (inPtr != nullptr && size_ > 0)
472  {
473  stl_algorithms::copy(inPtr, inPtr + size_, begin());
474  }
475  }
476 
477  //============================================================================
478  // Method Description:
487  template<typename Bool,
488  std::enable_if_t<std::is_same<Bool, bool>::value, int> = 0>
489  NdArray(pointer inPtr, size_type size, Bool takeOwnership) noexcept :
490  shape_(1, size),
491  size_(size),
492  array_(inPtr),
493  ownsPtr_(takeOwnership)
494  {}
495 
496  //============================================================================
497  // Method Description:
507  template<typename Bool,
508  std::enable_if_t<std::is_same<Bool, bool>::value, int> = 0>
509  NdArray(pointer inPtr, uint32 numRows, uint32 numCols, Bool takeOwnership) noexcept :
510  shape_(numRows, numCols),
511  size_(numRows * numCols),
512  array_(inPtr),
513  ownsPtr_(takeOwnership)
514  {}
515 
516  //============================================================================
517  // Method Description:
523  NdArray(const NdArray<dtype>& inOtherArray) :
524  shape_(inOtherArray.shape_),
525  size_(inOtherArray.size_),
526  endianess_(inOtherArray.endianess_)
527  {
528  newArray();
529  if (size_ > 0)
530  {
531  stl_algorithms::copy(inOtherArray.cbegin(), inOtherArray.cend(), begin());
532  }
533  }
534 
535  //============================================================================
536  // Method Description:
542  NdArray(NdArray<dtype>&& inOtherArray) noexcept :
543  shape_(inOtherArray.shape_),
544  size_(inOtherArray.size_),
545  endianess_(inOtherArray.endianess_),
546  array_(inOtherArray.array_),
547  ownsPtr_(inOtherArray.ownsPtr_)
548  {
549  inOtherArray.shape_.rows = inOtherArray.shape_.cols = 0;
550  inOtherArray.size_ = 0;
551  inOtherArray.ownsPtr_ = false;
552  inOtherArray.array_ = nullptr;
553  }
554 
555  //============================================================================
556  // Method Description:
559  ~NdArray() noexcept
560  {
561  deleteArray();
562  }
563 
564  //============================================================================
565  // Method Description:
574  {
575  if (&rhs != this)
576  {
577  if (rhs.size_ > 0)
578  {
579  newArray(rhs.shape_);
580  endianess_ = rhs.endianess_;
581 
582  stl_algorithms::copy(rhs.cbegin(), rhs.cend(), begin());
583  }
584  }
585 
586  return *this;
587  }
588 
589  //============================================================================
590  // Method Description:
600  {
601  if (array_ != nullptr)
602  {
603  stl_algorithms::fill(begin(), end(), inValue);
604  }
605 
606  return *this;
607  }
608 
609  //============================================================================
610  // Method Description:
619  {
620  if (&rhs != this)
621  {
622  deleteArray();
623  shape_ = rhs.shape_;
624  size_ = rhs.size_;
625  endianess_ = rhs.endianess_;
626  array_ = rhs.array_;
627  ownsPtr_ = rhs.ownsPtr_;
628 
629  rhs.shape_.rows = rhs.shape_.cols = rhs.size_ = 0;
630  rhs.array_ = nullptr;
631  rhs.ownsPtr_ = false;
632  }
633 
634  return *this;
635  }
636 
637  //============================================================================
638  // Method Description:
646  reference operator[](int32 inIndex) noexcept
647  {
648  if (inIndex < 0)
649  {
650  inIndex += size_;
651  }
652 
653  return array_[inIndex];
654  }
655 
656  //============================================================================
657  // Method Description:
665  const_reference operator[](int32 inIndex) const noexcept
666  {
667  if (inIndex < 0)
668  {
669  inIndex += size_;
670  }
671 
672  return array_[inIndex];
673  }
674 
675  //============================================================================
676  // Method Description:
684  reference operator()(int32 inRowIndex, int32 inColIndex) noexcept
685  {
686  if (inRowIndex < 0)
687  {
688  inRowIndex += shape_.rows;
689  }
690 
691  if (inColIndex < 0)
692  {
693  inColIndex += shape_.cols;
694  }
695 
696  return array_[inRowIndex * shape_.cols + inColIndex];
697  }
698 
699  //============================================================================
700  // Method Description:
708  const_reference operator()(int32 inRowIndex, int32 inColIndex) const noexcept
709  {
710  if (inRowIndex < 0)
711  {
712  inRowIndex += shape_.rows;
713  }
714 
715  if (inColIndex < 0)
716  {
717  inColIndex += shape_.cols;
718  }
719 
720  return array_[inRowIndex * shape_.cols + inColIndex];
721  }
722 
723  //============================================================================
724  // Method Description:
733  NdArray<dtype> operator[](const Slice& inSlice) const
734  {
735  Slice inSliceCopy(inSlice);
736 
737  uint32 counter = 0;
738  NdArray<dtype> returnArray(1, inSliceCopy.numElements(size_));
739  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
740  {
741  returnArray[counter++] = at(i);
742  }
743 
744  return returnArray;
745  }
746 
747  //============================================================================
748  // Method Description:
757  {
758  if (inMask.shape() != shape_)
759  {
760  THROW_INVALID_ARGUMENT_ERROR("input inMask must have the same shape as the NdArray it will be masking.");
761  }
762 
763  auto indices = inMask.flatnonzero();
764  auto outArray = NdArray<dtype>(1, indices.size());
765  for (size_type i = 0; i < indices.size(); ++i)
766  {
767  outArray[i] = operator[](indices[i]);
768  }
769 
770  return outArray;
771  }
772 
773  //============================================================================
774  // Method Description:
783  {
784  if (inIndices.max().item() > size_ - 1)
785  {
786  THROW_INVALID_ARGUMENT_ERROR("input indices must be less than the array size.");
787  }
788 
789  auto outArray = NdArray<dtype>(1, static_cast<size_type>(inIndices.size()));
790  size_type i = 0;
791  for (auto& index : inIndices)
792  {
793  outArray[i++] = operator[](index);
794  }
795 
796  return outArray;
797  }
798 
799  //============================================================================
800  // Method Description:
809  NdArray<dtype> operator()(const Slice& inRowSlice, const Slice& inColSlice) const
810  {
811  Slice inRowSliceCopy(inRowSlice);
812  Slice inColSliceCopy(inColSlice);
813 
814  NdArray<dtype> returnArray(inRowSliceCopy.numElements(shape_.rows), inColSliceCopy.numElements(shape_.cols));
815 
816  uint32 rowCounter = 0;
817  uint32 colCounter = 0;
818  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
819  {
820  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
821  {
822  returnArray(rowCounter, colCounter++) = at(row, col);
823  }
824  colCounter = 0;
825  ++rowCounter;
826  }
827 
828  return returnArray;
829  }
830 
831  //============================================================================
832  // Method Description:
841  NdArray<dtype> operator()(const Slice& inRowSlice, int32 inColIndex) const
842  {
843  Slice inRowSliceCopy(inRowSlice);
844 
845  NdArray<dtype> returnArray(inRowSliceCopy.numElements(shape_.rows), 1);
846 
847  uint32 rowCounter = 0;
848  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
849  {
850  returnArray(rowCounter++, 0) = at(row, inColIndex);
851  }
852 
853  return returnArray;
854  }
855 
856  //============================================================================
857  // Method Description:
866  NdArray<dtype> operator()(int32 inRowIndex, const Slice& inColSlice) const
867  {
868  Slice inColSliceCopy(inColSlice);
869 
870  NdArray<dtype> returnArray(1, inColSliceCopy.numElements(shape_.cols));
871 
872  uint32 colCounter = 0;
873  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
874  {
875  returnArray(0, colCounter++) = at(inRowIndex, col);
876  }
877 
878  return returnArray;
879  }
880 
881  //============================================================================
882  // Method Description:
891  Slice cSlice(int32 inStartIdx = 0, uint32 inStepSize = 1) const noexcept
892  {
893  return Slice(inStartIdx, shape_.cols, inStepSize);
894  }
895 
896  //============================================================================
897  // Method Description:
906  Slice rSlice(int32 inStartIdx = 0, uint32 inStepSize = 1) const noexcept
907  {
908  return Slice(inStartIdx, shape_.rows, inStepSize);
909  }
910 
911  //============================================================================
912  // Method Description:
920  reference at(int32 inIndex)
921  {
922  // this doesn't allow for calling the first element as -size_...
923  // but why would you really want to do that anyway?
924  if (std::abs(inIndex) > static_cast<int64>(size_ - 1))
925  {
926  std::string errStr = "Input index " + utils::num2str(inIndex);
927  errStr += " is out of bounds for array of size " + utils::num2str(size_) + ".";
929  }
930 
931  return operator[](inIndex);
932  }
933 
934  //============================================================================
935  // Method Description:
943  const_reference at(int32 inIndex) const
944  {
945  // this doesn't allow for calling the first element as -size_...
946  // but why would you really want to do that anyway?
947  if (std::abs(inIndex) > static_cast<int64>(size_ - 1))
948  {
949  std::string errStr = "Input index " + utils::num2str(inIndex);
950  errStr += " is out of bounds for array of size " + utils::num2str(size_) + ".";
952  }
953 
954  return operator[](inIndex);
955  }
956 
957  //============================================================================
958  // Method Description:
966  reference at(int32 inRowIndex, int32 inColIndex)
967  {
968  // this doesn't allow for calling the first element as -size_...
969  // but why would you really want to do that anyway?
970  if (std::abs(inRowIndex) > static_cast<int32>(shape_.rows - 1))
971  {
972  std::string errStr = "Row index " + utils::num2str(inRowIndex);
973  errStr += " is out of bounds for array of size " + utils::num2str(shape_.rows) + ".";
975  }
976 
977  // this doesn't allow for calling the first element as -size_...
978  // but why would you really want to that anyway?
979  if (std::abs(inColIndex) > static_cast<int32>(shape_.cols - 1))
980  {
981  std::string errStr = "Column index " + utils::num2str(inColIndex);
982  errStr += " is out of bounds for array of size " + utils::num2str(shape_.cols) + ".";
984  }
985 
986  return operator()(inRowIndex, inColIndex);
987  }
988 
989  //============================================================================
990  // Method Description:
998  const_reference at(int32 inRowIndex, int32 inColIndex) const
999  {
1000  // this doesn't allow for calling the first element as -size_...
1001  // but why would you really want to do that anyway?
1002  if (std::abs(inRowIndex) > static_cast<int32>(shape_.rows - 1))
1003  {
1004  std::string errStr = "Row index " + utils::num2str(inRowIndex);
1005  errStr += " is out of bounds for array of size " + utils::num2str(shape_.rows) + ".";
1007  }
1008 
1009  // this doesn't allow for calling the first element as -size_...
1010  // but why would you really want to do that anyway?
1011  if (std::abs(inColIndex) > static_cast<int32>(shape_.cols - 1))
1012  {
1013  std::string errStr = "Column index " + utils::num2str(inColIndex);
1014  errStr += " is out of bounds for array of size " + utils::num2str(shape_.cols) + ".";
1016  }
1017 
1018  return operator()(inRowIndex, inColIndex);
1019  }
1020 
1021  //============================================================================
1022  // Method Description:
1030  NdArray<dtype> at(const Slice& inSlice) const
1031  {
1032  // the slice operator already provides bounds checking. just including
1033  // the at method for completeness
1034  return operator[](inSlice);
1035  }
1036 
1037  //============================================================================
1038  // Method Description:
1046  NdArray<dtype> at(const Slice& inRowSlice, const Slice& inColSlice) const
1047  {
1048  // the slice operator already provides bounds checking. just including
1049  // the at method for completeness
1050  return operator()(inRowSlice, inColSlice);
1051  }
1052 
1053  //============================================================================
1054  // Method Description:
1062  NdArray<dtype> at(const Slice& inRowSlice, int32 inColIndex) const
1063  {
1064  // the slice operator already provides bounds checking. just including
1065  // the at method for completeness
1066  return operator()(inRowSlice, inColIndex);
1067  }
1068 
1069  //============================================================================
1070  // Method Description:
1078  NdArray<dtype> at(int32 inRowIndex, const Slice& inColSlice) const
1079  {
1080  // the slice operator already provides bounds checking. just including
1081  // the at method for completeness
1082  return operator()(inRowIndex, inColSlice);
1083  }
1084 
1085  //============================================================================
1086  // Method Description:
1091  iterator begin() noexcept
1092  {
1093  return iterator(array_);
1094  }
1095 
1096  //============================================================================
1097  // Method Description:
1106  {
1107  if (inRow >= shape_.rows)
1108  {
1109  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1110  }
1111 
1112  return begin() += (inRow * shape_.cols);
1113  }
1114 
1115  //============================================================================
1116  // Method Description:
1121  const_iterator begin() const noexcept
1122  {
1123  return cbegin();
1124  }
1125 
1126  //============================================================================
1127  // Method Description:
1136  {
1137  return cbegin(inRow);
1138  }
1139 
1140  //============================================================================
1141  // Method Description:
1147  const_iterator cbegin() const noexcept
1148  {
1149  return const_iterator(array_);
1150  }
1151 
1152  //============================================================================
1153  // Method Description:
1162  {
1163  if (inRow >= shape_.rows)
1164  {
1165  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1166  }
1167 
1168  return cbegin() += (inRow * shape_.cols);
1169  }
1170 
1171  //============================================================================
1172  // Method Description:
1178  {
1179  return column_iterator(array_, shape_.rows, shape_.cols);
1180  }
1181 
1182  //============================================================================
1183  // Method Description:
1192  {
1193  if (inCol >= shape_.cols)
1194  {
1195  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1196  }
1197 
1198  return colbegin() += (inCol * shape_.rows);
1199  }
1200 
1201  //============================================================================
1202  // Method Description:
1208  {
1209  return ccolbegin();
1210  }
1211 
1212  //============================================================================
1213  // Method Description:
1222  {
1223  return ccolbegin(inCol);
1224  }
1225 
1226  //============================================================================
1227  // Method Description:
1234  {
1235  return const_column_iterator(array_, shape_.rows, shape_.cols);
1236  }
1237 
1238  //============================================================================
1239  // Method Description:
1248  {
1249  if (inCol >= shape_.cols)
1250  {
1251  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1252  }
1253 
1254  return ccolbegin() += (inCol * shape_.rows);
1255  }
1256 
1257  //============================================================================
1258  // Method Description:
1264  {
1265  return reverse_iterator(end());
1266  }
1267 
1268  //============================================================================
1269  // Method Description:
1278  {
1279  if (inRow >= shape_.rows)
1280  {
1281  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1282  }
1283 
1284  return rbegin() += (shape_.rows - inRow - 1) * shape_.cols;
1285  }
1286 
1287  //============================================================================
1288  // Method Description:
1294  {
1295  return crbegin();
1296  }
1297 
1298  //============================================================================
1299  // Method Description:
1308  {
1309  return crbegin(inRow);
1310  }
1311 
1312  //============================================================================
1313  // Method Description:
1320  {
1321  return const_reverse_iterator(cend());
1322  }
1323 
1324  //============================================================================
1325  // Method Description:
1334  {
1335  if (inRow >= shape_.rows)
1336  {
1337  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1338  }
1339 
1340  return crbegin() += (shape_.rows - inRow - 1) * shape_.cols;
1341  }
1342 
1343  //============================================================================
1344  // Method Description:
1350  {
1351  return reverse_column_iterator(colend());
1352  }
1353 
1354  //============================================================================
1355  // Method Description:
1364  {
1365  if (inCol >= shape_.cols)
1366  {
1367  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1368  }
1369 
1370  return rcolbegin() += (shape_.cols - inCol - 1) * shape_.rows;
1371  }
1372 
1373  //============================================================================
1374  // Method Description:
1380  {
1381  return crcolbegin();
1382  }
1383 
1384  //============================================================================
1385  // Method Description:
1394  {
1395  return crcolbegin(inCol);
1396  }
1397 
1398  //============================================================================
1399  // Method Description:
1406  {
1408  }
1409 
1410  //============================================================================
1411  // Method Description:
1420  {
1421  if (inCol >= shape_.cols)
1422  {
1423  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1424  }
1425 
1426  return crcolbegin() += (shape_.cols - inCol - 1) * shape_.rows;
1427  }
1428 
1429  //============================================================================
1430  // Method Description:
1435  iterator end() noexcept
1436  {
1437  return begin() += size_;
1438  }
1439 
1440  //============================================================================
1441  // Method Description:
1450  {
1451  if (inRow >= shape_.rows)
1452  {
1453  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1454  }
1455 
1456  return begin(inRow) += shape_.cols;
1457  }
1458 
1459  //============================================================================
1460  // Method Description:
1465  const_iterator end() const noexcept
1466  {
1467  return cend();
1468  }
1469 
1470  //============================================================================
1471  // Method Description:
1480  {
1481  return cend(inRow);
1482  }
1483 
1484  //============================================================================
1485  // Method Description:
1491  const_iterator cend() const noexcept
1492  {
1493  return cbegin() += size_;
1494  }
1495 
1496  //============================================================================
1497  // Method Description:
1506  {
1507  if (inRow >= shape_.rows)
1508  {
1509  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1510  }
1511 
1512  return cbegin(inRow) += shape_.cols;
1513  }
1514 
1515  //============================================================================
1516  // Method Description:
1522  {
1523  return rbegin() += size_;
1524  }
1525 
1526  //============================================================================
1527  // Method Description:
1536  {
1537  if (inRow >= shape_.rows)
1538  {
1539  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1540  }
1541 
1542  return rbegin(inRow) += shape_.cols;
1543  }
1544 
1545  //============================================================================
1546  // Method Description:
1551  const_reverse_iterator rend() const noexcept
1552  {
1553  return crend();
1554  }
1555 
1556  //============================================================================
1557  // Method Description:
1566  {
1567  return crend(inRow);
1568  }
1569 
1570  //============================================================================
1571  // Method Description:
1578  {
1579  return crbegin() += size_;
1580  }
1581 
1582  //============================================================================
1583  // Method Description:
1592  {
1593  if (inRow >= shape_.rows)
1594  {
1595  THROW_INVALID_ARGUMENT_ERROR("input row is greater than the number of rows in the array.");
1596  }
1597 
1598  return crbegin(inRow) += shape_.cols;
1599  }
1600 
1601  //============================================================================
1602  // Method Description:
1608  {
1609  return colbegin() += size_;
1610  }
1611 
1612  //============================================================================
1613  // Method Description:
1622  {
1623  if (inCol >= shape_.cols)
1624  {
1625  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1626  }
1627 
1628  return colbegin(inCol) += shape_.rows;
1629  }
1630 
1631  //============================================================================
1632  // Method Description:
1637  const_column_iterator colend() const noexcept
1638  {
1639  return ccolend();
1640  }
1641 
1642  //============================================================================
1643  // Method Description:
1652  {
1653  return ccolend(inCol);
1654  }
1655 
1656  //============================================================================
1657  // Method Description:
1663  const_column_iterator ccolend() const noexcept
1664  {
1665  return ccolbegin() += size_;
1666  }
1667 
1668  //============================================================================
1669  // Method Description:
1678  {
1679  if (inCol >= shape_.cols)
1680  {
1681  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1682  }
1683 
1684  return ccolbegin(inCol) += shape_.rows;
1685  }
1686 
1687  //============================================================================
1688  // Method Description:
1694  {
1695  return rcolbegin() += size_;
1696  }
1697 
1698  //============================================================================
1699  // Method Description:
1708  {
1709  if (inCol >= shape_.cols)
1710  {
1711  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1712  }
1713 
1714  return rcolbegin(inCol) += shape_.rows;
1715  }
1716 
1717  //============================================================================
1718  // Method Description:
1724  {
1725  return crcolend();
1726  }
1727 
1728  //============================================================================
1729  // Method Description:
1738  {
1739  return crcolend(inCol);
1740  }
1741 
1742  //============================================================================
1743  // Method Description:
1750  {
1751  return crcolbegin() += size_;
1752  }
1753 
1754  //============================================================================
1755  // Method Description:
1764  {
1765  if (inCol >= shape_.cols)
1766  {
1767  THROW_INVALID_ARGUMENT_ERROR("input col is greater than the number of cols in the array.");
1768  }
1769 
1770  return crcolbegin(inCol) += shape_.rows;
1771  }
1772 
1773  //============================================================================
1774  // Method Description:
1785  {
1787 
1788  const auto function = [](dtype i) -> bool
1789  {
1790  return i != dtype{ 0 };
1791  };
1792 
1793  switch (inAxis)
1794  {
1795  case Axis::NONE:
1796  {
1797  NdArray<bool> returnArray = { stl_algorithms::all_of(cbegin(), cend(), function) };
1798  return returnArray;
1799  }
1800  case Axis::COL:
1801  {
1802  NdArray<bool> returnArray(1, shape_.rows);
1803  for (uint32 row = 0; row < shape_.rows; ++row)
1804  {
1805  returnArray(0, row) = stl_algorithms::all_of(cbegin(row), cend(row), function);
1806  }
1807 
1808  return returnArray;
1809  }
1810  case Axis::ROW:
1811  {
1812  NdArray<dtype> arrayTransposed = transpose();
1813  NdArray<bool> returnArray(1, arrayTransposed.shape_.rows);
1814  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1815  {
1816  returnArray(0, row) = stl_algorithms::all_of(arrayTransposed.cbegin(row), arrayTransposed.cend(row), function);
1817  }
1818 
1819  return returnArray;
1820  }
1821  default:
1822  {
1823  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1824  return {}; // get rid of compiler warning
1825  }
1826  }
1827  }
1828 
1829  //============================================================================
1830  // Method Description:
1841  {
1843 
1844  const auto function = [](dtype i) -> bool
1845  {
1846  return i != dtype{ 0 };
1847  };
1848 
1849  switch (inAxis)
1850  {
1851  case Axis::NONE:
1852  {
1853  NdArray<bool> returnArray = { stl_algorithms::any_of(cbegin(), cend(), function) };
1854  return returnArray;
1855  }
1856  case Axis::COL:
1857  {
1858  NdArray<bool> returnArray(1, shape_.rows);
1859  for (uint32 row = 0; row < shape_.rows; ++row)
1860  {
1861  returnArray(0, row) = stl_algorithms::any_of(cbegin(row), cend(row), function);
1862  }
1863 
1864  return returnArray;
1865  }
1866  case Axis::ROW:
1867  {
1868  NdArray<dtype> arrayTransposed = transpose();
1869  NdArray<bool> returnArray(1, arrayTransposed.shape_.rows);
1870  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1871  {
1872  returnArray(0, row) = stl_algorithms::any_of(arrayTransposed.cbegin(row), arrayTransposed.cend(row), function);
1873  }
1874 
1875  return returnArray;
1876  }
1877  default:
1878  {
1879  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1880  return {}; // get rid of compiler warning
1881  }
1882  }
1883  }
1884 
1885  //============================================================================
1886  // Method Description:
1898  {
1900 
1901  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
1902  {
1903  return lhs < rhs;
1904  };
1905 
1906  switch (inAxis)
1907  {
1908  case Axis::NONE:
1909  {
1910  NdArray<uint32> returnArray = { static_cast<uint32>(stl_algorithms::max_element(cbegin(),
1911  cend(), comparitor) - cbegin()) };
1912  return returnArray;
1913  }
1914  case Axis::COL:
1915  {
1916  NdArray<uint32> returnArray(1, shape_.rows);
1917  for (uint32 row = 0; row < shape_.rows; ++row)
1918  {
1919  returnArray(0, row) = static_cast<uint32>(stl_algorithms::max_element(cbegin(row),
1920  cend(row), comparitor) - cbegin(row));
1921  }
1922 
1923  return returnArray;
1924  }
1925  case Axis::ROW:
1926  {
1927  NdArray<dtype> arrayTransposed = transpose();
1928  NdArray<uint32> returnArray(1, arrayTransposed.shape_.rows);
1929  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1930  {
1931  returnArray(0, row) = static_cast<uint32>(stl_algorithms::max_element(arrayTransposed.cbegin(row),
1932  arrayTransposed.cend(row), comparitor) - arrayTransposed.cbegin(row));
1933  }
1934 
1935  return returnArray;
1936  }
1937  default:
1938  {
1939  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
1940  return {}; // get rid of compiler warning
1941  }
1942  }
1943  }
1944 
1945  //============================================================================
1946  // Method Description:
1958  {
1960 
1961  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
1962  {
1963  return lhs < rhs;
1964  };
1965 
1966  switch (inAxis)
1967  {
1968  case Axis::NONE:
1969  {
1970  NdArray<uint32> returnArray = { static_cast<uint32>(stl_algorithms::min_element(cbegin(),
1971  cend(), comparitor) - cbegin()) };
1972  return returnArray;
1973  }
1974  case Axis::COL:
1975  {
1976  NdArray<uint32> returnArray(1, shape_.rows);
1977  for (uint32 row = 0; row < shape_.rows; ++row)
1978  {
1979  returnArray(0, row) = static_cast<uint32>(stl_algorithms::min_element(cbegin(row),
1980  cend(row), comparitor) - cbegin(row));
1981  }
1982 
1983  return returnArray;
1984  }
1985  case Axis::ROW:
1986  {
1987  NdArray<dtype> arrayTransposed = transpose();
1988  NdArray<uint32> returnArray(1, arrayTransposed.shape_.rows);
1989  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1990  {
1991  returnArray(0, row) = static_cast<uint32>(stl_algorithms::min_element(arrayTransposed.cbegin(row),
1992  arrayTransposed.cend(row), comparitor) - arrayTransposed.cbegin(row));
1993  }
1994 
1995  return returnArray;
1996  }
1997  default:
1998  {
1999  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2000  return {}; // get rid of compiler warning
2001  }
2002  }
2003  }
2004 
2005  //============================================================================
2006  // Method Description:
2017  {
2019 
2020  switch (inAxis)
2021  {
2022  case Axis::NONE:
2023  {
2024  std::vector<uint32> idx(size_);
2025  std::iota(idx.begin(), idx.end(), 0);
2026 
2027  const auto function = [this](uint32 i1, uint32 i2) noexcept -> bool
2028  {
2029  return (*this)[i1] < (*this)[i2];
2030  };
2031 
2032  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2033  return NdArray<uint32>(idx);
2034  }
2035  case Axis::COL:
2036  {
2037  NdArray<uint32> returnArray(shape_);
2038  for (uint32 row = 0; row < shape_.rows; ++row)
2039  {
2040  std::vector<uint32> idx(shape_.cols);
2041  std::iota(idx.begin(), idx.end(), 0);
2042 
2043  const auto function = [this, row](uint32 i1, uint32 i2) noexcept -> bool
2044  {
2045  return operator()(row, i1) < operator()(row, i2);
2046  };
2047 
2048  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2049 
2050  for (uint32 col = 0; col < shape_.cols; ++col)
2051  {
2052  returnArray(row, col) = idx[col];
2053  }
2054  }
2055  return returnArray;
2056  }
2057  case Axis::ROW:
2058  {
2059  NdArray<dtype> arrayTransposed = transpose();
2060  NdArray<uint32> returnArray(shape_.cols, shape_.rows);
2061  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
2062  {
2063  std::vector<uint32> idx(arrayTransposed.shape_.cols);
2064  std::iota(idx.begin(), idx.end(), 0);
2065 
2066  const auto function = [&arrayTransposed, row](uint32 i1, uint32 i2) noexcept -> bool
2067  {
2068  return arrayTransposed(row, i1) < arrayTransposed(row, i2);
2069  };
2070 
2071  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2072 
2073  for (uint32 col = 0; col < arrayTransposed.shape_.cols; ++col)
2074  {
2075  returnArray(row, col) = idx[col];
2076  }
2077  }
2078  return returnArray.transpose();
2079  }
2080  default:
2081  {
2082  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2083  return {}; // get rid of compiler warning
2084  }
2085  }
2086  }
2087 
2088  //============================================================================
2089  // Method Description:
2098  template<typename dtypeOut, typename dtype_ = dtype,
2103  {
2104  NdArray<dtypeOut> outArray(shape_);
2105 
2106  if (std::is_same<dtypeOut, dtype>::value)
2107  {
2108  std::copy(cbegin(), cend(), outArray.begin());
2109  }
2110  else
2111  {
2112  const auto function = [](dtype value) -> dtypeOut
2113  {
2114  return static_cast<dtypeOut>(value);
2115  };
2116 
2117  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2118  }
2119 
2120  return outArray;
2121  }
2122 
2123  //============================================================================
2124  // Method Description:
2133  template<typename dtypeOut, typename dtype_ = dtype,
2138  {
2139  NdArray<dtypeOut> outArray(shape_);
2140 
2141  const auto function = [](const_reference value) -> dtypeOut
2142  {
2143  return std::complex<typename dtypeOut::value_type>(value);
2144  };
2145 
2146  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2147 
2148  return outArray;
2149  }
2150 
2151  //============================================================================
2152  // Method Description:
2161  template<typename dtypeOut, typename dtype_ = dtype,
2166  {
2167  NdArray<dtypeOut> outArray(shape_);
2168 
2169  if (std::is_same<dtypeOut, dtype>::value)
2170  {
2171  std::copy(cbegin(), cend(), outArray.begin());
2172  }
2173  else
2174  {
2175  const auto function = [](const_reference value) noexcept -> dtypeOut
2176  {
2177  return complex_cast<typename dtypeOut::value_type>(value);
2178  };
2179 
2180  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2181  }
2182 
2183  return outArray;
2184  }
2185 
2186  //============================================================================
2187  // Method Description:
2196  template<typename dtypeOut, typename dtype_ = dtype,
2201  {
2202  NdArray<dtypeOut> outArray(shape_);
2203 
2204  const auto function = [](const_reference value) -> dtypeOut
2205  {
2206  return static_cast<dtypeOut>(value.real());
2207  };
2208 
2209  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2210 
2211  return outArray;
2212  }
2213 
2214  //============================================================================
2215  // Method Description:
2221  value_type back() const noexcept
2222  {
2223  return *(cend() - 1);
2224  }
2225 
2226  //============================================================================
2227  // Method Description:
2233  reference back() noexcept
2234  {
2235  return *(end() - 1);
2236  }
2237 
2238  //============================================================================
2239  // Method Description:
2246  {
2247  return *(cend(row) - 1);
2248  }
2249 
2250  //============================================================================
2251  // Method Description:
2258  {
2259  return *(end(row) - 1);
2260  }
2261 
2262  //============================================================================
2263  // Method Description:
2272  {
2273  STATIC_ASSERT_INTEGER(dtype);
2274 
2275  switch (endianess_)
2276  {
2277  case Endian::BIG:
2278  {
2279  *this = newbyteorder(Endian::LITTLE);
2280  break;
2281  }
2282  case Endian::LITTLE:
2283  {
2284  *this = newbyteorder(Endian::BIG);
2285  break;
2286  }
2287  case Endian::NATIVE:
2288  {
2289 #if BOOST_ENDIAN_BIG_BYTE
2290  *this = newbyteorder(Endian::LITTLE);
2291 #elif BOOST_ENDIAN_LITTLE_BYTE
2292  *this = newbyteorder(Endian::BIG);
2293 #endif
2294  break;
2295  }
2296  }
2297 
2298  return *this;
2299  }
2300 
2301  //============================================================================
2302  // Method Description:
2313  {
2315 
2316  NdArray<dtype> outArray(shape_);
2317  boost::algorithm::clamp_range(cbegin(), cend(), outArray.begin(), inMin, inMax,
2318  [](dtype lhs, dtype rhs) noexcept -> bool
2319  {
2320  return lhs < rhs;
2321  });
2322 
2323  return outArray;
2324  }
2325 
2326  //============================================================================
2327  // Method Description:
2335  {
2336  return operator()(rSlice(), inColumn);
2337  }
2338 
2339  //============================================================================
2340  // Method Description:
2349  {
2351 
2352  switch (inAxis)
2353  {
2354  case Axis::NONE:
2355  {
2356  NdArray<bool> returnArray = { stl_algorithms::find(cbegin(), cend(), inValue) != cend() };
2357  return returnArray;
2358  }
2359  case Axis::COL:
2360  {
2361  NdArray<bool> returnArray(1, shape_.rows);
2362  for (uint32 row = 0; row < shape_.rows; ++row)
2363  {
2364  returnArray(0, row) = stl_algorithms::find(cbegin(row), cend(row), inValue) != cend(row);
2365  }
2366 
2367  return returnArray;
2368  }
2369  case Axis::ROW:
2370  {
2371  NdArray<dtype> transArray = transpose();
2372  NdArray<bool> returnArray(1, transArray.shape_.rows);
2373  for (uint32 row = 0; row < transArray.shape_.rows; ++row)
2374  {
2375  returnArray(0, row) = stl_algorithms::find(transArray.cbegin(row), transArray.cend(row), inValue) != transArray.cend(row);
2376  }
2377 
2378  return returnArray;
2379  }
2380  default:
2381  {
2382  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2383  return {}; // get rid of compiler warning
2384  }
2385  }
2386  }
2387 
2388  //============================================================================
2389  // Method Description:
2398  {
2399  return NdArray<dtype>(*this);
2400  }
2401 
2402  //============================================================================
2403  // Method Description:
2414  {
2416 
2417  switch (inAxis)
2418  {
2419  case Axis::NONE:
2420  {
2421  NdArray<dtype> returnArray(1, size_);
2422  returnArray[0] = front();
2423  for (uint32 i = 1; i < size_; ++i)
2424  {
2425  returnArray[i] = returnArray[i - 1] * array_[i];
2426  }
2427 
2428  return returnArray;
2429  }
2430  case Axis::COL:
2431  {
2432  NdArray<dtype> returnArray(shape_);
2433  for (uint32 row = 0; row < shape_.rows; ++row)
2434  {
2435  returnArray(row, 0) = operator()(row, 0);
2436  for (uint32 col = 1; col < shape_.cols; ++col)
2437  {
2438  returnArray(row, col) = returnArray(row, col - 1) * operator()(row, col);
2439  }
2440  }
2441 
2442  return returnArray;
2443  }
2444  case Axis::ROW:
2445  {
2446  NdArray<dtype> returnArray(shape_);
2447  for (uint32 col = 0; col < shape_.cols; ++col)
2448  {
2449  returnArray(0, col) = operator()(0, col);
2450  for (uint32 row = 1; row < shape_.rows; ++row)
2451  {
2452  returnArray(row, col) = returnArray(row - 1, col) * operator()(row, col);
2453  }
2454  }
2455 
2456  return returnArray;
2457  }
2458  default:
2459  {
2460  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2461  return {}; // get rid of compiler warning
2462  }
2463  }
2464  }
2465 
2466  //============================================================================
2467  // Method Description:
2478  {
2480 
2481  switch (inAxis)
2482  {
2483  case Axis::NONE:
2484  {
2485  NdArray<dtype> returnArray(1, size_);
2486  returnArray[0] = front();
2487  for (uint32 i = 1; i < size_; ++i)
2488  {
2489  returnArray[i] = returnArray[i - 1] + array_[i];
2490  }
2491 
2492  return returnArray;
2493  }
2494  case Axis::COL:
2495  {
2496  NdArray<dtype> returnArray(shape_);
2497  for (uint32 row = 0; row < shape_.rows; ++row)
2498  {
2499  returnArray(row, 0) = operator()(row, 0);
2500  for (uint32 col = 1; col < shape_.cols; ++col)
2501  {
2502  returnArray(row, col) = returnArray(row, col - 1) + operator()(row, col);
2503  }
2504  }
2505 
2506  return returnArray;
2507  }
2508  case Axis::ROW:
2509  {
2510  NdArray<dtype> returnArray(shape_);
2511  for (uint32 col = 0; col < shape_.cols; ++col)
2512  {
2513  returnArray(0, col) = operator()(0, col);
2514  for (uint32 row = 1; row < shape_.rows; ++row)
2515  {
2516  returnArray(row, col) = returnArray(row - 1, col) + operator()(row, col);
2517  }
2518  }
2519 
2520  return returnArray;
2521  }
2522  default:
2523  {
2524  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2525  return {}; // get rid of compiler warning
2526  }
2527  }
2528  }
2529 
2530  //============================================================================
2531  // Method Description:
2535  pointer data() noexcept
2536  {
2537  return array_;
2538  }
2539 
2540  //============================================================================
2541  // Method Description:
2545  const_pointer data() const noexcept
2546  {
2547  return array_;
2548  }
2549 
2550  //============================================================================
2551  // Method Description:
2558  {
2559  ownsPtr_ = false;
2560  return data();
2561  }
2562 
2563  //============================================================================
2564  // Method Description:
2574  NdArray<dtype> diagonal(int32 inOffset = 0, Axis inAxis = Axis::ROW) const
2575  {
2576  switch (inAxis)
2577  {
2578  case Axis::ROW:
2579  {
2580  std::vector<dtype> diagnolValues;
2581  int32 col = inOffset;
2582  for (uint32 row = 0; row < shape_.rows; ++row)
2583  {
2584  if (col < 0)
2585  {
2586  ++col;
2587  continue;
2588  }
2589  if (col >= static_cast<int32>(shape_.cols))
2590  {
2591  break;
2592  }
2593 
2594  diagnolValues.push_back(operator()(row, static_cast<uint32>(col)));
2595  ++col;
2596  }
2597 
2598  return NdArray<dtype>(diagnolValues);
2599  }
2600  case Axis::COL:
2601  {
2602  std::vector<dtype> diagnolValues;
2603  uint32 col = 0;
2604  for (int32 row = inOffset; row < static_cast<int32>(shape_.rows); ++row)
2605  {
2606  if (row < 0)
2607  {
2608  ++col;
2609  continue;
2610  }
2611  if (col >= shape_.cols)
2612  {
2613  break;
2614  }
2615 
2616  diagnolValues.push_back(operator()(static_cast<uint32>(row), col));
2617  ++col;
2618  }
2619 
2620  return NdArray<dtype>(diagnolValues);
2621  }
2622  default:
2623  {
2624  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2625  return {}; // get rid of compiler warning
2626  }
2627  }
2628  }
2629 
2630  //============================================================================
2631  // Method Description:
2644  NdArray<dtype> dot(const NdArray<dtype>& inOtherArray) const
2645  {
2647 
2648  if (shape_ == inOtherArray.shape_ && (shape_.rows == 1 || shape_.cols == 1))
2649  {
2650  dtype dotProduct = std::inner_product(cbegin(), cend(), inOtherArray.cbegin(), dtype{ 0 });
2651  NdArray<dtype> returnArray = { dotProduct };
2652  return returnArray;
2653  }
2654  if (shape_.cols == inOtherArray.shape_.rows)
2655  {
2656  // 2D array, use matrix multiplication
2657  NdArray<dtype> returnArray(shape_.rows, inOtherArray.shape_.cols);
2658  auto otherArrayT = inOtherArray.transpose();
2659 
2660  for (uint32 i = 0; i < shape_.rows; ++i)
2661  {
2662  for (uint32 j = 0; j < otherArrayT.shape_.rows; ++j)
2663  {
2664  returnArray(i, j) = std::inner_product(otherArrayT.cbegin(j), otherArrayT.cend(j), cbegin(i), dtype{ 0 });
2665  }
2666  }
2667 
2668  return returnArray;
2669  }
2670 
2671  std::string errStr = "shapes of [" + utils::num2str(shape_.rows) + ", " + utils::num2str(shape_.cols) + "]";
2672  errStr += " and [" + utils::num2str(inOtherArray.shape_.rows) + ", " + utils::num2str(inOtherArray.shape_.cols) + "]";
2673  errStr += " are not consistent.";
2675 
2676  return NdArray<dtype>(); // get rid of compiler warning
2677  }
2678 
2679  //============================================================================
2680  // Method Description:
2688  void dump(const std::string& inFilename) const
2689  {
2690  filesystem::File f(inFilename);
2691  if (!f.hasExt())
2692  {
2693  f.withExt(".bin");
2694  }
2695 
2696  std::ofstream ofile(f.fullName().c_str(), std::ios::binary);
2697  if (!ofile.good())
2698  {
2699  THROW_RUNTIME_ERROR("Unable to open the input file:\n\t" + inFilename);
2700  }
2701 
2702  if (array_ != nullptr)
2703  {
2704  ofile.write(reinterpret_cast<const char*>(array_), size_ * sizeof(dtype));
2705  }
2706  ofile.close();
2707  }
2708 
2709  //============================================================================
2710  // Method Description:
2716  Endian endianess() const noexcept
2717  {
2718  STATIC_ASSERT_ARITHMETIC(dtype);
2719 
2720  return endianess_;
2721  }
2722 
2723  //============================================================================
2724  // Method Description:
2734  NdArray<dtype>& fill(value_type inFillValue) noexcept
2735  {
2736  stl_algorithms::fill(begin(), end(), inFillValue);
2737  return *this;
2738  }
2739 
2740  //============================================================================
2741  // Method Description:
2749  {
2751 
2752  std::vector<uint32> indices;
2753  uint32 idx = 0;
2754  for (auto value : *this)
2755  {
2756  if (value != dtype{ 0 })
2757  {
2758  indices.push_back(idx);
2759  }
2760  ++idx;
2761  }
2762 
2763  return NdArray<uint32>(indices);
2764  }
2765 
2766  //============================================================================
2767  // Method Description:
2776  {
2777  NdArray<dtype> outArray(1, size_);
2778  stl_algorithms::copy(cbegin(), cend(), outArray.begin());
2779  return outArray;
2780  }
2781 
2782  //============================================================================
2783  // Method Description:
2789  value_type front() const noexcept
2790  {
2791  return *cbegin();
2792  }
2793 
2794  //============================================================================
2795  // Method Description:
2801  reference front() noexcept
2802  {
2803  return *begin();
2804  }
2805 
2806  //============================================================================
2807  // Method Description:
2814  {
2815  return *cbegin(row);
2816  }
2817 
2818  //============================================================================
2819  // Method Description:
2826  {
2827  return *begin(row);
2828  }
2829 
2830  //============================================================================
2831  // Method Description:
2840  {
2841  return operator[](inIndices);
2842  }
2843 
2844  //============================================================================
2845  // Method Description:
2856  {
2857  return operator[](inMask);
2858  }
2859 
2860  //============================================================================
2861  // Method Description:
2868  bool isempty() const noexcept
2869  {
2870  return size_ == 0;
2871  }
2872 
2873  //============================================================================
2874  // Method Description:
2881  bool isflat() const noexcept
2882  {
2883  return shape_.rows == 1 || shape_.cols == 1;
2884  }
2885 
2886  //============================================================================
2887  // Method Description:
2894  {
2896 
2897  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
2898  {
2899  return lhs < rhs;
2900  };
2901 
2902  switch (inAxis)
2903  {
2904  case Axis::NONE:
2905  {
2906  return { stl_algorithms::is_sorted(cbegin(), cend(), comparitor) };
2907  }
2908  case Axis::ROW:
2909  {
2910  NdArray<bool> returnArray(shape_.cols, 1);
2911  auto transposedArray = transpose();
2912  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
2913  {
2914  returnArray(0, row) = stl_algorithms::is_sorted(transposedArray.cbegin(row),
2915  transposedArray.cend(row), comparitor);
2916  }
2917 
2918  return returnArray;
2919  }
2920  case Axis::COL:
2921  {
2922  NdArray<bool> returnArray(1, shape_.rows);
2923  for (uint32 row = 0; row < shape_.rows; ++row)
2924  {
2925  returnArray(0, row) = stl_algorithms::is_sorted(cbegin(row), cend(row), comparitor);
2926  }
2927 
2928  return returnArray;
2929  }
2930  default:
2931  {
2932  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
2933  return {}; // get rid of compiler warning
2934  }
2935  }
2936  }
2937 
2938  //============================================================================
2939  // Method Description:
2944  bool issquare() const noexcept
2945  {
2946  return shape_.issquare();
2947  }
2948 
2949  //============================================================================
2950  // Method Description:
2959  {
2960  if (size_ != 1)
2961  {
2962  THROW_INVALID_ARGUMENT_ERROR("Can only convert an array of size 1 to a C++ scaler");
2963  }
2964 
2965  return front();
2966  }
2967 
2968  //============================================================================
2969  // Method Description:
2980  {
2982 
2983  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
2984  {
2985  return lhs < rhs;
2986  };
2987 
2988  switch (inAxis)
2989  {
2990  case Axis::NONE:
2991  {
2992  NdArray<dtype> returnArray = { *stl_algorithms::max_element(cbegin(), cend(), comparitor) };
2993  return returnArray;
2994  }
2995  case Axis::COL:
2996  {
2997  NdArray<dtype> returnArray(1, shape_.rows);
2998  for (uint32 row = 0; row < shape_.rows; ++row)
2999  {
3000  returnArray(0, row) = *stl_algorithms::max_element(cbegin(row), cend(row), comparitor);
3001  }
3002 
3003  return returnArray;
3004  }
3005  case Axis::ROW:
3006  {
3007  NdArray<dtype> transposedArray = transpose();
3008  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3009  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3010  {
3011  returnArray(0, row) = *stl_algorithms::max_element(transposedArray.cbegin(row),
3012  transposedArray.cend(row), comparitor);
3013  }
3014 
3015  return returnArray;
3016  }
3017  default:
3018  {
3019  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3020  return {}; // get rid of compiler warning
3021  }
3022  }
3023  }
3024 
3025  //============================================================================
3026  // Method Description:
3037  {
3039 
3040  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3041  {
3042  return lhs < rhs;
3043  };
3044 
3045  switch (inAxis)
3046  {
3047  case Axis::NONE:
3048  {
3049  NdArray<dtype> returnArray = { *stl_algorithms::min_element(cbegin(), cend(), comparitor) };
3050  return returnArray;
3051  }
3052  case Axis::COL:
3053  {
3054  NdArray<dtype> returnArray(1, shape_.rows);
3055  for (uint32 row = 0; row < shape_.rows; ++row)
3056  {
3057  returnArray(0, row) = *stl_algorithms::min_element(cbegin(row), cend(row), comparitor);
3058  }
3059 
3060  return returnArray;
3061  }
3062  case Axis::ROW:
3063  {
3064  NdArray<dtype> transposedArray = transpose();
3065  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3066  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3067  {
3068  returnArray(0, row) = *stl_algorithms::min_element(transposedArray.cbegin(row),
3069  transposedArray.cend(row), comparitor);
3070  }
3071 
3072  return returnArray;
3073  }
3074  default:
3075  {
3076  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3077  return {}; // get rid of compiler warning
3078  }
3079  }
3080  }
3081 
3082  //============================================================================
3083  // Method Description:
3096  {
3098 
3099  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3100  {
3101  return lhs < rhs;
3102  };
3103 
3104  if (size_ == 0)
3105  {
3106  THROW_RUNTIME_ERROR("Median is undefined for an array of size = 0.");
3107  }
3108 
3109  switch (inAxis)
3110  {
3111  case Axis::NONE:
3112  {
3113  NdArray<dtype> copyArray(*this);
3114 
3115  const uint32 middleIdx = size_ / 2; // integer division
3116  stl_algorithms::nth_element(copyArray.begin(), copyArray.begin() + middleIdx, copyArray.end(), comparitor);
3117 
3118  dtype medianValue = copyArray.array_[middleIdx];
3119  if (size_ % 2 == 0)
3120  {
3121  const uint32 lhsIndex = middleIdx - 1;
3122  stl_algorithms::nth_element(copyArray.begin(), copyArray.begin() + lhsIndex, copyArray.end(), comparitor);
3123  medianValue = (medianValue + copyArray.array_[lhsIndex]) / dtype{2}; // potentially integer division, ok
3124  }
3125 
3126  return { medianValue };
3127  }
3128  case Axis::COL:
3129  {
3130  NdArray<dtype> copyArray(*this);
3131  NdArray<dtype> returnArray(1, shape_.rows);
3132 
3133  const bool isEven = shape_.cols % 2 == 0;
3134  for (uint32 row = 0; row < shape_.rows; ++row)
3135  {
3136  const uint32 middleIdx = shape_.cols / 2; // integer division
3137  stl_algorithms::nth_element(copyArray.begin(row), copyArray.begin(row) + middleIdx,
3138  copyArray.end(row), comparitor);
3139 
3140  dtype medianValue = copyArray(row, middleIdx);
3141  if (isEven)
3142  {
3143  const uint32 lhsIndex = middleIdx - 1;
3144  stl_algorithms::nth_element(copyArray.begin(row), copyArray.begin(row) + lhsIndex,
3145  copyArray.end(row), comparitor);
3146  medianValue = (medianValue + copyArray(row, lhsIndex)) / dtype{2}; // potentially integer division, ok
3147  }
3148 
3149  returnArray(0, row) = medianValue;
3150  }
3151 
3152  return returnArray;
3153  }
3154  case Axis::ROW:
3155  {
3156  NdArray<dtype> transposedArray = transpose();
3157  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3158 
3159  const bool isEven = shape_.rows % 2 == 0;
3160  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3161  {
3162  const uint32 middleIdx = transposedArray.shape_.cols / 2; // integer division
3163  stl_algorithms::nth_element(transposedArray.begin(row), transposedArray.begin(row) + middleIdx,
3164  transposedArray.end(row), comparitor);
3165 
3166  dtype medianValue = transposedArray(row, middleIdx);
3167  if (isEven)
3168  {
3169  const uint32 lhsIndex = middleIdx - 1;
3170  stl_algorithms::nth_element(transposedArray.begin(row), transposedArray.begin(row) + lhsIndex,
3171  transposedArray.end(row), comparitor);
3172  medianValue = (medianValue + transposedArray(row, lhsIndex)) / dtype{2}; // potentially integer division, ok
3173  }
3174 
3175  returnArray(0, row) = medianValue;
3176  }
3177 
3178  return returnArray;
3179  }
3180  default:
3181  {
3182  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3183  return {}; // get rid of compiler warning
3184  }
3185  }
3186  }
3187 
3188  //============================================================================
3189  // Method Description:
3193  NdArray<dtype>& nans() noexcept
3194  {
3195  STATIC_ASSERT_FLOAT(dtype);
3196 
3198  return *this;
3199  }
3200 
3201  //============================================================================
3202  // Method Description:
3210  uint64 nbytes() const noexcept
3211  {
3212  return static_cast<uint64>(sizeof(dtype) * size_);
3213  }
3214 
3215  //============================================================================
3216  // Method Description:
3229  NdArray<dtype> newbyteorder(Endian inEndianess) const
3230  {
3231  STATIC_ASSERT_INTEGER(dtype);
3232 
3233  switch (endianess_)
3234  {
3235  case Endian::NATIVE:
3236  {
3237  switch (inEndianess)
3238  {
3239  case Endian::NATIVE:
3240  {
3241  return NdArray(*this);
3242  }
3243  case Endian::BIG:
3244  {
3245  NdArray<dtype> outArray(shape_);
3246 
3247  stl_algorithms::transform(cbegin(), end(), outArray.begin(), boost::endian::native_to_big<dtype>);
3248 
3249  outArray.endianess_ = Endian::BIG;
3250  return outArray;
3251  }
3252  case Endian::LITTLE:
3253  {
3254  NdArray<dtype> outArray(shape_);
3255 
3256  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), boost::endian::native_to_little<dtype>);
3257 
3258  outArray.endianess_ = Endian::LITTLE;
3259  return outArray;
3260  }
3261  default:
3262  {
3263  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3264  return {}; // get rid of compiler warning
3265  }
3266  }
3267  break;
3268  }
3269  case Endian::BIG:
3270  {
3271  switch (inEndianess)
3272  {
3273  case Endian::NATIVE:
3274  {
3275  NdArray<dtype> outArray(shape_);
3276 
3277  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), boost::endian::big_to_native<dtype>);
3278 
3279  outArray.endianess_ = Endian::NATIVE;
3280  return outArray;
3281  }
3282  case Endian::BIG:
3283  {
3284  return NdArray(*this);
3285  }
3286  case Endian::LITTLE:
3287  {
3288  NdArray<dtype> outArray(shape_);
3289 
3290  stl_algorithms::transform(cbegin(), cend(), outArray.begin(),
3291  [](dtype value) noexcept -> dtype
3292  {
3293  return boost::endian::native_to_little<dtype>(boost::endian::big_to_native<dtype>(value));
3294  });
3295 
3296  outArray.endianess_ = Endian::LITTLE;
3297  return outArray;
3298  }
3299  default:
3300  {
3301  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3302  return {}; // get rid of compiler warning
3303  }
3304  }
3305  break;
3306  }
3307  case Endian::LITTLE:
3308  {
3309  switch (inEndianess)
3310  {
3311  case Endian::NATIVE:
3312  {
3313  NdArray<dtype> outArray(shape_);
3314 
3315  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), boost::endian::little_to_native<dtype>);
3316 
3317  outArray.endianess_ = Endian::NATIVE;
3318  return outArray;
3319  }
3320  case Endian::BIG:
3321  {
3322  NdArray<dtype> outArray(shape_);
3323 
3324  const auto function = [](dtype value) noexcept -> dtype
3325  {
3326  return boost::endian::native_to_big<dtype>(boost::endian::little_to_native<dtype>(value));
3327  };
3328 
3329  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
3330 
3331  outArray.endianess_ = Endian::BIG;
3332  return outArray;
3333  }
3334  case Endian::LITTLE:
3335  {
3336  return NdArray(*this);
3337  }
3338  default:
3339  {
3340  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3341  return {}; // get rid of compiler warning
3342  }
3343  }
3344  break;
3345  }
3346  default:
3347  {
3348  THROW_INVALID_ARGUMENT_ERROR("Unimplemented endian type.");
3349  return {}; // get rid of compiler warning
3350  }
3351  }
3352  }
3353 
3354  //============================================================================
3355  // Method Description:
3366  {
3368 
3369  const auto function = [](dtype i) -> bool
3370  {
3371  return i != dtype{ 0 };
3372  };
3373 
3374  switch (inAxis)
3375  {
3376  case Axis::NONE:
3377  {
3378  NdArray<bool> returnArray = { stl_algorithms::none_of(cbegin(), cend(), function) };
3379  return returnArray;
3380  }
3381  case Axis::COL:
3382  {
3383  NdArray<bool> returnArray(1, shape_.rows);
3384  for (uint32 row = 0; row < shape_.rows; ++row)
3385  {
3386  returnArray(0, row) = stl_algorithms::none_of(cbegin(row), cend(row), function);
3387  }
3388 
3389  return returnArray;
3390  }
3391  case Axis::ROW:
3392  {
3393  NdArray<dtype> arrayTransposed = transpose();
3394  NdArray<bool> returnArray(1, arrayTransposed.shape_.rows);
3395  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
3396  {
3397  returnArray(0, row) = stl_algorithms::none_of(arrayTransposed.cbegin(row), arrayTransposed.cend(row), function);
3398  }
3399 
3400  return returnArray;
3401  }
3402  default:
3403  {
3404  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3405  return {}; // get rid of compiler warning
3406  }
3407  }
3408  }
3409 
3410  //============================================================================
3411  // Method Description:
3421  std::pair<NdArray<uint32>, NdArray<uint32>> nonzero() const;
3422 
3423  //============================================================================
3424  // Method Description:
3431  uint32 numCols() const noexcept
3432  {
3433  return shape_.cols;
3434  }
3435 
3436  //============================================================================
3437  // Method Description:
3444  uint32 numRows() const noexcept
3445  {
3446  return shape_.rows;
3447  }
3448 
3449  //============================================================================
3450  // Method Description:
3454  NdArray<dtype>& ones() noexcept
3455  {
3457 
3458  fill(dtype{ 1 });
3459  return *this;
3460  }
3461 
3462  //============================================================================
3463  // Method Description:
3468  bool ownsInternalData() noexcept
3469  {
3470  return ownsPtr_;
3471  }
3472 
3473  //============================================================================
3474  // Method Description:
3490  {
3492 
3493  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3494  {
3495  return lhs < rhs;
3496  };
3497 
3498  switch (inAxis)
3499  {
3500  case Axis::NONE:
3501  {
3502  if (inKth >= size_)
3503  {
3504  std::string errStr = "kth(=" + utils::num2str(inKth);
3505  errStr += ") out of bounds (" + utils::num2str(size_) + ")";
3507  }
3508 
3509  stl_algorithms::nth_element(begin(), begin() + inKth, end(), comparitor);
3510  break;
3511  }
3512  case Axis::COL:
3513  {
3514  if (inKth >= shape_.cols)
3515  {
3516  std::string errStr = "kth(=" + utils::num2str(inKth);
3517  errStr += ") out of bounds (" + utils::num2str(shape_.cols) + ")";
3519  }
3520 
3521  for (uint32 row = 0; row < shape_.rows; ++row)
3522  {
3523  stl_algorithms::nth_element(begin(row), begin(row) + inKth, end(row), comparitor);
3524  }
3525  break;
3526  }
3527  case Axis::ROW:
3528  {
3529  if (inKth >= shape_.rows)
3530  {
3531  std::string errStr = "kth(=" + utils::num2str(inKth);
3532  errStr += ") out of bounds (" + utils::num2str(shape_.rows) + ")";
3534  }
3535 
3536  NdArray<dtype> transposedArray = transpose();
3537  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3538  {
3539  stl_algorithms::nth_element(transposedArray.begin(row), transposedArray.begin(row) + inKth,
3540  transposedArray.end(row), comparitor);
3541  }
3542  *this = transposedArray.transpose();
3543  break;
3544  }
3545  }
3546 
3547  return *this;
3548  }
3549 
3550  //============================================================================
3551  // Method Description:
3555  void print() const
3556  {
3558 
3559  std::cout << *this;
3560  }
3561 
3562  //============================================================================
3563  // Method Description:
3574  {
3576 
3577  switch (inAxis)
3578  {
3579  case Axis::NONE:
3580  {
3581  dtype product = std::accumulate(cbegin(), cend(),
3582  dtype{ 1 }, std::multiplies<dtype>());
3583  NdArray<dtype> returnArray = { product };
3584  return returnArray;
3585  }
3586  case Axis::COL:
3587  {
3588  NdArray<dtype> returnArray(1, shape_.rows);
3589  for (uint32 row = 0; row < shape_.rows; ++row)
3590  {
3591  returnArray(0, row) = std::accumulate(cbegin(row), cend(row),
3592  dtype{ 1 }, std::multiplies<dtype>());
3593  }
3594 
3595  return returnArray;
3596  }
3597  case Axis::ROW:
3598  {
3599  NdArray<dtype> transposedArray = transpose();
3600  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3601  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3602  {
3603  returnArray(0, row) = std::accumulate(transposedArray.cbegin(row), transposedArray.cend(row),
3604  dtype{ 1 }, std::multiplies<dtype>());
3605  }
3606 
3607  return returnArray;
3608  }
3609  default:
3610  {
3611  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3612  return {}; // get rid of compiler warning
3613  }
3614  }
3615  }
3616 
3617  //============================================================================
3618  // Method Description:
3629  {
3631 
3632  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3633  {
3634  return lhs < rhs;
3635  };
3636 
3637  switch (inAxis)
3638  {
3639  case Axis::NONE:
3640  {
3641  const auto result = stl_algorithms::minmax_element(cbegin(), cend(), comparitor);
3642  NdArray<dtype> returnArray = { *result.second - *result.first };
3643  return returnArray;
3644  }
3645  case Axis::COL:
3646  {
3647  NdArray<dtype> returnArray(1, shape_.rows);
3648  for (uint32 row = 0; row < shape_.rows; ++row)
3649  {
3650  const auto result = stl_algorithms::minmax_element(cbegin(row), cend(row), comparitor);
3651  returnArray(0, row) = *result.second - *result.first;
3652  }
3653 
3654  return returnArray;
3655  }
3656  case Axis::ROW:
3657  {
3658  NdArray<dtype> transposedArray = transpose();
3659  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3660  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3661  {
3662  const auto result = stl_algorithms::minmax_element(transposedArray.cbegin(row), transposedArray.cend(row), comparitor);
3663  returnArray(0, row) = *result.second - *result.first;
3664  }
3665 
3666  return returnArray;
3667  }
3668  default:
3669  {
3670  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
3671  return {}; // get rid of compiler warning
3672  }
3673  }
3674  }
3675 
3676  //============================================================================
3677  // Method Description:
3685  NdArray<dtype>& put(int32 inIndex, value_type inValue)
3686  {
3687  at(inIndex) = inValue;
3688 
3689  return *this;
3690  }
3691 
3692  //============================================================================
3693  // Method Description:
3702  NdArray<dtype>& put(int32 inRow, int32 inCol, value_type inValue)
3703  {
3704  at(inRow, inCol) = inValue;
3705 
3706  return *this;
3707  }
3708 
3709  //============================================================================
3710  // Method Description:
3718  NdArray<dtype>& put(const NdArray<uint32>& inIndices, value_type inValue)
3719  {
3720  for (auto index : inIndices)
3721  {
3722  put(index, inValue);
3723  }
3724 
3725  return *this;
3726  }
3727 
3728  //============================================================================
3729  // Method Description:
3737  NdArray<dtype>& put(const NdArray<uint32>& inIndices, const NdArray<dtype>& inValues)
3738  {
3739  if (inIndices.size() != inValues.size())
3740  {
3741  THROW_INVALID_ARGUMENT_ERROR("Input indices do not match values dimensions.");
3742  }
3743 
3744  uint32 counter = 0;
3745  for (auto index : inIndices)
3746  {
3747  put(index, inValues[counter++]);
3748  }
3749 
3750  return *this;
3751  }
3752 
3753  //============================================================================
3754  // Method Description:
3762  NdArray<dtype>& put(const Slice& inSlice, value_type inValue)
3763  {
3764  Slice inSliceCopy(inSlice);
3765  inSliceCopy.makePositiveAndValidate(size_);
3766 
3767  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
3768  {
3769  put(i, inValue);
3770  }
3771 
3772  return *this;
3773  }
3774 
3775  //============================================================================
3776  // Method Description:
3784  NdArray<dtype>& put(const Slice& inSlice, const NdArray<dtype>& inValues)
3785  {
3786  Slice inSliceCopy(inSlice);
3787  inSliceCopy.makePositiveAndValidate(size_);
3788 
3789  std::vector<uint32> indices;
3790  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
3791  {
3792  indices.push_back(i);
3793  }
3794 
3795  return put(NdArray<uint32>(indices), inValues);
3796  }
3797 
3798  //============================================================================
3799  // Method Description:
3808  NdArray<dtype>& put(const Slice& inRowSlice, const Slice& inColSlice, value_type inValue)
3809  {
3810  Slice inRowSliceCopy(inRowSlice);
3811  Slice inColSliceCopy(inColSlice);
3812 
3813  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3814  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3815 
3816  std::vector<uint32> indices;
3817  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3818  {
3819  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3820  {
3821  put(row, col, inValue);
3822  }
3823  }
3824 
3825  return *this;
3826  }
3827 
3828  //============================================================================
3829  // Method Description:
3838  NdArray<dtype>& put(const Slice& inRowSlice, int32 inColIndex, value_type inValue)
3839  {
3840  Slice inRowSliceCopy(inRowSlice);
3841  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3842 
3843  std::vector<uint32> indices;
3844  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3845  {
3846  put(row, inColIndex, inValue);
3847  }
3848 
3849  return *this;
3850  }
3851 
3852  //============================================================================
3853  // Method Description:
3862  NdArray<dtype>& put(int32 inRowIndex, const Slice& inColSlice, value_type inValue)
3863  {
3864  Slice inColSliceCopy(inColSlice);
3865  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3866 
3867  std::vector<uint32> indices;
3868  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3869  {
3870  put(inRowIndex, col, inValue);
3871  }
3872 
3873  return *this;
3874  }
3875 
3876  //============================================================================
3877  // Method Description:
3886  NdArray<dtype>& put(const Slice& inRowSlice, const Slice& inColSlice, const NdArray<dtype>& inValues)
3887  {
3888  Slice inRowSliceCopy(inRowSlice);
3889  Slice inColSliceCopy(inColSlice);
3890 
3891  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3892  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3893 
3894  std::vector<uint32> indices;
3895  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3896  {
3897  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3898  {
3899  const uint32 index = row * shape_.cols + col;
3900  indices.push_back(index);
3901  }
3902  }
3903 
3904  return put(NdArray<uint32>(indices), inValues);
3905  }
3906 
3907  //============================================================================
3908  // Method Description:
3917  NdArray<dtype>& put(const Slice& inRowSlice, int32 inColIndex, const NdArray<dtype>& inValues)
3918  {
3919  Slice inRowSliceCopy(inRowSlice);
3920  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3921 
3922  std::vector<uint32> indices;
3923  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3924  {
3925  const uint32 index = row * shape_.cols + inColIndex;
3926  indices.push_back(index);
3927  }
3928 
3929  return put(NdArray<uint32>(indices), inValues);
3930  }
3931 
3932  //============================================================================
3933  // Method Description:
3942  NdArray<dtype>& put(int32 inRowIndex, const Slice& inColSlice, const NdArray<dtype>& inValues)
3943  {
3944  Slice inColSliceCopy(inColSlice);
3945  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3946 
3947  std::vector<uint32> indices;
3948  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3949  {
3950  const uint32 index = inRowIndex * shape_.cols + col;
3951  indices.push_back(index);
3952  }
3953 
3954  return put(NdArray<uint32>(indices), inValues);
3955  }
3956 
3957  //============================================================================
3958  // Method Description:
3965  {
3966  if (inMask.shape() != shape_)
3967  {
3968  THROW_INVALID_ARGUMENT_ERROR("input inMask must be the same shape as the array it is masking.");
3969  }
3970 
3971  return put(inMask.flatnonzero(), inValue);
3972  }
3973 
3974  //============================================================================
3975  // Method Description:
3981  NdArray<dtype>& putMask(const NdArray<bool>& inMask, const NdArray<dtype>& inValues)
3982  {
3983  if (inMask.shape() != shape_)
3984  {
3985  THROW_INVALID_ARGUMENT_ERROR("input inMask must be the same shape as the array it is masking.");
3986  }
3987 
3988  return put(inMask.flatnonzero(), inValues);
3989  }
3990 
3991  //============================================================================
3992  // Method Description:
3999  NdArray<dtype>& ravel() noexcept
4000  {
4001  reshape(size_);
4002  return *this;
4003  }
4004 
4005  //============================================================================
4006  // Method Description:
4016  NdArray<dtype> repeat(uint32 inNumRows, uint32 inNumCols) const
4017  {
4018  NdArray<dtype> returnArray(shape_.rows * inNumRows, shape_.cols * inNumCols);
4019 
4020  for (uint32 row = 0; row < inNumRows; ++row)
4021  {
4022  for (uint32 col = 0; col < inNumCols; ++col)
4023  {
4024  std::vector<uint32> indices(shape_.size());
4025 
4026  const uint32 rowStart = row * shape_.rows;
4027  const uint32 colStart = col * shape_.cols;
4028 
4029  const uint32 rowEnd = (row + 1) * shape_.rows;
4030  const uint32 colEnd = (col + 1) * shape_.cols;
4031 
4032  uint32 counter = 0;
4033  for (uint32 rowIdx = rowStart; rowIdx < rowEnd; ++rowIdx)
4034  {
4035  for (uint32 colIdx = colStart; colIdx < colEnd; ++colIdx)
4036  {
4037  indices[counter++] = rowIdx * returnArray.shape_.cols + colIdx;
4038  }
4039  }
4040 
4041  returnArray.put(NdArray<uint32>(indices), *this);
4042  }
4043  }
4044 
4045  return returnArray;
4046  }
4047 
4048  //============================================================================
4049  // Method Description:
4059  NdArray<dtype> repeat(const Shape& inRepeatShape) const
4060  {
4061  return repeat(inRepeatShape.rows, inRepeatShape.cols);
4062  }
4063 
4064  //============================================================================
4065  // Method Description:
4071  void replace(value_type oldValue, value_type newValue)
4072  {
4074 
4075  stl_algorithms::replace(begin(), end(), oldValue, newValue);
4076  }
4077 
4078  //============================================================================
4079  // Method Description:
4090  {
4091  if (inSize != size_)
4092  {
4093  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into shape ";
4094  errStr += "[" + utils::num2str(1) + ", " + utils::num2str(inSize) + "]";
4095  THROW_RUNTIME_ERROR(errStr);
4096  }
4097 
4098  shape_.rows = 1;
4099  shape_.cols = inSize;
4100 
4101  return *this;
4102  }
4103 
4104  //============================================================================
4105  // Method Description:
4116  NdArray<dtype>& reshape(int32 inNumRows, int32 inNumCols)
4117  {
4118  if (inNumRows < 0)
4119  {
4120  if (size_ % inNumCols == 0)
4121  {
4122  return reshape(size_ / inNumCols, inNumCols);
4123  }
4124 
4125  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into a shape ";
4126  errStr += "with " + utils::num2str(inNumCols) + " columns";
4128 
4129  }
4130 
4131  if (inNumCols < 0)
4132  {
4133  if (size_ % inNumRows == 0)
4134  {
4135  return reshape(inNumRows, size_ / inNumRows);
4136  }
4137 
4138  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into a shape ";
4139  errStr += "with " + utils::num2str(inNumRows) + " rows";
4141 
4142  }
4143 
4144  if (static_cast<uint32>(inNumRows * inNumCols) != size_)
4145  {
4146  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into shape ";
4147  errStr += "[" + utils::num2str(inNumRows) + ", " + utils::num2str(inNumCols) + "]";
4149  }
4150 
4151  shape_.rows = static_cast<uint32>(inNumRows);
4152  shape_.cols = static_cast<uint32>(inNumCols);
4153 
4154  return *this;
4155  }
4156 
4157  //============================================================================
4158  // Method Description:
4169  NdArray<dtype>& reshape(const Shape& inShape)
4170  {
4171  return reshape(inShape.rows, inShape.cols);
4172  }
4173 
4174  //============================================================================
4175  // Method Description:
4184  NdArray<dtype>& resizeFast(uint32 inNumRows, uint32 inNumCols)
4185  {
4186  newArray(Shape(inNumRows, inNumCols));
4187  return *this;
4188  }
4189 
4190  //============================================================================
4191  // Method Description:
4200  NdArray<dtype>& resizeFast(const Shape& inShape)
4201  {
4202  return resizeFast(inShape.rows, inShape.cols);
4203  }
4204 
4205  //============================================================================
4206  // Method Description:
4217  NdArray<dtype>& resizeSlow(uint32 inNumRows, uint32 inNumCols)
4218  {
4219  std::vector<dtype> oldData(size_);
4220  stl_algorithms::copy(begin(), end(), oldData.begin());
4221 
4222  const Shape inShape(inNumRows, inNumCols);
4223  const Shape oldShape = shape_;
4224 
4225  newArray(inShape);
4226 
4227  for (uint32 row = 0; row < inShape.rows; ++row)
4228  {
4229  for (uint32 col = 0; col < inShape.cols; ++col)
4230  {
4231  if (row >= oldShape.rows || col >= oldShape.cols)
4232  {
4233  operator()(row, col) = dtype{ 0 }; // zero fill
4234  }
4235  else
4236  {
4237  operator()(row, col) = oldData[row * oldShape.cols + col];
4238  }
4239  }
4240  }
4241 
4242  return *this;
4243  }
4244 
4245  //============================================================================
4246  // Method Description:
4257  NdArray<dtype>& resizeSlow(const Shape& inShape)
4258  {
4259  return resizeSlow(inShape.rows, inShape.cols);
4260  }
4261 
4262  //============================================================================
4263  // Method Description:
4274  NdArray<dtype> round(uint8 inNumDecimals = 0) const
4275  {
4276  STATIC_ASSERT_FLOAT(dtype);
4277 
4278  NdArray<dtype> returnArray(shape_);
4279  const double multFactor = utils::power(10.0, inNumDecimals);
4280  const auto function = [multFactor](dtype value) noexcept -> dtype
4281  {
4282  return static_cast<dtype>(std::nearbyint(static_cast<double>(value) * multFactor) / multFactor);
4283  };
4284 
4285  stl_algorithms::transform(cbegin(), cend(), returnArray.begin(), function);
4286 
4287  return returnArray;
4288  }
4289 
4290  //============================================================================
4291  // Method Description:
4299  {
4300  return NdArray<dtype>(cbegin(inRow), cend(inRow));
4301  }
4302 
4303  //============================================================================
4304  // Method Description:
4312  Shape shape() const noexcept
4313  {
4314  return shape_;
4315  }
4316 
4317  //============================================================================
4318  // Method Description:
4326  size_type size() const noexcept
4327  {
4328  return size_;
4329  }
4330 
4331  //============================================================================
4332  // Method Description:
4343  {
4345 
4346  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
4347  {
4348  return lhs < rhs;
4349  };
4350 
4351  switch (inAxis)
4352  {
4353  case Axis::NONE:
4354  {
4355  stl_algorithms::sort(begin(), end(), comparitor);
4356  break;
4357  }
4358  case Axis::COL:
4359  {
4360  for (uint32 row = 0; row < shape_.rows; ++row)
4361  {
4362  stl_algorithms::sort(begin(row), end(row), comparitor);
4363  }
4364  break;
4365  }
4366  case Axis::ROW:
4367  {
4368  NdArray<dtype> transposedArray = transpose();
4369  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
4370  {
4371  stl_algorithms::sort(transposedArray.begin(row), transposedArray.end(row), comparitor);
4372  }
4373 
4374  *this = transposedArray.transpose();
4375  break;
4376  }
4377  }
4378 
4379  return *this;
4380  }
4381 
4382  //============================================================================
4383  // Method Description:
4389  std::string str() const
4390  {
4392 
4393  std::string out;
4394  out += "[";
4395  for (uint32 row = 0; row < shape_.rows; ++row)
4396  {
4397  out += "[";
4398  for (uint32 col = 0; col < shape_.cols; ++col)
4399  {
4400  out += utils::value2str(operator()(row, col)) + ", ";
4401  }
4402 
4403  if (row == shape_.rows - 1)
4404  {
4405  out += "]";
4406  }
4407  else
4408  {
4409  out += "]\n";
4410  }
4411  }
4412  out += "]\n";
4413  return out;
4414  }
4415 
4416  //============================================================================
4417  // Method Description:
4428  {
4430 
4431  switch (inAxis)
4432  {
4433  case Axis::NONE:
4434  {
4435  NdArray<dtype> returnArray = { std::accumulate(cbegin(), cend(), dtype{ 0 }) };
4436  return returnArray;
4437  }
4438  case Axis::COL:
4439  {
4440  NdArray<dtype> returnArray(1, shape_.rows);
4441  for (uint32 row = 0; row < shape_.rows; ++row)
4442  {
4443  returnArray(0, row) = std::accumulate(cbegin(row), cend(row), dtype{ 0 });
4444  }
4445 
4446  return returnArray;
4447  }
4448  case Axis::ROW:
4449  {
4450  NdArray<dtype> transposedArray = transpose();
4451  const Shape transShape = transposedArray.shape();
4452  NdArray<dtype> returnArray(1, transShape.rows);
4453  for (uint32 row = 0; row < transShape.rows; ++row)
4454  {
4455  returnArray(0, row) = std::accumulate(transposedArray.cbegin(row), transposedArray.cend(row), dtype{ 0 });
4456  }
4457 
4458  return returnArray;
4459  }
4460  default:
4461  {
4462  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
4463  return {}; // get rid of compiler warning
4464  }
4465  }
4466  }
4467 
4468  //============================================================================
4469  // Method Description:
4478  {
4479  return transpose();
4480  }
4481 
4482  //============================================================================
4483  // Method Description:
4495  void tofile(const std::string& inFilename, const std::string& inSep = "") const
4496  {
4498 
4499  if (inSep.empty())
4500  {
4501  dump(inFilename);
4502  }
4503  else
4504  {
4505  filesystem::File f(inFilename);
4506  if (!f.hasExt())
4507  {
4508  f.withExt("txt");
4509  }
4510 
4511  std::ofstream ofile(f.fullName().c_str());
4512  if (!ofile.good())
4513  {
4514  THROW_RUNTIME_ERROR("Input file could not be opened:\n\t" + inFilename);
4515  }
4516 
4517  uint32 counter = 0;
4518  for (auto value : *this)
4519  {
4520  ofile << value;
4521  if (counter++ != size_ - 1)
4522  {
4523  ofile << inSep;
4524  }
4525  }
4526  ofile.close();
4527  }
4528  }
4529 
4530  //============================================================================
4531  // Method Description:
4537  std::vector<dtype> toStlVector() const
4538  {
4539  return std::vector<dtype>(cbegin(), cend());
4540  }
4541 
4542  //============================================================================
4543  // Method Description:
4554  value_type trace(uint32 inOffset = 0, Axis inAxis = Axis::ROW) const noexcept
4555  {
4557 
4558  uint32 rowStart = 0;
4559  uint32 colStart = 0;
4560  switch (inAxis)
4561  {
4562  case Axis::ROW:
4563  {
4564  rowStart += inOffset;
4565  break;
4566  }
4567  case Axis::COL:
4568  {
4569  colStart += inOffset;
4570  break;
4571  }
4572  default:
4573  {
4574  // if the user input NONE, override back to ROW
4575  inAxis = Axis::ROW;
4576  break;
4577  }
4578  }
4579 
4580  if (rowStart >= shape_.rows || colStart >= shape_.cols)
4581  {
4582  return dtype{ 0 };
4583  }
4584 
4585  uint32 col = colStart;
4586  dtype sum = 0;
4587  for (uint32 row = rowStart; row < shape_.rows; ++row)
4588  {
4589  if (col >= shape_.cols)
4590  {
4591  break;
4592  }
4593  sum += operator()(row, col++);
4594  }
4595 
4596  return sum;
4597  }
4598 
4599  //============================================================================
4600  // Method Description:
4609  {
4610  NdArray<dtype> transArray(shape_.cols, shape_.rows);
4611  for (uint32 row = 0; row < shape_.rows; ++row)
4612  {
4613  for (uint32 col = 0; col < shape_.cols; ++col)
4614  {
4615  transArray(col, row) = operator()(row, col);
4616  }
4617  }
4618  return transArray;
4619  }
4620 
4621  //============================================================================
4622  // Method Description:
4626  NdArray<dtype>& zeros() noexcept
4627  {
4629 
4630  fill(dtype{ 0 });
4631  return *this;
4632  }
4633 
4634  private:
4635  //====================================Attributes==============================
4636  allocator_type allocator_{};
4637  Shape shape_{ 0, 0 };
4638  size_type size_{ 0 };
4639  Endian endianess_{ Endian::NATIVE };
4640  pointer array_{ nullptr };
4641  bool ownsPtr_{ false };
4642 
4643  //============================================================================
4644  // Method Description:
4647  void deleteArray() noexcept
4648  {
4649  if (ownsPtr_ && array_ != nullptr)
4650  {
4651  allocator_.deallocate(array_, size_);
4652  }
4653 
4654  array_ = nullptr;
4655  shape_.rows = shape_.cols = 0;
4656  size_ = 0;
4657  ownsPtr_ = false;
4658  endianess_ = Endian::NATIVE;
4659  }
4660 
4661  //============================================================================
4662  // Method Description:
4665  void newArray()
4666  {
4667  if (size_ > 0)
4668  {
4669  array_ = allocator_.allocate(size_);
4670  ownsPtr_ = true;
4671  }
4672  }
4673 
4674  //============================================================================
4675  // Method Description:
4681  void newArray(const Shape& inShape)
4682  {
4683  deleteArray();
4684 
4685  shape_ = inShape;
4686  size_ = inShape.size();
4687  newArray();
4688  }
4689  };
4690 
4691  // NOTE: this needs to be defined outside of the class to get rid of a compiler
4692  // error in Visual Studio
4693  template<typename dtype, class _Alloc>
4694  std::pair<NdArray<uint32>, NdArray<uint32>> NdArray<dtype, _Alloc>::nonzero() const
4695  {
4697 
4698  std::vector<uint32> rowIndices;
4699  std::vector<uint32> colIndices;
4700 
4701  for (uint32 row = 0; row < shape_.rows; ++row)
4702  {
4703  for (uint32 col = 0; col < shape_.cols; ++col)
4704  {
4705  if (operator()(row, col) != dtype{ 0 })
4706  {
4707  rowIndices.push_back(row);
4708  colIndices.push_back(col);
4709  }
4710  }
4711  }
4712 
4713  return std::make_pair(NdArray<uint32>(rowIndices), NdArray<uint32>(colIndices));
4714  }
4715 } // namespace nc
nc::NdArray::rcolend
const_reverse_column_iterator rcolend() const noexcept
Definition: NdArrayCore.hpp:1723
STATIC_ASSERT_INTEGER
#define STATIC_ASSERT_INTEGER(dtype)
Definition: StaticAsserts.hpp:41
nc::NdArray< dtype >::const_reverse_column_iterator
std::reverse_iterator< const_column_iterator > const_reverse_column_iterator
Definition: NdArrayCore.hpp:102
StaticAsserts.hpp
nc::NdArray::crbegin
const_reverse_iterator crbegin(size_type inRow) const
Definition: NdArrayCore.hpp:1333
nc::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: TypeTraits.hpp:41
nc::NdArray::item
value_type item() const
Definition: NdArrayCore.hpp:2958
nc::NdArray::colbegin
column_iterator colbegin(size_type inCol)
Definition: NdArrayCore.hpp:1191
nc::NdArray::contains
NdArray< bool > contains(value_type inValue, Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2348
nc::Slice::stop
int32 stop
Definition: Slice.hpp:49
nc::NdArray::put
NdArray< dtype > & put(int32 inRowIndex, const Slice &inColSlice, value_type inValue)
Definition: NdArrayCore.hpp:3862
nc::NdArray::cend
const_iterator cend(size_type inRow) const
Definition: NdArrayCore.hpp:1505
nc::NdArray::any
NdArray< bool > any(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1840
nc::NdArray::toStlVector
std::vector< dtype > toStlVector() const
Definition: NdArrayCore.hpp:4537
nc::NdArray::shape
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4312
nc::Axis::NONE
@ NONE
nc::int32
std::int32_t int32
Definition: Types.hpp:37
nc::NdArray::operator=
NdArray< dtype > & operator=(NdArray< dtype > &&rhs) noexcept
Definition: NdArrayCore.hpp:618
nc::NdArrayColumnIterator
Custom column iterator for NdArray.
Definition: NdArrayIterators.hpp:828
nc::NdArray::cbegin
const_iterator cbegin(size_type inRow) const
Definition: NdArrayCore.hpp:1161
nc::NdArray< dtype >::reverse_column_iterator
std::reverse_iterator< column_iterator > reverse_column_iterator
Definition: NdArrayCore.hpp:101
nc::NdArray::NdArray
NdArray(const NdArray< dtype > &inOtherArray)
Definition: NdArrayCore.hpp:523
nc::Slice::makePositiveAndValidate
void makePositiveAndValidate(uint32 inArraySize)
Definition: Slice.hpp:114
Error.hpp
STATIC_ASSERT_ARITHMETIC
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:38
nc::Axis::ROW
@ ROW
nc::NdArray::dot
NdArray< dtype > dot(const NdArray< dtype > &inOtherArray) const
Definition: NdArrayCore.hpp:2644
nc::NdArray::sort
NdArray< dtype > & sort(Axis inAxis=Axis::NONE)
Definition: NdArrayCore.hpp:4342
nc::Endian::BIG
@ BIG
nc::NdArray::NdArray
NdArray()=default
StdComplexOperators.hpp
nc::NdArray::operator[]
reference operator[](int32 inIndex) noexcept
Definition: NdArrayCore.hpp:646
nc::NdArray::put
NdArray< dtype > & put(const Slice &inRowSlice, const Slice &inColSlice, value_type inValue)
Definition: NdArrayCore.hpp:3808
nc::NdArray::round
NdArray< dtype > round(uint8 inNumDecimals=0) const
Definition: NdArrayCore.hpp:4274
nc::NdArray::copy
NdArray< dtype > copy() const
Definition: NdArrayCore.hpp:2397
nc::NdArray::at
NdArray< dtype > at(int32 inRowIndex, const Slice &inColSlice) const
Definition: NdArrayCore.hpp:1078
nc::NdArray::back
reference back(size_type row)
Definition: NdArrayCore.hpp:2257
nc::NdArray::nans
NdArray< dtype > & nans() noexcept
Definition: NdArrayCore.hpp:3193
nc::NdArray::begin
const_iterator begin() const noexcept
Definition: NdArrayCore.hpp:1121
nc::NdArray::at
reference at(int32 inIndex)
Definition: NdArrayCore.hpp:920
nc::NdArray::operator()
NdArray< dtype > operator()(const Slice &inRowSlice, int32 inColIndex) const
Definition: NdArrayCore.hpp:841
nc::NdArray::trace
value_type trace(uint32 inOffset=0, Axis inAxis=Axis::ROW) const noexcept
Definition: NdArrayCore.hpp:4554
nc::NdArray::at
NdArray< dtype > at(const Slice &inRowSlice, int32 inColIndex) const
Definition: NdArrayCore.hpp:1062
nc::NdArray::NdArray
NdArray(std::vector< std::array< dtype, Dim1Size >> &in2dArray, bool copy=true)
Definition: NdArrayCore.hpp:330
nc::NdArray::NdArray
NdArray(std::array< dtype, ArraySize > &inArray, bool copy=true)
Definition: NdArrayCore.hpp:213
nc::NdArray::operator[]
NdArray< dtype > operator[](const NdArray< bool > &inMask) const
Definition: NdArrayCore.hpp:756
nc::NdArray::reshape
NdArray< dtype > & reshape(const Shape &inShape)
Definition: NdArrayCore.hpp:4169
Constants.hpp
nc::NdArray::crcolbegin
const_reverse_column_iterator crcolbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1419
nc::NdArray::resizeSlow
NdArray< dtype > & resizeSlow(const Shape &inShape)
Definition: NdArrayCore.hpp:4257
nc::NdArray::NdArray
NdArray(const std::initializer_list< dtype > &inList)
Definition: NdArrayCore.hpp:159
nc::NdArray< dtype >::const_reference
const dtype & const_reference
Definition: NdArrayCore.hpp:90
nc::uint8
std::uint8_t uint8
Definition: Types.hpp:43
nc::NdArray::reshape
NdArray< dtype > & reshape(size_type inSize)
Definition: NdArrayCore.hpp:4089
nc::uint64
std::uint64_t uint64
Definition: Types.hpp:40
nc::NdArray::put
NdArray< dtype > & put(int32 inRowIndex, const Slice &inColSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3942
nc::NdArray::tofile
void tofile(const std::string &inFilename, const std::string &inSep="") const
Definition: NdArrayCore.hpp:4495
nc::utils::num2str
std::string num2str(dtype inNumber)
Definition: num2str.hpp:47
nc::NdArray::issquare
bool issquare() const noexcept
Definition: NdArrayCore.hpp:2944
nc::NdArray::prod
NdArray< dtype > prod(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3573
nc::NdArray::diagonal
NdArray< dtype > diagonal(int32 inOffset=0, Axis inAxis=Axis::ROW) const
Definition: NdArrayCore.hpp:2574
nc::NdArray::operator=
NdArray< dtype > & operator=(const NdArray< dtype > &rhs)
Definition: NdArrayCore.hpp:573
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX
#define STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype)
Definition: StaticAsserts.hpp:51
nc::NdArray::putMask
NdArray< dtype > & putMask(const NdArray< bool > &inMask, value_type inValue)
Definition: NdArrayCore.hpp:3964
nc::NdArray::rend
const_reverse_iterator rend() const noexcept
Definition: NdArrayCore.hpp:1551
nc::NdArray::const_column_iterator
NdArrayConstColumnIterator< dtype, size_type, const_pointer, difference_type > const_column_iterator
Definition: NdArrayCore.hpp:100
nc::NdArray::at
const_reference at(int32 inRowIndex, int32 inColIndex) const
Definition: NdArrayCore.hpp:998
nc::NdArray::transpose
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4608
nc::NdArray::nbytes
uint64 nbytes() const noexcept
Definition: NdArrayCore.hpp:3210
nc::NdArray::byteswap
NdArray< dtype > & byteswap()
Definition: NdArrayCore.hpp:2271
nc::NdArray::getByMask
NdArray< dtype > getByMask(const NdArray< bool > &inMask) const
Definition: NdArrayCore.hpp:2855
nc::NdArray< dtype >::size_type
uint32 size_type
Definition: NdArrayCore.hpp:91
nc::NdArray::ccolend
const_column_iterator ccolend() const noexcept
Definition: NdArrayCore.hpp:1663
nc::NdArray::crend
const_reverse_iterator crend(size_type inRow) const
Definition: NdArrayCore.hpp:1591
nc::NdArray::at
const_reference at(int32 inIndex) const
Definition: NdArrayCore.hpp:943
nc::NdArray::max
NdArray< dtype > max(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2979
nc::NdArray::NdArray
NdArray(const std::initializer_list< std::initializer_list< dtype > > &inList)
Definition: NdArrayCore.hpp:177
nc::NdArray< dtype >::const_pointer
typename AllocTraits::const_pointer const_pointer
Definition: NdArrayCore.hpp:88
nc::NdArray
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:75
nc::Shape::issquare
constexpr bool issquare() const noexcept
Definition: Core/Shape.hpp:124
nc::NdArray::put
NdArray< dtype > & put(const NdArray< uint32 > &inIndices, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3737
nc::NdArray::end
iterator end(size_type inRow)
Definition: NdArrayCore.hpp:1449
nc::NdArray::front
value_type front() const noexcept
Definition: NdArrayCore.hpp:2789
nc::NdArray::back
value_type back(size_type row) const
Definition: NdArrayCore.hpp:2245
nc::NdArray::rcolend
reverse_column_iterator rcolend(size_type inCol)
Definition: NdArrayCore.hpp:1707
nc::NdArray::put
NdArray< dtype > & put(const Slice &inRowSlice, const Slice &inColSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3886
nc::NdArray::back
value_type back() const noexcept
Definition: NdArrayCore.hpp:2221
nc::NdArray::ownsInternalData
bool ownsInternalData() noexcept
Definition: NdArrayCore.hpp:3468
nc::NdArray::front
reference front() noexcept
Definition: NdArrayCore.hpp:2801
nc::NdArray< dtype >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: NdArrayCore.hpp:97
nc::NdArray::at
NdArray< dtype > at(const Slice &inSlice) const
Definition: NdArrayCore.hpp:1030
nc::stl_algorithms::transform
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:703
nc::NdArray::clip
NdArray< dtype > clip(value_type inMin, value_type inMax) const
Definition: NdArrayCore.hpp:2312
nc::constants::j
constexpr auto j
Definition: Constants.hpp:46
nc::uint32
std::uint32_t uint32
Definition: Types.hpp:41
nc::NdArray::rSlice
Slice rSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:906
nc::NdArray::NdArray
NdArray(std::vector< dtype > &inVector, bool copy=true)
Definition: NdArrayCore.hpp:270
nc::stl_algorithms::is_sorted
bool is_sorted(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:232
nc::NdArray< dtype >::allocator_type
std::allocator< dtype > allocator_type
Definition: NdArrayCore.hpp:86
nc::NdArray::crend
const_reverse_iterator crend() const noexcept
Definition: NdArrayCore.hpp:1577
nc::NdArray::colend
const_column_iterator colend(size_type inCol) const
Definition: NdArrayCore.hpp:1651
nc::NdArray::cSlice
Slice cSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:891
nc::NdArray::numCols
uint32 numCols() const noexcept
Definition: NdArrayCore.hpp:3431
nc::NdArray::iterator
NdArrayIterator< dtype, pointer, difference_type > iterator
Definition: NdArrayCore.hpp:94
nc::NdArrayConstColumnIterator
Custom column const_iterator for NdArray.
Definition: NdArrayIterators.hpp:497
nc::NdArray::str
std::string str() const
Definition: NdArrayCore.hpp:4389
nc::NdArray::colend
column_iterator colend() noexcept
Definition: NdArrayCore.hpp:1607
nc::NdArray::newbyteorder
NdArray< dtype > newbyteorder(Endian inEndianess) const
Definition: NdArrayCore.hpp:3229
num2str.hpp
nc::NdArray::dataRelease
pointer dataRelease() noexcept
Definition: NdArrayCore.hpp:2557
nc::Shape
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:41
nc::stl_algorithms::max_element
ForwardIt max_element(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:269
nc::NdArray::put
NdArray< dtype > & put(int32 inIndex, value_type inValue)
Definition: NdArrayCore.hpp:3685
nc::NdArray::reshape
NdArray< dtype > & reshape(int32 inNumRows, int32 inNumCols)
Definition: NdArrayCore.hpp:4116
nc::stl_algorithms::all_of
bool all_of(InputIt first, InputIt last, UnaryPredicate p) noexcept
Definition: StlAlgorithms.hpp:58
nc::NdArray::ccolbegin
const_column_iterator ccolbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1247
nc::Slice::start
int32 start
Definition: Slice.hpp:48
nc::stl_algorithms::fill
void fill(ForwardIt first, ForwardIt last, const T &value) noexcept
Definition: StlAlgorithms.hpp:175
STATIC_ASSERT_FLOAT
#define STATIC_ASSERT_FLOAT(dtype)
Definition: StaticAsserts.hpp:44
nc::NdArray::column
NdArray< dtype > column(uint32 inColumn)
Definition: NdArrayCore.hpp:2334
nc::stl_algorithms::copy
OutputIt copy(InputIt first, InputIt last, OutputIt destination) noexcept
Definition: StlAlgorithms.hpp:96
nc::NdArray::isflat
bool isflat() const noexcept
Definition: NdArrayCore.hpp:2881
nc::NdArray::end
const_iterator end() const noexcept
Definition: NdArrayCore.hpp:1465
nc::NdArray::rend
const_reverse_iterator rend(size_type inRow) const
Definition: NdArrayCore.hpp:1565
nc::NdArray::NdArray
NdArray(const Shape &inShape)
Definition: NdArrayCore.hpp:145
nc::NdArray::colbegin
column_iterator colbegin() noexcept
Definition: NdArrayCore.hpp:1177
nc::NdArray::colend
column_iterator colend(size_type inCol)
Definition: NdArrayCore.hpp:1621
nc::NdArray::end
iterator end() noexcept
Definition: NdArrayCore.hpp:1435
nc::Endian
Endian
Enum for endianess.
Definition: Types.hpp:51
nc::NdArray::rbegin
const_reverse_iterator rbegin(size_type inRow) const
Definition: NdArrayCore.hpp:1307
nc::NdArray::NdArray
NdArray(const_pointer inPtr, uint32 numRows, uint32 numCols)
Definition: NdArrayCore.hpp:466
nc::NdArray::size
size_type size() const noexcept
Definition: NdArrayCore.hpp:4326
nc::Shape::cols
uint32 cols
Definition: Core/Shape.hpp:46
nc::NdArray::rcolend
reverse_column_iterator rcolend() noexcept
Definition: NdArrayCore.hpp:1693
nc::NdArray::repeat
NdArray< dtype > repeat(const Shape &inRepeatShape) const
Definition: NdArrayCore.hpp:4059
nc::NdArray::dump
void dump(const std::string &inFilename) const
Definition: NdArrayCore.hpp:2688
nc::NdArray::sum
NdArray< dtype > sum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:4427
nc::NdArray::swapaxes
NdArray< dtype > swapaxes() const
Definition: NdArrayCore.hpp:4477
nc::NdArray::rbegin
const_reverse_iterator rbegin() const noexcept
Definition: NdArrayCore.hpp:1293
nc::NdArray< dtype >::reference
dtype & reference
Definition: NdArrayCore.hpp:89
nc::NdArray::operator=
NdArray< dtype > & operator=(value_type inValue) noexcept
Definition: NdArrayCore.hpp:599
nc::NdArray::put
NdArray< dtype > & put(const Slice &inRowSlice, int32 inColIndex, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3917
nc::NdArray::rcolbegin
reverse_column_iterator rcolbegin() noexcept
Definition: NdArrayCore.hpp:1349
nc::NdArray::cend
const_iterator cend() const noexcept
Definition: NdArrayCore.hpp:1491
nc::NdArray::NdArray
NdArray(NdArray< dtype > &&inOtherArray) noexcept
Definition: NdArrayCore.hpp:542
nc::NdArray::rcolend
const_reverse_column_iterator rcolend(size_type inCol) const
Definition: NdArrayCore.hpp:1737
nc::Slice::numElements
uint32 numElements(uint32 inArraySize)
Definition: Slice.hpp:165
nc::Axis
Axis
Enum To describe an axis.
Definition: Types.hpp:47
nc::stl_algorithms::find
InputIt find(InputIt first, InputIt last, const T &value) noexcept
Definition: StlAlgorithms.hpp:196
THROW_RUNTIME_ERROR
#define THROW_RUNTIME_ERROR(msg)
Definition: Error.hpp:38
nc::NdArray::put
NdArray< dtype > & put(const Slice &inRowSlice, int32 inColIndex, value_type inValue)
Definition: NdArrayCore.hpp:3838
nc::stl_algorithms::nth_element
void nth_element(RandomIt first, RandomIt nth, RandomIt last) noexcept
Definition: StlAlgorithms.hpp:398
nc::NdArray< dtype >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: NdArrayCore.hpp:96
nc::constants::nan
const double nan
NaN.
Definition: Constants.hpp:45
power.hpp
nc::NdArray::rend
reverse_iterator rend(size_type inRow)
Definition: NdArrayCore.hpp:1535
nc::Slice::step
int32 step
Definition: Slice.hpp:50
nc::NdArray::put
NdArray< dtype > & put(const Slice &inSlice, value_type inValue)
Definition: NdArrayCore.hpp:3762
nc::NdArray::zeros
NdArray< dtype > & zeros() noexcept
Definition: NdArrayCore.hpp:4626
Shape.hpp
nc::NdArray::flatten
NdArray< dtype > flatten() const
Definition: NdArrayCore.hpp:2775
nc::NdArray::put
NdArray< dtype > & put(const Slice &inSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3784
Filesystem.hpp
nc::NdArray::cumsum
NdArray< dtype > cumsum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2477
nc::NdArray::ones
NdArray< dtype > & ones() noexcept
Definition: NdArrayCore.hpp:3454
nc::NdArray::NdArray
NdArray(const std::deque< dtype > &inDeque)
Definition: NdArrayCore.hpp:357
nc::NdArray< dtype >::value_type
dtype value_type
Definition: NdArrayCore.hpp:85
nc::NdArray::endianess
Endian endianess() const noexcept
Definition: NdArrayCore.hpp:2716
nc::NdArray::NdArray
NdArray(size_type inSquareSize)
Definition: NdArrayCore.hpp:117
nc
Definition: Coordinate.hpp:45
nc::NdArray::ccolbegin
const_column_iterator ccolbegin() const noexcept
Definition: NdArrayCore.hpp:1233
nc::stl_algorithms::any_of
bool any_of(InputIt first, InputIt last, UnaryPredicate p) noexcept
Definition: StlAlgorithms.hpp:77
nc::NdArray::data
pointer data() noexcept
Definition: NdArrayCore.hpp:2535
nc::NdArray::ccolend
const_column_iterator ccolend(size_type inCol) const
Definition: NdArrayCore.hpp:1677
nc::NdArray::crcolbegin
const_reverse_column_iterator crcolbegin() const noexcept
Definition: NdArrayCore.hpp:1405
nc::NdArray::rend
reverse_iterator rend() noexcept
Definition: NdArrayCore.hpp:1521
nc::NdArray::at
reference at(int32 inRowIndex, int32 inColIndex)
Definition: NdArrayCore.hpp:966
nc::Shape::rows
uint32 rows
Definition: Core/Shape.hpp:45
nc::NdArray::operator()
NdArray< dtype > operator()(int32 inRowIndex, const Slice &inColSlice) const
Definition: NdArrayCore.hpp:866
nc::NdArray::argmin
NdArray< uint32 > argmin(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1957
sqr.hpp
nc::int64
std::int64_t int64
Definition: Types.hpp:36
DtypeInfo.hpp
nc::stl_algorithms::replace
void replace(ForwardIt first, ForwardIt last, const T &oldValue, const T &newValue) noexcept
Definition: StlAlgorithms.hpp:436
nc::NdArrayConstIterator
Custom const_iterator for NdArray.
Definition: NdArrayIterators.hpp:43
nc::NdArray::operator[]
NdArray< dtype > operator[](const Slice &inSlice) const
Definition: NdArrayCore.hpp:733
nc::NdArray::row
NdArray< dtype > row(uint32 inRow)
Definition: NdArrayCore.hpp:4298
nc::NdArray::column_iterator
NdArrayColumnIterator< dtype, size_type, pointer, difference_type > column_iterator
Definition: NdArrayCore.hpp:99
nc::NdArray::NdArray
NdArray(pointer inPtr, uint32 numRows, uint32 numCols, Bool takeOwnership) noexcept
Definition: NdArrayCore.hpp:509
nc::NdArray::argsort
NdArray< uint32 > argsort(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2016
nc::NdArray::getByIndices
NdArray< dtype > getByIndices(const NdArray< uint32 > &inIndices) const
Definition: NdArrayCore.hpp:2839
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
nc::NdArrayIterator
Custom iterator for NdArray.
Definition: NdArrayIterators.hpp:318
nc::NdArray::rbegin
reverse_iterator rbegin() noexcept
Definition: NdArrayCore.hpp:1263
nc::NdArray::put
NdArray< dtype > & put(int32 inRow, int32 inCol, value_type inValue)
Definition: NdArrayCore.hpp:3702
nc::Shape::size
constexpr uint32 size() const noexcept
Definition: Core/Shape.hpp:103
nc::utils::power
dtype power(dtype inValue, uint8 inPower) noexcept
Definition: Utils/power.hpp:49
nc::NdArray::cbegin
const_iterator cbegin() const noexcept
Definition: NdArrayCore.hpp:1147
nc::NdArray::cumprod
NdArray< dtype > cumprod(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2413
nc::stl_algorithms::sort
void sort(RandomIt first, RandomIt last) noexcept
Definition: StlAlgorithms.hpp:630
StlAlgorithms.hpp
nc::NdArray::NdArray
NdArray(const std::deque< std::deque< dtype >> &in2dDeque)
Definition: NdArrayCore.hpp:374
nc::NdArray::end
const_iterator end(size_type inRow) const
Definition: NdArrayCore.hpp:1479
nc::NdArray::back
reference back() noexcept
Definition: NdArrayCore.hpp:2233
nc::NdArray::astype
NdArray< dtypeOut > astype() const
Definition: NdArrayCore.hpp:2102
nc::NdArray::const_iterator
NdArrayConstIterator< dtype, const_pointer, difference_type > const_iterator
Definition: NdArrayCore.hpp:95
nc::NdArray::colbegin
const_column_iterator colbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1221
nc::NdArray::NdArray
NdArray(const std::vector< std::vector< dtype >> &in2dVector)
Definition: NdArrayCore.hpp:295
nc::stl_algorithms::min_element
ForwardIt min_element(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:305
nc::NdArray::resizeFast
NdArray< dtype > & resizeFast(uint32 inNumRows, uint32 inNumCols)
Definition: NdArrayCore.hpp:4184
nc::NdArray::colbegin
const_column_iterator colbegin() const noexcept
Definition: NdArrayCore.hpp:1207
nc::NdArray::operator()
const_reference operator()(int32 inRowIndex, int32 inColIndex) const noexcept
Definition: NdArrayCore.hpp:708
nc::NdArray::crcolend
const_reverse_column_iterator crcolend(size_type inCol) const
Definition: NdArrayCore.hpp:1763
nc::NdArray::argmax
NdArray< uint32 > argmax(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1897
nc::NdArray::flatnonzero
NdArray< uint32 > flatnonzero() const
Definition: NdArrayCore.hpp:2748
nc::NdArray::replace
void replace(value_type oldValue, value_type newValue)
Definition: NdArrayCore.hpp:4071
value2str.hpp
nc::NdArray::operator()
reference operator()(int32 inRowIndex, int32 inColIndex) noexcept
Definition: NdArrayCore.hpp:684
nc::stl_algorithms::stable_sort
void stable_sort(RandomIt first, RandomIt last) noexcept
Definition: StlAlgorithms.hpp:665
nc::NdArray::putMask
NdArray< dtype > & putMask(const NdArray< bool > &inMask, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3981
nc::NdArray::rcolbegin
const_reverse_column_iterator rcolbegin(size_type inCol) const
Definition: NdArrayCore.hpp:1393
nc::NdArray::none
NdArray< bool > none(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3365
nc::stl_algorithms::minmax_element
std::pair< ForwardIt, ForwardIt > minmax_element(ForwardIt first, ForwardIt last) noexcept
Definition: StlAlgorithms.hpp:342
nc::NdArray::isempty
bool isempty() const noexcept
Definition: NdArrayCore.hpp:2868
nc::NdArray::front
value_type front(size_type row) const
Definition: NdArrayCore.hpp:2813
nc::NdArray::crbegin
const_reverse_iterator crbegin() const noexcept
Definition: NdArrayCore.hpp:1319
Types.hpp
nc::NdArray::nonzero
std::pair< NdArray< uint32 >, NdArray< uint32 > > nonzero() const
Definition: NdArrayCore.hpp:4694
nc::NdArray::rcolbegin
const_reverse_column_iterator rcolbegin() const noexcept
Definition: NdArrayCore.hpp:1379
nc::NdArray::NdArray
NdArray(pointer inPtr, size_type size, Bool takeOwnership) noexcept
Definition: NdArrayCore.hpp:489
nc::NdArray::numRows
uint32 numRows() const noexcept
Definition: NdArrayCore.hpp:3444
nc::NdArray::front
reference front(size_type row)
Definition: NdArrayCore.hpp:2825
nc::NdArray::begin
iterator begin() noexcept
Definition: NdArrayCore.hpp:1091
nc::NdArray::at
NdArray< dtype > at(const Slice &inRowSlice, const Slice &inColSlice) const
Definition: NdArrayCore.hpp:1046
nc::Axis::COL
@ COL
nc::random::f
dtype f(dtype inDofN, dtype inDofD)
Definition: f.hpp:58
nc::utils::value2str
std::string value2str(dtype inValue)
Definition: value2str.hpp:49
nc::NdArray::rbegin
reverse_iterator rbegin(size_type inRow)
Definition: NdArrayCore.hpp:1277
nc::NdArray::rcolbegin
reverse_column_iterator rcolbegin(size_type inCol)
Definition: NdArrayCore.hpp:1363
nc::Slice
A Class for slicing into NdArrays.
Definition: Slice.hpp:44
nc::NdArray::resizeFast
NdArray< dtype > & resizeFast(const Shape &inShape)
Definition: NdArrayCore.hpp:4200
nc::NdArray::ptp
NdArray< dtype > ptp(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3628
nc::NdArray::NdArray
NdArray(const std::list< dtype > &inList)
Definition: NdArrayCore.hpp:407
nc::NdArray::operator[]
const_reference operator[](int32 inIndex) const noexcept
Definition: NdArrayCore.hpp:665
nc::NdArray::data
const_pointer data() const noexcept
Definition: NdArrayCore.hpp:2545
nc::NdArray::operator[]
NdArray< dtype > operator[](const NdArray< size_type > &inIndices) const
Definition: NdArrayCore.hpp:782
nc::NdArray::NdArray
NdArray(std::array< std::array< dtype, Dim1Size >, Dim0Size > &in2dArray, bool copy=true)
Definition: NdArrayCore.hpp:241
nc::NdArray::NdArray
NdArray(const_pointer inPtr, size_type size)
Definition: NdArrayCore.hpp:446
nc::stl_algorithms::none_of
bool none_of(InputIt first, InputIt last, UnaryPredicate p) noexcept
Definition: StlAlgorithms.hpp:380
nc::NdArray< dtype >::pointer
typename AllocTraits::pointer pointer
Definition: NdArrayCore.hpp:87
nc::NdArray::colend
const_column_iterator colend() const noexcept
Definition: NdArrayCore.hpp:1637
nc::NdArray::partition
NdArray< dtype > & partition(uint32 inKth, Axis inAxis=Axis::NONE)
Definition: NdArrayCore.hpp:3489
nc::NdArray::issorted
NdArray< bool > issorted(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2893
NdArrayIterators.hpp
nc::NdArray::crcolend
const_reverse_column_iterator crcolend() const noexcept
Definition: NdArrayCore.hpp:1749
nc::NdArray::fill
NdArray< dtype > & fill(value_type inFillValue) noexcept
Definition: NdArrayCore.hpp:2734
nc::NdArray::NdArray
NdArray(Iterator inFirst, Iterator inLast)
Definition: NdArrayCore.hpp:427
nc::Endian::LITTLE
@ LITTLE
nc::Endian::NATIVE
@ NATIVE
nc::NdArray::all
NdArray< bool > all(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:1784
nc::NdArray::~NdArray
~NdArray() noexcept
Definition: NdArrayCore.hpp:559
nc::NdArray::begin
const_iterator begin(size_type inRow) const
Definition: NdArrayCore.hpp:1135
nc::NdArray::median
NdArray< dtype > median(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3095
TypeTraits.hpp
nc::NdArray::ravel
NdArray< dtype > & ravel() noexcept
Definition: NdArrayCore.hpp:3999
nc::NdArray::repeat
NdArray< dtype > repeat(uint32 inNumRows, uint32 inNumCols) const
Definition: NdArrayCore.hpp:4016
nc::NdArray< dtype >::difference_type
typename AllocTraits::difference_type difference_type
Definition: NdArrayCore.hpp:92
nc::NdArray::NdArray
NdArray(size_type inNumRows, size_type inNumCols)
Definition: NdArrayCore.hpp:131
nc::NdArray::print
void print() const
Definition: NdArrayCore.hpp:3555
Slice.hpp
nc::filesystem::File
Provides simple filesystem functions.
Definition: Filesystem.hpp:40
nc::NdArray::put
NdArray< dtype > & put(const NdArray< uint32 > &inIndices, value_type inValue)
Definition: NdArrayCore.hpp:3718
nc::NdArray::begin
iterator begin(size_type inRow)
Definition: NdArrayCore.hpp:1105
nc::abs
auto abs(dtype inValue) noexcept
Definition: abs.hpp:52
nc::NdArray::resizeSlow
NdArray< dtype > & resizeSlow(uint32 inNumRows, uint32 inNumCols)
Definition: NdArrayCore.hpp:4217
nc::NdArray::operator()
NdArray< dtype > operator()(const Slice &inRowSlice, const Slice &inColSlice) const
Definition: NdArrayCore.hpp:809
nc::NdArray::min
NdArray< dtype > min(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3036