-
Notifications
You must be signed in to change notification settings - Fork 2
/
su2.hh
124 lines (105 loc) · 2.73 KB
/
su2.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#pragma once
#include"accum_type.hh"
#include"traceless_antiherm.hh"
#include<complex>
//#include<cmath>
using Complex = std::complex<double>;
class _su2 {
public:
const size_t N_c = 2;
explicit _su2() : a(0), b(0) {}
explicit _su2(Complex a, Complex b) : a(a), b(b) {}
_su2(const _su2& U) : a(U.a), b(U.b) {}
friend inline _su2 operator+(const _su2 &U1, const _su2 &U2);
friend inline _su2 operator-(const _su2 &U1, const _su2 &U2);
friend inline _su2 operator*(const _su2 &U1, const _su2 &U2);
friend inline _su2 operator*(const Complex &U1, const _su2 &U2);
friend inline _su2 operator*(const _su2 &U1, const Complex &U2);
_su2& operator*=(const _su2 &U1) {
Complex a = this->a;
this->a = a*U1.a - this->b*std::conj(U1.b);
this->b = a*U1.b + this->b*std::conj(U1.a);
return *this;
}
_su2 round(size_t n) const {
double dn = n;
return _su2(Complex(std::round(std::real(a)*dn), std::round(std::imag(a)*dn))/dn,
Complex(std::round(std::real(b)*dn), std::round(std::imag(b)*dn))/dn);
}
inline Complex geta() const {
return(a);
}
inline Complex getb() const {
return(b);
}
inline void operator=(const _su2 &U) {
a = U.geta();
b = U.getb();
}
inline void operator+=(const _su2 &U) {
a += U.a;
b += U.b;
}
void set(const Complex _a, const Complex _b) {
a = _a;
b = _b;
}
inline _su2 dagger() const {
return(_su2(std::conj(a), -b));
}
inline double retrace() {
return(2.*std::real(a));
}
Complex det() {
return(a*std::conj(a) + b*std::conj(b));
}
void restoreSU() {
double r = sqrt(std::abs(a)*std::abs(a) + std::abs(b)*std::abs(b));
a /= r;
b /= r;
}
private:
Complex a, b;
};
inline double retrace(_su2 const &U) {
double a = std::real(U.geta());
return(2*a);
}
inline Complex trace(_su2 const &U) {
double a = std::real(U.geta());
return(Complex(2*a, 0.));
}
template<> inline _su2 traceless_antiherm(const _su2& x) {
return(_su2(0.5*(x.geta()-std::conj(x.geta())), x.getb()));
}
inline _su2 operator*(const _su2 &U1, const _su2 &U2) {
_su2 res;
res.a = U1.a*U2.a - U1.b*std::conj(U2.b);
res.b = U1.a*U2.b + U1.b*std::conj(U2.a);
return(res);
}
inline _su2 operator+(const _su2 &U1, const _su2 &U2) {
_su2 res;
res.a = U1.a + U2.a;
res.b = U1.b + U2.b;
return(res);
}
inline _su2 operator-(const _su2 &U1, const _su2 &U2) {
_su2 res;
res.a = U1.a - U2.a;
res.b = U1.b - U2.b;
return(res);
}
inline _su2 operator*(const Complex &U1, const _su2 &U2) {
_su2 res;
res.a = U2.a * U1;
res.b = U2.b * U1;
return(res);
}
inline _su2 operator*(const _su2 &U1, const Complex &U2) {
_su2 res;
res.a = U1.a * U2;
res.b = U1.b * U2;
return(res);
}
using su2 = _su2;