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