NumCpp  2.11.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
NdArrayOperators.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <algorithm>
31 #include <cmath>
32 #include <complex>
33 #include <functional>
34 
45 
46 namespace nc
47 {
48  //============================================================================
49  // Method Description:
56  template<typename dtype>
58  {
60 
61  return broadcast::broadcaster(lhs, rhs, std::plus<dtype>());
62  }
63 
64  //============================================================================
65  // Method Description:
72  template<typename dtype>
73  NdArray<std::complex<dtype>>& operator+=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
74  {
76 
77  const auto function = [](const std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
78  { return val1 + val2; };
79  return broadcast::broadcaster(lhs, rhs, function);
80  }
81 
82  //============================================================================
83  // Method Description:
90  template<typename dtype>
92  {
94 
95  const auto function = [rhs](dtype& value) -> dtype { return value += rhs; };
96 
97  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
98 
99  return lhs;
100  }
101 
102  //============================================================================
103  // Method Description:
110  template<typename dtype>
111  NdArray<std::complex<dtype>>& operator+=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
112  {
114 
115  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype> { return value += rhs; };
116 
117  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
118 
119  return lhs;
120  }
121 
122  //============================================================================
123  // Method Description:
130  template<typename dtype>
132  {
134 
135  return broadcast::broadcaster<dtype>(lhs, rhs, std::plus<dtype>());
136  }
137 
138  //============================================================================
139  // Method Description:
146  template<typename dtype>
147  NdArray<std::complex<dtype>> operator+(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
148  {
150 
151  const auto function = [](const auto& val1, const auto& val2) -> std::complex<dtype> { return val1 + val2; };
152  return broadcast::broadcaster<std::complex<dtype>>(lhs, rhs, function);
153  }
154 
155  //============================================================================
156  // Method Description:
163  template<typename dtype>
164  NdArray<std::complex<dtype>> operator+(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
165  {
166  return rhs + lhs;
167  }
168 
169  //============================================================================
170  // Method Description:
177  template<typename dtype>
179  {
180  lhs += rhs;
181  return lhs;
182  }
183 
184  //============================================================================
185  // Method Description:
192  template<typename dtype>
193  NdArray<dtype> operator+(dtype lhs, const NdArray<dtype>& rhs)
194  {
195  return rhs + lhs;
196  }
197 
198  //============================================================================
199  // Method Description:
206  template<typename dtype>
207  NdArray<std::complex<dtype>> operator+(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
208  {
210 
211  const auto function = [rhs](dtype value) -> std::complex<dtype> { return value + rhs; };
212 
213  NdArray<std::complex<dtype>> returnArray(lhs.shape());
214 
215  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
216 
217  return returnArray;
218  }
219 
220  //============================================================================
221  // Method Description:
228  template<typename dtype>
229  NdArray<std::complex<dtype>> operator+(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
230  {
231  return rhs + lhs;
232  }
233 
234  //============================================================================
235  // Method Description:
242  template<typename dtype>
243  NdArray<std::complex<dtype>> operator+(NdArray<std::complex<dtype>> lhs, dtype rhs)
244  {
245  lhs += rhs;
246  return lhs;
247  }
248 
249  //============================================================================
250  // Method Description:
257  template<typename dtype>
258  NdArray<std::complex<dtype>> operator+(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
259  {
260  return rhs + lhs;
261  }
262 
263  //============================================================================
264  // Method Description:
271  template<typename dtype>
273  {
275 
276  return broadcast::broadcaster(lhs, rhs, std::minus<dtype>());
277  }
278 
279  //============================================================================
280  // Method Description:
287  template<typename dtype>
288  NdArray<std::complex<dtype>>& operator-=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
289  {
291 
292  const auto function = [](const std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
293  { return val1 - val2; };
294  return broadcast::broadcaster(lhs, rhs, function);
295  }
296 
297  //============================================================================
298  // Method Description:
305  template<typename dtype>
307  {
309 
310  const auto function = [rhs](dtype& value) -> dtype { return value -= rhs; };
311 
312  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
313 
314  return lhs;
315  }
316 
317  //============================================================================
318  // Method Description:
325  template<typename dtype>
326  NdArray<std::complex<dtype>>& operator-=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
327  {
329 
330  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype> { return value -= rhs; };
331 
332  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
333 
334  return lhs;
335  }
336 
337  //============================================================================
338  // Method Description:
345  template<typename dtype>
347  {
349 
350  return broadcast::broadcaster<dtype>(lhs, rhs, std::minus<dtype>());
351  }
352 
353  //============================================================================
354  // Method Description:
361  template<typename dtype>
362  NdArray<std::complex<dtype>> operator-(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
363  {
365 
366  const auto function = [](const auto& val1, const auto& val2) -> std::complex<dtype> { return val1 - val2; };
367  return broadcast::broadcaster<std::complex<dtype>>(lhs, rhs, function);
368  }
369 
370  //============================================================================
371  // Method Description:
378  template<typename dtype>
379  NdArray<std::complex<dtype>> operator-(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
380  {
382 
383  const auto function = [](const auto& val1, const auto& val2) -> std::complex<dtype> { return val1 - val2; };
384  return broadcast::broadcaster<std::complex<dtype>>(lhs, rhs, function);
385  }
386 
387  //============================================================================
388  // Method Description:
395  template<typename dtype>
397  {
398  lhs -= rhs;
399  return lhs;
400  }
401 
402  //============================================================================
403  // Method Description:
410  template<typename dtype>
411  NdArray<dtype> operator-(dtype lhs, const NdArray<dtype>& rhs)
412  {
414 
415  const auto function = [lhs](dtype value) -> dtype { return lhs - value; };
416 
417  NdArray<dtype> returnArray(rhs.shape());
418 
419  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
420 
421  return returnArray;
422  }
423 
424  //============================================================================
425  // Method Description:
432  template<typename dtype>
433  NdArray<std::complex<dtype>> operator-(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
434  {
436 
437  const auto function = [rhs](dtype value) -> std::complex<dtype> { return value - rhs; };
438 
439  NdArray<std::complex<dtype>> returnArray(lhs.shape());
440 
441  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
442 
443  return returnArray;
444  }
445 
446  //============================================================================
447  // Method Description:
454  template<typename dtype>
455  NdArray<std::complex<dtype>> operator-(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
456  {
458 
459  const auto function = [lhs](dtype value) -> std::complex<dtype> { return lhs - value; };
460 
461  NdArray<std::complex<dtype>> returnArray(rhs.shape());
462 
463  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
464 
465  return returnArray;
466  }
467 
468  //============================================================================
469  // Method Description:
476  template<typename dtype>
477  NdArray<std::complex<dtype>> operator-(NdArray<std::complex<dtype>> lhs, dtype rhs)
478  {
479  lhs -= rhs;
480  return lhs;
481  }
482 
483  //============================================================================
484  // Method Description:
491  template<typename dtype>
492  NdArray<std::complex<dtype>> operator-(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
493  {
495 
496  const auto function = [lhs](std::complex<dtype> value) -> std::complex<dtype> { return lhs - value; };
497 
498  NdArray<std::complex<dtype>> returnArray(rhs.shape());
499 
500  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
501 
502  return returnArray;
503  }
504 
505  //============================================================================
506  // Method Description:
511  template<typename dtype>
513  {
514  const auto function = [](dtype value) -> dtype { return -value; };
515 
516  auto returnArray = NdArray<dtype>(inArray.shape());
517  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
518  return returnArray;
519  }
520 
521  //============================================================================
522  // Method Description:
529  template<typename dtype>
531  {
533 
534  return broadcast::broadcaster(lhs, rhs, std::multiplies<dtype>());
535  }
536 
537  //============================================================================
538  // Method Description:
545  template<typename dtype>
546  NdArray<std::complex<dtype>>& operator*=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
547  {
549 
550  const auto function = [](const std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
551  { return val1 * val2; };
552  return broadcast::broadcaster(lhs, rhs, function);
553  }
554 
555  //============================================================================
556  // Method Description:
563  template<typename dtype>
565  {
567 
568  const auto function = [rhs](dtype& value) -> dtype { return value *= rhs; };
569 
570  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
571 
572  return lhs;
573  }
574 
575  //============================================================================
576  // Method Description:
583  template<typename dtype>
584  NdArray<std::complex<dtype>>& operator*=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
585  {
587 
588  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype> { return value *= rhs; };
589 
590  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
591 
592  return lhs;
593  }
594 
595  //============================================================================
596  // Method Description:
603  template<typename dtype>
605  {
607 
608  return broadcast::broadcaster<dtype>(lhs, rhs, std::multiplies<dtype>());
609  }
610 
611  //============================================================================
612  // Method Description:
619  template<typename dtype>
620  NdArray<std::complex<dtype>> operator*(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
621  {
623 
624  const auto function = [](const auto& val1, const auto& val2) -> std::complex<dtype> { return val1 * val2; };
625  return broadcast::broadcaster<std::complex<dtype>>(lhs, rhs, function);
626  }
627 
628  //============================================================================
629  // Method Description:
636  template<typename dtype>
637  NdArray<std::complex<dtype>> operator*(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
638  {
639  return rhs * lhs;
640  }
641 
642  //============================================================================
643  // Method Description:
650  template<typename dtype>
652  {
653  lhs *= rhs;
654  return lhs;
655  }
656 
657  //============================================================================
658  // Method Description:
665  template<typename dtype>
666  NdArray<dtype> operator*(dtype lhs, const NdArray<dtype>& rhs)
667  {
668  return rhs * lhs;
669  }
670 
671  //============================================================================
672  // Method Description:
679  template<typename dtype>
680  NdArray<std::complex<dtype>> operator*(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
681  {
683 
684  const auto function = [rhs](dtype value) -> std::complex<dtype> { return value * rhs; };
685 
686  NdArray<std::complex<dtype>> returnArray(lhs.shape());
687 
688  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
689 
690  return returnArray;
691  }
692 
693  //============================================================================
694  // Method Description:
701  template<typename dtype>
702  NdArray<std::complex<dtype>> operator*(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
703  {
704  return rhs * lhs;
705  }
706 
707  //============================================================================
708  // Method Description:
715  template<typename dtype>
716  NdArray<std::complex<dtype>> operator*(NdArray<std::complex<dtype>> lhs, dtype rhs)
717  {
718  lhs *= rhs;
719  return lhs;
720  }
721 
722  //============================================================================
723  // Method Description:
730  template<typename dtype>
731  NdArray<std::complex<dtype>> operator*(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
732  {
733  return rhs * lhs;
734  }
735 
736  //============================================================================
737  // Method Description:
744  template<typename dtype>
746  {
748 
749  return broadcast::broadcaster(lhs, rhs, std::divides<dtype>());
750  }
751 
752  //============================================================================
753  // Method Description:
760  template<typename dtype>
761  NdArray<std::complex<dtype>>& operator/=(NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
762  {
764 
765  const auto function = [](const std::complex<dtype>& val1, dtype val2) -> std::complex<dtype>
766  { return val1 / val2; };
767  return broadcast::broadcaster(lhs, rhs, function);
768  }
769 
770  //============================================================================
771  // Method Description:
778  template<typename dtype>
780  {
782 
783  const auto function = [rhs](dtype& value) -> dtype { return value /= rhs; };
784 
785  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
786 
787  return lhs;
788  }
789 
790  //============================================================================
791  // Method Description:
798  template<typename dtype>
799  NdArray<std::complex<dtype>>& operator/=(NdArray<std::complex<dtype>>& lhs, dtype rhs)
800  {
802 
803  const auto function = [rhs](std::complex<dtype>& value) -> std::complex<dtype> { return value /= rhs; };
804 
805  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
806 
807  return lhs;
808  }
809 
810  //============================================================================
811  // Method Description:
818  template<typename dtype>
820  {
822 
823  return broadcast::broadcaster<dtype>(lhs, rhs, std::divides<dtype>());
824  }
825 
826  //============================================================================
827  // Method Description:
834  template<typename dtype>
835  NdArray<std::complex<dtype>> operator/(const NdArray<dtype>& lhs, const NdArray<std::complex<dtype>>& rhs)
836  {
838 
839  const auto function = [](const auto& val1, const auto& val2) -> std::complex<dtype> { return val1 / val2; };
840  return broadcast::broadcaster<std::complex<dtype>>(lhs, rhs, function);
841  }
842 
843  //============================================================================
844  // Method Description:
851  template<typename dtype>
852  NdArray<std::complex<dtype>> operator/(const NdArray<std::complex<dtype>>& lhs, const NdArray<dtype>& rhs)
853  {
855 
856  const auto function = [](const auto& val1, const auto& val2) -> std::complex<dtype> { return val1 / val2; };
857  return broadcast::broadcaster<std::complex<dtype>>(lhs, rhs, function);
858  }
859 
860  //============================================================================
861  // Method Description:
868  template<typename dtype>
870  {
871  lhs /= rhs;
872  return lhs;
873  }
874 
875  //============================================================================
876  // Method Description:
883  template<typename dtype>
884  NdArray<dtype> operator/(dtype lhs, const NdArray<dtype>& rhs)
885  {
887 
888  const auto function = [lhs](dtype value) -> dtype { return lhs / value; };
889 
890  NdArray<dtype> returnArray(rhs.shape());
891 
892  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
893 
894  return returnArray;
895  }
896 
897  //============================================================================
898  // Method Description:
905  template<typename dtype>
906  NdArray<std::complex<dtype>> operator/(const NdArray<dtype>& lhs, const std::complex<dtype>& rhs)
907  {
909 
910  const auto function = [rhs](dtype value) -> std::complex<dtype> { return value / rhs; };
911 
912  NdArray<std::complex<dtype>> returnArray(lhs.shape());
913 
914  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
915 
916  return returnArray;
917  }
918 
919  //============================================================================
920  // Method Description:
927  template<typename dtype>
928  NdArray<std::complex<dtype>> operator/(const std::complex<dtype>& lhs, const NdArray<dtype>& rhs)
929  {
931 
932  const auto function = [lhs](dtype value) -> std::complex<dtype> { return lhs / value; };
933 
934  NdArray<std::complex<dtype>> returnArray(rhs.shape());
935 
936  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
937 
938  return returnArray;
939  }
940 
941  //============================================================================
942  // Method Description:
949  template<typename dtype>
950  NdArray<std::complex<dtype>> operator/(NdArray<std::complex<dtype>> lhs, dtype rhs)
951  {
952  lhs /= rhs;
953  return lhs;
954  }
955 
956  //============================================================================
957  // Method Description:
964  template<typename dtype>
965  NdArray<std::complex<dtype>> operator/(dtype lhs, const NdArray<std::complex<dtype>>& rhs)
966  {
968 
969  const auto function = [lhs](const std::complex<dtype>& value) -> std::complex<dtype> { return lhs / value; };
970 
971  NdArray<std::complex<dtype>> returnArray(rhs.shape());
972 
973  stl_algorithms::transform(rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
974 
975  return returnArray;
976  }
977 
978  //============================================================================
979  // Method Description:
986  template<typename dtype, std::enable_if_t<std::is_integral_v<dtype> || std::is_floating_point_v<dtype>, int> = 0>
988  {
989  if constexpr (std::is_integral_v<dtype>)
990  {
991  return broadcast::broadcaster(lhs, rhs, std::modulus<dtype>());
992  }
993  else
994  {
995  const auto function = [](const dtype value1, const dtype value2) -> dtype
996  { return std::fmod(value1, value2); };
997  return broadcast::broadcaster(lhs, rhs, function);
998  }
999  }
1000 
1001  //============================================================================
1002  // Method Description:
1009  template<typename dtype, std::enable_if_t<std::is_integral_v<dtype> || std::is_floating_point_v<dtype>, int> = 0>
1011  {
1012  if constexpr (std::is_integral_v<dtype>)
1013  {
1014  const auto function = [rhs](dtype& value) -> dtype { return value %= rhs; };
1015  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1016  }
1017  else
1018  {
1019  const auto function = [rhs](dtype& value) -> void { value = std::fmod(value, rhs); };
1020  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1021  }
1022 
1023  return lhs;
1024  }
1025 
1026  //============================================================================
1027  // Method Description:
1034  template<typename dtype, std::enable_if_t<std::is_integral_v<dtype> || std::is_floating_point_v<dtype>, int> = 0>
1036  {
1037  if constexpr (std::is_integral_v<dtype>)
1038  {
1039  return broadcast::broadcaster<dtype>(lhs, rhs, std::modulus<dtype>());
1040  }
1041  else
1042  {
1043  const auto function = [](dtype value1, dtype value2) -> dtype { return std::fmod(value1, value2); };
1044  return broadcast::broadcaster<dtype>(lhs, rhs, function);
1045  }
1046  }
1047 
1048  //============================================================================
1049  // Method Description:
1056  template<typename dtype>
1058  {
1059  lhs %= rhs;
1060  return lhs;
1061  }
1062 
1063  //============================================================================
1064  // Method Description:
1071  template<typename dtype, std::enable_if_t<std::is_integral_v<dtype>, int> = 0>
1072  NdArray<dtype> operator%(dtype lhs, const NdArray<dtype>& rhs)
1073  {
1074  NdArray<dtype> returnArray(rhs.shape());
1076  rhs.end(),
1077  returnArray.begin(),
1078  [lhs](dtype value) -> dtype { return lhs % value; });
1079 
1080  return returnArray;
1081  }
1082 
1083  //============================================================================
1084  // Method Description:
1091  template<typename dtype, std::enable_if_t<std::is_floating_point_v<dtype>, int> = 0>
1092  NdArray<dtype> operator%(dtype lhs, const NdArray<dtype>& rhs)
1093  {
1094  NdArray<dtype> returnArray(rhs.shape());
1095  stl_algorithms::transform(rhs.begin(),
1096  rhs.end(),
1097  returnArray.begin(),
1098  [lhs](dtype value) -> dtype { return std::fmod(lhs, value); });
1099 
1100  return returnArray;
1101  }
1102 
1103  //============================================================================
1104  // Method Description:
1111  template<typename dtype>
1113  {
1114  STATIC_ASSERT_INTEGER(dtype);
1115 
1116  return broadcast::broadcaster(lhs, rhs, std::bit_or<dtype>());
1117  }
1118 
1119  //============================================================================
1120  // Method Description:
1127  template<typename dtype>
1129  {
1130  STATIC_ASSERT_INTEGER(dtype);
1131 
1132  const auto function = [rhs](dtype& value) -> dtype { return value |= rhs; };
1133 
1134  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1135 
1136  return lhs;
1137  }
1138 
1139  //============================================================================
1140  // Method Description:
1147  template<typename dtype>
1149  {
1150  STATIC_ASSERT_INTEGER(dtype);
1151 
1152  return broadcast::broadcaster<dtype>(lhs, rhs, std::bit_or<dtype>());
1153  }
1154 
1155  //============================================================================
1156  // Method Description:
1163  template<typename dtype>
1165  {
1166  lhs |= rhs;
1167  return lhs;
1168  }
1169 
1170  //============================================================================
1171  // Method Description:
1178  template<typename dtype>
1179  NdArray<dtype> operator|(dtype lhs, const NdArray<dtype>& rhs)
1180  {
1181  return rhs | lhs;
1182  }
1183 
1184  //============================================================================
1185  // Method Description:
1192  template<typename dtype>
1194  {
1195  STATIC_ASSERT_INTEGER(dtype);
1196 
1197  return broadcast::broadcaster(lhs, rhs, std::bit_and<dtype>());
1198  }
1199 
1200  //============================================================================
1201  // Method Description:
1208  template<typename dtype>
1210  {
1211  STATIC_ASSERT_INTEGER(dtype);
1212 
1213  const auto function = [rhs](dtype& value) -> dtype { return value &= rhs; };
1214 
1215  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1216 
1217  return lhs;
1218  }
1219 
1220  //============================================================================
1221  // Method Description:
1228  template<typename dtype>
1230  {
1231  STATIC_ASSERT_INTEGER(dtype);
1232 
1233  return broadcast::broadcaster<dtype>(lhs, rhs, std::bit_and<dtype>());
1234  }
1235 
1236  //============================================================================
1237  // Method Description:
1244  template<typename dtype>
1246  {
1247  lhs &= rhs;
1248  return lhs;
1249  }
1250 
1251  //============================================================================
1252  // Method Description:
1259  template<typename dtype>
1260  NdArray<dtype> operator&(dtype lhs, const NdArray<dtype>& rhs)
1261  {
1262  return rhs & lhs;
1263  }
1264 
1265  //============================================================================
1266  // Method Description:
1273  template<typename dtype>
1275  {
1276  STATIC_ASSERT_INTEGER(dtype);
1277 
1278  return broadcast::broadcaster(lhs, rhs, std::bit_xor<dtype>());
1279  }
1280 
1281  //============================================================================
1282  // Method Description:
1289  template<typename dtype>
1291  {
1292  STATIC_ASSERT_INTEGER(dtype);
1293 
1294  const auto function = [rhs](dtype& value) -> dtype { return value ^= rhs; };
1295 
1296  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1297 
1298  return lhs;
1299  }
1300 
1301  //============================================================================
1302  // Method Description:
1309  template<typename dtype>
1311  {
1312  STATIC_ASSERT_INTEGER(dtype);
1313 
1314  return broadcast::broadcaster<dtype>(lhs, rhs, std::bit_xor<dtype>());
1315  }
1316 
1317  //============================================================================
1318  // Method Description:
1325  template<typename dtype>
1327  {
1328  lhs ^= rhs;
1329  return lhs;
1330  }
1331 
1332  //============================================================================
1333  // Method Description:
1340  template<typename dtype>
1341  NdArray<dtype> operator^(dtype lhs, const NdArray<dtype>& rhs)
1342  {
1343  return rhs ^ lhs;
1344  }
1345 
1346  //============================================================================
1347  // Method Description:
1353  template<typename dtype>
1355  {
1356  STATIC_ASSERT_INTEGER(dtype);
1357 
1358  const auto function = [](dtype value) -> dtype { return ~value; };
1359 
1360  NdArray<dtype> returnArray(inArray.shape());
1361 
1362  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
1363 
1364  return returnArray;
1365  }
1366 
1367  //============================================================================
1368  // Method Description:
1375  template<typename dtype>
1377  {
1378  STATIC_ASSERT_ARITHMETIC(dtype);
1379 
1380  const auto function = [](dtype value1, dtype value2) -> bool
1381  { return !utils::essentiallyEqual(value1, dtype{ 0 }) && !utils::essentiallyEqual(value2, dtype{ 0 }); };
1382 
1383  return broadcast::broadcaster<bool>(lhs, rhs, function);
1384  }
1385 
1386  //============================================================================
1387  // Method Description:
1394  template<typename dtype>
1395  NdArray<bool> operator&&(const NdArray<dtype>& lhs, dtype rhs)
1396  {
1397  STATIC_ASSERT_ARITHMETIC(dtype);
1398 
1399  NdArray<bool> returnArray(lhs.shape());
1400 
1401  const auto function = [rhs](dtype value) -> bool { return value && rhs; };
1402 
1403  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1404 
1405  return returnArray;
1406  }
1407 
1408  //============================================================================
1409  // Method Description:
1416  template<typename dtype>
1417  NdArray<bool> operator&&(dtype lhs, const NdArray<dtype>& rhs)
1418  {
1419  return rhs && lhs;
1420  }
1421 
1422  //============================================================================
1423  // Method Description:
1430  template<typename dtype>
1432  {
1433  STATIC_ASSERT_ARITHMETIC(dtype);
1434 
1435  const auto function = [](dtype value1, dtype value2) -> bool
1436  { return !utils::essentiallyEqual(value1, dtype{ 0 }) || !utils::essentiallyEqual(value2, dtype{ 0 }); };
1437 
1438  return broadcast::broadcaster<bool>(lhs, rhs, function);
1439  }
1440 
1441  //============================================================================
1442  // Method Description:
1449  template<typename dtype>
1450  NdArray<bool> operator||(const NdArray<dtype>& lhs, dtype rhs)
1451  {
1452  STATIC_ASSERT_ARITHMETIC(dtype);
1453 
1454  NdArray<bool> returnArray(lhs.shape());
1455 
1456  const auto function = [rhs](dtype value) -> bool { return value || rhs; };
1457 
1458  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1459 
1460  return returnArray;
1461  }
1462 
1463  //============================================================================
1464  // Method Description:
1471  template<typename dtype>
1472  NdArray<bool> operator||(dtype lhs, const NdArray<dtype>& rhs)
1473  {
1474  return rhs || lhs;
1475  }
1476 
1477  //============================================================================
1478  // Method Description:
1484  template<typename dtype>
1486  {
1487  STATIC_ASSERT_ARITHMETIC(dtype);
1488 
1489  NdArray<bool> returnArray(inArray.shape());
1490 
1491  const auto function = [](dtype value) -> dtype { return !value; };
1492 
1493  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
1494 
1495  return returnArray;
1496  }
1497 
1498  //============================================================================
1499  // Method Description:
1507  template<typename dtype>
1509  {
1510  const auto equalTo = [](dtype lhs_, dtype rhs_) noexcept -> bool
1511  { return utils::essentiallyEqual(lhs_, rhs_); };
1512 
1513  return broadcast::broadcaster<bool>(lhs, rhs, equalTo);
1514  }
1515 
1516  //============================================================================
1517  // Method Description:
1525  template<typename dtype>
1526  NdArray<bool> operator==(const NdArray<dtype>& lhs, dtype inValue)
1527  {
1528  NdArray<bool> returnArray(lhs.shape());
1529 
1530  const auto equalTo = [inValue](dtype value) noexcept -> bool
1531  { return utils::essentiallyEqual(inValue, value); };
1532 
1533  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), equalTo);
1534 
1535  return returnArray;
1536  }
1537 
1538  //============================================================================
1539  // Method Description:
1547  template<typename dtype>
1548  NdArray<bool> operator==(dtype inValue, const NdArray<dtype>& inArray)
1549  {
1550  return inArray == inValue;
1551  }
1552 
1553  //============================================================================
1554  // Method Description:
1562  template<typename dtype>
1564  {
1565  const auto notEqualTo = [](dtype lhs_, dtype rhs_) noexcept -> bool
1566  { return !utils::essentiallyEqual(lhs_, rhs_); };
1567 
1568  return broadcast::broadcaster<bool>(lhs, rhs, notEqualTo);
1569  }
1570 
1571  //============================================================================
1572  // Method Description:
1580  template<typename dtype>
1581  NdArray<bool> operator!=(const NdArray<dtype>& lhs, dtype inValue)
1582  {
1583  NdArray<bool> returnArray(lhs.shape());
1584 
1585  const auto notEqualTo = [inValue](dtype value) noexcept -> bool
1586  { return !utils::essentiallyEqual(inValue, value); };
1587 
1588  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), notEqualTo);
1589 
1590  return returnArray;
1591  }
1592 
1593  //============================================================================
1594  // Method Description:
1602  template<typename dtype>
1603  NdArray<bool> operator!=(dtype inValue, const NdArray<dtype>& inArray)
1604  {
1605  return inArray != inValue;
1606  }
1607 
1608  //============================================================================
1609  // Method Description:
1617  template<typename dtype>
1618  NdArray<bool> operator<(const NdArray<dtype>& lhs, const NdArray<dtype>& rhs)
1619  {
1621 
1622  const auto function = [](dtype lhs_, dtype rhs_) noexcept -> bool { return lhs_ < rhs_; };
1623  return broadcast::broadcaster<bool>(lhs, rhs, function);
1624  }
1625 
1626  //============================================================================
1627  // Method Description:
1635  template<typename dtype>
1636  NdArray<bool> operator<(const NdArray<dtype>& lhs, dtype inValue)
1637  {
1639 
1640  NdArray<bool> returnArray(lhs.shape());
1641 
1642  const auto function = [inValue](dtype value) noexcept -> bool { return value < inValue; };
1643 
1644  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1645 
1646  return returnArray;
1647  }
1648 
1649  //============================================================================
1650  // Method Description:
1658  template<typename dtype>
1659  NdArray<bool> operator<(dtype inValue, const NdArray<dtype>& inArray)
1660  {
1662 
1663  NdArray<bool> returnArray(inArray.shape());
1664 
1665  const auto function = [inValue](dtype value) noexcept -> bool { return inValue < value; };
1666 
1667  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
1668 
1669  return returnArray;
1670  }
1671 
1672  //============================================================================
1673  // Method Description:
1681  template<typename dtype>
1683  {
1685 
1686  const auto function = [](dtype lhs_, dtype rhs_) noexcept -> bool { return lhs_ > rhs_; };
1687  return broadcast::broadcaster<bool>(lhs, rhs, function);
1688  }
1689 
1690  //============================================================================
1691  // Method Description:
1699  template<typename dtype>
1700  NdArray<bool> operator>(const NdArray<dtype>& lhs, dtype inValue)
1701  {
1703 
1704  NdArray<bool> returnArray(lhs.shape());
1705 
1706  const auto function = [inValue](dtype value) noexcept -> bool { return value > inValue; };
1707 
1708  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1709 
1710  return returnArray;
1711  }
1712 
1713  //============================================================================
1714  // Method Description:
1722  template<typename dtype>
1723  NdArray<bool> operator>(dtype inValue, const NdArray<dtype>& inArray)
1724  {
1726 
1727  NdArray<bool> returnArray(inArray.shape());
1728 
1729  const auto function = [inValue](dtype value) noexcept -> bool { return inValue > value; };
1730 
1731  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
1732 
1733  return returnArray;
1734  }
1735 
1736  //============================================================================
1737  // Method Description:
1745  template<typename dtype>
1746  NdArray<bool> operator<=(const NdArray<dtype>& lhs, const NdArray<dtype>& rhs)
1747  {
1749 
1750  const auto function = [](dtype lhs_, dtype rhs_) noexcept -> bool { return lhs_ <= rhs_; };
1751  return broadcast::broadcaster<bool>(lhs, rhs, function);
1752  }
1753 
1754  //============================================================================
1755  // Method Description:
1763  template<typename dtype>
1764  NdArray<bool> operator<=(const NdArray<dtype>& lhs, dtype inValue)
1765  {
1767 
1768  NdArray<bool> returnArray(lhs.shape());
1769 
1770  const auto function = [inValue](dtype value) noexcept -> bool { return value <= inValue; };
1771 
1772  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1773 
1774  return returnArray;
1775  }
1776 
1777  //============================================================================
1778  // Method Description:
1786  template<typename dtype>
1787  NdArray<bool> operator<=(dtype inValue, const NdArray<dtype>& inArray)
1788  {
1790 
1791  NdArray<bool> returnArray(inArray.shape());
1792 
1793  const auto function = [inValue](dtype value) noexcept -> bool { return inValue <= value; };
1794 
1795  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
1796 
1797  return returnArray;
1798  }
1799 
1800  //============================================================================
1801  // Method Description:
1809  template<typename dtype>
1811  {
1813 
1814  const auto function = [](dtype lhs_, dtype rhs_) noexcept -> bool { return lhs_ >= rhs_; };
1815  return broadcast::broadcaster<bool>(lhs, rhs, function);
1816  }
1817 
1818  //============================================================================
1819  // Method Description:
1827  template<typename dtype>
1828  NdArray<bool> operator>=(const NdArray<dtype>& lhs, dtype inValue)
1829  {
1831 
1832  NdArray<bool> returnArray(lhs.shape());
1833 
1834  const auto function = [inValue](dtype value) noexcept -> bool { return value >= inValue; };
1835 
1836  stl_algorithms::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
1837 
1838  return returnArray;
1839  }
1840 
1841  //============================================================================
1842  // Method Description:
1850  template<typename dtype>
1851  NdArray<bool> operator>=(dtype inValue, const NdArray<dtype>& inArray)
1852  {
1854 
1855  NdArray<bool> returnArray(inArray.shape());
1856 
1857  const auto function = [inValue](dtype value) noexcept -> bool { return inValue >= value; };
1858 
1859  stl_algorithms::transform(inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
1860 
1861  return returnArray;
1862  }
1863 
1864  //============================================================================
1865  // Method Description:
1872  template<typename dtype>
1873  NdArray<dtype>& operator<<=(NdArray<dtype>& lhs, uint8 inNumBits)
1874  {
1875  STATIC_ASSERT_INTEGER(dtype);
1876 
1877  const auto function = [inNumBits](dtype& value) -> void { value <<= inNumBits; };
1878 
1879  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1880 
1881  return lhs;
1882  }
1883 
1884  //============================================================================
1885  // Method Description:
1892  template<typename dtype>
1893  NdArray<dtype> operator<<(const NdArray<dtype>& lhs, uint8 inNumBits)
1894  {
1895  STATIC_ASSERT_INTEGER(dtype);
1896 
1897  NdArray<dtype> returnArray(lhs);
1898  returnArray <<= inNumBits;
1899  return returnArray;
1900  }
1901 
1902  //============================================================================
1903  // Method Description:
1910  template<typename dtype>
1912  {
1913  STATIC_ASSERT_INTEGER(dtype);
1914 
1915  const auto function = [inNumBits](dtype& value) -> void { value >>= inNumBits; };
1916 
1917  stl_algorithms::for_each(lhs.begin(), lhs.end(), function);
1918 
1919  return lhs;
1920  }
1921 
1922  //============================================================================
1923  // Method Description:
1930  template<typename dtype>
1932  {
1933  STATIC_ASSERT_INTEGER(dtype);
1934 
1935  NdArray<dtype> returnArray(lhs);
1936  returnArray >>= inNumBits;
1937  return returnArray;
1938  }
1939 
1940  //============================================================================
1941  // Method Description:
1946  template<typename dtype>
1948  {
1949  STATIC_ASSERT_ARITHMETIC(dtype);
1950 
1951  const auto function = [](dtype& value) -> void { ++value; };
1952 
1953  stl_algorithms::for_each(rhs.begin(), rhs.end(), function);
1954 
1955  return rhs;
1956  }
1957 
1958  //============================================================================
1959  // Method Description:
1965  template<typename dtype>
1967  {
1968  auto copy = NdArray<dtype>(lhs);
1969  ++lhs;
1970  return copy;
1971  }
1972 
1973  //============================================================================
1974  // Method Description:
1979  template<typename dtype>
1981  {
1982  STATIC_ASSERT_ARITHMETIC(dtype);
1983 
1984  const auto function = [](dtype& value) -> void { --value; };
1985 
1986  stl_algorithms::for_each(rhs.begin(), rhs.end(), function);
1987 
1988  return rhs;
1989  }
1990 
1991  //============================================================================
1992  // Method Description:
1998  template<typename dtype>
2000  {
2001  auto copy = NdArray<dtype>(lhs);
2002  --lhs;
2003  return copy;
2004  }
2005 
2006  //============================================================================
2007  // Method Description:
2014  template<typename dtype>
2015  std::ostream& operator<<(std::ostream& inOStream, const NdArray<dtype>& inArray)
2016  {
2018 
2019  inOStream << inArray.str();
2020  return inOStream;
2021  }
2022 } // namespace nc
#define STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype)
Definition: StaticAsserts.hpp:56
#define STATIC_ASSERT_INTEGER(dtype)
Definition: StaticAsserts.hpp:43
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:39
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:138
const_iterator cbegin() const noexcept
Definition: NdArrayCore.hpp:1318
iterator end() noexcept
Definition: NdArrayCore.hpp:1576
const_iterator cend() const noexcept
Definition: NdArrayCore.hpp:1626
std::string str() const
Definition: NdArrayCore.hpp:4535
iterator begin() noexcept
Definition: NdArrayCore.hpp:1268
const Shape & shape() const noexcept
Definition: NdArrayCore.hpp:4464
NdArray< dtypeIn1 > & broadcaster(NdArray< dtypeIn1 > &inArray1, const NdArray< dtypeIn2 > &inArray2, const Function &function, const AdditionalFunctionArgs &&... additionalFunctionArgs)
Definition: NdArrayBroadcast.hpp:52
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:775
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:225
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:48
Definition: Cartesian.hpp:40
NdArray< dtype > operator&(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1229
bool operator==(const DateTime &lhs, const DateTime &rhs) noexcept
Equality operator for DateTime.
Definition: DateTime/DateTime.hpp:473
bool operator>=(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:98
NdArray< dtype > & operator%=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:987
Duration operator-(const DateTime &lhs, const DateTime &rhs) noexcept
Subtraction operator.
Definition: DateTime/DateTime.hpp:551
bool operator>(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:84
NdArray< bool > operator||(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1431
NdArray< dtype > operator|(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1148
NdArray< dtype > & operator+=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:57
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:302
NdArray< bool > operator!(const NdArray< dtype > &inArray)
Definition: NdArrayOperators.hpp:1485
bool operator!=(const DateTime &lhs, const DateTime &rhs) noexcept
Non Equality operator for DateTime.
Definition: DateTime/DateTime.hpp:486
dtype fmod(dtype inValue1, dtype inValue2) noexcept
Definition: fmod.hpp:52
bool operator<(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:46
NdArray< dtype > & operator>>=(NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:1911
NdArray< dtype > operator%(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1035
NdArray< dtype > operator>>(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:1931
NdArray< dtype > & operator-=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:272
NdArray< dtype > & operator^=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1274
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:604
NdArray< dtype > & operator|=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1112
std::uint8_t uint8
Definition: Types.hpp:42
NdArray< dtype > copy(const NdArray< dtype > &inArray)
Definition: copy.hpp:44
NdArray< dtype > & operator<<=(NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:1873
bool operator<=(const std::complex< T > &lhs, const std::complex< T > &rhs) noexcept
Definition: StdComplexOperators.hpp:65
NdArray< dtype > & operator--(NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1980
NdArray< bool > operator&&(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1376
NdArray< dtype > & operator++(NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1947
std::ostream & operator<<(std::ostream &os, Duration duration)
Output stream operator for the Duration type.
Definition: Clock.hpp:30
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:819
NdArray< dtype > & operator/=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:745
NdArray< dtype > operator^(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1310
NdArray< dtype > operator~(const NdArray< dtype > &inArray)
Definition: NdArrayOperators.hpp:1354
NdArray< dtype > & operator&=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1193
NdArray< dtype > & operator*=(NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:530