HILA
Loading...
Searching...
No Matches
sun_max_staple_sum_rot.h
Go to the documentation of this file.
1/** @file sun_max_staple_sum_rot.h */
2
3#ifndef SUN_MAX_STAPLE_SUM_ROT_H
4#define SUN_MAX_STAPLE_SUM_ROT_H
5
6#include <numeric>
7#include "sun_matrix.h"
8#include "plumbing/shuffle.h"
10
11
12/**
13 * @brief Find \f$ SU(N) \f$ matrix U that maximizes ReTr(U*staple) for given staple
14 *
15 * @tparam T float/double/long double
16 * @tparam N Number of colors
17 * @param U \f$ SU(N) \f$ matrix that maximizes ReTr(U*staple)
18 * @param staple Staple
19 */
20template <typename T, int N>
22
23 SU<N, T> tl0(staple);
24 SU<N, T> U(1.0);
25
26 // get a random permutation of the list of possible matrix indices
27 std::array<int, N> tperm;
28 std::iota(tperm.begin(), tperm.end(), 0);
29 hila::shuffle(tperm);
30
31 // run thourgh the different SU(2) subgroups of SU(N) (in the order given by the permuatation
32 // iperm), to build up the SU(N) matrix that that has maximum overlap with l0:
33 int niter = 15 * (N - 1) * N;
34 if (N == 2)
35 niter = 1;
36
37 int iter, tt1, tt2, t1, t2,ic1;
38 Complex<T> tvnn11, tvnn12, tvnn21, tvnn22, ttl01, ttl02;
39 T tu1, tu2, tu3, tu4, k, ki, lnorm, dlnorm, dilnorm;
40 for (iter = 0; iter < niter; ++iter) {
41 for (tt1 = 0; tt1 < N - 1; ++tt1) {
42 t1 = tperm[tt1];
43 for (tt2 = tt1 + 1; tt2 < N; ++tt2) {
44 t2 = tperm[tt2];
45
46 tvnn11 = tl0.e(t1, t1);
47 tvnn12 = tl0.e(t1, t2);
48 tvnn21 = tl0.e(t2, t1);
49 tvnn22 = tl0.e(t2, t2);
50
51 // get inverse of SU(2) projection of the 2x2 matrix tvnnXX:
52
53 // compute vector representation of tu=proj_SU2(tvnnXX):
54 tu1 = 0.5 * (tvnn11.real() + tvnn22.real());
55 tu2 = 0.5 * (tvnn12.imag() + tvnn21.imag());
56 tu3 = 0.5 * (tvnn12.real() - tvnn21.real());
57 tu4 = 0.5 * (tvnn11.imag() - tvnn22.imag());
58 ki = 1.0 / sqrt(tu1 * tu1 + tu2 * tu2 + tu3 * tu3 + tu4 * tu4);
59 tu1 *= ki;
60 tu2 *= ki;
61 tu3 *= ki;
62 tu4 *= ki;
63
64 // compute matrix representation of tui = inverse(tu):
65 // (re-using variables tvnnXX to hold tui)
66 tvnn11.re = tu1;
67 tvnn11.im = -tu4;
68 tvnn12.re = -tu3;
69 tvnn12.im = -tu2;
70 tvnn21.re = tu3;
71 tvnn21.im = -tu2;
72 tvnn22.re = tu1;
73 tvnn22.im = tu4;
74
75
76 // apply SU(2) subgroup rotation tui to tl0:
77 for (ic1 = 0; ic1 < N; ++ic1) {
78 ttl01 = tl0.e(t1, ic1);
79 ttl02 = tl0.e(t2, ic1);
80 tl0.e(t1, ic1) = tvnn11 * ttl01 + tvnn12 * ttl02;
81 tl0.e(t2, ic1) = tvnn21 * ttl01 + tvnn22 * ttl02;
82 }
83
84 // apply SU(2) subgroup rotation tui to U:
85 for (ic1 = 0; ic1 < N; ++ic1) {
86 ttl01 = U.e(t1, ic1);
87 ttl02 = U.e(t2, ic1);
88 U.e(t1, ic1) = tvnn11 * ttl01 + tvnn12 * ttl02;
89 U.e(t2, ic1) = tvnn21 * ttl01 + tvnn22 * ttl02;
90 }
91 }
92 }
93
94 // check whether tl0 has reached the form H + c*id,
95 // with H hermitian and c purely imaginary scalar:
96 ttl01 = tl0.e(N - 1, N - 1);
97 lnorm = ttl01.squarenorm();
98 dlnorm = 0;
99 dilnorm = ttl01.imag();
100 for (t1 = 0; t1 < N - 1; ++t1) {
101 ttl01 = tl0.e(t1, t1);
102 lnorm += ttl01.squarenorm();
103 dlnorm += ::squarenorm(ttl01.imag() - dilnorm);
104 for (t2 = t1 + 1; t2 < N; ++t2) {
105 dlnorm += 0.5 * ::squarenorm(tl0.e(t1, t2) - tl0.e(t2, t1).conj());
106 }
107 }
108 lnorm = ::sqrt(lnorm);
109 dlnorm = ::sqrt(dlnorm);
110 if (dlnorm < fp<T>::epsilon * (lnorm + (T)N) * (T)N) {
111 break;
112 }
113 }
114
115 //U.reunitarize();
116
117 return U;
118}
119
120/**
121 * @brief \f$ SU(N) \f$ overrelaxation using \f$ SU(N) \f$ matrix obtained
122 * from max_staple_sum_rot() routine
123 *
124 * @tparam T float/double/long double
125 * @tparam N Number of colors
126 * @param U \f$ SU(N) \f$ link to perform overrelaxation on
127 * @param staple Staple to compute overrelaxation with
128 */
129template <typename T, int N, typename Btype>
130int suN_overrelax(SU<N, T> &U, const SU<N, T> &staple, Btype beta) {
131 SU<N, T> tstaple = staple.dagger();
132 SU<N, T> tU = suN_max_staple_sum_rot(tstaple);
133 if(N==2) {
134 U = tU * U.dagger() * tU;
135 return 1;
136 } else {
137 tU = tU * U.dagger() * tU;
138 T ds = real(mul_trace((tU - U), tstaple));
139 if(ds > 0 || hila::random() < exp(beta/N * ds)) {
140 U = tU;
141 return 1;
142 }
143 }
144 return 0;
145}
146
147#endif
hila::arithmetic_type< T > squarenorm(const Array< n, m, T > &rhs)
Return square norm of Array.
Definition array.h:1019
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
Definition array.h:689
Complex definition.
Definition cmplx.h:58
T real() const
Real part of Complex number.
Definition cmplx.h:157
T squarenorm() const
Compute square norm of Complex number.
Definition cmplx.h:249
T imag() const
Imaginary part of Complex number.
Definition cmplx.h:166
Rtype dagger() const
Hermitian conjugate of matrix.
Definition matrix.h:1094
T e(const int i, const int j) const
Standard array indexing operation for matrices.
Definition matrix.h:279
Class for SU(N) matrix.
Definition sun_matrix.h:110
auto mul_trace(const Mtype1 &a, const Mtype2 &b)
Returns trace of product of two matrices.
Definition matrix.h:2586
double random()
Real valued uniform random number generator.
Definition hila_gpu.cpp:121
void shuffle(T &arr)
Definition shuffle.h:23
SU(N) Matrix definitions.
int suN_overrelax(SU< N, T > &U, const SU< N, T > &staple, Btype beta)
overrelaxation using matrix obtained from max_staple_sum_rot() routine
SU< N, T > suN_max_staple_sum_rot(const SU< N, T > &staple)
Find matrix U that maximizes ReTr(U*staple) for given staple.