NumCpp  2.6.2
A Templatized Header Only C++ Implementation of the Python NumPy Library
NdArrayOperators.hpp
Go to the documentation of this file.
1 
28 #pragma once
29 
37 
38 #include <algorithm>
39 #include <complex>
40 #include <functional>
41 
42 namespace nc
43 {
44  //============================================================================
45  // Method Description:
52  template<typename dtype>
54  {
56 
57  if (lhs.shape() != rhs.shape())
58  {
59  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
60  }
61 
62  stl_algorithms::transform(lhs.begin(), lhs.end(),
63  rhs.cbegin(), lhs.begin(), std::plus<dtype>());
64 
65  return lhs;
66  }
67 
68  //============================================================================
69  // Method Description:
76  template<typename dtype>
77  NdArray<std::complex<dtype>>& operator+=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
78  {
80 
81  if (lhs.shape() != rhs.shape())
82  {
83  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
84  }
85 
86  const auto function = [](std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
87  {
88  return val1 + val2;
89  };
90 
91  stl_algorithms::transform(lhs.begin(), lhs.end(),
92  rhs.cbegin(), lhs.begin(), function);
93 
94  return lhs;
95  }
96 
97  //============================================================================
98  // Method Description:
106  template<typename dtype>
108  {
110 
111  const auto function = [rhs](dtype& value) -> dtype
112  {
113  return value += rhs;
114  };
115 
116  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
117 
118  return lhs;
119  }
120 
121  //============================================================================
122  // Method Description:
130  template<typename dtype>
131  NdArray<std::complex<dtype>>& operator+=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
132  {
134 
135  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype>
136  {
137  return value += rhs;
138  };
139 
140  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
141 
142  return lhs;
143  }
144 
145  //============================================================================
146  // Method Description:
153  template<typename dtype>
155  {
157 
158  if (lhs.shape() != rhs.shape())
159  {
160  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
161  }
162 
163  NdArray<dtype> returnArray(lhs.shape());
164 
165  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
166  rhs.cbegin(), returnArray.begin(), std::plus<dtype>());
167 
168  return returnArray;
169  }
170 
171  //============================================================================
172  // Method Description:
179  template<typename dtype>
180  NdArray<std::complex<dtype>> operator+(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
181  {
183 
184  if (lhs.shape() != rhs.shape())
185  {
186  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
187  }
188 
189  const auto function = [](dtype val1, const std::complex<dtype>& val2) -> std::complex<dtype>
190  {
191  return val1 + val2;
192  };
193 
194  NdArray<std::complex<dtype>> returnArray(lhs.shape());
195 
196  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
197  rhs.cbegin(), returnArray.begin(), function);
198 
199  return returnArray;
200  }
201 
202  //============================================================================
203  // Method Description:
210  template<typename dtype>
211  NdArray<std::complex<dtype>> operator+(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
212  {
213  return rhs + lhs;
214  }
215 
216  //============================================================================
217  // Method Description:
224  template<typename dtype>
225  NdArray<dtype> operator+(const NdArray<dtype>& lhs, dtype rhs)
226  {
228 
229  const auto function = [rhs](dtype value) -> dtype
230  {
231  return value + rhs;
232  };
233 
234  NdArray<dtype> returnArray(lhs.shape());
235 
236  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
237 
238  return returnArray;
239  }
240 
241  //============================================================================
242  // Method Description:
249  template<typename dtype>
250  NdArray<dtype> operator+(dtype lhs, const NdArray<dtype>& rhs)
251  {
252  return rhs + lhs;
253  }
254 
255  //============================================================================
256  // Method Description:
263  template<typename dtype>
264  NdArray<std::complex<dtype>> operator+(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
265  {
267 
268  const auto function = [rhs](dtype value) -> std::complex<dtype>
269  {
270  return value + rhs;
271  };
272 
273  NdArray<std::complex<dtype>> returnArray(lhs.shape());
274 
275  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
276 
277  return returnArray;
278  }
279 
280  //============================================================================
281  // Method Description:
288  template<typename dtype>
289  NdArray<std::complex<dtype>> operator+(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
290  {
291  return rhs + lhs;
292  }
293 
294  //============================================================================
295  // Method Description:
302  template<typename dtype>
303  NdArray<std::complex<dtype>> operator+(const NdArray<std::complex<dtype>>& lhs, dtype rhs)
304  {
306 
307  const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
308  {
309  return value + rhs;
310  };
311 
312  NdArray<std::complex<dtype>> returnArray(lhs.shape());
313 
314  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
315 
316  return returnArray;
317  }
318 
319  //============================================================================
320  // Method Description:
327  template<typename dtype>
328  NdArray<std::complex<dtype>> operator+(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
329  {
330  return rhs + lhs;
331  }
332 
333  //============================================================================
334  // Method Description:
341  template<typename dtype>
343  {
345 
346  if (lhs.shape() != rhs.shape())
347  {
348  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
349  }
350 
351  stl_algorithms::transform(lhs.begin(), lhs.end(),
352  rhs.cbegin(), lhs.begin(), std::minus<dtype>());
353 
354  return lhs;
355  }
356 
357  //============================================================================
358  // Method Description:
365  template<typename dtype>
366  NdArray<std::complex<dtype>>& operator-=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
367  {
369 
370  if (lhs.shape() != rhs.shape())
371  {
372  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
373  }
374 
375  const auto function = [](std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
376  {
377  return val1 - val2;
378  };
379 
380  stl_algorithms::transform(lhs.begin(), lhs.end(),
381  rhs.cbegin(), lhs.begin(), function);
382 
383  return lhs;
384  }
385 
386  //============================================================================
387  // Method Description:
395  template<typename dtype>
397  {
399 
400  const auto function = [rhs](dtype& value) -> dtype
401  {
402  return value -= rhs;
403  };
404 
405  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
406 
407  return lhs;
408  }
409 
410  //============================================================================
411  // Method Description:
419  template<typename dtype>
420  NdArray<std::complex<dtype>>& operator-=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
421  {
423 
424  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype>
425  {
426  return value -= rhs;
427  };
428 
429  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
430 
431  return lhs;
432  }
433 
434  //============================================================================
435  // Method Description:
442  template<typename dtype>
444  {
446 
447  if (lhs.shape() != rhs.shape())
448  {
449  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
450  }
451 
452  NdArray<dtype> returnArray(lhs.shape());
453 
454  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
455  rhs.cbegin(), returnArray.begin(), std::minus<dtype>());
456 
457  return returnArray;
458  }
459 
460  //============================================================================
461  // Method Description:
468  template<typename dtype>
469  NdArray<std::complex<dtype>> operator-(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
470  {
472 
473  if (lhs.shape() != rhs.shape())
474  {
475  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
476  }
477 
478  const auto function = [](dtype val1, const std::complex<dtype>& val2) -> std::complex<dtype>
479  {
480  return val1 - val2;
481  };
482 
483  NdArray<std::complex<dtype>> returnArray(lhs.shape());
484 
485  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
486  rhs.cbegin(), returnArray.begin(), function);
487 
488  return returnArray;
489  }
490 
491  //============================================================================
492  // Method Description:
499  template<typename dtype>
500  NdArray<std::complex<dtype>> operator-(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
501  {
503 
504  if (lhs.shape() != rhs.shape())
505  {
506  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
507  }
508 
509  const auto function = [](const std::complex<dtype>&val1, dtype val2) -> std::complex<dtype>
510  {
511  return val1 - val2;
512  };
513 
514  NdArray<std::complex<dtype>> returnArray(lhs.shape());
515 
516  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
517  rhs.cbegin(), returnArray.begin(), function);
518 
519  return returnArray;
520  }
521 
522  //============================================================================
523  // Method Description:
530  template<typename dtype>
531  NdArray<dtype> operator-(const NdArray<dtype>& lhs, dtype rhs)
532  {
534 
535  const auto function = [rhs](dtype value) -> dtype
536  {
537  return value - rhs;
538  };
539 
540  NdArray<dtype> returnArray(lhs.shape());
541 
542  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
543 
544  return returnArray;
545  }
546 
547  //============================================================================
548  // Method Description:
555  template<typename dtype>
556  NdArray<dtype> operator-(dtype lhs, const NdArray<dtype>& rhs)
557  {
559 
560  const auto function = [lhs](dtype value) -> dtype
561  {
562  return lhs - value;
563  };
564 
565  NdArray<dtype> returnArray(rhs.shape());
566 
567  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
568 
569  return returnArray;
570  }
571 
572  //============================================================================
573  // Method Description:
580  template<typename dtype>
581  NdArray<std::complex<dtype>> operator-(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
582  {
584 
585  const auto function = [rhs](dtype value) -> std::complex<dtype>
586  {
587  return value - rhs;
588  };
589 
590  NdArray<std::complex<dtype>> returnArray(lhs.shape());
591 
592  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
593 
594  return returnArray;
595  }
596 
597  //============================================================================
598  // Method Description:
605  template<typename dtype>
606  NdArray<std::complex<dtype>> operator-(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
607  {
609 
610  const auto function = [lhs](dtype value) -> std::complex<dtype>
611  {
612  return lhs - value;
613  };
614 
615  NdArray<std::complex<dtype>> returnArray(rhs.shape());
616 
617  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
618 
619  return returnArray;
620  }
621 
622  //============================================================================
623  // Method Description:
630  template<typename dtype>
631  NdArray<std::complex<dtype>> operator-(const NdArray<std::complex<dtype>>& lhs, dtype rhs)
632  {
634 
635  const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
636  {
637  return value - rhs;
638  };
639 
640  NdArray<std::complex<dtype>> returnArray(lhs.shape());
641 
642  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
643 
644  return returnArray;
645  }
646 
647  //============================================================================
648  // Method Description:
655  template<typename dtype>
656  NdArray<std::complex<dtype>> operator-(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
657  {
659 
660  const auto function = [lhs](std::complex<dtype> value) -> std::complex<dtype>
661  {
662  return lhs - value;
663  };
664 
665  NdArray<std::complex<dtype>> returnArray(rhs.shape());
666 
667  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
668 
669  return returnArray;
670  }
671 
672  //============================================================================
673  // Method Description:
678  template<typename dtype>
680  {
681  const auto function = [](dtype value) -> dtype
682  {
683  return -value;
684  };
685 
686  auto returnArray = NdArray<dtype>(inArray.shape());
687  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
688  return returnArray;
689  }
690 
691  //============================================================================
692  // Method Description:
699  template<typename dtype>
701  {
703 
704  if (lhs.shape() != rhs.shape())
705  {
706  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
707  }
708 
709  stl_algorithms::transform(lhs.begin(), lhs.end(),
710  rhs.cbegin(), lhs.begin(), std::multiplies<dtype>());
711 
712  return lhs;
713  }
714 
715  //============================================================================
716  // Method Description:
723  template<typename dtype>
724  NdArray<std::complex<dtype>>& operator*=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
725  {
727 
728  if (lhs.shape() != rhs.shape())
729  {
730  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
731  }
732 
733  const auto function = [](std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
734  {
735  return val1 * val2;
736  };
737 
738  stl_algorithms::transform(lhs.begin(), lhs.end(),
739  rhs.cbegin(), lhs.begin(), function);
740 
741  return lhs;
742  }
743 
744  //============================================================================
745  // Method Description:
753  template<typename dtype>
755  {
757 
758  const auto function = [rhs](dtype& value) -> dtype
759  {
760  return value *= rhs;
761  };
762 
763  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
764 
765  return lhs;
766  }
767 
768  //============================================================================
769  // Method Description:
777  template<typename dtype>
778  NdArray<std::complex<dtype>>& operator*=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
779  {
781 
782  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype>
783  {
784  return value *= rhs;
785  };
786 
787  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
788 
789  return lhs;
790  }
791 
792  //============================================================================
793  // Method Description:
800  template<typename dtype>
802  {
804 
805  if (lhs.shape() != rhs.shape())
806  {
807  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
808  }
809 
810  NdArray<dtype> returnArray(lhs.shape());
811 
812  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
813  rhs.cbegin(), returnArray.begin(), std::multiplies<dtype>());
814 
815  return returnArray;
816  }
817 
818  //============================================================================
819  // Method Description:
826  template<typename dtype>
827  NdArray<std::complex<dtype>> operator*(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
828  {
830 
831  if (lhs.shape() != rhs.shape())
832  {
833  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
834  }
835 
836  const auto function = [](dtype val1, const std::complex<dtype>& val2) -> std::complex<dtype>
837  {
838  return val1 * val2;
839  };
840 
841  NdArray<std::complex<dtype>> returnArray(lhs.shape());
842 
843  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
844  rhs.cbegin(), returnArray.begin(), function);
845 
846  return returnArray;
847  }
848 
849  //============================================================================
850  // Method Description:
857  template<typename dtype>
858  NdArray<std::complex<dtype>> operator*(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
859  {
860  return rhs * lhs;
861  }
862 
863  //============================================================================
864  // Method Description:
871  template<typename dtype>
872  NdArray<dtype> operator*(const NdArray<dtype>& lhs, dtype rhs)
873  {
875 
876  const auto function = [rhs](dtype value) -> dtype
877  {
878  return value * rhs;
879  };
880 
881  NdArray<dtype> returnArray(lhs.shape());
882 
883  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
884 
885  return returnArray;
886  }
887 
888  //============================================================================
889  // Method Description:
896  template<typename dtype>
897  NdArray<dtype> operator*(dtype lhs, const NdArray<dtype>& rhs)
898  {
899  return rhs * lhs;
900  }
901 
902  //============================================================================
903  // Method Description:
910  template<typename dtype>
911  NdArray<std::complex<dtype>> operator*(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
912  {
914 
915  const auto function = [rhs](dtype value) -> std::complex<dtype>
916  {
917  return value * rhs;
918  };
919 
920  NdArray<std::complex<dtype>> returnArray(lhs.shape());
921 
922  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
923 
924  return returnArray;
925  }
926 
927  //============================================================================
928  // Method Description:
935  template<typename dtype>
936  NdArray<std::complex<dtype>> operator*(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
937  {
938  return rhs * lhs;
939  }
940 
941  //============================================================================
942  // Method Description:
949  template<typename dtype>
950  NdArray<std::complex<dtype>> operator*(const NdArray<std::complex<dtype>>& lhs, dtype rhs)
951  {
953 
954  const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
955  {
956  return value * rhs;
957  };
958 
959  NdArray<std::complex<dtype>> returnArray(lhs.shape());
960 
961  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
962 
963  return returnArray;
964  }
965 
966  //============================================================================
967  // Method Description:
974  template<typename dtype>
975  NdArray<std::complex<dtype>> operator*(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
976  {
977  return rhs * lhs;
978  }
979 
980  //============================================================================
981  // Method Description:
988  template<typename dtype>
990  {
992 
993  if (lhs.shape() != rhs.shape())
994  {
995  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
996  }
997 
998  stl_algorithms::transform(lhs.begin(), lhs.end(),
999  rhs.cbegin(), lhs.begin(), std::divides<dtype>());
1000 
1001  return lhs;
1002  }
1003 
1004  //============================================================================
1005  // Method Description:
1012  template<typename dtype>
1013  NdArray<std::complex<dtype>>& operator/=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
1014  {
1015  STATIC_ASSERT_ARITHMETIC(dtype);
1016 
1017  if (lhs.shape() != rhs.shape())
1018  {
1019  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1020  }
1021 
1022  const auto function = [](std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
1023  {
1024  return val1 / val2;
1025  };
1026 
1027  stl_algorithms::transform(lhs.begin(), lhs.end(),
1028  rhs.cbegin(), lhs.begin(), function);
1029 
1030  return lhs;
1031  }
1032 
1033  //============================================================================
1034  // Method Description:
1042  template<typename dtype>
1044  {
1046 
1047  const auto function = [rhs](dtype& value) -> dtype
1048  {
1049  return value /= rhs;
1050  };
1051 
1052  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1053 
1054  return lhs;
1055  }
1056 
1057  //============================================================================
1058  // Method Description:
1066  template<typename dtype>
1067  NdArray<std::complex<dtype>>& operator/=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
1068  {
1069  STATIC_ASSERT_ARITHMETIC(dtype);
1070 
1071  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype>
1072  {
1073  return value /= rhs;
1074  };
1075 
1076  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1077 
1078  return lhs;
1079  }
1080 
1081  //============================================================================
1082  // Method Description:
1089  template<typename dtype>
1091  {
1093 
1094  if (lhs.shape() != rhs.shape())
1095  {
1096  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1097  }
1098 
1099  NdArray<dtype> returnArray(lhs.shape());
1100 
1101  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1102  rhs.cbegin(), returnArray.begin(), std::divides<dtype>());
1103 
1104  return returnArray;
1105  }
1106 
1107  //============================================================================
1108  // Method Description:
1115  template<typename dtype>
1116  NdArray<std::complex<dtype>> operator/(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
1117  {
1118  STATIC_ASSERT_ARITHMETIC(dtype);
1119 
1120  if (lhs.shape() != rhs.shape())
1121  {
1122  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1123  }
1124 
1125  NdArray<std::complex<dtype>> returnArray(lhs.shape());
1126 
1127  const auto function = [](dtype val1, const std::complex<dtype>& val2) -> std::complex<dtype>
1128  {
1129  return val1 / val2;
1130  };
1131 
1132  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1133  rhs.cbegin(), returnArray.begin(), function);
1134 
1135  return returnArray;
1136  }
1137 
1138  //============================================================================
1139  // Method Description:
1146  template<typename dtype>
1147  NdArray<std::complex<dtype>> operator/(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
1148  {
1149  STATIC_ASSERT_ARITHMETIC(dtype);
1150 
1151  if (lhs.shape() != rhs.shape())
1152  {
1153  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1154  }
1155 
1156  const auto function = [](const std::complex<dtype>&val1, dtype val2) -> std::complex<dtype>
1157  {
1158  return val1 / val2;
1159  };
1160 
1161  NdArray<std::complex<dtype>> returnArray(lhs.shape());
1162 
1163  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1164  rhs.cbegin(), returnArray.begin(), function);
1165 
1166  return returnArray;
1167  }
1168 
1169  //============================================================================
1170  // Method Description:
1177  template<typename dtype>
1178  NdArray<dtype> operator/(const NdArray<dtype>& lhs, dtype rhs)
1179  {
1181 
1182  const auto function = [rhs](dtype value) -> dtype
1183  {
1184  return value / rhs;
1185  };
1186 
1187  NdArray<dtype> returnArray(lhs.shape());
1188 
1189  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1190 
1191  return returnArray;
1192  }
1193 
1194  //============================================================================
1195  // Method Description:
1202  template<typename dtype>
1203  NdArray<dtype> operator/(dtype lhs, const NdArray<dtype>& rhs)
1204  {
1206 
1207  const auto function = [lhs](dtype value) -> dtype
1208  {
1209  return lhs / value;
1210  };
1211 
1212  NdArray<dtype> returnArray(rhs.shape());
1213 
1214  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
1215 
1216  return returnArray;
1217  }
1218 
1219  //============================================================================
1220  // Method Description:
1227  template<typename dtype>
1228  NdArray<std::complex<dtype>> operator/(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
1229  {
1230  STATIC_ASSERT_ARITHMETIC(dtype);
1231 
1232  const auto function = [rhs](dtype value) -> std::complex<dtype>
1233  {
1234  return value / rhs;
1235  };
1236 
1237  NdArray<std::complex<dtype>> returnArray(lhs.shape());
1238 
1239  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1240 
1241  return returnArray;
1242  }
1243 
1244  //============================================================================
1245  // Method Description:
1252  template<typename dtype>
1253  NdArray<std::complex<dtype>> operator/(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
1254  {
1255  STATIC_ASSERT_ARITHMETIC(dtype);
1256 
1257  const auto function = [lhs](dtype value) -> std::complex<dtype>
1258  {
1259  return lhs / value;
1260  };
1261 
1262  NdArray<std::complex<dtype>> returnArray(rhs.shape());
1263 
1264  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
1265 
1266  return returnArray;
1267  }
1268 
1269  //============================================================================
1270  // Method Description:
1277  template<typename dtype>
1278  NdArray<std::complex<dtype>> operator/(const NdArray<std::complex<dtype>>& lhs, dtype rhs)
1279  {
1280  STATIC_ASSERT_ARITHMETIC(dtype);
1281 
1282  const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
1283  {
1284  return value / rhs;
1285  };
1286 
1287  NdArray<std::complex<dtype>> returnArray(lhs.shape());
1288 
1289  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1290 
1291  return returnArray;
1292  }
1293 
1294  //============================================================================
1295  // Method Description:
1302  template<typename dtype>
1303  NdArray<std::complex<dtype>> operator/(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
1304  {
1305  STATIC_ASSERT_ARITHMETIC(dtype);
1306 
1307  const auto function = [lhs](std::complex<dtype> value) -> std::complex<dtype>
1308  {
1309  return lhs / value;
1310  };
1311 
1312  NdArray<std::complex<dtype>> returnArray(rhs.shape());
1313 
1314  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
1315 
1316  return returnArray;
1317  }
1318 
1319  //============================================================================
1320  // Method Description:
1327  template<typename dtype>
1329  {
1330  STATIC_ASSERT_ARITHMETIC(dtype);
1331 
1332  if (lhs.shape() != rhs.shape())
1333  {
1334  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1335  }
1336 
1337  stl_algorithms::transform(lhs.begin(), lhs.end(),
1338  rhs.cbegin(), lhs.begin(), std::modulus<dtype>());
1339 
1340  return lhs;
1341  }
1342 
1343  //============================================================================
1344  // Method Description:
1352  template<typename dtype>
1354  {
1355  STATIC_ASSERT_ARITHMETIC(dtype);
1356 
1357  const auto function = [rhs](dtype& value) -> dtype
1358  {
1359  return value %= rhs;
1360  };
1361 
1362  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1363 
1364  return lhs;
1365  }
1366 
1367  //============================================================================
1368  // Method Description:
1375  template<typename dtype>
1377  {
1378  auto returnArray = NdArray<dtype>(lhs);
1379  returnArray %= rhs;
1380  return returnArray;
1381  }
1382 
1383  //============================================================================
1384  // Method Description:
1391  template<typename dtype>
1392  NdArray<dtype> operator%(const NdArray<dtype>& lhs, dtype rhs)
1393  {
1394  auto returnArray = NdArray<dtype>(lhs);
1395  returnArray %= rhs;
1396  return returnArray;
1397  }
1398 
1399  //============================================================================
1400  // Method Description:
1407  template<typename dtype>
1408  NdArray<dtype> operator%(dtype lhs, const NdArray<dtype>& rhs)
1409  {
1410  NdArray<dtype> returnArray(rhs.shape());
1411  stl_algorithms::transform(rhs.begin(), rhs.end(), returnArray.begin(),
1412  [lhs](dtype value) -> dtype
1413  {
1414  return lhs % value;
1415  });
1416 
1417  return returnArray;
1418  }
1419 
1420  //============================================================================
1421  // Method Description:
1428  template<typename dtype>
1430  {
1431  STATIC_ASSERT_INTEGER(dtype);
1432 
1433  if (lhs.shape() != rhs.shape())
1434  {
1435  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1436  }
1437 
1438  stl_algorithms::transform(lhs.begin(), lhs.end(),
1439  rhs.cbegin(), lhs.begin(), std::bit_or<dtype>());
1440 
1441  return lhs;
1442  }
1443 
1444  //============================================================================
1445  // Method Description:
1453  template<typename dtype>
1455  {
1456  STATIC_ASSERT_INTEGER(dtype);
1457 
1458  const auto function = [rhs](dtype& value) -> dtype
1459  {
1460  return value |= rhs;
1461  };
1462 
1463  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1464 
1465  return lhs;
1466  }
1467 
1468  //============================================================================
1469  // Method Description:
1476  template<typename dtype>
1478  {
1479  auto returnArray = NdArray<dtype>(lhs);
1480  returnArray |= rhs;
1481  return returnArray;
1482  }
1483 
1484  //============================================================================
1485  // Method Description:
1492  template<typename dtype>
1493  NdArray<dtype> operator|(const NdArray<dtype>& lhs, dtype rhs)
1494  {
1495  auto returnArray = NdArray<dtype>(lhs);
1496  returnArray |= rhs;
1497  return returnArray;
1498  }
1499 
1500  //============================================================================
1501  // Method Description:
1508  template<typename dtype>
1509  NdArray<dtype> operator|(dtype lhs, const NdArray<dtype>& rhs)
1510  {
1511  return rhs | lhs;
1512  }
1513 
1514  //============================================================================
1515  // Method Description:
1522  template<typename dtype>
1524  {
1525  STATIC_ASSERT_INTEGER(dtype);
1526 
1527  if (lhs.shape() != rhs.shape())
1528  {
1529  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1530  }
1531 
1532  stl_algorithms::transform(lhs.begin(), lhs.end(),
1533  rhs.cbegin(), lhs.begin(), std::bit_and<dtype>());
1534 
1535  return lhs;
1536  }
1537 
1538  //============================================================================
1539  // Method Description:
1547  template<typename dtype>
1549  {
1550  STATIC_ASSERT_INTEGER(dtype);
1551 
1552  const auto function = [rhs](dtype& value) -> dtype
1553  {
1554  return value &= rhs;
1555  };
1556 
1557  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1558 
1559  return lhs;
1560  }
1561 
1562  //============================================================================
1563  // Method Description:
1570  template<typename dtype>
1572  {
1573  auto returnArray = NdArray<dtype>(lhs);
1574  returnArray &= rhs;
1575  return returnArray;
1576  }
1577 
1578  //============================================================================
1579  // Method Description:
1586  template<typename dtype>
1587  NdArray<dtype> operator&(const NdArray<dtype>& lhs, dtype rhs)
1588  {
1589  auto returnArray = NdArray<dtype>(lhs);
1590  returnArray &= rhs;
1591  return returnArray;
1592  }
1593 
1594  //============================================================================
1595  // Method Description:
1602  template<typename dtype>
1603  NdArray<dtype> operator&(dtype lhs, const NdArray<dtype>& rhs)
1604  {
1605  return rhs & lhs;
1606  }
1607 
1608  //============================================================================
1609  // Method Description:
1616  template<typename dtype>
1618  {
1619  STATIC_ASSERT_INTEGER(dtype);
1620 
1621  if (lhs.shape() != rhs.shape())
1622  {
1623  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1624  }
1625 
1626  stl_algorithms::transform(lhs.begin(), lhs.end(),
1627  rhs.cbegin(), lhs.begin(), std::bit_xor<dtype>());
1628 
1629  return lhs;
1630  }
1631 
1632  //============================================================================
1633  // Method Description:
1641  template<typename dtype>
1643  {
1644  STATIC_ASSERT_INTEGER(dtype);
1645 
1646  const auto function = [rhs](dtype& value) -> dtype
1647  {
1648  return value ^= rhs;
1649  };
1650 
1651  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1652 
1653  return lhs;
1654  }
1655 
1656  //============================================================================
1657  // Method Description:
1664  template<typename dtype>
1666  {
1667  auto returnArray = NdArray<dtype>(lhs);
1668  returnArray ^= rhs;
1669  return returnArray;
1670  }
1671 
1672  //============================================================================
1673  // Method Description:
1680  template<typename dtype>
1681  NdArray<dtype> operator^(const NdArray<dtype>& lhs, dtype rhs)
1682  {
1683  auto returnArray = NdArray<dtype>(lhs);
1684  returnArray ^= rhs;
1685  return returnArray;
1686  }
1687 
1688  //============================================================================
1689  // Method Description:
1696  template<typename dtype>
1697  NdArray<dtype> operator^(dtype lhs, const NdArray<dtype>& rhs)
1698  {
1699  return rhs ^ lhs;
1700  }
1701 
1702  //============================================================================
1703  // Method Description:
1709  template<typename dtype>
1711  {
1712  STATIC_ASSERT_INTEGER(dtype);
1713 
1714  const auto function = [](dtype value) -> dtype
1715  {
1716  return ~value;
1717  };
1718 
1719  NdArray<dtype> returnArray(inArray.shape());
1720 
1721  stl_algorithms::transform(inArray.cbegin(), inArray.cend(),
1722  returnArray.begin(), function);
1723 
1724  return returnArray;
1725  }
1726 
1727  //============================================================================
1728  // Method Description:
1735  template<typename dtype>
1737  {
1738  STATIC_ASSERT_ARITHMETIC(dtype);
1739 
1740  if (lhs.shape() != rhs.shape())
1741  {
1742  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1743  }
1744 
1745  const auto function = [](dtype value1, dtype value2) -> bool
1746  {
1747  return value1 && value2;
1748  };
1749 
1750  NdArray<bool> returnArray(lhs.shape());
1751  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1752  rhs.cbegin(), returnArray.begin(), function);
1753 
1754  return returnArray;
1755  }
1756 
1757  //============================================================================
1758  // Method Description:
1765  template<typename dtype>
1766  NdArray<bool> operator&&(const NdArray<dtype>& lhs, dtype rhs)
1767  {
1768  STATIC_ASSERT_ARITHMETIC(dtype);
1769 
1770  NdArray<bool> returnArray(lhs.shape());
1771 
1772  const auto function = [rhs](dtype value) -> bool
1773  {
1774  return value && rhs;
1775  };
1776 
1777  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1778  returnArray.begin(), function);
1779 
1780  return returnArray;
1781  }
1782 
1783  //============================================================================
1784  // Method Description:
1791  template<typename dtype>
1792  NdArray<bool> operator&&(dtype lhs, const NdArray<dtype>& rhs)
1793  {
1794  return rhs && lhs;
1795  }
1796 
1797  //============================================================================
1798  // Method Description:
1805  template<typename dtype>
1807  {
1808  STATIC_ASSERT_ARITHMETIC(dtype);
1809 
1810  if (lhs.shape() != rhs.shape())
1811  {
1812  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1813  }
1814 
1815  const auto function = [](dtype value1, dtype value2) -> bool
1816  {
1817  return value1 || value2;
1818  };
1819 
1820  NdArray<bool> returnArray(lhs.shape());
1821  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1822  rhs.cbegin(), returnArray.begin(), function);
1823 
1824  return returnArray;
1825  }
1826 
1827  //============================================================================
1828  // Method Description:
1835  template<typename dtype>
1836  NdArray<bool> operator||(const NdArray<dtype>& lhs, dtype rhs)
1837  {
1838  STATIC_ASSERT_ARITHMETIC(dtype);
1839 
1840  NdArray<bool> returnArray(lhs.shape());
1841 
1842  const auto function = [rhs](dtype value) -> bool
1843  {
1844  return value || rhs;
1845  };
1846 
1847  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1848  returnArray.begin(), function);
1849 
1850  return returnArray;
1851  }
1852 
1853  //============================================================================
1854  // Method Description:
1861  template<typename dtype>
1862  NdArray<bool> operator||(dtype lhs, const NdArray<dtype>& rhs)
1863  {
1864  return rhs || lhs;
1865  }
1866 
1867  //============================================================================
1868  // Method Description:
1874  template<typename dtype>
1876  {
1877  STATIC_ASSERT_ARITHMETIC(dtype);
1878 
1879  NdArray<bool> returnArray(inArray.shape());
1880 
1881  const auto function = [](dtype value) -> dtype
1882  {
1883  return !value;
1884  };
1885 
1886  stl_algorithms::transform(inArray.cbegin(), inArray.cend(),
1887  returnArray.begin(), function);
1888 
1889  return returnArray;
1890  }
1891 
1892  //============================================================================
1893  // Method Description:
1901  template<typename dtype>
1903  {
1904  if (lhs.shape() != rhs.shape())
1905  {
1906  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1907  }
1908 
1909  const auto equalTo = [](dtype lhs, dtype rhs) noexcept -> bool
1910  {
1911  return utils::essentiallyEqual(lhs, rhs);
1912  };
1913 
1914  NdArray<bool> returnArray(lhs.shape());
1915 
1916  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1917  rhs.cbegin(), returnArray.begin(), equalTo);
1918 
1919  return returnArray;
1920  }
1921 
1922  //============================================================================
1923  // Method Description:
1931  template<typename dtype>
1932  NdArray<bool> operator==(const NdArray<dtype>& lhs, dtype inValue)
1933  {
1934  NdArray<bool> returnArray(lhs.shape());
1935 
1936  const auto equalTo = [inValue](dtype value) noexcept -> bool
1937  {
1938  return utils::essentiallyEqual(inValue, value);
1939  };
1940 
1941  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1942  returnArray.begin(), equalTo);
1943 
1944  return returnArray;
1945  }
1946 
1947  //============================================================================
1948  // Method Description:
1956  template<typename dtype>
1957  NdArray<bool> operator==(dtype inValue, const NdArray<dtype>& inArray)
1958  {
1959  return inArray == inValue;
1960  }
1961 
1962  //============================================================================
1963  // Method Description:
1971  template<typename dtype>
1973  {
1974  if (lhs.shape() != rhs.shape())
1975  {
1976  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
1977  }
1978 
1979  const auto notEqualTo = [](dtype lhs, dtype rhs) noexcept -> bool
1980  {
1981  return !utils::essentiallyEqual(lhs, rhs);
1982  };
1983 
1984  NdArray<bool> returnArray(lhs.shape());
1985 
1986  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
1987  rhs.cbegin(), returnArray.begin(), notEqualTo);
1988 
1989  return returnArray;
1990  }
1991 
1992  //============================================================================
1993  // Method Description:
2001  template<typename dtype>
2002  NdArray<bool> operator!=(const NdArray<dtype>& lhs, dtype inValue)
2003  {
2004  NdArray<bool> returnArray(lhs.shape());
2005 
2006  const auto notEqualTo = [inValue](dtype value) noexcept -> bool
2007  {
2008  return !utils::essentiallyEqual(inValue, value);
2009  };
2010 
2011  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2012  returnArray.begin(), notEqualTo);
2013 
2014  return returnArray;
2015  }
2016 
2017  //============================================================================
2018  // Method Description:
2026  template<typename dtype>
2027  NdArray<bool> operator!=(dtype inValue, const NdArray<dtype>& inArray)
2028  {
2029  return inArray != inValue;
2030  }
2031 
2032  //============================================================================
2033  // Method Description:
2041  template<typename dtype>
2042  NdArray<bool> operator<(const NdArray<dtype>& lhs, const NdArray<dtype>& rhs)
2043  {
2045 
2046  if (lhs.shape() != rhs.shape())
2047  {
2048  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
2049  }
2050 
2051  NdArray<bool> returnArray(lhs.shape());
2052 
2053  const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
2054  {
2055  return lhs < rhs;
2056  };
2057 
2058  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2059  rhs.cbegin(), returnArray.begin(), function);
2060 
2061  return returnArray;
2062  }
2063 
2064  //============================================================================
2065  // Method Description:
2073  template<typename dtype>
2074  NdArray<bool> operator<(const NdArray<dtype>& lhs, dtype inValue)
2075  {
2077 
2078  NdArray<bool> returnArray(lhs.shape());
2079 
2080  const auto function = [inValue](dtype value) noexcept -> bool
2081  {
2082  return value < inValue;
2083  };
2084 
2085  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2086  returnArray.begin(), function);
2087 
2088  return returnArray;
2089  }
2090 
2091  //============================================================================
2092  // Method Description:
2100  template<typename dtype>
2101  NdArray<bool> operator<(dtype inValue, const NdArray<dtype>& inArray)
2102  {
2104 
2105  NdArray<bool> returnArray(inArray.shape());
2106 
2107  const auto function = [inValue](dtype value) noexcept -> bool
2108  {
2109  return inValue < value;
2110  };
2111 
2112  stl_algorithms::transform(inArray.cbegin(), inArray.cend(),
2113  returnArray.begin(), function);
2114 
2115  return returnArray;
2116  }
2117 
2118  //============================================================================
2119  // Method Description:
2127  template<typename dtype>
2129  {
2131 
2132  if (lhs.shape() != rhs.shape())
2133  {
2134  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
2135  }
2136 
2137  NdArray<bool> returnArray(lhs.shape());
2138 
2139  const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
2140  {
2141  return lhs > rhs;
2142  };
2143 
2144  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2145  rhs.cbegin(), returnArray.begin(), function);
2146 
2147  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2148  rhs.cbegin(), returnArray.begin(), function);
2149 
2150  return returnArray;
2151  }
2152 
2153  //============================================================================
2154  // Method Description:
2162  template<typename dtype>
2163  NdArray<bool> operator>(const NdArray<dtype>& lhs, dtype inValue)
2164  {
2166 
2167  NdArray<bool> returnArray(lhs.shape());
2168 
2169  const auto function = [inValue](dtype value) noexcept -> bool
2170  {
2171  return value > inValue;
2172  };
2173 
2174  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2175  returnArray.begin(), function);
2176 
2177  return returnArray;
2178  }
2179 
2180  //============================================================================
2181  // Method Description:
2189  template<typename dtype>
2190  NdArray<bool> operator>(dtype inValue, const NdArray<dtype>& inArray)
2191  {
2193 
2194  NdArray<bool> returnArray(inArray.shape());
2195 
2196  const auto function = [inValue](dtype value) noexcept -> bool
2197  {
2198  return inValue > value;
2199  };
2200 
2201  stl_algorithms::transform(inArray.cbegin(), inArray.cend(),
2202  returnArray.begin(), function);
2203 
2204  return returnArray;
2205  }
2206 
2207  //============================================================================
2208  // Method Description:
2216  template<typename dtype>
2217  NdArray<bool> operator<=(const NdArray<dtype>& lhs, const NdArray<dtype>& rhs)
2218  {
2220 
2221  if (lhs.shape() != rhs.shape())
2222  {
2223  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
2224  }
2225 
2226  NdArray<bool> returnArray(lhs.shape());
2227 
2228  const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
2229  {
2230  return lhs <= rhs;
2231  };
2232 
2233  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2234  rhs.cbegin(), returnArray.begin(), function);
2235 
2236  return returnArray;
2237  }
2238 
2239  //============================================================================
2240  // Method Description:
2248  template<typename dtype>
2249  NdArray<bool> operator<=(const NdArray<dtype>& lhs, dtype inValue)
2250  {
2252 
2253  NdArray<bool> returnArray(lhs.shape());
2254 
2255  const auto function = [inValue](dtype value) noexcept -> bool
2256  {
2257  return value <= inValue;
2258  };
2259 
2260  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2261  returnArray.begin(), function);
2262 
2263  return returnArray;
2264  }
2265 
2266  //============================================================================
2267  // Method Description:
2275  template<typename dtype>
2276  NdArray<bool> operator<=(dtype inValue, const NdArray<dtype>& inArray)
2277  {
2279 
2280  NdArray<bool> returnArray(inArray.shape());
2281 
2282  const auto function = [inValue](dtype value) noexcept -> bool
2283  {
2284  return inValue <= value;
2285  };
2286 
2287  stl_algorithms::transform(inArray.cbegin(), inArray.cend(),
2288  returnArray.begin(), function);
2289 
2290  return returnArray;
2291  }
2292 
2293  //============================================================================
2294  // Method Description:
2302  template<typename dtype>
2304  {
2306 
2307  if (lhs.shape() != rhs.shape())
2308  {
2309  THROW_INVALID_ARGUMENT_ERROR("Array dimensions do not match.");
2310  }
2311 
2312  NdArray<bool> returnArray(lhs.shape());
2313 
2314  const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
2315  {
2316  return lhs >= rhs;
2317  };
2318 
2319  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2320  rhs.cbegin(), returnArray.begin(), function);
2321 
2322  return returnArray;
2323  }
2324 
2325  //============================================================================
2326  // Method Description:
2334  template<typename dtype>
2335  NdArray<bool> operator>=(const NdArray<dtype>& lhs, dtype inValue)
2336  {
2338 
2339  NdArray<bool> returnArray(lhs.shape());
2340 
2341  const auto function = [inValue](dtype value) noexcept -> bool
2342  {
2343  return value >= inValue;
2344  };
2345 
2346  stl_algorithms::transform(lhs.cbegin(), lhs.cend(),
2347  returnArray.begin(), function);
2348 
2349  return returnArray;
2350  }
2351 
2352  //============================================================================
2353  // Method Description:
2361  template<typename dtype>
2362  NdArray<bool> operator>=(dtype inValue, const NdArray<dtype>& inArray)
2363  {
2365 
2366  NdArray<bool> returnArray(inArray.shape());
2367 
2368  const auto function = [inValue](dtype value) noexcept -> bool
2369  {
2370  return inValue >= value;
2371  };
2372 
2373  stl_algorithms::transform(inArray.cbegin(), inArray.cend(),
2374  returnArray.begin(), function);
2375 
2376  return returnArray;
2377  }
2378 
2379  //============================================================================
2380  // Method Description:
2388  template<typename dtype>
2389  NdArray<dtype>& operator<<=(NdArray<dtype>& lhs, uint8 inNumBits)
2390  {
2391  STATIC_ASSERT_INTEGER(dtype);
2392 
2393  const auto function = [inNumBits](dtype& value) -> void
2394  {
2395  value <<= inNumBits;
2396  };
2397 
2398  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
2399 
2400  return lhs;
2401  }
2402 
2403  //============================================================================
2404  // Method Description:
2412  template<typename dtype>
2413  NdArray<dtype> operator<<(const NdArray<dtype>& lhs, uint8 inNumBits)
2414  {
2415  STATIC_ASSERT_INTEGER(dtype);
2416 
2417  NdArray<dtype> returnArray(lhs);
2418  returnArray <<= inNumBits;
2419  return returnArray;
2420  }
2421 
2422  //============================================================================
2423  // Method Description:
2431  template<typename dtype>
2433  {
2434  STATIC_ASSERT_INTEGER(dtype);
2435 
2436  const auto function = [inNumBits](dtype& value) -> void
2437  {
2438  value >>= inNumBits;
2439  };
2440 
2441  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
2442 
2443  return lhs;
2444  }
2445 
2446  //============================================================================
2447  // Method Description:
2455  template<typename dtype>
2457  {
2458  STATIC_ASSERT_INTEGER(dtype);
2459 
2460  NdArray<dtype> returnArray(lhs);
2461  returnArray >>= inNumBits;
2462  return returnArray;
2463  }
2464 
2465  //============================================================================
2466  // Method Description:
2472  template<typename dtype>
2474  {
2475  STATIC_ASSERT_ARITHMETIC(dtype);
2476 
2477  const auto function = [](dtype& value) -> void
2478  {
2479  ++value;
2480  };
2481 
2482  stl_algorithms::for_each(rhs.begin(), rhs.end(), function);
2483 
2484  return rhs;
2485  }
2486 
2487  //============================================================================
2488  // Method Description:
2495  template<typename dtype>
2497  {
2498  auto copy = NdArray<dtype>(lhs);
2499  ++lhs;
2500  return copy;
2501  }
2502 
2503  //============================================================================
2504  // Method Description:
2510  template<typename dtype>
2512  {
2513  STATIC_ASSERT_ARITHMETIC(dtype);
2514 
2515  const auto function = [](dtype& value) -> void
2516  {
2517  --value;
2518  };
2519 
2520  stl_algorithms::for_each(rhs.begin(), rhs.end(), function);
2521 
2522  return rhs;
2523  }
2524 
2525  //============================================================================
2526  // Method Description:
2533  template<typename dtype>
2535  {
2536  auto copy = NdArray<dtype>(lhs);
2537  --lhs;
2538  return copy;
2539  }
2540 
2541  //============================================================================
2542  // Method Description:
2550  template<typename dtype>
2551  std::ostream& operator<<(std::ostream& inOStream, const NdArray<dtype>& inArray)
2552  {
2554 
2555  inOStream << inArray.str();
2556  return inOStream;
2557  }
2558 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
#define STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype)
Definition: StaticAsserts.hpp:50
#define STATIC_ASSERT_INTEGER(dtype)
Definition: StaticAsserts.hpp:40
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:37
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:72
const_iterator cbegin() const noexcept
Definition: NdArrayCore.hpp:1270
iterator end() noexcept
Definition: NdArrayCore.hpp:1558
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4483
const_iterator cend() const noexcept
Definition: NdArrayCore.hpp:1614
std::string str() const
Definition: NdArrayCore.hpp:4560
iterator begin() noexcept
Definition: NdArrayCore.hpp:1214
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:702
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:213
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:52
Definition: Coordinate.hpp:45
NdArray< dtype > operator&(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1571
bool operator>=(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:97
NdArray< dtype > & operator%=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1328
bool operator>(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:83
NdArray< bool > operator||(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1806
NdArray< bool > operator==(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1902
NdArray< dtype > operator|(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1477
NdArray< bool > operator!=(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1972
NdArray< dtype > operator<<(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2413
NdArray< dtype > & operator+=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:53
NdArray< dtype > operator%(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1376
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:310
NdArray< bool > operator!(const NdArray< dtype > &inArray)
Definition: NdArrayOperators.hpp:1875
bool operator<(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:45
NdArray< dtype > & operator>>=(NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2432
NdArray< dtype > operator>>(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2456
NdArray< dtype > & operator-=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:342
NdArray< dtype > & operator^=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1617
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:801
NdArray< dtype > & operator|=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1429
std::uint8_t uint8
Definition: Types.hpp:42
NdArray< dtype > copy(const NdArray< dtype > &inArray)
Definition: copy.hpp:46
NdArray< dtype > & operator<<=(NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2389
bool operator<=(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:64
NdArray< dtype > & operator--(NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:2511
NdArray< bool > operator&&(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1736
NdArray< dtype > operator-(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:443
NdArray< dtype > & operator++(NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:2473
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1090
NdArray< dtype > & operator/=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:989
NdArray< dtype > operator^(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1665
NdArray< dtype > operator~(const NdArray< dtype > &inArray)
Definition: NdArrayOperators.hpp:1710
NdArray< dtype > & operator&=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1523
NdArray< dtype > & operator*=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:700