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)) {
306 "Vector operand size is not a multiple of matrix operand size");
308 const size_t num_colmns =
size()/x.
size();
309 const size_t num_rows = x.
size();
310 for (
size_t i = 0; i < num_rows; i++) {
311 for (
size_t j = 0; j < num_colmns; j++) {
312 memory[i*num_rows + j] += x[i];
317 "Vector operand size is not a multiple of matrix operand size");
319 std::vector<T> m(x.
size());
320 const size_t num_colmns = x.
size()/
size();
321 const size_t num_rows =
size();
322 for (
size_t i = 0; i < num_rows; i++) {
323 for (
size_t j = 0; j < num_colmns; j++) {
324 m[i*num_colmns + j] = memory[i] + x[i*num_colmns + j];
342 "Vector operand size is not a multiple of matrix operand size");
344 const size_t num_colmns =
size()/x.
size();
345 const size_t num_rows = x.
size();
346 for (
size_t i = 0; i < num_rows; i++) {
347 for (
size_t j = 0; j < num_colmns; j++) {
348 memory[i*num_colmns + j] += x[j];
353 "Vector operand size is not a multiple of matrix operand size");
355 std::vector<T> m(x.
size());
356 const size_t num_colmns = x.
size()/
size();
357 const size_t num_rows =
size();
358 for (
size_t i = 0; i < num_rows; i++) {
359 for (
size_t j = 0; j < num_colmns; j++) {
360 m[i*num_colmns + j] = memory[j] + x[i*num_colmns + j];
378 "Vector operand size is not a multiple of matrix operand size");
380 const size_t num_colmns =
size()/x.
size();
381 const size_t num_rows = x.
size();
382 for (
size_t i = 0; i < num_rows; i++) {
383 for (
size_t j = 0; j < num_colmns; j++) {
384 memory[i*num_colmns + j] -= x[i];
389 "Vector operand size is not a multiple of matrix operand size");
391 std::vector<T> m(x.
size());
392 const size_t num_colmns = x.
size()/
size();
393 const size_t num_rows =
size();
394 for (
size_t i = 0; i < num_colmns; i++) {
395 for (
size_t j = 0; j < num_rows; j++) {
396 m[i*num_colmns + j] = memory[i] - x[i*num_colmns + j];
414 "Vector operand size is not a multiple of matrix operand size");
416 const size_t num_colmns =
size()/x.
size();
417 const size_t num_rows = x.
size();
418 for (
size_t i = 0; i < num_rows; i++) {
419 for (
size_t j = 0; j < num_colmns; j++) {
420 memory[i*num_colmns + j] -= x[j];
425 "Vector operand size is not a multiple of matrix operand size");
427 std::vector<T> m(x.
size());
428 const size_t num_colmns = x.
size()/
size();
429 const size_t num_rows =
size();
430 for (
size_t i = 0; i < num_rows; i++) {
431 for (
size_t j = 0; j < num_colmns; j++) {
432 m[i*num_colmns + j] = memory[j] - x[i*num_colmns + j];
450 "Vector operand size is not a multiple of matrix operand size");
452 const size_t num_colmns =
size()/x.
size();
453 const size_t num_rows = x.
size();
454 for (
size_t i = 0; i < num_rows; i++) {
455 for (
size_t j = 0; j < num_colmns; j++) {
456 memory[i*num_colmns + j] *= x[i];
461 "Vector operand size is not a multiple of matrix operand size");
463 std::vector<T> m(x.
size());
464 const size_t num_colmns = x.
size()/
size();
465 const size_t num_rows =
size();
466 for (
size_t i = 0; i < num_rows; i++) {
467 for (
size_t j = 0; j < num_colmns; j++) {
468 m[i*num_colmns + j] = memory[i]*x[i*num_colmns + j];
486 "Vector operand size is not a multiple of matrix operand size");
488 const size_t num_colmns =
size()/x.
size();
489 const size_t num_rows = x.
size();
490 for (
size_t i = 0; i < num_rows; i++) {
491 for (
size_t j = 0; j < num_colmns; j++) {
492 memory[i*num_colmns + j] *= x[j];
497 "Vector operand size is not a multiple of matrix operand size");
499 std::vector<T> m(x.
size());
500 const size_t num_colmns = x.
size()/
size();
501 const size_t num_rows =
size();
502 for (
size_t i = 0; i < num_rows; i++) {
503 for (
size_t j = 0; j < num_colmns; j++) {
504 m[i*num_colmns + j] = memory[j]*x[i*num_colmns + j];
522 "Vector operand size is not a multiple of matrix operand size");
524 const size_t num_colmns =
size()/x.
size();
525 const size_t num_rows = x.
size();
526 for (
size_t i = 0; i < num_rows; i++) {
527 for (
size_t j = 0; j < num_colmns; j++) {
528 memory[i*num_colmns + j] /= x[i];
533 "Vector operand size is not a multiple of matrix operand size");
535 std::vector<T> m(x.
size());
536 const size_t num_colmns = x.
size()/
size();
537 const size_t num_rows =
size();
538 for (
size_t i = 0; i < num_rows; i++) {
539 for (
size_t j = 0; j < num_colmns; j++) {
540 m[i*num_colmns + j] = memory[i]/x[i*num_colmns + j];
558 "Vector operand size is not a multiple of matrix operand size");
560 const size_t num_colmns =
size()/x.
size();
561 const size_t num_rows = x.
size();
562 for (
size_t i = 0; i < num_rows; i++) {
563 for (
size_t j = 0; j < num_colmns; j++) {
564 memory[i*num_colmns + j] /= x[j];
569 "Vector operand size is not a multiple of matrix operand size");
571 std::vector<T> m(x.
size());
572 const size_t num_colmns = x.
size()/
size();
573 const size_t num_rows =
size();
574 for (
size_t i = 0; i < num_rows; i++) {
575 for (
size_t j = 0; j < num_colmns; j++) {
576 m[i*num_colmns + j] = memory[j]/x[i*num_colmns + j];
594 "Vector operand size is not a multiple of matrix operand size");
596 const size_t num_colmns =
size()/x.
size();
597 const size_t num_rows = x.
size();
598 for (
size_t i = 0; i < num_rows; i++) {
599 for (
size_t j = 0; j < num_colmns; j++) {
601 memory[i*num_colmns + j] = std::atan(x[i]/memory[i*num_colmns + j]);
603 memory[i*num_colmns + j] = std::atan2(x[i], memory[i*num_colmns + j]);
609 "Vector operand size is not a multiple of matrix operand size");
611 std::vector<T> m(x.
size());
612 const size_t num_colmns = x.
size()/
size();
613 const size_t num_rows =
size();
614 for (
size_t i = 0; i < num_rows; i++) {
615 for (
size_t j = 0; j < num_colmns; j++) {
617 m[i*num_colmns + j] = std::atan(x[i*num_colmns + j]/memory[i]);
619 m[i*num_colmns + j] = std::atan2(x[i*num_colmns + j], memory[i]);
638 "Vector operand size is not a multiple of matrix operand size");
640 const size_t num_colmns =
size()/x.
size();
641 const size_t num_rows = x.
size();
642 for (
size_t i = 0; i < num_colmns; i++) {
643 for (
size_t j = 0; j < num_rows; j++) {
645 memory[i*num_colmns + j] = std::atan(x[j]/memory[i*num_colmns + j]);
647 memory[i*num_colmns + j] = std::atan2(x[j], memory[i*num_colmns + j]);
653 "Vector operand size is not a multiple of matrix operand size");
655 std::vector<T> m(x.
size());
656 const size_t num_colmns = x.
size()/
size();
657 const size_t num_rows =
size();
658 for (
size_t i = 0; i < num_rows; i++) {
659 for (
size_t j = 0; j < num_colmns; j++) {
661 m[i*num_colmns + j] = std::atan(x[i*num_colmns + j]/memory[j]);
663 m[i*num_colmns + j] = std::atan2(x[i*num_colmns + j], memory[j]);
682 "Vector operand size is not a multiple of matrix operand size");
684 const size_t num_colmns =
size()/x.
size();
685 const size_t num_rows = x.
size();
686 for (
size_t i = 0; i < num_rows; i++) {
687 for (
size_t j = 0; j < num_colmns; j++) {
688 memory[i*num_colmns + j] = std::pow(memory[i*num_colmns + j], x[i]);
693 "Vector operand size is not a multiple of matrix operand size");
695 std::vector<T> m(x.
size());
696 const size_t num_colmns = x.
size()/
size();
697 const size_t num_rows =
size();
698 for (
size_t i = 0; i < num_colmns; i++) {
699 for (
size_t j = 0; j < num_rows; j++) {
700 m[i*num_colmns + j] = std::pow(memory[i], x[i*num_colmns + j]);
718 "Vector operand size is not a multiple of matrix operand size");
720 const size_t num_colmns =
size()/x.
size();
721 const size_t num_rows = x.
size();
722 for (
size_t i = 0; i < num_rows; i++) {
723 for (
size_t j = 0; j < num_colmns; j++) {
724 memory[i*num_colmns + j] = std::pow(memory[i*num_colmns + j], x[j]);
729 "Vector operand size is not a multiple of matrix operand size");
731 std::vector<T> m(x.
size());
732 const size_t num_colmns = x.
size()/
size();
733 const size_t num_rows =
size();
734 for (
size_t i = 0; i < num_rows; i++) {
735 for (
size_t j = 0; j < num_colmns; j++) {
736 m[i*num_colmns + j] = std::pow(memory[j], x[i*num_colmns + j]);
756 template<jit::
float_scalar T>
760 const T right = b.
at(0);
761 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
765 }
else if (a.
size() == 1) {
766 const T left = a.
at(0);
767 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
774 "Left and right sizes are incompatable.");
775 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
790 template<jit::
float_scalar T>
797 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
798 if (a.
at(i) != b.
at(i)) {
814 template<jit::
float_scalar T>
818 const T right = b.
at(0);
819 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
823 }
else if (a.
size() == 1) {
824 const T left = a.
at(0);
825 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
826 b[i] = left - b.
at(i);
832 "Left and right sizes are incompatable.");
833 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
848 template<jit::
float_scalar T>
852 const T right = b.
at(0);
853 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
857 }
else if (a.
size() == 1) {
858 const T left = a.
at(0);
859 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
866 "Left and right sizes are incompatable.");
867 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
882 template<jit::
float_scalar T>
886 const T right = b.
at(0);
887 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
891 }
else if (a.
size() == 1) {
892 const T left = a.
at(0);
893 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
900 "Left and right sizes are incompatable.");
901 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
917 template<jit::
float_scalar T>
929 const T left = a.
at(0);
932 const T middle = b.
at(0);
933 for (
size_t i = 0, ie = c.
size(); i < ie; i++) {
934 if constexpr (use_fma) {
935 c[i] = std::fma(left, middle, c.
at(i));
937 c[i] = left*middle + c.
at(i);
941 }
else if (c.
size() == 1) {
942 const T right = c.
at(0);
943 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
944 if constexpr (use_fma) {
945 b[i] = std::fma(left, b.
at(i), right);
947 b[i] = left*b.
at(i) + right;
954 "Size mismatch between middle and right.");
955 for (
size_t i = 0, ie = b.
size(); i < ie; i++) {
956 if constexpr (use_fma) {
957 b[i] = std::fma(left, b.
at(i), c.
at(i));
959 b[i] = left*b.
at(i) + c.
at(i);
963 }
else if (b.
size() == 1) {
964 const T middle = b.
at(0);
966 const T right = c.
at(0);
967 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
968 if constexpr (use_fma) {
969 a[i] = std::fma(a.
at(i), middle, right);
971 a[i] = a.
at(i)*middle + right;
978 "Size mismatch between left and right.");
979 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
980 if constexpr (use_fma) {
981 a[i] = std::fma(a.
at(i), middle, c.
at(i));
983 a[i] = a.
at(i)*middle + c.
at(i);
987 }
else if (c.
size() == 1) {
989 "Size mismatch between left and middle.");
990 const T right = c.
at(0);
991 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
992 if constexpr (use_fma) {
993 a[i] = std::fma(a.
at(i), b.
at(i), right);
995 a[i] = a.
at(i)*b.
at(i) + right;
1004 "Left, middle and right sizes are incompatable.");
1005 for (
size_t i = 0, ie = a.
size(); i < ie; i++) {
1006 if constexpr (use_fma) {
1007 a[i] = std::fma(a.
at(i), b.
at(i), c.
at(i));
1009 a[i] = a.
at(i)*b.
at(i) + c.
at(i);
1024 template<jit::
float_scalar T>
1027 if (exponent.
size() == 1) {
1028 const T right = exponent.
at(0);
1029 if (std::imag(right) == 0) {
1030 const int64_t right_int =
static_cast<int64_t
> (std::real(right));
1031 if (std::real(right) - right_int) {
1032 if (right ==
static_cast<T
> (0.5)) {
1037 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1038 base[i] = std::pow(base.
at(i), right);
1043 if (right_int > 0) {
1044 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1045 const T left = base.
at(i);
1046 for (
size_t j = 0, je = right_int - 1; j < je; j++) {
1051 }
else if (right_int == 0) {
1052 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1057 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1058 const T left =
static_cast<T
> (1.0)/base.
at(i);
1060 for (
size_t j = 0, je = std::abs(right_int) - 1; j < je; j++) {
1067 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1068 base[i] = std::pow(base.
at(i), right);
1072 }
else if (base.
size() == 1) {
1073 const T left = base.
at(0);
1074 for (
size_t i = 0, ie = exponent.
size(); i < ie; i++) {
1075 exponent[i] = std::pow(left, exponent.
at(i));
1081 "Left and right sizes are incompatable.");
1082 for (
size_t i = 0, ie = base.
size(); i < ie; i++) {
1083 base[i] = std::pow(base.
at(i), exponent.
at(i));
1097 template<jit::
float_scalar T>
1100 if (y.
size() == 1) {
1101 const T right = y.
at(0);
1102 for (
size_t i = 0, ie = x.
size(); i < ie; i++) {
1104 x[i] = std::atan(right/x[i]);
1106 x[i] = std::atan2(right, x[i]);
1110 }
else if (x.
size() == 1) {
1111 const T left = x.
at(0);
1112 for (
size_t i = 0, ie = y.
size(); i < ie; i++) {
1114 y[i] = std::atan(y[i]/left);
1116 y[i] = std::atan2(y[i], left);
1123 "Left and right sizes are incompatable.");
1124 for (
size_t i = 0, ie = x.
size(); i < ie; i++) {
1126 x[i] = std::atan(y[i]/x[i]);
1128 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:375
void multiply_row(const buffer< T > &x)
Multiply row operation.
Definition backend.hpp:447
void add_col(const buffer< T > &x)
Add col operation.
Definition backend.hpp:339
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
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:715
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:555
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:679
void sin()
Take sin.
Definition backend.hpp:241
void add_row(const buffer< T > &x)
Add row operation.
Definition backend.hpp:303
void subtract_col(const buffer< T > &x)
Subtract col operation.
Definition backend.hpp:411
void multiply_col(const buffer< T > &x)
Multiply col operation.
Definition backend.hpp:483
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:744
void divide_row(const buffer< T > &x)
Divide row operation.
Definition backend.hpp:519
void atan_col(const buffer< T > &x)
Atan col operation.
Definition backend.hpp:635
void atan_row(const buffer< T > &x)
Atan row operation.
Definition backend.hpp:591
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:918
buffer< T > operator*(buffer< T > &a, buffer< T > &b)
Multiply operation.
Definition backend.hpp:849
bool operator==(const buffer< T > &a, const buffer< T > &b)
Equal operation.
Definition backend.hpp:791
buffer< T > atan(buffer< T > &x, buffer< T > &y)
Take the inverse tangent.
Definition backend.hpp:1098
buffer< T > operator/(buffer< T > &a, buffer< T > &b)
Divide operation.
Definition backend.hpp:883
buffer< T > operator-(buffer< T > &a, buffer< T > &b)
Subtract operation.
Definition backend.hpp:815
buffer< T > operator+(buffer< T > &a, buffer< T > &b)
Add operation.
Definition backend.hpp:757
buffer< T > pow(buffer< T > &base, buffer< T > &exponent)
Take the power.
Definition backend.hpp:1025
complex_type< T > erfi(const complex_type< T > z)
erfi(z) = -i erf(iz)
Definition special_functions.hpp:1580
Utilities for writting jit source code.
Implimentations for special functions.