28 template<jit::
float_scalar T>
32 std::vector<T> memory;
91 const T
at(
const size_t index)
const {
92 return memory.at(index);
101 memory.assign(memory.size(), d);
109 void set(
const std::vector<T> &d) {
110 memory.assign(d.cbegin(), d.cend());
117 return memory.size();
126 const T same = memory.at(0);
127 for (
size_t i = 1, ie = memory.size(); i < ie; i++) {
128 if (memory.at(i) != same) {
142 for (
const T &d : memory) {
143 if (d !=
static_cast<T
> (0.0)) {
157 for (
const T &d : memory) {
158 if (d ==
static_cast<T
> (0.0)) {
172 for (
const T &d : memory) {
173 if (std::real(d) > std::real(
static_cast<T
> (0.0))) {
187 for (
const T &d : memory) {
188 if (std::fmod(std::real(d), std::real(
static_cast<T
> (2.0)))) {
202 for (
const T &d : memory) {
203 if (d !=
static_cast<T
> (-1.0)) {
215 for (T &d : memory) {
224 for (T &d : memory) {
233 for (T &d : memory) {
242 for (T &d : memory) {
251 for (T &d : memory) {
260 for (T &d : memory) {
271 return memory.data();
280 for (
const T &x : memory) {
282 if (std::isnan(std::real(x)) || std::isinf(std::real(x)) ||
283 std::isnan(std::imag(x)) || std::isinf(std::imag(x))) {
287 if (std::isnan(x) || std::isinf(x)) {
304 const size_t num_rows =
size()/num_columns;
305 for (
size_t j = 0; j < num_columns; j++) {
306 b[j] = memory[index*num_rows + j];
319 const size_t num_rows =
size()/num_columns;
321 for (
size_t i = 0; i < num_rows; i++) {
322 b[i] = memory[i*num_rows + index];
338 "Vector operand size is not a multiple of matrix operand size");
340 const size_t num_columns =
size()/x.
size();
341 const size_t num_rows = x.
size();
342 for (
size_t i = 0; i < num_rows; i++) {
343 for (
size_t j = 0; j < num_columns; j++) {
344 memory[i*num_rows + j] += x[i];
349 "Vector operand size is not a multiple of matrix operand size");
351 std::vector<T> m(x.
size());
352 const size_t num_columns = x.
size()/
size();
353 const size_t num_rows =
size();
354 for (
size_t i = 0; i < num_rows; i++) {
355 for (
size_t j = 0; j < num_columns; j++) {
356 m[i*num_columns + j] = memory[i] + x[i*num_columns + j];
374 "Vector operand size is not a multiple of matrix operand size");
376 const size_t num_columns =
size()/x.
size();
377 const size_t num_rows = x.
size();
378 for (
size_t i = 0; i < num_rows; i++) {
379 for (
size_t j = 0; j < num_columns; j++) {
380 memory[i*num_columns + j] += x[j];
385 "Vector operand size is not a multiple of matrix operand size");
387 std::vector<T> m(x.
size());
388 const size_t num_columns = x.
size()/
size();
389 const size_t num_rows =
size();
390 for (
size_t i = 0; i < num_rows; i++) {
391 for (
size_t j = 0; j < num_columns; j++) {
392 m[i*num_columns + j] = memory[j] + x[i*num_columns + j];
410 "Vector operand size is not a multiple of matrix operand size");
412 const size_t num_columns =
size()/x.
size();
413 const size_t num_rows = x.
size();
414 for (
size_t i = 0; i < num_rows; i++) {
415 for (
size_t j = 0; j < num_columns; j++) {
416 memory[i*num_columns + j] -= x[i];
421 "Vector operand size is not a multiple of matrix operand size");
423 std::vector<T> m(x.
size());
424 const size_t num_columns = x.
size()/
size();
425 const size_t num_rows =
size();
426 for (
size_t i = 0; i < num_columns; i++) {
427 for (
size_t j = 0; j < num_rows; j++) {
428 m[i*num_columns + j] = memory[i] - x[i*num_columns + j];
446 "Vector operand size is not a multiple of matrix operand size");
448 const size_t num_columns =
size()/x.
size();
449 const size_t num_rows = x.
size();
450 for (
size_t i = 0; i < num_rows; i++) {
451 for (
size_t j = 0; j < num_columns; j++) {
452 memory[i*num_columns + j] -= x[j];
457 "Vector operand size is not a multiple of matrix operand size");
459 std::vector<T> m(x.
size());
460 const size_t num_columns = x.
size()/
size();
461 const size_t num_rows =
size();
462 for (
size_t i = 0; i < num_rows; i++) {
463 for (
size_t j = 0; j < num_columns; j++) {
464 m[i*num_columns + j] = memory[j] - x[i*num_columns + j];
482 "Vector operand size is not a multiple of matrix operand size");
484 const size_t num_columns =
size()/x.
size();
485 const size_t num_rows = x.
size();
486 for (
size_t i = 0; i < num_rows; i++) {
487 for (
size_t j = 0; j < num_columns; j++) {
488 memory[i*num_columns + j] *= x[i];
493 "Vector operand size is not a multiple of matrix operand size");
495 std::vector<T> m(x.
size());
496 const size_t num_columns = x.
size()/
size();
497 const size_t num_rows =
size();
498 for (
size_t i = 0; i < num_rows; i++) {
499 for (
size_t j = 0; j < num_columns; j++) {
500 m[i*num_columns + j] = memory[i]*x[i*num_columns + j];
518 "Vector operand size is not a multiple of matrix operand size");
520 const size_t num_columns =
size()/x.
size();
521 const size_t num_rows = x.
size();
522 for (
size_t i = 0; i < num_rows; i++) {
523 for (
size_t j = 0; j < num_columns; j++) {
524 memory[i*num_columns + j] *= x[j];
529 "Vector operand size is not a multiple of matrix operand size");
531 std::vector<T> m(x.
size());
532 const size_t num_columns = x.
size()/
size();
533 const size_t num_rows =
size();
534 for (
size_t i = 0; i < num_rows; i++) {
535 for (
size_t j = 0; j < num_columns; j++) {
536 m[i*num_columns + j] = memory[j]*x[i*num_columns + j];
554 "Vector operand size is not a multiple of matrix operand size");
556 const size_t num_columns =
size()/x.
size();
557 const size_t num_rows = x.
size();
558 for (
size_t i = 0; i < num_rows; i++) {
559 for (
size_t j = 0; j < num_columns; j++) {
560 memory[i*num_columns + j] /= x[i];
565 "Vector operand size is not a multiple of matrix operand size");
567 std::vector<T> m(x.
size());
568 const size_t num_columns = x.
size()/
size();
569 const size_t num_rows =
size();
570 for (
size_t i = 0; i < num_rows; i++) {
571 for (
size_t j = 0; j < num_columns; j++) {
572 m[i*num_columns + j] = memory[i]/x[i*num_columns + j];
590 "Vector operand size is not a multiple of matrix operand size");
592 const size_t num_columns =
size()/x.
size();
593 const size_t num_rows = x.
size();
594 for (
size_t i = 0; i < num_rows; i++) {
595 for (
size_t j = 0; j < num_columns; j++) {
596 memory[i*num_columns + j] /= x[j];
601 "Vector operand size is not a multiple of matrix operand size");
603 std::vector<T> m(x.
size());
604 const size_t num_columns = x.
size()/
size();
605 const size_t num_rows =
size();
606 for (
size_t i = 0; i < num_rows; i++) {
607 for (
size_t j = 0; j < num_columns; j++) {
608 m[i*num_columns + j] = memory[j]/x[i*num_columns + j];
626 "Vector operand size is not a multiple of matrix operand size");
628 const size_t num_columns =
size()/x.
size();
629 const size_t num_rows = x.
size();
630 for (
size_t i = 0; i < num_rows; i++) {
631 for (
size_t j = 0; j < num_columns; j++) {
633 memory[i*num_columns + j] = std::atan(x[i]/memory[i*num_columns + j]);
635 memory[i*num_columns + j] = std::atan2(x[i], memory[i*num_columns + j]);
641 "Vector operand size is not a multiple of matrix operand size");
643 std::vector<T> m(x.
size());
644 const size_t num_columns = x.
size()/
size();
645 const size_t num_rows =
size();
646 for (
size_t i = 0; i < num_rows; i++) {
647 for (
size_t j = 0; j < num_columns; j++) {
649 m[i*num_columns + j] = std::atan(x[i*num_columns + j]/memory[i]);
651 m[i*num_columns + j] = std::atan2(x[i*num_columns + j], memory[i]);
670 "Vector operand size is not a multiple of matrix operand size");
672 const size_t num_columns =
size()/x.
size();
673 const size_t num_rows = x.
size();
674 for (
size_t i = 0; i < num_columns; i++) {
675 for (
size_t j = 0; j < num_rows; j++) {
677 memory[i*num_columns + j] = std::atan(x[j]/memory[i*num_columns + j]);
679 memory[i*num_columns + j] = std::atan2(x[j], memory[i*num_columns + j]);
685 "Vector operand size is not a multiple of matrix operand size");
687 std::vector<T> m(x.
size());
688 const size_t num_columns = x.
size()/
size();
689 const size_t num_rows =
size();
690 for (
size_t i = 0; i < num_rows; i++) {
691 for (
size_t j = 0; j < num_columns; j++) {
693 m[i*num_columns + j] = std::atan(x[i*num_columns + j]/memory[j]);
695 m[i*num_columns + j] = std::atan2(x[i*num_columns + j], memory[j]);
714 "Vector operand size is not a multiple of matrix operand size");
716 const size_t num_columns =
size()/x.
size();
717 const size_t num_rows = x.
size();
718 for (
size_t i = 0; i < num_rows; i++) {
719 for (
size_t j = 0; j < num_columns; j++) {
720 memory[i*num_columns + j] = std::pow(memory[i*num_columns + j], x[i]);
725 "Vector operand size is not a multiple of matrix operand size");
727 std::vector<T> m(x.
size());
728 const size_t num_columns = x.
size()/
size();
729 const size_t num_rows =
size();
730 for (
size_t i = 0; i < num_columns; i++) {
731 for (
size_t j = 0; j < num_rows; j++) {
732 m[i*num_columns + j] = std::pow(memory[i], x[i*num_columns + j]);
750 "Vector operand size is not a multiple of matrix operand size");
752 const size_t num_columns =
size()/x.
size();
753 const size_t num_rows = x.
size();
754 for (
size_t i = 0; i < num_rows; i++) {
755 for (
size_t j = 0; j < num_columns; j++) {
756 memory[i*num_columns + j] = std::pow(memory[i*num_columns + j], x[j]);
761 "Vector operand size is not a multiple of matrix operand size");
763 std::vector<T> m(x.
size());
764 const size_t num_columns = x.
size()/
size();
765 const size_t num_rows =
size();
766 for (
size_t i = 0; i < num_rows; i++) {
767 for (
size_t j = 0; j < num_columns; j++) {
768 m[i*num_columns + j] = std::pow(memory[j], x[i*num_columns + j]);
788 template<jit::
float_scalar T>
792 const T right = b.
at(0);
793 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
797 }
else if (a.
size() == 1) {
798 const T left = a.
at(0);
799 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
806 "Left and right sizes are incompatible.");
807 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
822 template<jit::
float_scalar T>
829 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
830 if (a.
at(i) != b.
at(i)) {
846 template<jit::
float_scalar T>
850 const T right = b.
at(0);
851 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
855 }
else if (a.
size() == 1) {
856 const T left = a.
at(0);
857 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
858 b[i] = left - b.
at(i);
864 "Left and right sizes are incompatible.");
865 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
880 template<jit::
float_scalar T>
884 const T right = b.
at(0);
885 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
889 }
else if (a.
size() == 1) {
890 const T left = a.
at(0);
891 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
898 "Left and right sizes are incompatible.");
899 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
914 template<jit::
float_scalar T>
918 const T right = b.
at(0);
919 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
923 }
else if (a.
size() == 1) {
924 const T left = a.
at(0);
925 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
932 "Left and right sizes are incompatible.");
933 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
949 template<jit::
float_scalar T>
961 const T left = a.
at(0);
964 const T middle = b.
at(0);
965 for (
size_t i = 0, ie = c.
size(); i < ie; i++) {
966 if constexpr (use_fma) {
967 c[i] = std::fma(left, middle, c.
at(i));
969 c[i] = left*middle + c.
at(i);
973 }
else if (c.
size() == 1) {
974 const T right = c.
at(0);
975 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
976 if constexpr (use_fma) {
977 b[i] = std::fma(left, b.
at(i), right);
979 b[i] = left*b.
at(i) + right;
986 "Size mismatch between middle and right.");
987 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
988 if constexpr (use_fma) {
989 b[i] = std::fma(left, b.
at(i), c.
at(i));
991 b[i] = left*b.
at(i) + c.
at(i);
995 }
else if (b.
size() == 1) {
996 const T middle = b.
at(0);
998 const T right = c.
at(0);
999 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
1000 if constexpr (use_fma) {
1001 a[i] = std::fma(a.
at(i), middle, right);
1003 a[i] = a.
at(i)*middle + right;
1010 "Size mismatch between left and right.");
1011 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
1012 if constexpr (use_fma) {
1013 a[i] = std::fma(a.
at(i), middle, c.
at(i));
1015 a[i] = a.
at(i)*middle + c.
at(i);
1019 }
else if (c.
size() == 1) {
1021 "Size mismatch between left and middle.");
1022 const T right = c.
at(0);
1023 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
1024 if constexpr (use_fma) {
1025 a[i] = std::fma(a.
at(i), b.
at(i), right);
1027 a[i] = a.
at(i)*b.
at(i) + right;
1036 "Left, middle and right sizes are incompatible.");
1037 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
1038 if constexpr (use_fma) {
1039 a[i] = std::fma(a.
at(i), b.
at(i), c.
at(i));
1041 a[i] = a.
at(i)*b.
at(i) + c.
at(i);
1056 template<jit::
float_scalar T>
1059 if (exponent.
size() == 1) {
1060 const T right = exponent.
at(0);
1061 if (std::imag(right) == 0) {
1062 const int64_t right_int =
static_cast<int64_t
> (std::real(right));
1063 if (std::real(right) - right_int) {
1064 if (right ==
static_cast<T
> (0.5)) {
1069 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1070 base[i] = std::pow(base.
at(i), right);
1075 if (right_int > 0) {
1076 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1077 const T left = base.
at(i);
1078 for (
size_t j = 0, je = right_int - 1; j < je; j++) {
1083 }
else if (right_int == 0) {
1084 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1089 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1090 const T left =
static_cast<T
> (1.0)/base.
at(i);
1092 for (
size_t j = 0, je = std::abs(right_int) - 1; j < je; j++) {
1099 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1100 base[i] = std::pow(base.
at(i), right);
1104 }
else if (base.
size() == 1) {
1105 const T left = base.
at(0);
1106 for (
size_t i = 0, ie = exponent.
size(); i < ie; i++) {
1107 exponent[i] = std::pow(left, exponent.
at(i));
1113 "Left and right sizes are incompatible.");
1114 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1115 base[i] = std::pow(base.
at(i), exponent.
at(i));
1129 template<jit::
float_scalar T>
1132 if (y.
size() == 1) {
1133 const T right = y.
at(0);
1134 for (
size_t i = 0, ie = x.
size(); i < ie; i++) {
1136 x[i] = std::atan(right/x[i]);
1138 x[i] = std::atan2(right, x[i]);
1142 }
else if (x.
size() == 1) {
1143 const T left = x.
at(0);
1144 for (
size_t i = 0, ie = y.
size(); i < ie; i++) {
1146 y[i] = std::atan(y[i]/left);
1148 y[i] = std::atan2(y[i], left);
1155 "Left and right sizes are incompatible.");
1156 for (
size_t i = 0, ie = x.
size(); i < ie; i++) {
1158 x[i] = std::atan(y[i]/x[i]);
1160 x[i] = std::atan2(y[i], x[i]);
Class representing a generic buffer.
Definition backend.hpp:29
void set(const std::vector< T > &d)
Assign a vector value.
Definition backend.hpp:109
void subtract_row(const buffer< T > &x)
Subtract row operation.
Definition backend.hpp:407
void multiply_row(const buffer< T > &x)
Multiply row operation.
Definition backend.hpp:479
void add_col(const buffer< T > &x)
Add col operation.
Definition backend.hpp:371
void erfi()
Take erfi.
Definition backend.hpp:259
void log()
Take log.
Definition backend.hpp:232
buffer(const buffer &d)
Construct a buffer backend from a buffer backend.
Definition backend.hpp:71
void sqrt()
Take sqrt.
Definition backend.hpp:214
buffer(const size_t s)
Construct a buffer backend with a size.
Definition backend.hpp:46
T & operator[](const size_t index)
Index operator.
Definition backend.hpp:77
bool is_normal() const
Check for normal values.
Definition backend.hpp:279
buffer()
Construct an empty buffer backend.
Definition backend.hpp:38
buffer< T > index_row(const size_t index, const size_t num_columns)
Index row.
Definition backend.hpp:302
bool is_negative() const
Is every element negative.
Definition backend.hpp:171
const T at(const size_t index) const
Get value at.
Definition backend.hpp:91
void pow_col(const buffer< T > &x)
Pow col operation.
Definition backend.hpp:747
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:125
buffer(const size_t s, const T d)
Construct a buffer backend with a size.
Definition backend.hpp:55
void divide_col(const buffer< T > &x)
Divide col operation.
Definition backend.hpp:587
bool is_none() const
Is every element negative one.
Definition backend.hpp:201
void pow_row(const buffer< T > &x)
Pow row operation.
Definition backend.hpp:711
void sin()
Take sin.
Definition backend.hpp:241
void add_row(const buffer< T > &x)
Add row operation.
Definition backend.hpp:335
void subtract_col(const buffer< T > &x)
Subtract col operation.
Definition backend.hpp:443
void multiply_col(const buffer< T > &x)
Multiply col operation.
Definition backend.hpp:515
bool is_even() const
Is every element even.
Definition backend.hpp:186
T base
Type def to retrieve the backend T type.
Definition backend.hpp:776
void divide_row(const buffer< T > &x)
Divide row operation.
Definition backend.hpp:551
void atan_col(const buffer< T > &x)
Atan col operation.
Definition backend.hpp:667
void atan_row(const buffer< T > &x)
Atan row operation.
Definition backend.hpp:623
buffer< T > index_column(const size_t index, const size_t num_columns)
Index column.
Definition backend.hpp:318
void exp()
Take exp.
Definition backend.hpp:223
bool has_zero() const
Is any element zero.
Definition backend.hpp:156
bool is_zero() const
Is every element zero.
Definition backend.hpp:141
size_t size() const
Get size of the buffer.
Definition backend.hpp:116
void set(const T d)
Assign a constant value.
Definition backend.hpp:100
T * data()
Get a pointer to the basic memory buffer.
Definition backend.hpp:270
void cos()
Take cos.
Definition backend.hpp:250
Complex scalar concept.
Definition register.hpp:24
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:950
buffer< T > operator*(buffer< T > &a, buffer< T > &b)
Multiply operation.
Definition backend.hpp:881
bool operator==(const buffer< T > &a, const buffer< T > &b)
Equal operation.
Definition backend.hpp:823
buffer< T > atan(buffer< T > &x, buffer< T > &y)
Take the inverse tangent.
Definition backend.hpp:1130
buffer< T > operator/(buffer< T > &a, buffer< T > &b)
Divide operation.
Definition backend.hpp:915
buffer< T > operator-(buffer< T > &a, buffer< T > &b)
Subtract operation.
Definition backend.hpp:847
buffer< T > operator+(buffer< T > &a, buffer< T > &b)
Add operation.
Definition backend.hpp:789
buffer< T > pow(buffer< T > &base, buffer< T > &exponent)
Take the power.
Definition backend.hpp:1057
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.