NumCpp  1.0
A C++ implementation of the Python Numpy library
NdArrayCore.hpp
Go to the documentation of this file.
1 #pragma once
30 
33 #include "NumCpp/Core/Shape.hpp"
34 #include "NumCpp/Core/Slice.hpp"
35 #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  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:
446  explicit NdArray(const_pointer inPtr, size_type size) :
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  explicit 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  explicit 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  const 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  const 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  return NdArray<bool>(); // get rid of compiler warning
1824  }
1825  }
1826  }
1827 
1828  //============================================================================
1829  // Method Description:
1840  {
1842 
1843  const auto function = [](dtype i) -> bool
1844  {
1845  return i != dtype{ 0 };
1846  };
1847 
1848  switch (inAxis)
1849  {
1850  case Axis::NONE:
1851  {
1852  NdArray<bool> returnArray = { stl_algorithms::any_of(cbegin(), cend(), function) };
1853  return returnArray;
1854  }
1855  case Axis::COL:
1856  {
1857  NdArray<bool> returnArray(1, shape_.rows);
1858  for (uint32 row = 0; row < shape_.rows; ++row)
1859  {
1860  returnArray(0, row) = stl_algorithms::any_of(cbegin(row), cend(row), function);
1861  }
1862 
1863  return returnArray;
1864  }
1865  case Axis::ROW:
1866  {
1867  NdArray<dtype> arrayTransposed = transpose();
1868  NdArray<bool> returnArray(1, arrayTransposed.shape_.rows);
1869  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1870  {
1871  returnArray(0, row) = stl_algorithms::any_of(arrayTransposed.cbegin(row), arrayTransposed.cend(row), function);
1872  }
1873 
1874  return returnArray;
1875  }
1876  default:
1877  {
1878  return NdArray<bool>(); // get rid of compiler warning
1879  }
1880  }
1881  }
1882 
1883  //============================================================================
1884  // Method Description:
1896  {
1898 
1899  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
1900  {
1901  return lhs < rhs;
1902  };
1903 
1904  switch (inAxis)
1905  {
1906  case Axis::NONE:
1907  {
1908  NdArray<uint32> returnArray = { static_cast<uint32>(stl_algorithms::max_element(cbegin(),
1909  cend(), comparitor) - cbegin()) };
1910  return returnArray;
1911  }
1912  case Axis::COL:
1913  {
1914  NdArray<uint32> returnArray(1, shape_.rows);
1915  for (uint32 row = 0; row < shape_.rows; ++row)
1916  {
1917  returnArray(0, row) = static_cast<uint32>(stl_algorithms::max_element(cbegin(row),
1918  cend(row), comparitor) - cbegin(row));
1919  }
1920 
1921  return returnArray;
1922  }
1923  case Axis::ROW:
1924  {
1925  NdArray<dtype> arrayTransposed = transpose();
1926  NdArray<uint32> returnArray(1, arrayTransposed.shape_.rows);
1927  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1928  {
1929  returnArray(0, row) = static_cast<uint32>(stl_algorithms::max_element(arrayTransposed.cbegin(row),
1930  arrayTransposed.cend(row), comparitor) - arrayTransposed.cbegin(row));
1931  }
1932 
1933  return returnArray;
1934  }
1935  default:
1936  {
1937  return NdArray<uint32>(); // get rid of compiler warning
1938  }
1939  }
1940  }
1941 
1942  //============================================================================
1943  // Method Description:
1955  {
1957 
1958  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
1959  {
1960  return lhs < rhs;
1961  };
1962 
1963  switch (inAxis)
1964  {
1965  case Axis::NONE:
1966  {
1967  NdArray<uint32> returnArray = { static_cast<uint32>(stl_algorithms::min_element(cbegin(),
1968  cend(), comparitor) - cbegin()) };
1969  return returnArray;
1970  }
1971  case Axis::COL:
1972  {
1973  NdArray<uint32> returnArray(1, shape_.rows);
1974  for (uint32 row = 0; row < shape_.rows; ++row)
1975  {
1976  returnArray(0, row) = static_cast<uint32>(stl_algorithms::min_element(cbegin(row),
1977  cend(row), comparitor) - cbegin(row));
1978  }
1979 
1980  return returnArray;
1981  }
1982  case Axis::ROW:
1983  {
1984  NdArray<dtype> arrayTransposed = transpose();
1985  NdArray<uint32> returnArray(1, arrayTransposed.shape_.rows);
1986  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
1987  {
1988  returnArray(0, row) = static_cast<uint32>(stl_algorithms::min_element(arrayTransposed.cbegin(row),
1989  arrayTransposed.cend(row), comparitor) - arrayTransposed.cbegin(row));
1990  }
1991 
1992  return returnArray;
1993  }
1994  default:
1995  {
1996  return NdArray<uint32>(); // get rid of compiler warning
1997  }
1998  }
1999  }
2000 
2001  //============================================================================
2002  // Method Description:
2013  {
2015 
2016  switch (inAxis)
2017  {
2018  case Axis::NONE:
2019  {
2020  std::vector<uint32> idx(size_);
2021  std::iota(idx.begin(), idx.end(), 0);
2022 
2023  const auto function = [this](uint32 i1, uint32 i2) noexcept -> bool
2024  {
2025  return (*this)[i1] < (*this)[i2];
2026  };
2027 
2028  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2029  return NdArray<uint32>(idx);
2030  }
2031  case Axis::COL:
2032  {
2033  NdArray<uint32> returnArray(shape_);
2034  for (uint32 row = 0; row < shape_.rows; ++row)
2035  {
2036  std::vector<uint32> idx(shape_.cols);
2037  std::iota(idx.begin(), idx.end(), 0);
2038 
2039  const auto function = [this, row](uint32 i1, uint32 i2) noexcept -> bool
2040  {
2041  return operator()(row, i1) < operator()(row, i2);
2042  };
2043 
2044  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2045 
2046  for (uint32 col = 0; col < shape_.cols; ++col)
2047  {
2048  returnArray(row, col) = idx[col];
2049  }
2050  }
2051  return returnArray;
2052  }
2053  case Axis::ROW:
2054  {
2055  NdArray<dtype> arrayTransposed = transpose();
2056  NdArray<uint32> returnArray(shape_.cols, shape_.rows);
2057  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
2058  {
2059  std::vector<uint32> idx(arrayTransposed.shape_.cols);
2060  std::iota(idx.begin(), idx.end(), 0);
2061 
2062  const auto function = [&arrayTransposed, row](uint32 i1, uint32 i2) noexcept -> bool
2063  {
2064  return arrayTransposed(row, i1) < arrayTransposed(row, i2);
2065  };
2066 
2067  stl_algorithms::stable_sort(idx.begin(), idx.end(), function);
2068 
2069  for (uint32 col = 0; col < arrayTransposed.shape_.cols; ++col)
2070  {
2071  returnArray(row, col) = idx[col];
2072  }
2073  }
2074  return returnArray.transpose();
2075  }
2076  default:
2077  {
2078  return NdArray<uint32>(); // get rid of compiler warning
2079  }
2080  }
2081  }
2082 
2083  //============================================================================
2084  // Method Description:
2093  template<typename dtypeOut, typename dtype_ = dtype,
2098  {
2099  NdArray<dtypeOut> outArray(shape_);
2100 
2101  if (std::is_same<dtypeOut, dtype>::value)
2102  {
2103  std::copy(cbegin(), cend(), outArray.begin());
2104  }
2105  else
2106  {
2107  const auto function = [](dtype value) -> dtypeOut
2108  {
2109  return static_cast<dtypeOut>(value);
2110  };
2111 
2112  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2113  }
2114 
2115  return outArray;
2116  }
2117 
2118  //============================================================================
2119  // Method Description:
2128  template<typename dtypeOut, typename dtype_ = dtype,
2133  {
2134  NdArray<dtypeOut> outArray(shape_);
2135 
2136  const auto function = [](const_reference value) -> dtypeOut
2137  {
2138  return std::complex<typename dtypeOut::value_type>(value);
2139  };
2140 
2141  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2142 
2143  return outArray;
2144  }
2145 
2146  //============================================================================
2147  // Method Description:
2156  template<typename dtypeOut, typename dtype_ = dtype,
2161  {
2162  NdArray<dtypeOut> outArray(shape_);
2163 
2164  if (std::is_same<dtypeOut, dtype>::value)
2165  {
2166  std::copy(cbegin(), cend(), outArray.begin());
2167  }
2168  else
2169  {
2170  const auto function = [](const_reference value) noexcept -> dtypeOut
2171  {
2172  return complex_cast<typename dtypeOut::value_type>(value);
2173  };
2174 
2175  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2176  }
2177 
2178  return outArray;
2179  }
2180 
2181  //============================================================================
2182  // Method Description:
2191  template<typename dtypeOut, typename dtype_ = dtype,
2196  {
2197  NdArray<dtypeOut> outArray(shape_);
2198 
2199  const auto function = [](const_reference value) -> dtypeOut
2200  {
2201  return static_cast<dtypeOut>(value.real());
2202  };
2203 
2204  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
2205 
2206  return outArray;
2207  }
2208 
2209  //============================================================================
2210  // Method Description:
2216  value_type back() const noexcept
2217  {
2218  return *(cend() - 1);
2219  }
2220 
2221  //============================================================================
2222  // Method Description:
2228  reference back() noexcept
2229  {
2230  return *(end() - 1);
2231  }
2232 
2233  //============================================================================
2234  // Method Description:
2241  {
2242  return *(cend(row) - 1);
2243  }
2244 
2245  //============================================================================
2246  // Method Description:
2253  {
2254  return *(end(row) - 1);
2255  }
2256 
2257  //============================================================================
2258  // Method Description:
2267  {
2268  STATIC_ASSERT_INTEGER(dtype);
2269 
2270  switch (endianess_)
2271  {
2272  case Endian::BIG:
2273  {
2274  *this = newbyteorder(Endian::LITTLE);
2275  break;
2276  }
2277  case Endian::LITTLE:
2278  {
2279  *this = newbyteorder(Endian::BIG);
2280  break;
2281  }
2282  case Endian::NATIVE:
2283  {
2284 #if BOOST_ENDIAN_BIG_BYTE
2285  *this = newbyteorder(Endian::LITTLE);
2286 #elif BOOST_ENDIAN_LITTLE_BYTE
2287  *this = newbyteorder(Endian::BIG);
2288 #endif
2289  break;
2290  }
2291  }
2292 
2293  return *this;
2294  }
2295 
2296  //============================================================================
2297  // Method Description:
2308  {
2310 
2311  NdArray<dtype> outArray(shape_);
2312  boost::algorithm::clamp_range(cbegin(), cend(), outArray.begin(), inMin, inMax,
2313  [](dtype lhs, dtype rhs) noexcept -> bool
2314  {
2315  return lhs < rhs;
2316  });
2317 
2318  return outArray;
2319  }
2320 
2321  //============================================================================
2322  // Method Description:
2330  {
2331  return operator()(rSlice(), inColumn);
2332  }
2333 
2334  //============================================================================
2335  // Method Description:
2344  {
2346 
2347  switch (inAxis)
2348  {
2349  case Axis::NONE:
2350  {
2351  NdArray<bool> returnArray = { stl_algorithms::find(cbegin(), cend(), inValue) != cend() };
2352  return returnArray;
2353  }
2354  case Axis::COL:
2355  {
2356  NdArray<bool> returnArray(1, shape_.rows);
2357  for (uint32 row = 0; row < shape_.rows; ++row)
2358  {
2359  returnArray(0, row) = stl_algorithms::find(cbegin(row), cend(row), inValue) != cend(row);
2360  }
2361 
2362  return returnArray;
2363  }
2364  case Axis::ROW:
2365  {
2366  NdArray<dtype> transArray = transpose();
2367  NdArray<bool> returnArray(1, transArray.shape_.rows);
2368  for (uint32 row = 0; row < transArray.shape_.rows; ++row)
2369  {
2370  returnArray(0, row) = stl_algorithms::find(transArray.cbegin(row), transArray.cend(row), inValue) != transArray.cend(row);
2371  }
2372 
2373  return returnArray;
2374  }
2375  default:
2376  {
2377  return NdArray<bool>(); // get rid of compiler warning
2378  }
2379  }
2380  }
2381 
2382  //============================================================================
2383  // Method Description:
2392  {
2393  return NdArray<dtype>(*this);
2394  }
2395 
2396  //============================================================================
2397  // Method Description:
2408  {
2410 
2411  switch (inAxis)
2412  {
2413  case Axis::NONE:
2414  {
2415  NdArray<dtype> returnArray(1, size_);
2416  returnArray[0] = front();
2417  for (uint32 i = 1; i < size_; ++i)
2418  {
2419  returnArray[i] = returnArray[i - 1] * array_[i];
2420  }
2421 
2422  return returnArray;
2423  }
2424  case Axis::COL:
2425  {
2426  NdArray<dtype> returnArray(shape_);
2427  for (uint32 row = 0; row < shape_.rows; ++row)
2428  {
2429  returnArray(row, 0) = operator()(row, 0);
2430  for (uint32 col = 1; col < shape_.cols; ++col)
2431  {
2432  returnArray(row, col) = returnArray(row, col - 1) * operator()(row, col);
2433  }
2434  }
2435 
2436  return returnArray;
2437  }
2438  case Axis::ROW:
2439  {
2440  NdArray<dtype> returnArray(shape_);
2441  for (uint32 col = 0; col < shape_.cols; ++col)
2442  {
2443  returnArray(0, col) = operator()(0, col);
2444  for (uint32 row = 1; row < shape_.rows; ++row)
2445  {
2446  returnArray(row, col) = returnArray(row - 1, col) * operator()(row, col);
2447  }
2448  }
2449 
2450  return returnArray;
2451  }
2452  default:
2453  {
2454  return NdArray<dtype>(); // get rid of compiler warning
2455  }
2456  }
2457  }
2458 
2459  //============================================================================
2460  // Method Description:
2471  {
2473 
2474  switch (inAxis)
2475  {
2476  case Axis::NONE:
2477  {
2478  NdArray<dtype> returnArray(1, size_);
2479  returnArray[0] = front();
2480  for (uint32 i = 1; i < size_; ++i)
2481  {
2482  returnArray[i] = returnArray[i - 1] + array_[i];
2483  }
2484 
2485  return returnArray;
2486  }
2487  case Axis::COL:
2488  {
2489  NdArray<dtype> returnArray(shape_);
2490  for (uint32 row = 0; row < shape_.rows; ++row)
2491  {
2492  returnArray(row, 0) = operator()(row, 0);
2493  for (uint32 col = 1; col < shape_.cols; ++col)
2494  {
2495  returnArray(row, col) = returnArray(row, col - 1) + operator()(row, col);
2496  }
2497  }
2498 
2499  return returnArray;
2500  }
2501  case Axis::ROW:
2502  {
2503  NdArray<dtype> returnArray(shape_);
2504  for (uint32 col = 0; col < shape_.cols; ++col)
2505  {
2506  returnArray(0, col) = operator()(0, col);
2507  for (uint32 row = 1; row < shape_.rows; ++row)
2508  {
2509  returnArray(row, col) = returnArray(row - 1, col) + operator()(row, col);
2510  }
2511  }
2512 
2513  return returnArray;
2514  }
2515  default:
2516  {
2517  return NdArray<dtype>(); // get rid of compiler warning
2518  }
2519  }
2520  }
2521 
2522  //============================================================================
2523  // Method Description:
2527  pointer data() noexcept
2528  {
2529  return array_;
2530  }
2531 
2532  //============================================================================
2533  // Method Description:
2537  const_pointer data() const noexcept
2538  {
2539  return array_;
2540  }
2541 
2542  //============================================================================
2543  // Method Description:
2550  {
2551  ownsPtr_ = false;
2552  return data();
2553  }
2554 
2555  //============================================================================
2556  // Method Description:
2566  NdArray<dtype> diagonal(int32 inOffset = 0, Axis inAxis = Axis::ROW) const
2567  {
2568  switch (inAxis)
2569  {
2570  case Axis::ROW:
2571  {
2572  std::vector<dtype> diagnolValues;
2573  int32 col = inOffset;
2574  for (uint32 row = 0; row < shape_.rows; ++row)
2575  {
2576  if (col < 0)
2577  {
2578  ++col;
2579  continue;
2580  }
2581  else if (col >= static_cast<int32>(shape_.cols))
2582  {
2583  break;
2584  }
2585 
2586  diagnolValues.push_back(operator()(row, static_cast<uint32>(col)));
2587  ++col;
2588  }
2589 
2590  return NdArray<dtype>(diagnolValues);
2591  }
2592  case Axis::COL:
2593  {
2594  std::vector<dtype> diagnolValues;
2595  uint32 col = 0;
2596  for (int32 row = inOffset; row < static_cast<int32>(shape_.rows); ++row)
2597  {
2598  if (row < 0)
2599  {
2600  ++col;
2601  continue;
2602  }
2603  else if (col >= shape_.cols)
2604  {
2605  break;
2606  }
2607 
2608  diagnolValues.push_back(operator()(static_cast<uint32>(row), col));
2609  ++col;
2610  }
2611 
2612  return NdArray<dtype>(diagnolValues);
2613  }
2614  default:
2615  {
2616  return NdArray<dtype>(); // get rid of compiler warning
2617  }
2618  }
2619  }
2620 
2621  //============================================================================
2622  // Method Description:
2635  NdArray<dtype> dot(const NdArray<dtype>& inOtherArray) const
2636  {
2638 
2639  if (shape_ == inOtherArray.shape_ && (shape_.rows == 1 || shape_.cols == 1))
2640  {
2641  dtype dotProduct = std::inner_product(cbegin(), cend(), inOtherArray.cbegin(), dtype{ 0 });
2642  NdArray<dtype> returnArray = { dotProduct };
2643  return returnArray;
2644  }
2645  else if (shape_.cols == inOtherArray.shape_.rows)
2646  {
2647  // 2D array, use matrix multiplication
2648  NdArray<dtype> returnArray(shape_.rows, inOtherArray.shape_.cols);
2649  auto otherArrayT = inOtherArray.transpose();
2650 
2651  for (uint32 i = 0; i < shape_.rows; ++i)
2652  {
2653  for (uint32 j = 0; j < otherArrayT.shape_.rows; ++j)
2654  {
2655  returnArray(i, j) = std::inner_product(otherArrayT.cbegin(j), otherArrayT.cend(j), cbegin(i), dtype{ 0 });
2656  }
2657  }
2658 
2659  return returnArray;
2660  }
2661  else
2662  {
2663  std::string errStr = "shapes of [" + utils::num2str(shape_.rows) + ", " + utils::num2str(shape_.cols) + "]";
2664  errStr += " and [" + utils::num2str(inOtherArray.shape_.rows) + ", " + utils::num2str(inOtherArray.shape_.cols) + "]";
2665  errStr += " are not consistent.";
2667  }
2668 
2669  return NdArray<dtype>(); // get rid of compiler warning
2670  }
2671 
2672  //============================================================================
2673  // Method Description:
2681  void dump(const std::string& inFilename) const
2682  {
2683  filesystem::File f(inFilename);
2684  if (!f.hasExt())
2685  {
2686  f.withExt(".bin");
2687  }
2688 
2689  std::ofstream ofile(f.fullName().c_str(), std::ios::binary);
2690  if (!ofile.good())
2691  {
2692  THROW_RUNTIME_ERROR("Unable to open the input file:\n\t" + inFilename);
2693  }
2694 
2695  if (array_ != nullptr)
2696  {
2697  ofile.write(reinterpret_cast<const char*>(array_), size_ * sizeof(dtype));
2698  }
2699  ofile.close();
2700  }
2701 
2702  //============================================================================
2703  // Method Description:
2709  Endian endianess() const noexcept
2710  {
2711  STATIC_ASSERT_ARITHMETIC(dtype);
2712 
2713  return endianess_;
2714  }
2715 
2716  //============================================================================
2717  // Method Description:
2727  NdArray<dtype>& fill(value_type inFillValue) noexcept
2728  {
2729  stl_algorithms::fill(begin(), end(), inFillValue);
2730  return *this;
2731  }
2732 
2733  //============================================================================
2734  // Method Description:
2742  {
2744 
2745  std::vector<uint32> indices;
2746  uint32 idx = 0;
2747  for (auto value : *this)
2748  {
2749  if (value != dtype{ 0 })
2750  {
2751  indices.push_back(idx);
2752  }
2753  ++idx;
2754  }
2755 
2756  return NdArray<uint32>(indices);
2757  }
2758 
2759  //============================================================================
2760  // Method Description:
2769  {
2770  NdArray<dtype> outArray(1, size_);
2771  stl_algorithms::copy(cbegin(), cend(), outArray.begin());
2772  return outArray;
2773  }
2774 
2775  //============================================================================
2776  // Method Description:
2782  value_type front() const noexcept
2783  {
2784  return *cbegin();
2785  }
2786 
2787  //============================================================================
2788  // Method Description:
2794  reference front() noexcept
2795  {
2796  return *begin();
2797  }
2798 
2799  //============================================================================
2800  // Method Description:
2807  {
2808  return *cbegin(row);
2809  }
2810 
2811  //============================================================================
2812  // Method Description:
2819  {
2820  return *begin(row);
2821  }
2822 
2823  //============================================================================
2824  // Method Description:
2833  {
2834  return operator[](inIndices);
2835  }
2836 
2837  //============================================================================
2838  // Method Description:
2849  {
2850  return operator[](inMask);
2851  }
2852 
2853  //============================================================================
2854  // Method Description:
2861  bool isempty() const noexcept
2862  {
2863  return size_ == 0;
2864  }
2865 
2866  //============================================================================
2867  // Method Description:
2874  bool isflat() const noexcept
2875  {
2876  return shape_.rows == 1 || shape_.cols == 1;
2877  }
2878 
2879  //============================================================================
2880  // Method Description:
2887  {
2889 
2890  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
2891  {
2892  return lhs < rhs;
2893  };
2894 
2895  switch (inAxis)
2896  {
2897  case Axis::NONE:
2898  {
2899  return { stl_algorithms::is_sorted(cbegin(), cend(), comparitor) };
2900  }
2901  case Axis::ROW:
2902  {
2903  NdArray<bool> returnArray(shape_.cols, 1);
2904  auto transposedArray = transpose();
2905  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
2906  {
2907  returnArray(0, row) = stl_algorithms::is_sorted(transposedArray.cbegin(row),
2908  transposedArray.cend(row), comparitor);
2909  }
2910 
2911  return returnArray;
2912  }
2913  case Axis::COL:
2914  {
2915  NdArray<bool> returnArray(1, shape_.rows);
2916  for (uint32 row = 0; row < shape_.rows; ++row)
2917  {
2918  returnArray(0, row) = stl_algorithms::is_sorted(cbegin(row), cend(row), comparitor);
2919  }
2920 
2921  return returnArray;
2922  }
2923  default:
2924  {
2925  return NdArray<bool>(); // get rid of compiler warning
2926  }
2927  }
2928  }
2929 
2930  //============================================================================
2931  // Method Description:
2936  bool issquare() const noexcept
2937  {
2938  return shape_.issquare();
2939  }
2940 
2941  //============================================================================
2942  // Method Description:
2951  {
2952  if (size_ != 1)
2953  {
2954  THROW_INVALID_ARGUMENT_ERROR("Can only convert an array of size 1 to a C++ scaler");
2955  }
2956 
2957  return front();
2958  }
2959 
2960  //============================================================================
2961  // Method Description:
2972  {
2974 
2975  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
2976  {
2977  return lhs < rhs;
2978  };
2979 
2980  switch (inAxis)
2981  {
2982  case Axis::NONE:
2983  {
2984  NdArray<dtype> returnArray = { *stl_algorithms::max_element(cbegin(), cend(), comparitor) };
2985  return returnArray;
2986  }
2987  case Axis::COL:
2988  {
2989  NdArray<dtype> returnArray(1, shape_.rows);
2990  for (uint32 row = 0; row < shape_.rows; ++row)
2991  {
2992  returnArray(0, row) = *stl_algorithms::max_element(cbegin(row), cend(row), comparitor);
2993  }
2994 
2995  return returnArray;
2996  }
2997  case Axis::ROW:
2998  {
2999  NdArray<dtype> transposedArray = transpose();
3000  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3001  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3002  {
3003  returnArray(0, row) = *stl_algorithms::max_element(transposedArray.cbegin(row),
3004  transposedArray.cend(row), comparitor);
3005  }
3006 
3007  return returnArray;
3008  }
3009  default:
3010  {
3011  return NdArray<dtype>(); // get rid of compiler warning
3012  }
3013  }
3014  }
3015 
3016  //============================================================================
3017  // Method Description:
3028  {
3030 
3031  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3032  {
3033  return lhs < rhs;
3034  };
3035 
3036  switch (inAxis)
3037  {
3038  case Axis::NONE:
3039  {
3040  NdArray<dtype> returnArray = { *stl_algorithms::min_element(cbegin(), cend(), comparitor) };
3041  return returnArray;
3042  }
3043  case Axis::COL:
3044  {
3045  NdArray<dtype> returnArray(1, shape_.rows);
3046  for (uint32 row = 0; row < shape_.rows; ++row)
3047  {
3048  returnArray(0, row) = *stl_algorithms::min_element(cbegin(row), cend(row), comparitor);
3049  }
3050 
3051  return returnArray;
3052  }
3053  case Axis::ROW:
3054  {
3055  NdArray<dtype> transposedArray = transpose();
3056  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3057  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3058  {
3059  returnArray(0, row) = *stl_algorithms::min_element(transposedArray.cbegin(row),
3060  transposedArray.cend(row), comparitor);
3061  }
3062 
3063  return returnArray;
3064  }
3065  default:
3066  {
3067  return NdArray<dtype>(); // get rid of compiler warning
3068  }
3069  }
3070  }
3071 
3072  //============================================================================
3073  // Method Description:
3086  {
3088 
3089  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3090  {
3091  return lhs < rhs;
3092  };
3093 
3094  if (size_ == 0)
3095  {
3096  THROW_RUNTIME_ERROR("Median is undefined for an array of size = 0.");
3097  }
3098 
3099  switch (inAxis)
3100  {
3101  case Axis::NONE:
3102  {
3103  NdArray<dtype> copyArray(*this);
3104 
3105  const uint32 middleIdx = size_ / 2; // integer division
3106  stl_algorithms::nth_element(copyArray.begin(), copyArray.begin() + middleIdx, copyArray.end(), comparitor);
3107 
3108  dtype medianValue = copyArray.array_[middleIdx];
3109  if (size_ % 2 == 0)
3110  {
3111  const uint32 lhsIndex = middleIdx - 1;
3112  stl_algorithms::nth_element(copyArray.begin(), copyArray.begin() + lhsIndex, copyArray.end(), comparitor);
3113  medianValue = (medianValue + copyArray.array_[lhsIndex]) / dtype{2}; // potentially integer division, ok
3114  }
3115 
3116  return { medianValue };
3117  }
3118  case Axis::COL:
3119  {
3120  NdArray<dtype> copyArray(*this);
3121  NdArray<dtype> returnArray(1, shape_.rows);
3122 
3123  const bool isEven = shape_.cols % 2 == 0;
3124  for (uint32 row = 0; row < shape_.rows; ++row)
3125  {
3126  const uint32 middleIdx = shape_.cols / 2; // integer division
3127  stl_algorithms::nth_element(copyArray.begin(row), copyArray.begin(row) + middleIdx,
3128  copyArray.end(row), comparitor);
3129 
3130  dtype medianValue = copyArray(row, middleIdx);
3131  if (isEven)
3132  {
3133  const uint32 lhsIndex = middleIdx - 1;
3134  stl_algorithms::nth_element(copyArray.begin(row), copyArray.begin(row) + lhsIndex,
3135  copyArray.end(row), comparitor);
3136  medianValue = (medianValue + copyArray(row, lhsIndex)) / dtype{2}; // potentially integer division, ok
3137  }
3138 
3139  returnArray(0, row) = medianValue;
3140  }
3141 
3142  return returnArray;
3143  }
3144  case Axis::ROW:
3145  {
3146  NdArray<dtype> transposedArray = transpose();
3147  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3148 
3149  const bool isEven = shape_.rows % 2 == 0;
3150  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3151  {
3152  const uint32 middleIdx = transposedArray.shape_.cols / 2; // integer division
3153  stl_algorithms::nth_element(transposedArray.begin(row), transposedArray.begin(row) + middleIdx,
3154  transposedArray.end(row), comparitor);
3155 
3156  dtype medianValue = transposedArray(row, middleIdx);
3157  if (isEven)
3158  {
3159  const uint32 lhsIndex = middleIdx - 1;
3160  stl_algorithms::nth_element(transposedArray.begin(row), transposedArray.begin(row) + lhsIndex,
3161  transposedArray.end(row), comparitor);
3162  medianValue = (medianValue + transposedArray(row, lhsIndex)) / dtype{2}; // potentially integer division, ok
3163  }
3164 
3165  returnArray(0, row) = medianValue;
3166  }
3167 
3168  return returnArray;
3169  }
3170  default:
3171  {
3172  return NdArray<dtype>(); // get rid of compiler warning
3173  }
3174  }
3175  }
3176 
3177  //============================================================================
3178  // Method Description:
3182  NdArray<dtype>& nans() noexcept
3183  {
3184  STATIC_ASSERT_FLOAT(dtype);
3185 
3187  return *this;
3188  }
3189 
3190  //============================================================================
3191  // Method Description:
3199  uint64 nbytes() const noexcept
3200  {
3201  return static_cast<uint64>(sizeof(dtype) * size_);
3202  }
3203 
3204  //============================================================================
3205  // Method Description:
3218  NdArray<dtype> newbyteorder(Endian inEndianess) const
3219  {
3220  STATIC_ASSERT_INTEGER(dtype);
3221 
3222  switch (endianess_)
3223  {
3224  case Endian::NATIVE:
3225  {
3226  switch (inEndianess)
3227  {
3228  case Endian::NATIVE:
3229  {
3230  return NdArray(*this);
3231  }
3232  case Endian::BIG:
3233  {
3234  NdArray<dtype> outArray(shape_);
3235 
3236  stl_algorithms::transform(cbegin(), end(), outArray.begin(), boost::endian::native_to_big<dtype>);
3237 
3238  outArray.endianess_ = Endian::BIG;
3239  return outArray;
3240  }
3241  case Endian::LITTLE:
3242  {
3243  NdArray<dtype> outArray(shape_);
3244 
3245  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), boost::endian::native_to_little<dtype>);
3246 
3247  outArray.endianess_ = Endian::LITTLE;
3248  return outArray;
3249  }
3250  default:
3251  {
3252  return NdArray<dtype>(); // get rid of compiler warning
3253  }
3254  }
3255  break;
3256  }
3257  case Endian::BIG:
3258  {
3259  switch (inEndianess)
3260  {
3261  case Endian::NATIVE:
3262  {
3263  NdArray<dtype> outArray(shape_);
3264 
3265  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), boost::endian::big_to_native<dtype>);
3266 
3267  outArray.endianess_ = Endian::NATIVE;
3268  return outArray;
3269  }
3270  case Endian::BIG:
3271  {
3272  return NdArray(*this);
3273  }
3274  case Endian::LITTLE:
3275  {
3276  NdArray<dtype> outArray(shape_);
3277 
3278  stl_algorithms::transform(cbegin(), cend(), outArray.begin(),
3279  [](dtype value) noexcept -> dtype
3280  {
3281  return boost::endian::native_to_little<dtype>(boost::endian::big_to_native<dtype>(value));
3282  });
3283 
3284  outArray.endianess_ = Endian::LITTLE;
3285  return outArray;
3286  }
3287  default:
3288  {
3289  return NdArray<dtype>(); // get rid of compiler warning
3290  }
3291  }
3292  break;
3293  }
3294  case Endian::LITTLE:
3295  {
3296  switch (inEndianess)
3297  {
3298  case Endian::NATIVE:
3299  {
3300  NdArray<dtype> outArray(shape_);
3301 
3302  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), boost::endian::little_to_native<dtype>);
3303 
3304  outArray.endianess_ = Endian::NATIVE;
3305  return outArray;
3306  }
3307  case Endian::BIG:
3308  {
3309  NdArray<dtype> outArray(shape_);
3310 
3311  const auto function = [](dtype value) noexcept -> dtype
3312  {
3313  return boost::endian::native_to_big<dtype>(boost::endian::little_to_native<dtype>(value));
3314  };
3315 
3316  stl_algorithms::transform(cbegin(), cend(), outArray.begin(), function);
3317 
3318  outArray.endianess_ = Endian::BIG;
3319  return outArray;
3320  }
3321  case Endian::LITTLE:
3322  {
3323  return NdArray(*this);
3324  }
3325  default:
3326  {
3327  return NdArray<dtype>(); // get rid of compiler warning
3328  }
3329  }
3330  break;
3331  }
3332  default:
3333  {
3334  return NdArray<dtype>(); // get rid of compiler warning
3335  }
3336  }
3337  }
3338 
3339  //============================================================================
3340  // Method Description:
3351  {
3353 
3354  const auto function = [](dtype i) -> bool
3355  {
3356  return i != dtype{ 0 };
3357  };
3358 
3359  switch (inAxis)
3360  {
3361  case Axis::NONE:
3362  {
3363  NdArray<bool> returnArray = { stl_algorithms::none_of(cbegin(), cend(), function) };
3364  return returnArray;
3365  }
3366  case Axis::COL:
3367  {
3368  NdArray<bool> returnArray(1, shape_.rows);
3369  for (uint32 row = 0; row < shape_.rows; ++row)
3370  {
3371  returnArray(0, row) = stl_algorithms::none_of(cbegin(row), cend(row), function);
3372  }
3373 
3374  return returnArray;
3375  }
3376  case Axis::ROW:
3377  {
3378  NdArray<dtype> arrayTransposed = transpose();
3379  NdArray<bool> returnArray(1, arrayTransposed.shape_.rows);
3380  for (uint32 row = 0; row < arrayTransposed.shape_.rows; ++row)
3381  {
3382  returnArray(0, row) = stl_algorithms::none_of(arrayTransposed.cbegin(row), arrayTransposed.cend(row), function);
3383  }
3384 
3385  return returnArray;
3386  }
3387  default:
3388  {
3389  return NdArray<bool>(); // get rid of compiler warning
3390  }
3391  }
3392  }
3393 
3394  //============================================================================
3395  // Method Description:
3405  std::pair<NdArray<uint32>, NdArray<uint32>> nonzero() const;
3406 
3407  //============================================================================
3408  // Method Description:
3415  uint32 numCols() const noexcept
3416  {
3417  return shape_.cols;
3418  }
3419 
3420  //============================================================================
3421  // Method Description:
3428  uint32 numRows() const noexcept
3429  {
3430  return shape_.rows;
3431  }
3432 
3433  //============================================================================
3434  // Method Description:
3438  NdArray<dtype>& ones() noexcept
3439  {
3441 
3442  fill(dtype{ 1 });
3443  return *this;
3444  }
3445 
3446  //============================================================================
3447  // Method Description:
3452  bool ownsInternalData() noexcept
3453  {
3454  return ownsPtr_;
3455  }
3456 
3457  //============================================================================
3458  // Method Description:
3474  {
3476 
3477  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3478  {
3479  return lhs < rhs;
3480  };
3481 
3482  switch (inAxis)
3483  {
3484  case Axis::NONE:
3485  {
3486  if (inKth >= size_)
3487  {
3488  std::string errStr = "kth(=" + utils::num2str(inKth);
3489  errStr += ") out of bounds (" + utils::num2str(size_) + ")";
3491  }
3492 
3493  stl_algorithms::nth_element(begin(), begin() + inKth, end(), comparitor);
3494  break;
3495  }
3496  case Axis::COL:
3497  {
3498  if (inKth >= shape_.cols)
3499  {
3500  std::string errStr = "kth(=" + utils::num2str(inKth);
3501  errStr += ") out of bounds (" + utils::num2str(shape_.cols) + ")";
3503  }
3504 
3505  for (uint32 row = 0; row < shape_.rows; ++row)
3506  {
3507  stl_algorithms::nth_element(begin(row), begin(row) + inKth, end(row), comparitor);
3508  }
3509  break;
3510  }
3511  case Axis::ROW:
3512  {
3513  if (inKth >= shape_.rows)
3514  {
3515  std::string errStr = "kth(=" + utils::num2str(inKth);
3516  errStr += ") out of bounds (" + utils::num2str(shape_.rows) + ")";
3518  }
3519 
3520  NdArray<dtype> transposedArray = transpose();
3521  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3522  {
3523  stl_algorithms::nth_element(transposedArray.begin(row), transposedArray.begin(row) + inKth,
3524  transposedArray.end(row), comparitor);
3525  }
3526  *this = transposedArray.transpose();
3527  break;
3528  }
3529  }
3530 
3531  return *this;
3532  }
3533 
3534  //============================================================================
3535  // Method Description:
3539  void print() const
3540  {
3542 
3543  std::cout << *this;
3544  }
3545 
3546  //============================================================================
3547  // Method Description:
3558  {
3560 
3561  switch (inAxis)
3562  {
3563  case Axis::NONE:
3564  {
3565  dtype product = std::accumulate(cbegin(), cend(),
3566  dtype{ 1 }, std::multiplies<dtype>());
3567  NdArray<dtype> returnArray = { product };
3568  return returnArray;
3569  }
3570  case Axis::COL:
3571  {
3572  NdArray<dtype> returnArray(1, shape_.rows);
3573  for (uint32 row = 0; row < shape_.rows; ++row)
3574  {
3575  returnArray(0, row) = std::accumulate(cbegin(row), cend(row),
3576  dtype{ 1 }, std::multiplies<dtype>());
3577  }
3578 
3579  return returnArray;
3580  }
3581  case Axis::ROW:
3582  {
3583  NdArray<dtype> transposedArray = transpose();
3584  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3585  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3586  {
3587  returnArray(0, row) = std::accumulate(transposedArray.cbegin(row), transposedArray.cend(row),
3588  dtype{ 1 }, std::multiplies<dtype>());
3589  }
3590 
3591  return returnArray;
3592  }
3593  default:
3594  {
3595  return NdArray<dtype>(); // get rid of compiler warning
3596  }
3597  }
3598  }
3599 
3600  //============================================================================
3601  // Method Description:
3612  {
3614 
3615  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
3616  {
3617  return lhs < rhs;
3618  };
3619 
3620  switch (inAxis)
3621  {
3622  case Axis::NONE:
3623  {
3624  const auto result = stl_algorithms::minmax_element(cbegin(), cend(), comparitor);
3625  NdArray<dtype> returnArray = { *result.second - *result.first };
3626  return returnArray;
3627  }
3628  case Axis::COL:
3629  {
3630  NdArray<dtype> returnArray(1, shape_.rows);
3631  for (uint32 row = 0; row < shape_.rows; ++row)
3632  {
3633  const auto result = stl_algorithms::minmax_element(cbegin(row), cend(row), comparitor);
3634  returnArray(0, row) = *result.second - *result.first;
3635  }
3636 
3637  return returnArray;
3638  }
3639  case Axis::ROW:
3640  {
3641  NdArray<dtype> transposedArray = transpose();
3642  NdArray<dtype> returnArray(1, transposedArray.shape_.rows);
3643  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
3644  {
3645  const auto result = stl_algorithms::minmax_element(transposedArray.cbegin(row), transposedArray.cend(row), comparitor);
3646  returnArray(0, row) = *result.second - *result.first;
3647  }
3648 
3649  return returnArray;
3650  }
3651  default:
3652  {
3653  return NdArray<dtype>(); // get rid of compiler warning
3654  }
3655  }
3656  }
3657 
3658  //============================================================================
3659  // Method Description:
3667  NdArray<dtype>& put(int32 inIndex, value_type inValue)
3668  {
3669  at(inIndex) = inValue;
3670 
3671  return *this;
3672  }
3673 
3674  //============================================================================
3675  // Method Description:
3684  NdArray<dtype>& put(int32 inRow, int32 inCol, value_type inValue)
3685  {
3686  at(inRow, inCol) = inValue;
3687 
3688  return *this;
3689  }
3690 
3691  //============================================================================
3692  // Method Description:
3700  NdArray<dtype>& put(const NdArray<uint32>& inIndices, value_type inValue)
3701  {
3702  for (auto index : inIndices)
3703  {
3704  put(index, inValue);
3705  }
3706 
3707  return *this;
3708  }
3709 
3710  //============================================================================
3711  // Method Description:
3719  NdArray<dtype>& put(const NdArray<uint32>& inIndices, const NdArray<dtype>& inValues)
3720  {
3721  if (inIndices.size() != inValues.size())
3722  {
3723  THROW_INVALID_ARGUMENT_ERROR("Input indices do not match values dimensions.");
3724  }
3725 
3726  uint32 counter = 0;
3727  for (auto index : inIndices)
3728  {
3729  put(index, inValues[counter++]);
3730  }
3731 
3732  return *this;
3733  }
3734 
3735  //============================================================================
3736  // Method Description:
3744  NdArray<dtype>& put(const Slice& inSlice, value_type inValue)
3745  {
3746  Slice inSliceCopy(inSlice);
3747  inSliceCopy.makePositiveAndValidate(size_);
3748 
3749  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
3750  {
3751  put(i, inValue);
3752  }
3753 
3754  return *this;
3755  }
3756 
3757  //============================================================================
3758  // Method Description:
3766  NdArray<dtype>& put(const Slice& inSlice, const NdArray<dtype>& inValues)
3767  {
3768  Slice inSliceCopy(inSlice);
3769  inSliceCopy.makePositiveAndValidate(size_);
3770 
3771  std::vector<uint32> indices;
3772  for (int32 i = inSliceCopy.start; i < inSliceCopy.stop; i += inSliceCopy.step)
3773  {
3774  indices.push_back(i);
3775  }
3776 
3777  return put(NdArray<uint32>(indices), inValues);
3778  }
3779 
3780  //============================================================================
3781  // Method Description:
3790  NdArray<dtype>& put(const Slice& inRowSlice, const Slice& inColSlice, value_type inValue)
3791  {
3792  Slice inRowSliceCopy(inRowSlice);
3793  Slice inColSliceCopy(inColSlice);
3794 
3795  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3796  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3797 
3798  std::vector<uint32> indices;
3799  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3800  {
3801  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3802  {
3803  put(row, col, inValue);
3804  }
3805  }
3806 
3807  return *this;
3808  }
3809 
3810  //============================================================================
3811  // Method Description:
3820  NdArray<dtype>& put(const Slice& inRowSlice, int32 inColIndex, value_type inValue)
3821  {
3822  Slice inRowSliceCopy(inRowSlice);
3823  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3824 
3825  std::vector<uint32> indices;
3826  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3827  {
3828  put(row, inColIndex, inValue);
3829  }
3830 
3831  return *this;
3832  }
3833 
3834  //============================================================================
3835  // Method Description:
3844  NdArray<dtype>& put(int32 inRowIndex, const Slice& inColSlice, value_type inValue)
3845  {
3846  Slice inColSliceCopy(inColSlice);
3847  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3848 
3849  std::vector<uint32> indices;
3850  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3851  {
3852  put(inRowIndex, col, inValue);
3853  }
3854 
3855  return *this;
3856  }
3857 
3858  //============================================================================
3859  // Method Description:
3868  NdArray<dtype>& put(const Slice& inRowSlice, const Slice& inColSlice, const NdArray<dtype>& inValues)
3869  {
3870  Slice inRowSliceCopy(inRowSlice);
3871  Slice inColSliceCopy(inColSlice);
3872 
3873  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3874  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3875 
3876  std::vector<uint32> indices;
3877  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3878  {
3879  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3880  {
3881  const uint32 index = row * shape_.cols + col;
3882  indices.push_back(index);
3883  }
3884  }
3885 
3886  return put(NdArray<uint32>(indices), inValues);
3887  }
3888 
3889  //============================================================================
3890  // Method Description:
3899  NdArray<dtype>& put(const Slice& inRowSlice, int32 inColIndex, const NdArray<dtype>& inValues)
3900  {
3901  Slice inRowSliceCopy(inRowSlice);
3902  inRowSliceCopy.makePositiveAndValidate(shape_.rows);
3903 
3904  std::vector<uint32> indices;
3905  for (int32 row = inRowSliceCopy.start; row < inRowSliceCopy.stop; row += inRowSliceCopy.step)
3906  {
3907  const uint32 index = row * shape_.cols + inColIndex;
3908  indices.push_back(index);
3909  }
3910 
3911  return put(NdArray<uint32>(indices), inValues);
3912  }
3913 
3914  //============================================================================
3915  // Method Description:
3924  NdArray<dtype>& put(int32 inRowIndex, const Slice& inColSlice, const NdArray<dtype>& inValues)
3925  {
3926  Slice inColSliceCopy(inColSlice);
3927  inColSliceCopy.makePositiveAndValidate(shape_.cols);
3928 
3929  std::vector<uint32> indices;
3930  for (int32 col = inColSliceCopy.start; col < inColSliceCopy.stop; col += inColSliceCopy.step)
3931  {
3932  const uint32 index = inRowIndex * shape_.cols + col;
3933  indices.push_back(index);
3934  }
3935 
3936  return put(NdArray<uint32>(indices), inValues);
3937  }
3938 
3939  //============================================================================
3940  // Method Description:
3947  {
3948  if (inMask.shape() != shape_)
3949  {
3950  THROW_INVALID_ARGUMENT_ERROR("input inMask must be the same shape as the array it is masking.");
3951  }
3952 
3953  return put(inMask.flatnonzero(), inValue);
3954  }
3955 
3956  //============================================================================
3957  // Method Description:
3963  NdArray<dtype>& putMask(const NdArray<bool>& inMask, const NdArray<dtype>& inValues)
3964  {
3965  if (inMask.shape() != shape_)
3966  {
3967  THROW_INVALID_ARGUMENT_ERROR("input inMask must be the same shape as the array it is masking.");
3968  }
3969 
3970  return put(inMask.flatnonzero(), inValues);
3971  }
3972 
3973  //============================================================================
3974  // Method Description:
3981  NdArray<dtype>& ravel() noexcept
3982  {
3983  reshape(size_);
3984  return *this;
3985  }
3986 
3987  //============================================================================
3988  // Method Description:
3998  NdArray<dtype> repeat(uint32 inNumRows, uint32 inNumCols) const
3999  {
4000  NdArray<dtype> returnArray(shape_.rows * inNumRows, shape_.cols * inNumCols);
4001 
4002  for (uint32 row = 0; row < inNumRows; ++row)
4003  {
4004  for (uint32 col = 0; col < inNumCols; ++col)
4005  {
4006  std::vector<uint32> indices(shape_.size());
4007 
4008  const uint32 rowStart = row * shape_.rows;
4009  const uint32 colStart = col * shape_.cols;
4010 
4011  const uint32 rowEnd = (row + 1) * shape_.rows;
4012  const uint32 colEnd = (col + 1) * shape_.cols;
4013 
4014  uint32 counter = 0;
4015  for (uint32 rowIdx = rowStart; rowIdx < rowEnd; ++rowIdx)
4016  {
4017  for (uint32 colIdx = colStart; colIdx < colEnd; ++colIdx)
4018  {
4019  indices[counter++] = rowIdx * returnArray.shape_.cols + colIdx;
4020  }
4021  }
4022 
4023  returnArray.put(NdArray<uint32>(indices), *this);
4024  }
4025  }
4026 
4027  return returnArray;
4028  }
4029 
4030  //============================================================================
4031  // Method Description:
4041  NdArray<dtype> repeat(const Shape& inRepeatShape) const
4042  {
4043  return repeat(inRepeatShape.rows, inRepeatShape.cols);
4044  }
4045 
4046  //============================================================================
4047  // Method Description:
4053  void replace(value_type oldValue, value_type newValue)
4054  {
4056 
4057  stl_algorithms::replace(begin(), end(), oldValue, newValue);
4058  }
4059 
4060  //============================================================================
4061  // Method Description:
4072  {
4073  if (inSize != size_)
4074  {
4075  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into shape ";
4076  errStr += "[" + utils::num2str(1) + ", " + utils::num2str(inSize) + "]";
4077  THROW_RUNTIME_ERROR(errStr);
4078  }
4079 
4080  shape_.rows = 1;
4081  shape_.cols = inSize;
4082 
4083  return *this;
4084  }
4085 
4086  //============================================================================
4087  // Method Description:
4098  NdArray<dtype>& reshape(int32 inNumRows, int32 inNumCols)
4099  {
4100  if (inNumRows < 0)
4101  {
4102  if (size_ % inNumCols == 0)
4103  {
4104  return reshape(size_ / inNumCols, inNumCols);
4105  }
4106  else
4107  {
4108  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into a shape ";
4109  errStr += "with " + utils::num2str(inNumCols) + " columns";
4111  }
4112  }
4113 
4114  if (inNumCols < 0)
4115  {
4116  if (size_ % inNumRows == 0)
4117  {
4118  return reshape(inNumRows, size_ / inNumRows);
4119  }
4120  else
4121  {
4122  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into a shape ";
4123  errStr += "with " + utils::num2str(inNumRows) + " rows";
4125  }
4126  }
4127 
4128  if (static_cast<uint32>(inNumRows * inNumCols) != size_)
4129  {
4130  std::string errStr = "Cannot reshape array of size " + utils::num2str(size_) + " into shape ";
4131  errStr += "[" + utils::num2str(inNumRows) + ", " + utils::num2str(inNumCols) + "]";
4133  }
4134 
4135  shape_.rows = static_cast<uint32>(inNumRows);
4136  shape_.cols = static_cast<uint32>(inNumCols);
4137 
4138  return *this;
4139  }
4140 
4141  //============================================================================
4142  // Method Description:
4153  NdArray<dtype>& reshape(const Shape& inShape)
4154  {
4155  return reshape(inShape.rows, inShape.cols);
4156  }
4157 
4158  //============================================================================
4159  // Method Description:
4168  NdArray<dtype>& resizeFast(uint32 inNumRows, uint32 inNumCols)
4169  {
4170  newArray(Shape(inNumRows, inNumCols));
4171  return *this;
4172  }
4173 
4174  //============================================================================
4175  // Method Description:
4184  NdArray<dtype>& resizeFast(const Shape& inShape)
4185  {
4186  return resizeFast(inShape.rows, inShape.cols);
4187  }
4188 
4189  //============================================================================
4190  // Method Description:
4201  NdArray<dtype>& resizeSlow(uint32 inNumRows, uint32 inNumCols)
4202  {
4203  std::vector<dtype> oldData(size_);
4204  stl_algorithms::copy(begin(), end(), oldData.begin());
4205 
4206  const Shape inShape(inNumRows, inNumCols);
4207  const Shape oldShape = shape_;
4208 
4209  newArray(inShape);
4210 
4211  for (uint32 row = 0; row < inShape.rows; ++row)
4212  {
4213  for (uint32 col = 0; col < inShape.cols; ++col)
4214  {
4215  if (row >= oldShape.rows || col >= oldShape.cols)
4216  {
4217  operator()(row, col) = dtype{ 0 }; // zero fill
4218  }
4219  else
4220  {
4221  operator()(row, col) = oldData[row * oldShape.cols + col];
4222  }
4223  }
4224  }
4225 
4226  return *this;
4227  }
4228 
4229  //============================================================================
4230  // Method Description:
4241  NdArray<dtype>& resizeSlow(const Shape& inShape)
4242  {
4243  return resizeSlow(inShape.rows, inShape.cols);
4244  }
4245 
4246  //============================================================================
4247  // Method Description:
4258  NdArray<dtype> round(uint8 inNumDecimals = 0) const
4259  {
4260  STATIC_ASSERT_FLOAT(dtype);
4261 
4262  NdArray<dtype> returnArray(shape_);
4263  const double multFactor = utils::power(10.0, inNumDecimals);
4264  const auto function = [multFactor](dtype value) noexcept -> dtype
4265  {
4266  return static_cast<dtype>(std::nearbyint(static_cast<double>(value) * multFactor) / multFactor);
4267  };
4268 
4269  stl_algorithms::transform(cbegin(), cend(), returnArray.begin(), function);
4270 
4271  return returnArray;
4272  }
4273 
4274  //============================================================================
4275  // Method Description:
4283  {
4284  return NdArray<dtype>(cbegin(inRow), cend(inRow));
4285  }
4286 
4287  //============================================================================
4288  // Method Description:
4296  Shape shape() const noexcept
4297  {
4298  return shape_;
4299  }
4300 
4301  //============================================================================
4302  // Method Description:
4310  size_type size() const noexcept
4311  {
4312  return size_;
4313  }
4314 
4315  //============================================================================
4316  // Method Description:
4327  {
4329 
4330  const auto comparitor = [](dtype lhs, dtype rhs) noexcept -> bool
4331  {
4332  return lhs < rhs;
4333  };
4334 
4335  switch (inAxis)
4336  {
4337  case Axis::NONE:
4338  {
4339  stl_algorithms::sort(begin(), end(), comparitor);
4340  break;
4341  }
4342  case Axis::COL:
4343  {
4344  for (uint32 row = 0; row < shape_.rows; ++row)
4345  {
4346  stl_algorithms::sort(begin(row), end(row), comparitor);
4347  }
4348  break;
4349  }
4350  case Axis::ROW:
4351  {
4352  NdArray<dtype> transposedArray = transpose();
4353  for (uint32 row = 0; row < transposedArray.shape_.rows; ++row)
4354  {
4355  stl_algorithms::sort(transposedArray.begin(row), transposedArray.end(row), comparitor);
4356  }
4357 
4358  *this = transposedArray.transpose();
4359  break;
4360  }
4361  }
4362 
4363  return *this;
4364  }
4365 
4366  //============================================================================
4367  // Method Description:
4373  std::string str() const
4374  {
4376 
4377  std::string out;
4378  out += "[";
4379  for (uint32 row = 0; row < shape_.rows; ++row)
4380  {
4381  out += "[";
4382  for (uint32 col = 0; col < shape_.cols; ++col)
4383  {
4384  out += utils::value2str(operator()(row, col)) + ", ";
4385  }
4386 
4387  if (row == shape_.rows - 1)
4388  {
4389  out += "]";
4390  }
4391  else
4392  {
4393  out += "]\n";
4394  }
4395  }
4396  out += "]\n";
4397  return out;
4398  }
4399 
4400  //============================================================================
4401  // Method Description:
4412  {
4414 
4415  switch (inAxis)
4416  {
4417  case Axis::NONE:
4418  {
4419  NdArray<dtype> returnArray = { std::accumulate(cbegin(), cend(), dtype{ 0 }) };
4420  return returnArray;
4421  }
4422  case Axis::COL:
4423  {
4424  NdArray<dtype> returnArray(1, shape_.rows);
4425  for (uint32 row = 0; row < shape_.rows; ++row)
4426  {
4427  returnArray(0, row) = std::accumulate(cbegin(row), cend(row), dtype{ 0 });
4428  }
4429 
4430  return returnArray;
4431  }
4432  case Axis::ROW:
4433  {
4434  NdArray<dtype> transposedArray = transpose();
4435  const Shape transShape = transposedArray.shape();
4436  NdArray<dtype> returnArray(1, transShape.rows);
4437  for (uint32 row = 0; row < transShape.rows; ++row)
4438  {
4439  returnArray(0, row) = std::accumulate(transposedArray.cbegin(row), transposedArray.cend(row), dtype{ 0 });
4440  }
4441 
4442  return returnArray;
4443  }
4444  default:
4445  {
4446  return NdArray<dtype>(); // get rid of compiler warning
4447  }
4448  }
4449  }
4450 
4451  //============================================================================
4452  // Method Description:
4461  {
4462  return transpose();
4463  }
4464 
4465  //============================================================================
4466  // Method Description:
4478  void tofile(const std::string& inFilename, const std::string& inSep = "") const
4479  {
4481 
4482  if (inSep.compare("") == 0)
4483  {
4484  dump(inFilename);
4485  }
4486  else
4487  {
4488  filesystem::File f(inFilename);
4489  if (!f.hasExt())
4490  {
4491  f.withExt("txt");
4492  }
4493 
4494  std::ofstream ofile(f.fullName().c_str());
4495  if (!ofile.good())
4496  {
4497  THROW_RUNTIME_ERROR("Input file could not be opened:\n\t" + inFilename);
4498  }
4499 
4500  uint32 counter = 0;
4501  for (auto value : *this)
4502  {
4503  ofile << value;
4504  if (counter++ != size_ - 1)
4505  {
4506  ofile << inSep;
4507  }
4508  }
4509  ofile.close();
4510  }
4511  }
4512 
4513  //============================================================================
4514  // Method Description:
4520  std::vector<dtype> toStlVector() const
4521  {
4522  return std::vector<dtype>(cbegin(), cend());
4523  }
4524 
4525  //============================================================================
4526  // Method Description:
4537  value_type trace(uint32 inOffset = 0, Axis inAxis = Axis::ROW) const noexcept
4538  {
4540 
4541  uint32 rowStart = 0;
4542  uint32 colStart = 0;
4543  switch (inAxis)
4544  {
4545  case Axis::ROW:
4546  {
4547  rowStart += inOffset;
4548  break;
4549  }
4550  case Axis::COL:
4551  {
4552  colStart += inOffset;
4553  break;
4554  }
4555  default:
4556  {
4557  // if the user input NONE, override back to ROW
4558  inAxis = Axis::ROW;
4559  break;
4560  }
4561  }
4562 
4563  if (rowStart >= shape_.rows || colStart >= shape_.cols)
4564  {
4565  return dtype{ 0 };
4566  }
4567 
4568  uint32 col = colStart;
4569  dtype sum = 0;
4570  for (uint32 row = rowStart; row < shape_.rows; ++row)
4571  {
4572  if (col >= shape_.cols)
4573  {
4574  break;
4575  }
4576  sum += operator()(row, col++);
4577  }
4578 
4579  return sum;
4580  }
4581 
4582  //============================================================================
4583  // Method Description:
4592  {
4593  NdArray<dtype> transArray(shape_.cols, shape_.rows);
4594  for (uint32 row = 0; row < shape_.rows; ++row)
4595  {
4596  for (uint32 col = 0; col < shape_.cols; ++col)
4597  {
4598  transArray(col, row) = operator()(row, col);
4599  }
4600  }
4601  return transArray;
4602  }
4603 
4604  //============================================================================
4605  // Method Description:
4609  NdArray<dtype>& zeros() noexcept
4610  {
4612 
4613  fill(dtype{ 0 });
4614  return *this;
4615  }
4616 
4617  private:
4618  //====================================Attributes==============================
4619  allocator_type allocator_{};
4620  Shape shape_{ 0, 0 };
4621  size_type size_{ 0 };
4622  Endian endianess_{ Endian::NATIVE };
4623  pointer array_{ nullptr };
4624  bool ownsPtr_{ false };
4625 
4626  //============================================================================
4627  // Method Description:
4630  void deleteArray() noexcept
4631  {
4632  if (ownsPtr_ && array_ != nullptr)
4633  {
4634  allocator_.deallocate(array_, size_);
4635  }
4636 
4637  array_ = nullptr;
4638  shape_.rows = shape_.cols = 0;
4639  size_ = 0;
4640  ownsPtr_ = false;
4641  endianess_ = Endian::NATIVE;
4642  }
4643 
4644  //============================================================================
4645  // Method Description:
4648  void newArray()
4649  {
4650  if (size_ > 0)
4651  {
4652  array_ = allocator_.allocate(size_);
4653  ownsPtr_ = true;
4654  }
4655  }
4656 
4657  //============================================================================
4658  // Method Description:
4664  void newArray(const Shape& inShape)
4665  {
4666  deleteArray();
4667 
4668  shape_ = inShape;
4669  size_ = inShape.size();
4670  newArray();
4671  }
4672  };
4673 
4674  // NOTE: this needs to be defined outside of the class to get rid of a compiler
4675  // error in Visual Studio
4676  template<typename dtype, class _Alloc>
4677  std::pair<NdArray<uint32>, NdArray<uint32>> NdArray<dtype, _Alloc>::nonzero() const
4678  {
4680 
4681  std::vector<uint32> rowIndices;
4682  std::vector<uint32> colIndices;
4683 
4684  for (uint32 row = 0; row < shape_.rows; ++row)
4685  {
4686  for (uint32 col = 0; col < shape_.cols; ++col)
4687  {
4688  if (operator()(row, col) != dtype{ 0 })
4689  {
4690  rowIndices.push_back(row);
4691  colIndices.push_back(col);
4692  }
4693  }
4694  }
4695 
4696  return std::make_pair(NdArray<uint32>(rowIndices), NdArray<uint32>(colIndices));
4697  }
4698 }
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:2950
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:2343
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:3844
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:1839
nc::NdArray::toStlVector
std::vector< dtype > toStlVector() const
Definition: NdArrayCore.hpp:4520
nc::NdArray::shape
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4296
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:2635
nc::NdArray::sort
NdArray< dtype > & sort(Axis inAxis=Axis::NONE)
Definition: NdArrayCore.hpp:4326
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:3790
nc::NdArray::round
NdArray< dtype > round(uint8 inNumDecimals=0) const
Definition: NdArrayCore.hpp:4258
nc::NdArray::copy
NdArray< dtype > copy() const
Definition: NdArrayCore.hpp:2391
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:2252
nc::NdArray::nans
NdArray< dtype > & nans() noexcept
Definition: NdArrayCore.hpp:3182
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:4537
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:4153
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:4241
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:4071
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:3924
nc::NdArray::tofile
void tofile(const std::string &inFilename, const std::string &inSep="") const
Definition: NdArrayCore.hpp:4478
nc::utils::num2str
std::string num2str(dtype inNumber)
Definition: num2str.hpp:47
nc::NdArray::issquare
bool issquare() const noexcept
Definition: NdArrayCore.hpp:2936
nc::NdArray::prod
NdArray< dtype > prod(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3557
nc::NdArray::diagonal
NdArray< dtype > diagonal(int32 inOffset=0, Axis inAxis=Axis::ROW) const
Definition: NdArrayCore.hpp:2566
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:3946
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:4591
nc::NdArray::nbytes
uint64 nbytes() const noexcept
Definition: NdArrayCore.hpp:3199
nc::NdArray::byteswap
NdArray< dtype > & byteswap()
Definition: NdArrayCore.hpp:2266
nc::NdArray::getByMask
NdArray< dtype > getByMask(const NdArray< bool > &inMask) const
Definition: NdArrayCore.hpp:2848
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:2971
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:3719
nc::NdArray::end
iterator end(size_type inRow)
Definition: NdArrayCore.hpp:1449
nc::NdArray::front
value_type front() const noexcept
Definition: NdArrayCore.hpp:2782
nc::NdArray::back
value_type back(size_type row) const
Definition: NdArrayCore.hpp:2240
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:3868
nc::NdArray::back
value_type back() const noexcept
Definition: NdArrayCore.hpp:2216
nc::NdArray::ownsInternalData
bool ownsInternalData() noexcept
Definition: NdArrayCore.hpp:3452
nc::NdArray::front
reference front() noexcept
Definition: NdArrayCore.hpp:2794
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::NdArray::clip
NdArray< dtype > clip(value_type inMin, value_type inMax) const
Definition: NdArrayCore.hpp:2307
nc::constants::j
constexpr auto j
Definition: Constants.hpp:46
nc::uint32
std::uint32_t uint32
Definition: Types.hpp:41
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::numCols
uint32 numCols() const noexcept
Definition: NdArrayCore.hpp:3415
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:4373
nc::NdArray::colend
column_iterator colend() noexcept
Definition: NdArrayCore.hpp:1607
nc::NdArray::newbyteorder
NdArray< dtype > newbyteorder(Endian inEndianess) const
Definition: NdArrayCore.hpp:3218
num2str.hpp
nc::NdArray::dataRelease
pointer dataRelease() noexcept
Definition: NdArrayCore.hpp:2549
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:3667
nc::NdArray::reshape
NdArray< dtype > & reshape(int32 inNumRows, int32 inNumCols)
Definition: NdArrayCore.hpp:4098
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:2329
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:2874
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:4310
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:4041
nc::NdArray::dump
void dump(const std::string &inFilename) const
Definition: NdArrayCore.hpp:2681
nc::NdArray::sum
NdArray< dtype > sum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:4411
nc::NdArray::swapaxes
NdArray< dtype > swapaxes() const
Definition: NdArrayCore.hpp:4460
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:3899
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:3820
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:3744
nc::NdArray::zeros
NdArray< dtype > & zeros() noexcept
Definition: NdArrayCore.hpp:4609
Shape.hpp
nc::NdArray::flatten
NdArray< dtype > flatten() const
Definition: NdArrayCore.hpp:2768
nc::NdArray::put
NdArray< dtype > & put(const Slice &inSlice, const NdArray< dtype > &inValues)
Definition: NdArrayCore.hpp:3766
Filesystem.hpp
nc::NdArray::cumsum
NdArray< dtype > cumsum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2470
nc::NdArray::ones
NdArray< dtype > & ones() noexcept
Definition: NdArrayCore.hpp:3438
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:2709
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:2527
nc::NdArray::ccolend
const_column_iterator ccolend(size_type inCol) const
Definition: NdArrayCore.hpp:1677
nc::NdArray::rSlice
const Slice rSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:906
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:1954
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:4282
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:2012
nc::NdArray::getByIndices
NdArray< dtype > getByIndices(const NdArray< uint32 > &inIndices) const
Definition: NdArrayCore.hpp:2832
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:3684
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::stl_algorithms::transform
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction) noexcept
Definition: StlAlgorithms.hpp:703
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:2407
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:2228
nc::NdArray::astype
NdArray< dtypeOut > astype() const
Definition: NdArrayCore.hpp:2097
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:4168
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:1895
nc::NdArray::flatnonzero
NdArray< uint32 > flatnonzero() const
Definition: NdArrayCore.hpp:2741
nc::NdArray::replace
void replace(value_type oldValue, value_type newValue)
Definition: NdArrayCore.hpp:4053
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:3963
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:3350
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:2861
nc::NdArray::front
value_type front(size_type row) const
Definition: NdArrayCore.hpp:2806
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:4677
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:3428
nc::NdArray::front
reference front(size_type row)
Definition: NdArrayCore.hpp:2818
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:4184
nc::NdArray::ptp
NdArray< dtype > ptp(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:3611
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:2537
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:3473
nc::NdArray::issorted
NdArray< bool > issorted(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2886
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:2727
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::cSlice
const Slice cSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:891
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:3085
TypeTraits.hpp
nc::NdArray::ravel
NdArray< dtype > & ravel() noexcept
Definition: NdArrayCore.hpp:3981
nc::NdArray::repeat
NdArray< dtype > repeat(uint32 inNumRows, uint32 inNumCols) const
Definition: NdArrayCore.hpp:3998
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:3539
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:3700
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:4201
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:3027