28 template<jit::
float_scalar T>
29 class buffer :
public std::vector<T> {
31 using std::vector<T>::size;
32 using std::vector<T>::data;
33 using std::vector<T>::assign;
56 std::vector<T> (s, d) {}
81 buffer(
const T
min,
const T dx,
const size_t num) : std::vector<T> (num) {
82 for (
size_t i = 0; i < num; i++) {
83 (*this)[i] = dx*i +
min;
101 void set(
const std::vector<T> &d) {
102 assign(d.cbegin(), d.cend());
111 const T same = (*this)[0];
112 for (
size_t i = 1, ie = size(); i < ie; i++) {
113 if ((*
this)[i] != same) {
127 for (
const T &d : *
this) {
128 if (d !=
static_cast<T
> (0.0)) {
142 for (
const T &d : *
this) {
143 if (d ==
static_cast<T
> (0.0)) {
157 for (
const T &d : *
this) {
158 if (std::real(d) > std::real(
static_cast<T
> (0.0))) {
172 for (
const T &d : *
this) {
173 if (std::fmod(std::real(d), std::real(
static_cast<T
> (2.0)))) {
187 for (
const T &d : *
this) {
188 if (d !=
static_cast<T
> (-1.0)) {
201#define apply_op(op) \
202for (T &d : *this) { \
251 void erf()
requires(std::floating_point<T>) {
268 for (
const T &x : *
this) {
270 if (std::isnan(std::real(x)) || std::isinf(std::real(x)) ||
271 std::isnan(std::imag(x)) || std::isinf(std::imag(x))) {
275 if (std::isnan(x) || std::isinf(x)) {
292 const size_t num_rows = size()/num_columns;
293 for (
size_t j = 0; j < num_columns; j++) {
294 b[j] = (*this)[index*num_rows + j];
307 const size_t num_rows = size()/num_columns;
309 for (
size_t i = 0; i < num_rows; i++) {
310 b[i] = (*this)[i*num_rows + index];
321#define row_op(opp, oppeq) \
322if (size() > x.size()) { \
323 assert(size()%x.size() == 0 && \
324 "Vector operand size is not a multiple of matrix operand size"); \
326 const size_t num_columns = size()/x.size(); \
327 const size_t num_rows = x.size(); \
328 for (size_t i = 0; i < num_rows; i++) { \
329 for (size_t j = 0; j < num_columns; j++) { \
330 (*this)[i*num_columns + j] oppeq x[i]; \
334 assert(x.size()%size() == 0 && \
335 "Vector operand size is not a multiple of matrix operand size"); \
337 std::vector<T> m(x.size()); \
338 const size_t num_columns = x.size()/size(); \
339 const size_t num_rows = size(); \
340 for (size_t i = 0; i < num_rows; i++) { \
341 for (size_t j = 0; j < num_columns; j++) { \
342 m[i*num_columns + j] = (*this)[i] opp x[i*num_columns + j]; \
366#define col_op(opp, oppeq) \
367if (size() > x.size()) { \
368 assert(size()%x.size() == 0 && \
369 "Vector operand size is not a multiple of matrix operand size"); \
371 const size_t num_columns = size()/x.size(); \
372 const size_t num_rows = x.size(); \
373 for (size_t i = 0; i < num_rows; i++) { \
374 for (size_t j = 0; j < num_columns; j++) { \
375 (*this)[i*num_columns + j] oppeq x[j]; \
379 assert(x.size()%size() == 0 && \
380 "Vector operand size is not a multiple of matrix operand size"); \
382 std::vector<T> m(x.size()); \
383 const size_t num_columns = x.size()/size(); \
384 const size_t num_rows = size(); \
385 for (size_t i = 0; i < num_rows; i++) { \
386 for (size_t j = 0; j < num_columns; j++) { \
387 m[i*num_columns + j] = (*this)[j] opp x[i*num_columns + j]; \
483 if (size() > x.size()) { \
484 assert(size()%x.size() == 0 && \
485 "Vector operand size is not a multiple of matrix operand size"); \
487 const size_t num_columns = size()/x.size(); \
488 const size_t num_rows = x.size(); \
489 for (size_t i = 0; i < num_rows; i++) { \
490 for (size_t j = 0; j < num_columns; j++) { \
491 (*this)[i*num_columns + j] = fn((*this)[i*num_columns + j], x[i]); \
495 assert(x.size()%size() == 0 && \
496 "Vector operand size is not a multiple of matrix operand size"); \
498 std::vector<T> m(x.size()); \
499 const size_t num_columns = x.size()/size(); \
500 const size_t num_rows = size(); \
501 for (size_t i = 0; i < num_rows; i++) { \
502 for (size_t j = 0; j < num_columns; j++) { \
503 m[i*num_columns + j] = fn((*this)[i], x[i*num_columns + j]); \
527 if (size() > x.size()) { \
528 assert(size()%x.size() == 0 && \
529 "Vector operand size is not a multiple of matrix operand size"); \
531 const size_t num_columns = size()/x.size(); \
532 const size_t num_rows = x.size(); \
533 for (size_t i = 0; i < num_rows; i++) { \
534 for (size_t j = 0; j < num_columns; j++) { \
535 (*this)[i*num_columns + j] = fn((*this)[i*num_columns + j], x[j]); \
539 assert(x.size()%size() == 0 && \
540 "Vector operand size is not a multiple of matrix operand size"); \
542 std::vector<T> m(x.size()); \
543 const size_t num_columns = x.size()/size(); \
544 const size_t num_rows = size(); \
545 for (size_t i = 0; i < num_rows; i++) { \
546 for (size_t j = 0; j < num_columns; j++) { \
547 m[i*num_columns + j] = fn((*this)[j], x[i*num_columns + j]); \
574 if (size() > x.size()) {
575 assert(size()%x.size() == 0 &&
576 "Vector operand size is not a multiple of matrix operand size");
578 const size_t num_columns = size()/x.size();
579 const size_t num_rows = x.size();
580 for (
size_t i = 0; i < num_rows; i++) {
581 for (
size_t j = 0; j < num_columns; j++) {
583 (*this)[i*num_columns + j] = std::atan(x[i]/(*
this)[i*num_columns + j]);
585 (*this)[i*num_columns + j] = std::atan2(x[i], (*
this)[i*num_columns + j]);
590 assert(x.size()%size() == 0 &&
591 "Vector operand size is not a multiple of matrix operand size");
593 std::vector<T> m(x.size());
594 const size_t num_columns = x.size()/size();
595 const size_t num_rows = size();
596 for (
size_t i = 0; i < num_rows; i++) {
597 for (
size_t j = 0; j < num_columns; j++) {
599 m[i*num_columns + j] = std::atan(x[i*num_columns + j]/(*
this)[i]);
601 m[i*num_columns + j] = std::atan2(x[i*num_columns + j], (*
this)[i]);
618 if (size() > x.size()) {
619 assert(size()%x.size() == 0 &&
620 "Vector operand size is not a multiple of matrix operand size");
622 const size_t num_columns = size()/x.size();
623 const size_t num_rows = x.size();
624 for (
size_t i = 0; i < num_columns; i++) {
625 for (
size_t j = 0; j < num_rows; j++) {
627 (*this)[i*num_columns + j] = std::atan(x[j]/(*
this)[i*num_columns + j]);
629 (*this)[i*num_columns + j] = std::atan2(x[j], (*
this)[i*num_columns + j]);
634 assert(x.size()%size() == 0 &&
635 "Vector operand size is not a multiple of matrix operand size");
637 std::vector<T> m(x.size());
638 const size_t num_columns = x.size()/size();
639 const size_t num_rows = size();
640 for (
size_t i = 0; i < num_rows; i++) {
641 for (
size_t j = 0; j < num_columns; j++) {
643 m[i*num_columns + j] = std::atan(x[i*num_columns + j]/(*
this)[j]);
645 m[i*num_columns + j] = std::atan2(x[i*num_columns + j], (*
this)[j]);
662 if (size() > x.size()) {
663 assert(size()%x.size() == 0 &&
664 "Vector operand size is not a multiple of matrix operand size");
666 const size_t num_columns = size()/x.size();
667 const size_t num_rows = x.size();
668 for (
size_t i = 0; i < num_rows; i++) {
669 for (
size_t j = 0; j < num_columns; j++) {
670 (*this)[i*num_columns + j] = std::pow((*
this)[i*num_columns + j], x[i]);
674 assert(x.size()%size() == 0 &&
675 "Vector operand size is not a multiple of matrix operand size");
677 std::vector<T> m(x.size());
678 const size_t num_columns = x.size()/size();
679 const size_t num_rows = size();
680 for (
size_t i = 0; i < num_columns; i++) {
681 for (
size_t j = 0; j < num_rows; j++) {
682 m[i*num_columns + j] = std::pow((*
this)[i], x[i*num_columns + j]);
698 if (size() > x.size()) {
699 assert(size()%x.size() == 0 &&
700 "Vector operand size is not a multiple of matrix operand size");
702 const size_t num_columns = size()/x.size();
703 const size_t num_rows = x.size();
704 for (
size_t i = 0; i < num_rows; i++) {
705 for (
size_t j = 0; j < num_columns; j++) {
706 (*this)[i*num_columns + j] = std::pow((*
this)[i*num_columns + j], x[j]);
710 assert(x.size()%size() == 0 &&
711 "Vector operand size is not a multiple of matrix operand size");
713 std::vector<T> m(x.size());
714 const size_t num_columns = x.size()/size();
715 const size_t num_rows = size();
716 for (
size_t i = 0; i < num_rows; i++) {
717 for (
size_t j = 0; j < num_columns; j++) {
718 m[i*num_columns + j] = std::pow((*
this)[j], x[i*num_columns + j]);
734 if (size() > x.size()) {
735 assert(size()%x.size() == 0 &&
736 "Vector operand size is not a multiple of matrix operand size");
738 const size_t num_columns = size()/x.size();
739 const size_t num_rows = x.size();
740 for (
size_t i = 0; i < num_rows; i++) {
741 for (
size_t j = 0; j < num_columns; j++) {
742 (*this)[i*num_columns + j] = std::hypot((*
this)[i*num_columns + j], x[i]);
746 assert(x.size()%size() == 0 &&
747 "Vector operand size is not a multiple of matrix operand size");
749 std::vector<T> m(x.size());
750 const size_t num_columns = x.size()/size();
751 const size_t num_rows = size();
752 for (
size_t i = 0; i < num_columns; i++) {
753 for (
size_t j = 0; j < num_rows; j++) {
754 m[i*num_columns + j] = std::hypot((*
this)[i], x[i*num_columns + j]);
770 if (size() > x.size()) {
771 assert(size()%x.size() == 0 &&
772 "Vector operand size is not a multiple of matrix operand size");
774 const size_t num_columns = size()/x.size();
775 const size_t num_rows = x.size();
776 for (
size_t i = 0; i < num_rows; i++) {
777 for (
size_t j = 0; j < num_columns; j++) {
778 (*this)[i*num_columns + j] = std::hypot((*
this)[i*num_columns + j], x[j]);
782 assert(x.size()%size() == 0 &&
783 "Vector operand size is not a multiple of matrix operand size");
785 std::vector<T> m(x.size());
786 const size_t num_columns = x.size()/size();
787 const size_t num_rows = size();
788 for (
size_t i = 0; i < num_rows; i++) {
789 for (
size_t j = 0; j < num_columns; j++) {
790 m[i*num_columns + j] = std::hypot((*
this)[j], x[i*num_columns + j]);
806 if (size() > x.size()) {
807 assert(size()%x.size() == 0 &&
808 "Vector operand size is not a multiple of matrix operand size");
810 const size_t num_columns = size()/x.size();
811 const size_t num_rows = x.size();
812 for (
size_t i = 0; i < num_rows; i++) {
813 for (
size_t j = 0; j < num_columns; j++) {
814 (*this)[i*num_columns + j] = std::copysign((*
this)[i*num_columns + j], x[i]);
818 assert(x.size()%size() == 0 &&
819 "Vector operand size is not a multiple of matrix operand size");
821 std::vector<T> m(x.size());
822 const size_t num_columns = x.size()/size();
823 const size_t num_rows = size();
824 for (
size_t i = 0; i < num_rows; i++) {
825 for (
size_t j = 0; j < num_columns; j++) {
826 m[i*num_columns + j] = std::copysign((*
this)[i], x[i*num_columns + j]);
842 if (size() > x.size()) {
843 assert(size()%x.size() == 0 &&
844 "Vector operand size is not a multiple of matrix operand size");
846 const size_t num_columns = size()/x.size();
847 const size_t num_rows = x.size();
848 for (
size_t i = 0; i < num_columns; i++) {
849 for (
size_t j = 0; j < num_rows; j++) {
850 (*this)[i*num_columns + j] = std::copysign((*
this)[i*num_columns + j], x[j]);
854 assert(x.size()%size() == 0 &&
855 "Vector operand size is not a multiple of matrix operand size");
857 std::vector<T> m(x.size());
858 const size_t num_columns = x.size()/size();
859 const size_t num_rows = size();
860 for (
size_t i = 0; i < num_rows; i++) {
861 for (
size_t j = 0; j < num_columns; j++) {
862 m[i*num_columns + j] = std::copysign((*
this)[j], x[i*num_columns + j]);
877 assert(d.imag() == 0.0 &&
"Imaginary part not zero.");
878 d =
static_cast<T
> (!d.real());
894 if constexpr (std::floating_point<T>) {
895 return (*
this)[0] ? t : f;
897 return (*
this)[0] !=
static_cast<T
> (0) ? t : f;
903 if constexpr (std::floating_point<T>) {
906 d = d !=
static_cast<T
> (0) ? t[0] : f[0];
911 assert(size() == f.size() &&
"Incompatable buffersize.");
912 for (
size_t i = 0, ie = size(); i < ie; i++) {
913 if constexpr (std::floating_point<T>) {
914 (*this)[i] = (*this)[i] ? t[0] : f[i];
916 (*this)[i] = (*this)[i] !=
static_cast<T
> (0) ? t[0] : f[i];
922 assert(size() == t.size() &&
"Incompatable buffersize.");
924 for (
size_t i = 0, ie = size(); i < ie; i++) {
925 if constexpr (std::floating_point<T>) {
926 (*this)[i] = (*this)[i] ? t[i] : f[0];
928 (*this)[i] = (*this)[i] !=
static_cast<T
> (0) ? t[i] : f[0];
933 assert(size() == f.size() &&
"Incompatable buffersize.");
934 for (
size_t i = 0, ie = size(); i < ie; i++) {
935 if constexpr (std::floating_point<T>) {
936 (*this)[i] = (*this)[i] ? t[i] : f[i];
938 (*this)[i] = (*this)[i] !=
static_cast<T
> (0) ? t[i] : f[i];
952#define logic_is(op) \
953for (T &d : *this) { \
984 template<jit::
float_scalar T>
986 if (a.size() != b.size()) {
990 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1003#define build_assoc_func(func) \
1004if (b.size() == 1) { \
1005 const T right = b[0]; \
1007 l = func(std::real(l), \
1008 std::real(right)); \
1011} else if (a.size() == 1) { \
1012 const T left = a[0]; \
1014 r = func(std::real(r), \
1020assert(a.size() == b.size() && \
1021 "Left and right sizes are incompatible."); \
1022for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1023 a[i] = func(std::real(a[i]), \
1037 template<jit::
float_scalar T>
1051 template<jit::
float_scalar T>
1061#define build_assoc_op(op) \
1062if (b.size() == 1) { \
1063 const T right = b[0]; \
1068} else if (a.size() == 1) { \
1069 const T left = a[0]; \
1076assert(a.size() == b.size() && \
1077 "Left and right sizes are incompatible."); \
1078for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1092 template<jit::
float_scalar T>
1103#define build_non_assoc_op(op, opeq) \
1104if (b.size() == 1) { \
1105 const T right = b[0]; \
1110} else if (a.size() == 1) { \
1111 const T left = a[0]; \
1118assert(a.size() == b.size() && \
1119 "Left and right sizes are incompatible."); \
1120for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1134 template<jit::
float_scalar T>
1148 template<jit::
float_scalar T>
1162 template<jit::
float_scalar T>
1172#define build_assoc_func(func) \
1173if (b.size() == 1) { \
1174 const T right = b[0]; \
1176 l = func(l, right); \
1179} else if (a.size() == 1) { \
1180 const T left = a[0]; \
1182 r = func(r, left); \
1187assert(a.size() == b.size() && \
1188 "Left and right sizes are incompatible."); \
1189for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1190 a[i] = func(a[i], b[i]); \
1203 template<std::
floating_po
int T>
1218 template<jit::
float_scalar T>
1227 if (a.size() == 1) {
1228 const T left = a[0];
1230 if (b.size() == 1) {
1231 const T middle = b[0];
1232 for (
size_t i = 0, ie = c.size(); i < ie; i++) {
1233 if constexpr (use_fma) {
1234 c[i] = std::fma(left, middle, c[i]);
1236 c[i] = left*middle + c[i];
1240 }
else if (c.size() == 1) {
1241 const T right = c[0];
1242 for (
size_t i = 0, ie = b.size(); i < ie; i++) {
1243 if constexpr (use_fma) {
1244 b[i] = std::fma(left, b[i], right);
1246 b[i] = left*b[i] + right;
1252 assert(b.size() == c.size() &&
1253 "Size mismatch between middle and right.");
1254 for (
size_t i = 0, ie = b.size(); i < ie; i++) {
1255 if constexpr (use_fma) {
1256 b[i] = std::fma(left, b[i], c[i]);
1258 b[i] = left*b[i] + c[i];
1262 }
else if (b.size() == 1) {
1263 const T middle = b[0];
1264 if (c.size() == 1) {
1265 const T right = c[0];
1266 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1267 if constexpr (use_fma) {
1268 a[i] = std::fma(a[i], middle, right);
1270 a[i] = a[i]*middle + right;
1276 assert(a.size() == c.size() &&
1277 "Size mismatch between left and right.");
1278 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1279 if constexpr (use_fma) {
1280 a[i] = std::fma(a[i], middle, c[i]);
1282 a[i] = a[i]*middle + c[i];
1286 }
else if (c.size() == 1) {
1287 assert(a.size() == b.size() &&
1288 "Size mismatch between left and middle.");
1289 const T right = c[0];
1290 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1291 if constexpr (use_fma) {
1292 a[i] = std::fma(a[i], b[i], right);
1294 a[i] = a[i]*b[i] + right;
1300 assert(a.size() == b.size() &&
1301 b.size() == c.size() &&
1302 a.size() == c.size() &&
1303 "Left, middle and right sizes are incompatible.");
1304 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1305 if constexpr (use_fma) {
1306 a[i] = std::fma(a[i], b[i], c[i]);
1308 a[i] = a[i]*b[i] + c[i];
1323 template<std::
floating_po
int T>
1325 if (b.size() == 1) {
1326 const T right = b[0];
1327 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1328 a[i] = std::fmod(a[i], right);
1331 }
else if (a.size() == 1) {
1332 const T left = a[0];
1333 for (
size_t i = 0, ie = b.size(); i < ie; i++) {
1334 b[i] = std::fmod(left, b[i]);
1339 assert(a.size() == b.size() &&
1340 "Left and right sizes are incompatible.");
1341 for (
size_t i = 0, ie = a.size(); i < ie; i++) {
1342 a[i] = std::fmod(a[i], b[i]);
1352#define logic_op(op) \
1353if (b.size() == 1) { \
1354 const T right = b[0]; \
1355 for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1356 a[i] = static_cast<T> (a[i] op right); \
1359} else if (a.size() == 1) { \
1360 const T left = a[0]; \
1361 for (size_t i = 0, ie = b.size(); i < ie; i++) { \
1362 b[i] = static_cast<T> (left op b[i]); \
1367assert(a.size() == b.size() && \
1368 "Left and right sizes are incompatible."); \
1369for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1370 a[i] = static_cast<T> (a[i] op b[i]); \
1383 template<jit::
float_scalar T>
1397 template<jit::
float_scalar T>
1411 template<std::
floating_po
int T>
1425 template<std::
floating_po
int T>
1426 inline buffer<T>
operator<(buffer<T> &a, buffer<T> &b) {
1439 template<std::
floating_po
int T>
1453 template<std::
floating_po
int T>
1454 inline buffer<T>
operator<=(buffer<T> &a, buffer<T> &b) {
1467 template<std::
floating_po
int T>
1481 template<std::
floating_po
int T>
1491#define branch_fn(fn) \
1492if (b.size() == 1) { \
1493 const T right = b[0]; \
1494 for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1495 a[i] = fn(a[i], right); \
1498} else if (a.size() == 1) { \
1499 const T left = a[0]; \
1500 for (size_t i = 0, ie = b.size(); i < ie; i++) { \
1501 b[i] = fn(left, b[i]); \
1506assert(a.size() == b.size() && \
1507 "Left and right sizes are incompatible."); \
1508for (size_t i = 0, ie = a.size(); i < ie; i++) { \
1509 a[i] = fn(a[i], b[i]); \
1522 template<std::
floating_po
int T>
1523 inline buffer<T>
min(buffer<T> &a, buffer<T> &b) {
1536 template<jit::
float_scalar T>
1538 if (exponent.size() == 1) {
1539 const T right = exponent[0];
1540 if (std::imag(right) == 0) {
1541 const int64_t right_int =
static_cast<int64_t
> (std::real(right));
1542 if (std::real(right) - right_int) {
1543 if (right ==
static_cast<T
> (0.5)) {
1548 for (
size_t i = 0, ie = base.size(); i < ie; i++) {
1549 base[i] = std::pow(base[i], right);
1554 if (right_int > 0) {
1555 for (
size_t i = 0, ie = base.size(); i < ie; i++) {
1556 const T left = base[i];
1557 for (
size_t j = 0, je = right_int - 1; j < je; j++) {
1562 }
else if (right_int == 0) {
1563 for (
size_t i = 0, ie = base.size(); i < ie; i++) {
1568 for (
size_t i = 0, ie = base.size(); i < ie; i++) {
1569 const T left =
static_cast<T
> (1.0)/base[i];
1571 for (
size_t j = 0, je = std::abs(right_int) - 1; j < je; j++) {
1578 for (
size_t i = 0, ie = base.size(); i < ie; i++) {
1579 base[i] = std::pow(base[i], right);
1583 }
else if (base.size() == 1) {
1584 const T left = base[0];
1585 for (
size_t i = 0, ie = exponent.size(); i < ie; i++) {
1586 exponent[i] = std::pow(left, exponent[i]);
1591 assert(base.size() == exponent.size() &&
1592 "Left and right sizes are incompatible.");
1593 for (
size_t i = 0, ie = base.size(); i < ie; i++) {
1594 base[i] = std::pow(base[i], exponent[i]);
1608 template<jit::
float_scalar T>
1610 if (y.size() == 1) {
1611 const T right = y[0];
1612 for (
size_t i = 0, ie = x.size(); i < ie; i++) {
1614 x[i] = std::atan(right/x[i]);
1616 x[i] = std::atan2(right, x[i]);
1620 }
else if (x.size() == 1) {
1621 const T left = x[0];
1622 for (
size_t i = 0, ie = y.size(); i < ie; i++) {
1624 y[i] = std::atan(y[i]/left);
1626 y[i] = std::atan2(y[i], left);
1632 assert(x.size() == y.size() &&
1633 "Left and right sizes are incompatible.");
1634 for (
size_t i = 0, ie = x.size(); i < ie; i++) {
1636 x[i] = std::atan(y[i]/x[i]);
1638 x[i] = std::atan2(y[i], x[i]);
1653 template<std::
floating_po
int T>
1656 if (y.size() == 1) {
1657 const T right = y[0];
1658 for (
size_t i = 0, ie = x.size(); i < ie; i++) {
1659 x[i] = std::copysign(x[i], right);
1662 }
else if (x.size() == 1) {
1663 const T left = x[0];
1664 for (
size_t i = 0, ie = y.size(); i < ie; i++) {
1665 y[i] = std::copysign(left, y[i]);
1670 assert(x.size() == y.size() &&
1671 "Left and right sizes are incompatible.");
1672 for (
size_t i = 0, ie = x.size(); i < ie; i++) {
1673 x[i] = std::copysign(x[i], y[i]);
#define col_op(opp, oppeq)
Applies an operator along a column.
Definition backend.hpp:366
#define col_fn(fn)
Applies a function along a column.
Definition backend.hpp:526
#define branch_fn(fn)
Applies a function with two operands.
Definition backend.hpp:1491
#define row_op(opp, oppeq)
Applies an operator along a row.
Definition backend.hpp:321
#define logic_op(op)
Applies a logical operator.
Definition backend.hpp:1352
#define build_assoc_func(func)
Applies an associative function.
Definition backend.hpp:1003
#define build_assoc_op(op)
Applies an associative operator.
Definition backend.hpp:1061
#define logic_is(op)
Applies a logical is operator.
Definition backend.hpp:952
#define build_non_assoc_op(op, opeq)
Applies a non-associative operator.
Definition backend.hpp:1103
#define apply_op(op)
Applies an operation over all elements in the buffer.
Definition backend.hpp:201
#define row_fn(fn)
Applies a function along a row.
Definition backend.hpp:482
Class representing a generic buffer.
Definition backend.hpp:29
void set(const std::vector< T > &d)
Assign a vector value.
Definition backend.hpp:101
void subtract_row(const buffer< T > &x)
Subtract row operation.
Definition backend.hpp:413
void multiply_row(const buffer< T > &x)
Multiply row operation.
Definition backend.hpp:437
void add_col(const buffer< T > &x)
Add col operation.
Definition backend.hpp:401
void erfi()
Take erfi.
Definition backend.hpp:258
void copysign_col(const buffer< T > &x)
copysign col operation.
Definition backend.hpp:841
void log()
Take log.
Definition backend.hpp:223
buffer(const buffer &d)
Construct a buffer backend from a buffer backend.
Definition backend.hpp:71
void sqrt()
Take sqrt.
Definition backend.hpp:209
buffer(const size_t s)
Construct a buffer backend with a size.
Definition backend.hpp:46
void hypot_row(const buffer< T > &x)
Hypot row operation.
Definition backend.hpp:733
bool is_normal() const
Check for normal values.
Definition backend.hpp:267
buffer()
Construct an empty buffer backend.
Definition backend.hpp:38
void isinf()
isinf query.
Definition backend.hpp:960
buffer< T > index_row(const size_t index, const size_t num_columns)
Index row.
Definition backend.hpp:290
bool is_negative() const
Is every element negative.
Definition backend.hpp:156
void pow_col(const buffer< T > &x)
Pow col operation.
Definition backend.hpp:697
buffer(const std::vector< T > &d)
Construct a buffer backend from a vector.
Definition backend.hpp:63
bool is_same() const
Is every element the same.
Definition backend.hpp:110
buffer(const size_t s, const T d)
Construct a buffer backend with a size.
Definition backend.hpp:55
buffer< T > operator!()
Not operation.
Definition backend.hpp:874
void divide_col(const buffer< T > &x)
Divide col operation.
Definition backend.hpp:473
void erf()
Take erf.
Definition backend.hpp:251
bool is_none() const
Is every element negative one.
Definition backend.hpp:186
void min_row(const buffer< T > &x)
Min row operation.
Definition backend.hpp:517
void pow_row(const buffer< T > &x)
Pow row operation.
Definition backend.hpp:661
void sin()
Take sin.
Definition backend.hpp:230
void add_row(const buffer< T > &x)
Add row operation.
Definition backend.hpp:356
buffer(const T min, const T dx, const size_t num)
Construct a buffer backend linearly.
Definition backend.hpp:81
void subtract_col(const buffer< T > &x)
Subtract col operation.
Definition backend.hpp:425
buffer< T > if_(const buffer< T > &t, const buffer< T > &f)
Apply condition.
Definition backend.hpp:892
void multiply_col(const buffer< T > &x)
Multiply col operation.
Definition backend.hpp:449
void min_col(const buffer< T > &x)
Min col operation.
Definition backend.hpp:561
bool is_even() const
Is every element even.
Definition backend.hpp:171
T base
Type def to retrieve the backend T type.
Definition backend.hpp:972
void divide_row(const buffer< T > &x)
Divide row operation.
Definition backend.hpp:461
void real()
Take cos.
Definition backend.hpp:244
void isnan()
isnan query.
Definition backend.hpp:967
void copysign_row(const buffer< T > &x)
copysign row operation.
Definition backend.hpp:805
void hypot_col(const buffer< T > &x)
Hypot col operation.
Definition backend.hpp:769
void atan_col(const buffer< T > &x)
Atan col operation.
Definition backend.hpp:617
void atan_row(const buffer< T > &x)
Atan row operation.
Definition backend.hpp:573
buffer< T > index_column(const size_t index, const size_t num_columns)
Index column.
Definition backend.hpp:306
void exp()
Take exp.
Definition backend.hpp:216
bool has_zero() const
Is any element zero.
Definition backend.hpp:141
bool is_zero() const
Is every element zero.
Definition backend.hpp:126
void set(const T d)
Assign a constant value.
Definition backend.hpp:92
void cos()
Take cos.
Definition backend.hpp:237
Complex scalar concept.
Definition register.hpp:25
subroutine assert(test, message)
Assert check.
Definition f_binding_test.f90:38
Name space for backend buffers.
Definition backend.hpp:19
buffer< T > fma(buffer< T > &a, buffer< T > &b, buffer< T > &c)
Fused multiply add operation.
Definition backend.hpp:1219
buffer< T > operator*(buffer< T > &a, buffer< T > &b)
Multiply operation.
Definition backend.hpp:1149
buffer< T > operator>=(buffer< T > &a, buffer< T > &b)
Greater than equal operation.
Definition backend.hpp:1440
buffer< T > operator&&(buffer< T > &a, buffer< T > &b)
And operation.
Definition backend.hpp:1468
buffer< T > min(buffer< T > &a, buffer< T > &b)
Min operation.
Definition backend.hpp:1052
buffer< T > max(buffer< T > &a, buffer< T > &b)
Max operation.
Definition backend.hpp:1038
bool operator==(const buffer< T > &a, const buffer< T > &b)
Equal operation.
Definition backend.hpp:985
buffer< T > atan(buffer< T > &x, buffer< T > &y)
Take the inverse tangent.
Definition backend.hpp:1609
buffer< T > operator>(buffer< T > &a, buffer< T > &b)
Greater than operation.
Definition backend.hpp:1412
buffer< T > operator<=(buffer< T > &a, buffer< T > &b)
Less than equal operation.
Definition backend.hpp:1454
buffer< T > operator!=(buffer< T > &a, buffer< T > &b)
Not equal operation.
Definition backend.hpp:1398
buffer< T > operator/(buffer< T > &a, buffer< T > &b)
Divide operation.
Definition backend.hpp:1163
buffer< T > operator-(buffer< T > &a, buffer< T > &b)
Subtract operation.
Definition backend.hpp:1135
buffer< T > operator+(buffer< T > &a, buffer< T > &b)
Add operation.
Definition backend.hpp:1093
buffer< T > operator%(buffer< T > &a, buffer< T > &b)
Modulo operation.
Definition backend.hpp:1324
buffer< T > operator||(buffer< T > &a, buffer< T > &b)
Or operation.
Definition backend.hpp:1482
buffer< T > operator<(buffer< T > &a, buffer< T > &b)
Less than operation.
Definition backend.hpp:1426
buffer< T > pow(buffer< T > &base, buffer< T > &exponent)
Take the power.
Definition backend.hpp:1537
buffer< T > copysign(buffer< T > &x, buffer< T > &y)
Copy the sign of x and apply it to y.
Definition backend.hpp:1654
buffer< T > hypot(buffer< T > &a, buffer< T > &b)
hypot operation.
Definition backend.hpp:1204
complex_type< T > erfi(const complex_type< T > z)
erfi(z) = -i erf(iz)
Definition special_functions.hpp:1583
Utilities for writing jit source code.
Implementations for special functions.