24 using base_type = hila::arithmetic_type<T>;
25 using argument_type = T;
29 sparse_el<T>() =
default;
30 ~sparse_el<T>() =
default;
31 sparse_el<T>(
const sparse_el<T> &a) =
default;
32 sparse_el<T>(
int i1,
int i2,
const T &v) : ind1(i1), ind2(i2), val(v) {}
34 inline sparse_el<T> &operator=(
const sparse_el<T> &s) & =
default;
35 sparse_el<T> &set(
const sparse_el<T> &s) {
42 sparse_el<T> &set(
int i1,
int i2,
const T &v) {
50template <
int N,
typename T>
56 sparse_el<Complex<T>> c[N];
57 Alg_gen() : size(0){};
59 inline Alg_gen &operator=(
const Alg_gen &s) & =
default;
60 Alg_gen &push(sparse_el<T> tel) {
65 Alg_gen &push(
int i1,
int i2,
const T &v) {
70 Alg_gen &push(
int i1,
int i2,
const Complex<T> &v) {
71 c[size].set(i1, i2, v);
76 sparse_el<T> res(c[size - 1]);
82 for (
int i = 0; i < size; ++i) {
83 res.
e(c[i].ind1, c[i].ind2) = c[i].val;
109template <
int N,
typename T>
121 SU &operator=(
const SU &su) && =
delete;
139 for (
int r = 0; r < N; r++) {
144 for (
int i = 0; i < N; i++)
147 for (
int i = 0; i < N; i++)
154 for (
int j = r + 1; j < N; j++) {
157 for (
int i = 0; i < N; i++) {
158 d +=
::conj(this->
e(r, i)) * this->
e(j, i);
161 for (
int i = 0; i < N; i++) {
162 this->
e(j, i) -= d * this->
e(r, i);
179 for (
int i = 0; i < N * N; i++) {
214 if constexpr (N == 2) {
218 this->
e(0, 0) = Complex<T>(v[0], v[3]);
219 this->
e(1, 1) = Complex<T>(v[0], -v[3]);
220 this->
e(0, 1) = Complex<T>(v[2], v[1]);
221 this->
e(1, 0) = Complex<T>(-v[2], v[1]);
228 for (
int h = 1; h <= nhits; h++) {
229 for (
int r = 0; r < N - 1; r++)
230 for (
int q = r + 1; q < N; q++) {
288 T sum = this->
e(0, 0).im;
289 for (
int i = 1; i < N; i++) {
290 a.e(i - 1) = (sum - i * this->
e(i, i).im) /
sqrt(0.5 * i * (i + 1));
291 sum += this->
e(i, i).im;
296 for (
int i = 0; i < N - 1; i++) {
297 for (
int j = i + 1; j < N; j++) {
298 auto od = this->
e(i, j) - this->
e(j, i).conj();
313 T sum = this->
e(0, 0).im;
314 for (
int i = 1; i < N; i++) {
315 a.e(i - 1) = scf * (sum - i * this->
e(i, i).im) /
sqrt(0.5 * i * (i + 1));
316 sum += this->
e(i, i).im;
321 for (
int i = 0; i < N - 1; i++) {
322 for (
int j = i + 1; j < N; j++) {
323 auto od = this->
e(i, j) - this->
e(j, i).conj();
324 a.e(k) = scf * od.re;
325 a.e(k + 1) = scf * od.im;
341 T sum = this->
e(0, 0).im;
342 for (
int i = 1; i < N; i++) {
343 a.e(i - 1) = (sum - i * this->
e(i, i).im) /
sqrt(0.5 * i * (i + 1));
344 sum += this->
e(i, i).im;
345 onenorm +=
abs(a.e(i - 1));
350 for (
int i = 0; i < N - 1; i++) {
351 for (
int j = i + 1; j < N; j++) {
352 auto od = this->
e(i, j) - this->
e(j, i).conj();
355 onenorm +=
abs(a.e(k)) +
abs(a.e(k + 1));
368template <
int N,
typename T>
372 using base_type = hila::arithmetic_type<T>;
373 using argument_type = T;
377 static constexpr int n_offdiag = N * (N - 1);
378 static constexpr int n_diag = N - 1;
379 static constexpr int N_a = N * N - 1;
409 for (
int i = 1; i < N; ++i) {
410 gen_list[i - 1].empty();
411 for (
int j = 0; j < i; ++j) {
412 gen_list[i - 1].push(j, j,
Complex<T>(0, 1.0 /
sqrt(2.0 * (i * (i + 1)))));
414 gen_list[i - 1].push(i, i,
Complex<T>(0, -i /
sqrt(2.0 * (i * (i + 1)))));
418 for (
int i = 0; i < N - 1; i++) {
419 for (
int j = i + 1; j < N; j++) {
432 static void generator_product_list(
const Alg_gen<N, T>(&gen_list)[N_a], Alg_gen<N, T>(out_only &gen_prod_list)[N_a][N_a]) {
437 for (i1 = 0; i1 < N * N - 1; ++i1) {
438 const auto &gen1 = gen_list[i1];
439 for (i2 = 0; i2 < N * N - 1; ++i2) {
441 const auto &gen2 = gen_list[i2];
442 for (
auto el1 = gen1.c; el1 != gen1.c + gen1.size; ++el1) {
443 for (
auto el2 = gen2.c; el2 != gen2.c + gen2.size; ++el2) {
444 if(el1->ind2==el2->ind1) {
445 temp.
e(el1->ind1, el2->ind2) += el1->val*el2->val;
449 for (j1 = 0; j1 < N; ++j1) {
450 for (j2 = 0; j2 < N; ++j2) {
451 if(temp.
e(j1,j2)!=0) {
452 gen_prod_list[i1][i2].push(j1, j2, temp.
e(j1, j2));
460 static void generator_product_list(Alg_gen<N, T>(out_only &gen_prod_list)[N_a][N_a]) {
463 Alg_gen<N, T> gen_list[N_a];
464 generator_list(gen_list);
465 generator_product_list(gen_list, gen_prod_list);
474 for (
int i = 1; i < N; i++) {
475 T r = this->c[i - 1] *
sqrt(0.5 / (i * (i + 1)));
477 for (
int j = 0; j < i; j++)
483 for (
int i = 0; i < N; i++)
488 for (
int i = 0; i < N - 1; i++)
489 for (
int j = i + 1; j < N; j++) {
490 Complex<T> v(this->c[k] * inv2, this->c[k + 1] * inv2);
492 m.
e(j, i) = -v.
conj();
506 for (
int i = 1; i < N; i++) {
507 T r = this->c[i - 1] *
sqrt(0.5 / (i * (i + 1)));
509 for (
int j = 0; j < i; j++)
515 for (
int i = 0; i < N; i++)
520 for (
int i = 0; i < N - 1; i++)
521 for (
int j = i + 1; j < N; j++) {
522 Complex<T> v(this->c[k] * inv2, this->c[k + 1] * inv2);
524 m.
e(j, i) = -v.
conj();
564 T dot(
const Algebra &rhs)
const {
566 for (
int i = 0; i < N_a; ++i) {
567 r += this->e(i) * rhs.e(i);
573template <
int N,
typename T>
595template <
int N,
typename T>
605template <
int N,
typename T>
613template <
int N,
typename T>
623 for (it = 0; it < maxit; ++it) {
626 for (i = 0; i < Algebra<SU<N, T>>::N_a; ++i) {
627 res.e(i) -= tres.e(i);
630 if (trn < fprec * (rn + 1.0)) {
634 chexp(tmat, tmat2, pl);
635 mult(a, tmat2, tmat);
641template <
int N,
typename T,
typename MT,
typename fT = hila::arithmetic_type<T>>
644 const Alg_gen<N, fT> (&genlist)[N * N - 1]) {
649 for (i1 = 0; i1 < N * N - 1; ++i1) {
650 const auto &gen1 = genlist[i1];
651 for (i2 = 0; i2 < N * N - 1; ++i2) {
653 const auto &gen2 = genlist[i2];
654 for (
auto el1 = gen1.c; el1 != gen1.c + gen1.size; ++el1) {
655 for (
auto el2 = gen2.c; el2 != gen2.c + gen2.size; ++el2) {
656 temp +=
real(el1->val * w1.
e(el1->ind2, el2->ind1) * el2->val *
657 w2.
e(el2->ind2, el1->ind1));
660 omat.e(i1, i2) = -2.0 * temp;
665template <
int N,
typename T,
typename MT,
typename fT = hila::arithmetic_type<T>>
669 Alg_gen<N, fT> genlist[N * N - 1];
671 project_to_algebra_bilinear(w1, w2, omat, genlist);
674template <
int N,
typename T,
typename MT,
typename fT = hila::arithmetic_type<T>>
677 const Alg_gen<N, fT> (&genprodlist)[N * N - 1][N * N - 1]) {
682 for (i1 = 0; i1 < N * N - 1; ++i1) {
683 for (i2 = 0; i2 < N * N - 1; ++i2) {
684 const auto &gen = genprodlist[i2][i1];
686 for (
auto el1 = gen.c; el1 != gen.c + gen.size; ++el1) {
687 temp +=
real(el1->val * w1.
e(el1->ind2, el1->ind1));
689 omat.e(i1, i2) = -2.0 * temp;
694template <
int N,
typename T,
typename MT,
typename fT = hila::arithmetic_type<T>>
698 Alg_gen<N, fT> genprodlist[N * N - 1][N * N - 1];
700 project_to_algebra_bilinear(w1, omat, genprodlist);
703template <const
int N,
typename T,
typename MT>
704void project_to_algebra_bilinear(
const MT (&w)[N][N],
706 const Alg_gen<N, T> (&genlist)[N * N - 1]) {
711 for (i1 = 0; i1 < N * N - 1; ++i1) {
712 const auto &gen1 = genlist[i1];
713 for (i2 = 0; i2 < N * N - 1; ++i2) {
715 const auto &gen2 = genlist[i2];
716 for (
auto el1 = gen1.c; el1 != gen1.c + gen1.size; ++el1) {
717 for (
auto el2 = gen2.c; el2 != gen2.c + gen2.size; ++el2) {
719 real(el1->val * w[el2->ind1][el2->ind2].e(el1->ind2, el1->ind1) * el2->val);
722 omat.e(i1, i2) = -2.0 * temp;
727template <
int N,
typename T,
typename MT>
728void project_to_algebra_bilinear(
const MT (&w)[N][N],
732 Alg_gen<N, T> genlist[N * N - 1];
734 project_to_algebra_bilinear(w, omat, genlist);
Array< n, m, T > exp(Array< n, m, T > a)
Exponential.
Array< n, m, T > cos(Array< n, m, T > a)
Cosine.
Array< n, m, T > sqrt(Array< n, m, T > a)
Square root.
Array< n, m, T > sin(Array< n, m, T > a)
Sine.
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
SU< N, T > expand_scaled(T scf) const
expand algebra to scaled matrix rep - antihermitian
static void generator_list(Alg_gen< N, T >(&gen_list)[N_a])
expand algebra to matrix rep - antihermitean
Algebra & gaussian_random(T width=sqrt(2.0))
Complex< T > conj() const
Compute conjugate of Complex number.
T arg() const
Compute argument of Complex number.
The main matrix type template Matrix_t. This is a base class type for "useful" types which are deriv...
void mult_by_2x2_left(int p, int q, const Matrix_t< 2, 2, R, Mt > &M)
Multiply -matrix from the left by matrix defined by sub matrix.
hila::arithmetic_type< T > norm() const
Calculate vector norm - sqrt of squarenorm.
Matrix_t()=default
Define default constructors to ensure std::is_trivial.
SU< N, T > conj() const
Returns complex conjugate of Matrix.
Complex< T > det() const
determinant function - if matrix size is < 5, use Laplace, otherwise LU
auto abs() const
Returns absolute value of Matrix.
Mtype & gaussian_random(base_type width=1.0)
Fills Matrix with gaussian random elements.
T e(const int i, const int j) const
Standard array indexing operation for matrices and vectors.
hila::arithmetic_type< Complex< T > > squarenorm() const
Calculate square norm - sum of squared elements.
Matrix class which defines matrix operations.
const SU & random(int nhits=16)
Generate random SU(N) matrix.
const SU & reunitarize()
Reunitarize SU(N) matrix.
const SU & fix_det()
Fix determinant.
Algebra< SU< N, T > > project_to_algebra() const
const SU & make_unitary()
Makes the matrix unitary by orthogonalizing the rows.
T abs(const Complex< T > &a)
Return absolute value of Complex number.
Definition of Matrix types.
Matrix_t< n, m, T, MT > chsexp(const Matrix_t< n, m, T, MT > &mat)
Calculate exp of a square matrix.
int chexp(const Matrix_t< n, m, T, MT > &mat, Matrix_t< n, m, T, MT > &omat, Mt(&pl)[n])
Calculate exp of a square matrix.
void mult(const Mt1 &a, const Mt2 &b, Mt3 &res)
compute product of two matrices and write result to existing matrix
Implement hila::swap for gauge fields.
logger_class log
Now declare the logger.