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