42template <const
int n, const
int m,
typename T>
46 "Array requires Complex or arithmetic type");
52 using base_type = hila::arithmetic_type<T>;
53 using argument_type = T;
55 static constexpr bool is_array() {
103 template <typename S, std::enable_if_t<hila::is_assignable<T &, S>::value,
int> = 0>
104 explicit inline Array(
const S rhs) {
105 for (
int i = 0; i < n * m; i++) {
111 inline Array(
const std::nullptr_t &z) {
112 for (
int i = 0; i < n * m; i++)
131 template <typename S, std::enable_if_t<hila::is_assignable<T &, S>::value,
int> = 0>
132 inline Array(std::initializer_list<S> rhs) {
133 assert(rhs.size() == n * m &&
"Array initializer list size must match variable size");
135 for (
auto it = rhs.begin(); it != rhs.end(); it++, i++) {
164 template <
int q = n,
int p = m, std::enable_if_t<q == 1,
int> = 0>
169 template <
int q = n,
int p = m, std::enable_if_t<p == 1,
int> = 0>
170 constexpr int size()
const {
174 template <
int q = n,
int p = m, std::enable_if_t<q == p,
int> = 0>
175 constexpr int size()
const {
195 inline T
e(
const int i,
const int j)
const {
201 inline T &
e(
const int i,
const int j) const_function {
207 template <
int q = n,
int p = m, std::enable_if_t<(q == 1 || p == 1),
int> = 0>
208 inline T
e(
const int i)
const {
222 template <
int q = n,
int p = m, std::enable_if_t<(q == 1 || p == 1),
int> = 0>
223 inline T &
e(
const int i) const_function {
248 static_assert(1 == m,
"asVector() only for column arrays");
254 static_assert(1 == m,
"asVector() only for column arrays");
259 static_assert(1 == m,
"asDiagonalMatrix() only for column arrays");
265 static_assert(1 == m,
"asDiagonalMatrix() only for column arrays");
272 template <typename S, std::enable_if_t<hila::is_assignable<S &, T>::value,
int> = 0>
275 for (
int i = 0; i < n * m; i++) {
289 for (
int i = 0; i < n * m; i++) {
333 template <typename S, std::enable_if_t<hila::is_assignable<T &, S>::value,
int> = 0>
335 for (
int i = 0; i < n * m; i++) {
341 template <typename S, std::enable_if_t<hila::is_assignable<T &, S>::value,
int> = 0>
343 for (
int i = 0; i < n; i++)
344 for (
int j = 0; j < m; j++) {
345 e(i, j) = rhs.e(i, j);
362 template <
typename S,
int n1,
int m1>
364 if constexpr (n != n1 || m != m1)
367 for (
int i = 0; i < n; i++)
368 for (
int j = 0; j < m; j++) {
369 if (
e(i, j) != rhs.
e(i, j))
388 template <
typename S,
int n1,
int m1>
390 return !(*
this == rhs);
422 template <typename S, std::enable_if_t<std::is_convertible<S, T>::value,
int> = 0>
424 for (
int i = 0; i < n; i++)
425 for (
int j = 0; j < m; j++) {
426 e(i, j) += rhs.e(i, j);
456 template <typename S, std::enable_if_t<std::is_convertible<S, T>::value,
int> = 0>
458 for (
int i = 0; i < n; i++)
459 for (
int j = 0; j < m; j++) {
460 e(i, j) -= rhs.e(i, j);
466 template <
typename S,
467 std::enable_if_t<std::is_convertible<hila::type_plus<T, S>, T>::value,
int> = 0>
469 for (
int i = 0; i < n * m; i++) {
476 template <
typename S,
477 std::enable_if_t<std::is_convertible<hila::type_minus<T, S>, T>::value,
int> = 0>
479 for (
int i = 0; i < n * m; i++) {
511 template <
typename S,
512 std::enable_if_t<std::is_convertible<hila::type_mul<T, S>, T>::value,
int> = 0>
514 for (
int i = 0; i < n; i++)
515 for (
int j = 0; j < m; j++) {
516 e(i, j) *= rhs.e(i, j);
522 template <
typename S,
523 std::enable_if_t<std::is_convertible<hila::type_mul<T, S>, T>::value,
int> = 0>
525 for (
int i = 0; i < n * m; i++) {
557 template <
typename S,
558 std::enable_if_t<std::is_convertible<hila::type_div<T, S>, T>::value,
int> = 0>
560 for (
int i = 0; i < n; i++)
561 for (
int j = 0; j < m; j++) {
562 e(i, j) /= rhs.e(i, j);
568 template <
typename S,
569 std::enable_if_t<std::is_convertible<hila::type_div<T, S>, T>::value,
int> = 0>
571 for (
int i = 0; i < n * m; i++) {
584 for (
int i = 0; i < n * m; i++) {
596 for (
int i = 0; i < m * n; i++) {
605 for (
int i = 0; i < m * n; i++) {
613 hila::arithmetic_type<T> result = 0;
614 for (
int i = 0; i < n * m; i++) {
626 for (
int i = 0; i < n * m; i++) {
639 for (
int i = 0; i < n * m; i++) {
646 std::string
str(
int prec = 8,
char separator =
' ')
const {
647 return this->
asMatrix().str(prec, separator);
654 hila::sort order = hila::sort::ascending)
const {
655 return this->
asMatrix().sort(permutation, order).asArray();
660 return this->
asMatrix().sort(order).asArray();
674template <const
int n, const
int m,
typename T>
688template <const
int n, const
int m,
typename T>
702template <const
int n, const
int m,
typename T>
740template <
int n,
int m,
typename A,
typename B>
743 for (
int i = 0; i < n * m; i++)
744 res.c[i] = a.c[i] * b.c[i];
781template <
int n,
int m,
typename A,
typename B>
784 for (
int i = 0; i < n * m; i++)
785 res.c[i] = a.c[i] - b.c[i];
790template <
int n,
int m,
typename T,
typename S,
791 std::enable_if_t<hila::is_complex_or_arithmetic<S>::value,
int> = 0>
794 for (
int i = 0; i < n * m; i++)
795 res.c[i] = a.c[i] + b;
800template <
int n,
int m,
typename T,
typename S,
801 std::enable_if_t<hila::is_complex_or_arithmetic<S>::value,
int> = 0>
807template <
int n,
int m,
typename T,
typename S,
808 std::enable_if_t<std::is_convertible<hila::type_minus<T, S>, T>::value,
int> = 0>
811 for (
int i = 0; i < n * m; i++)
812 res.c[i] = a.c[i] - b;
817template <
int n,
int m,
typename T,
typename S,
818 std::enable_if_t<std::is_convertible<hila::type_minus<T, S>, T>::value,
int> = 0>
821 for (
int i = 0; i < n * m; i++)
822 res.c[i] = b - a.c[i];
861template <
int n,
int m,
typename T>
869template <
int n,
int m,
typename A,
typename B,
870 std::enable_if_t<!std::is_same<A, B>::value,
int> = 0>
873 using R = hila::type_mul<A, B>;
876 for (
int i = 0; i < n; i++)
877 for (
int j = 0; j < m; j++)
878 res.
e(i, j) = a.
e(i, j) * b.
e(i, j);
916template <
int n,
int m,
typename A,
typename B>
919 for (
int i = 0; i < n; i++)
920 for (
int j = 0; j < m; j++)
921 res.
e(i, j) = a.
e(i, j) / b.
e(i, j);
927template <
int n,
int m,
typename T,
typename S,
928 std::enable_if_t<hila::is_complex_or_arithmetic<S>::value,
int> = 0>
931 for (
int i = 0; i < n * m; i++)
932 res.c[i] = a.c[i] * b;
937template <
int n,
int m,
typename T,
typename S,
938 std::enable_if_t<hila::is_complex_or_arithmetic<S>::value,
int> = 0>
945template <
int n,
int m,
typename T,
typename S,
946 std::enable_if_t<hila::is_complex_or_arithmetic<S>::value,
int> = 0>
949 for (
int i = 0; i < n * m; i++)
950 res.c[i] = a.c[i] / b;
955template <
int n,
int m,
typename T,
typename S,
956 std::enable_if_t<hila::is_complex_or_arithmetic<S>::value,
int> = 0>
959 for (
int i = 0; i < n * m; i++)
960 res.c[i] = b / a.c[i];
977template <
int n,
int m,
typename T>
995template <
int n,
int m,
typename T>
1000template <
int n,
int m,
typename T>
1002 return prettyprint(A.
asMatrix(), prec);
1018template <
int n,
int m,
typename T>
1040template <
int n,
int m,
typename T>
1042 for (
int i = 0; i < n * m; i++)
1043 a.c[i] = sqrt(a.c[i]);
1050template <
int n,
int m,
typename T>
1052 for (
int i = 0; i < n * m; i++)
1053 a.c[i] = cbrt(a.c[i]);
1060template <
int n,
int m,
typename T>
1062 for (
int i = 0; i < n * m; i++)
1063 a.c[i] = exp(a.c[i]);
1070template <
int n,
int m,
typename T>
1072 for (
int i = 0; i < n * m; i++)
1073 a.c[i] = log(a.c[i]);
1080template <
int n,
int m,
typename T>
1082 for (
int i = 0; i < n * m; i++)
1083 a.c[i] = sin(a.c[i]);
1090template <
int n,
int m,
typename T>
1092 for (
int i = 0; i < n * m; i++)
1093 a.c[i] = cos(a.c[i]);
1100template <
int n,
int m,
typename T>
1102 for (
int i = 0; i < n * m; i++)
1103 a.c[i] = tan(a.c[i]);
1110template <
int n,
int m,
typename T>
1112 for (
int i = 0; i < n * m; i++)
1113 a.c[i] = asin(a.c[i]);
1120template <
int n,
int m,
typename T>
1122 for (
int i = 0; i < n * m; i++)
1123 a.c[i] = acos(a.c[i]);
1130template <
int n,
int m,
typename T>
1132 for (
int i = 0; i < n * m; i++)
1133 a.c[i] = atan(a.c[i]);
1140template <
int n,
int m,
typename T>
1142 for (
int i = 0; i < n * m; i++)
1143 a.c[i] = sinh(a.c[i]);
1150template <
int n,
int m,
typename T>
1152 for (
int i = 0; i < n * m; i++)
1153 a.c[i] = cosh(a.c[i]);
1160template <
int n,
int m,
typename T>
1162 for (
int i = 0; i < n * m; i++)
1163 a.c[i] = tanh(a.c[i]);
1170template <
int n,
int m,
typename T>
1172 for (
int i = 0; i < n * m; i++)
1173 a.c[i] = asinh(a.c[i]);
1180template <
int n,
int m,
typename T>
1182 for (
int i = 0; i < n * m; i++)
1183 a.c[i] = acosh(a.c[i]);
1190template <
int n,
int m,
typename T>
1192 for (
int i = 0; i < n * m; i++)
1193 a.c[i] = atanh(a.c[i]);
1205template <
int n,
int m,
typename T>
1207 for (
int i = 0; i < n * m; i++)
1208 a.c[i] = pow(a.c[i], b);
1212template <
int n,
int m,
typename T>
1214 for (
int i = 0; i < n * m; i++)
1215 a.c[i] = pow(a.c[i], b);
1219template <
int n,
int m,
typename T>
1221 for (
int i = 0; i < n * m; i++)
1222 a.c[i] = pow(a.c[i], b.c[i]);
1231template <int n, int m, typename T, std::enable_if_t<hila::is_arithmetic<T>::value,
int> = 0>
1233 for (
int i = 0; i < n * m; i++)
1234 a.c[i] = round(a.c[i]);
1243template <int n, int m, typename T, std::enable_if_t<hila::is_arithmetic<T>::value,
int> = 0>
1245 for (
int i = 0; i < n * m; i++)
1246 a.c[i] = floor(a.c[i]);
1255template <int n, int m, typename T, std::enable_if_t<hila::is_arithmetic<T>::value,
int> = 0>
1257 for (
int i = 0; i < n * m; i++)
1258 a.c[i] = ceil(a.c[i]);
1267template <int n, int m, typename T, std::enable_if_t<hila::is_arithmetic<T>::value,
int> = 0>
1269 for (
int i = 0; i < n * m; i++)
1270 a.c[i] = trunc(a.c[i]);
1290template <
typename Ntype,
typename T,
int n,
int m,
1291 std::enable_if_t<hila::is_arithmetic_or_extended<T>::value,
int> = 0>
1294 for (
int i = 0; i < n * m; i++)
1295 res.c[i] = mat.c[i];
1299template <
typename Ntype,
typename T,
int n,
int m,
1300 std::enable_if_t<hila::is_complex<T>::value,
int> = 0>
1303 for (
int i = 0; i < n * m; i++)
1304 res.c[i] = cast_to<Ntype>(mat.c[i]);
1311template <
int n,
typename T =
double>
1315template <
int n,
int m,
typename T =
double>
Array< n, m, T > conj(const Array< n, m, T > &arg)
Return conjugate Array.
std::ostream & operator<<(std::ostream &strm, const Array< n, m, T > &A)
Stream operator.
Array< n, m, hila::arithmetic_type< T > > imag(const Array< n, m, T > &arg)
Return imaginary part of Array.
hila::arithmetic_type< T > squarenorm(const Array< n, m, T > &rhs)
Return square norm of Array.
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
Array(const S rhs)
Scalar constructor.
Array< n, m, T > & operator+=(const Array< n, m, S > &rhs) &
Add assign operator with Array or scalar.
Array(std::initializer_list< S > rhs)
Initializer list constructor.
auto operator/(const Array< n, m, A > &a, const Array< n, m, B > &b)
Division operator.
Array< n, m, T > floor(Array< n, m, T > a)
Floor.
constexpr int rows() const
Returns number of rows.
constexpr int size() const
Returns size of Vector Array or square Array.
T & e(const int i, const int j)
Const overload.
Array< n, m, T > & operator=(const S rhs) &
Scalar assignment operator.
std::string str(int prec=8, char separator=' ') const
Convert to string for printing.
Array< n, m, T > round(Array< n, m, T > a)
Rounding.
Array< n, m, T > operator+() const
Unary + operator.
Array< n, m, T > asin(Array< n, m, T > a)
Inverse Sine.
auto operator-(const Array< n, m, A > &a, const Array< n, m, B > &b)
Subtraction operator.
bool operator==(const Array< n1, m1, S > &rhs) const
Compare equality of Arrays.
Array< n, m, T > & operator/=(const Array< n, m, S > &rhs) &
Division assign with array or scalar.
Array< n, m, T > exp(Array< n, m, T > a)
Exponential.
T e(const int i) const
Const overload.
Array< n, m, T > tanh(Array< n, m, T > a)
Hyperbolic tangent.
Array< n, m, T > trunc(Array< n, m, T > a)
Truncation.
T & e(const int i)
Standard array indexing operation for 1D Array.
Array< n, m, T > sort(Vector< N, int > &permutation, hila::sort order=hila::sort::ascending) const
implement sort as casting to array
Array< n, m, hila::arithmetic_type< T > > real() const
Returns real part of Array.
Array< n, m, T > cosh(Array< n, m, T > a)
Hyperbolic Cosine.
Array< n, m, T > tan(Array< n, m, T > a)
Tangent.
auto operator+(const Array< n, m, A > &a, const Array< n, m, B > &b)
Addition operator.
Array()=default
Default constructor.
Array< n, m, T > & operator*=(const S rhs) &
multiply assign with scalar
Array< n, m, hila::arithmetic_type< T > > imag() const
return imaginary part
Array< n, m, T > operator-() const
Unary - operator.
Array< n, m, T > & operator-=(const Array< n, m, S > &rhs) &
Subtract assign operator with Array or scalar.
constexpr int columns() const
Returns number of columns.
T e(const int i, const int j) const
Standard array indexing operation for 2D Array.
Array< n, m, T > cos(Array< n, m, T > a)
Cosine.
bool operator!=(const Array< n1, m1, S > &rhs) const
Compare non-equality of two Arrays.
Array< n, m, T > cbrt(Array< n, m, T > a)
Cuberoot.
hila::arithmetic_type< T > squarenorm() const
calculate square norm - sum of squared elements
Vector< n, T > & asVector()
Cast Array1D to Vector.
Array< n, m, T > acos(Array< n, m, T > a)
Inverse Cosine.
Array< n, m, T > acosh(Array< n, m, T > a)
Inverse Hyperbolic Cosine.
Array< n, m, T > sqrt(Array< n, m, T > a)
Square root.
Array< n, m, T > conj() const
Returns element wise Complex conjugate of Array.
Array< n, m, T > asinh(Array< n, m, T > a)
Inverse Hyperbolic Sine.
Matrix< n, m, T > & asMatrix()
Cast Array to Matrix.
Array< n, m, T > & random()
Fill Array with random elements.
Array< n, m, T > ceil(Array< n, m, T > a)
Ceiling.
Array< n, m, T > atan(Array< n, m, T > a)
Inverse Tangent.
Array< n, m, T > pow(Array< n, m, T > a, int b)
Power.
Array< n, m, T > & operator*=(const Array< n, m, S > &rhs) &
Multiply assign scalar or array.
Array(const Array< n, m, T > &v)=default
Copy constructor.
Array< n, m, T > operator*(Array< n, m, T > a, const Array< n, m, T > &b)
Multiplication operator.
Array< n, m, T > sin(Array< n, m, T > a)
Sine.
Array< n, m, T > sinh(Array< n, m, T > a)
Hyperbolic Sine.
Array< n, m, T > & gaussian_random(double width=1.0)
Fill Array with Gaussian random elements.
Array< n, m, T > atanh(Array< n, m, T > a)
Inverse Hyperbolic Tangent.
Array< n, m, T > log(Array< n, m, T > a)
Logarithm.
Define type DiagonalMatrix<n,T>
Matrix class which defines matrix operations.
T arg(const Complex< T > &a)
Return argument of Complex number.
Definition of Matrix types.
Implement hila::swap for gauge fields.
T gaussian_random()
Template function T hila::gaussian_random<T>(),generates gaussian random value of type T,...
double random()
Real valued uniform random number generator.
Array< n, m, Ntype > cast_to(const Array< n, m, T > &mat)
Array casting operation.
std::string to_string(const Array< n, m, T > &A, int prec=8, char separator=' ')
Converts Array object to string.
hila::is_complex_or_arithmetic<T>::value