Xped
Loading...
Searching...
No Matches
Spin.hpp
Go to the documentation of this file.
1#ifndef XPED_SPIN_HPP_
2#define XPED_SPIN_HPP_
3
6
7// #include "Xped/Symmetry/S1xS2.hpp"
10#include "Xped/Symmetry/U1.hpp"
11
12namespace Xped {
13
14template <typename Symmetry_, std::size_t spin_index = 0>
15class Spin
16{
17 typedef double Scalar;
18 typedef Symmetry_ Symmetry;
20 using qType = typename Symmetry::qType;
21
22public:
23 Spin(){};
24 Spin(std::size_t D_input);
25
26 OperatorType Id_1s() const { return Id_1s_; }
27 OperatorType Zero_1s() const { return Zero_1s_; }
28 OperatorType F_1s() const { return F_1s_; }
29
30 // OperatorType n_1s() const { return n_1s(UP) + n_1s(DN); }
31
32 // dipole
33 OperatorType Sz_1s() const { return Sz_1s_; }
34 OperatorType Sp_1s() const { return Sp_1s_; }
35 OperatorType Sm_1s() const { return Sm_1s_; }
36
37 // quadrupole
38 OperatorType Qz_1s() const { return Qz_1s_; }
39 OperatorType Qp_1s() const { return Qp_1s_; }
40 OperatorType Qm_1s() const { return Qm_1s_; }
41 OperatorType Qpz_1s() const { return Qpz_1s_; }
42 OperatorType Qmz_1s() const { return Qmz_1s_; }
43
47
49
50protected:
51 std::size_t D;
52
53 void fill_basis();
55
57 qType getQ(SPINOP_LABEL Sa) const;
58
60 std::unordered_map<std::string, std::pair<qType, std::size_t>> labels;
61
62 OperatorType Id_1s_; // identity
64 OperatorType F_1s_; // fermionic sign
65
66 OperatorType n_1s_; // particle number
67
68 // orbital spin
72
73 // orbital quadrupole
79
83};
84
85template <typename Symmetry_, std::size_t spin_index>
87 : D(D_input)
88{
89 // create basis for one spin site
90 fill_basis();
91 // std::cout << basis_1s_.info() << std::endl;
93}
94
95template <typename Symmetry_, std::size_t spin_index>
97{
98 Id_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_);
99 Id_1s_.setIdentity();
100
101 Zero_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_);
102 Zero_1s_.setZero();
103
104 F_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_);
105
106 Sz_1s_ = OperatorType(getQ(SPINOP_LABEL::SZ), basis_1s_);
107 Sp_1s_ = OperatorType(getQ(SPINOP_LABEL::SP), basis_1s_);
108 Sm_1s_ = OperatorType(getQ(SPINOP_LABEL::SM), basis_1s_);
109
110 Qz_1s_ = OperatorType(getQ(SPINOP_LABEL::SZ), basis_1s_);
111 Qp_1s_ = OperatorType(getQ(SPINOP_LABEL::QP), basis_1s_);
112 Qm_1s_ = OperatorType(getQ(SPINOP_LABEL::QM), basis_1s_);
113 Qpz_1s_ = OperatorType(getQ(SPINOP_LABEL::SP), basis_1s_);
114 Qmz_1s_ = OperatorType(getQ(SPINOP_LABEL::SM), basis_1s_);
115
116 exp_i_pi_Sz_1s_ = OperatorType(getQ(SPINOP_LABEL::SZ), basis_1s_);
117 if constexpr(Symmetry::ALL_IS_TRIVIAL) {
118 exp_i_pi_Sx_1s_ = OperatorType(getQ(SPINOP_LABEL::SX), basis_1s_);
119 exp_i_pi_Sy_1s_ = OperatorType(getQ(SPINOP_LABEL::iSY), basis_1s_);
120 }
121
122 OperatorType Sbase = OperatorType(getQ(SPINOP_LABEL::SP), basis_1s_, labels);
123 Sbase.setZero();
124
125 double S = 0.5 * (D - 1);
126 std::size_t Sx2 = D - 1;
127
128 for(std::size_t i = 0; i < D - 1; ++i) {
129 int Q = -static_cast<int>(Sx2) + 2 * static_cast<int>(i);
130 double m = -S + static_cast<double>(i);
131 Sbase(std::to_string(Q + 2), std::to_string(Q)) = 0.5 * sqrt(S * (S + 1.) - m * (m + 1.));
132 }
133
134 Sm_1s_ = 2. * Sbase;
135 Sp_1s_ = Sm_1s_.adjoint();
136 Sz_1s_ = 0.5 * (Sp_1s_ * Sm_1s_ - Sm_1s_ * Sp_1s_);
137 F_1s_ = 0.5 * Id_1s_ - Sz_1s_;
138
139 // cout << "Spin:" << endl;
140 // cout << "Id=" << endl << MatrixXd(Id_1s_.template plain<double>().data) << endl;
141 // cout << "Sbase=" << endl << MatrixXd(Sbase.template plain<double>().data) << endl;
142 // cout << "Sp=" << endl << MatrixXd(Sp_1s_.template plain<double>().data) << endl;
143 // cout << "Sm=" << endl << MatrixXd(Sm_1s_.template plain<double>().data) << endl;
144 // cout << "Sz=" << endl << MatrixXd(Sz_1s_.template plain<double>().data) << endl;
145 // cout << Id_1s_ << endl;
146
147 Qz_1s_ = 1. / sqrt(3.) * (3. * Sz_1s_ * Sz_1s_ - S * (S + 1.) * Id_1s_);
148 Qp_1s_ = Sp_1s_ * Sp_1s_;
149 Qm_1s_ = Sm_1s_ * Sm_1s_;
150 Qpz_1s_ = Sp_1s_ * Sz_1s_ + Sz_1s_ * Sp_1s_;
151 Qmz_1s_ = Sm_1s_ * Sz_1s_ + Sz_1s_ * Sm_1s_;
152
153 // if constexpr(Symmetry::IS_TRIVIAL) {
154 // // The exponentials are only correct for integer spin S=1,2,3,...!
155 // // for (size_t i=0; i<D; ++i) // <- don't want this basis order
156 // for(int i = D - 1; i >= 0; --i) {
157 // int Q1 = -static_cast<int>(Sx2) + 2 * static_cast<int>(i);
158 // int Q2 = +static_cast<int>(Sx2) - 2 * static_cast<int>(i);
159 // stringstream ssQ1;
160 // ssQ1 << Q1;
161 // stringstream ssQ2;
162 // ssQ2 << Q2;
163
164 // // exp(i*pi*Sx) has -1 on the antidiagonal for S=1,3,5,...
165 // // and +1 for S=2,4,6,...
166 // exp_i_pi_Sx_1s_(ssQ1.str(), ssQ2.str()) = pow(-1., D);
167
168 // // exp(i*pi*Sy) has alternating +-1 on the antidiagonal
169 // // starting with -1 for even D and with +1 for odd D
170 // exp_i_pi_Sy_1s_(ssQ1.str(), ssQ2.str()) = pow(-1., D + 1) * pow(-1, i);
171 // }
172 // }
173
174 // for(int i = D - 1; i >= 0; --i) {
175 // double m = -S + static_cast<double>(i);
176 // int Q = -static_cast<int>(Sx2) + 2 * static_cast<int>(i);
177 // stringstream ssQ;
178 // ssQ << Q;
179 // exp_i_pi_Sz_1s_(ssQ.str(), ssQ.str()) = pow(-1., m);
180 // }
181
182 return;
183}
184
185template <typename Symmetry_, std::size_t spin_index>
187{
188 // double S = 0.5 * (D - 1);
189 std::size_t Sx2 = D - 1;
190 typename Symmetry::qType Q = Symmetry::qvacuum();
191
192 if constexpr(Symmetry::ALL_IS_TRIVIAL) {
193 basis_1s_.push_back(Q, D);
194 // for(int i = D - 1; i >= 0; --i) {
195 for(int i = 0; i < D; ++i) {
196 int Qint = -static_cast<int>(Sx2) + 2 * static_cast<int>(i);
197 labels.insert(std::make_pair(std::to_string(Qint), std::make_pair(Q, i)));
198 }
199 } else if constexpr(Symmetry::IS_SPIN[spin_index]) {
200 assert(D >= 1);
201 // for(int i = D - 1; i >= 0; --i) {
202 for(int i = 0; i < D; ++i) {
203 int Qint = -static_cast<int>(Sx2) + 2 * static_cast<int>(i);
204 Q[spin_index] = Symmetry::IS_MODULAR[spin_index] ? util::constFct::posmod<Symmetry::MOD_N[spin_index]>(Qint) : Qint;
205 labels.insert(std::make_pair(std::to_string(Qint), std::make_pair(Q, basis_1s_.inner_dim(Q))));
206 basis_1s_.push_back(Q, 1);
207 }
208 basis_1s_.sort();
209 } else {
210 basis_1s_.push_back(Q, D);
211 // for(int i = D - 1; i >= 0; --i) {
212 for(int i = 0; i < D; ++i) {
213 int Qint = -static_cast<int>(Sx2) + 2 * static_cast<int>(i);
214 labels.insert(std::make_pair(std::to_string(Qint), std::make_pair(Q, i)));
215 }
216 }
217}
218
219template <typename Symmetry_, std::size_t spin_index>
220typename Symmetry_::qType Spin<Symmetry_, spin_index>::getQ(SPINOP_LABEL Sa) const
221{
222 typename Symmetry::qType Q = Symmetry::qvacuum();
223 if constexpr(Symmetry::ALL_IS_TRIVIAL) {
224 return Q;
225 } else if constexpr(Symmetry::IS_SPIN[spin_index]) {
226 assert(Sa != SPINOP_LABEL::SX and Sa != SPINOP_LABEL::iSY);
227 if(Sa == SPINOP_LABEL::SZ or Sa == SPINOP_LABEL::QZ) {
228 Q[spin_index] = 0;
229 } else if(Sa == SPINOP_LABEL::SP or Sa == SPINOP_LABEL::QPZ) {
230 Q[spin_index] = Symmetry::IS_MODULAR[spin_index] ? util::constFct::posmod<Symmetry::MOD_N[spin_index]>(2) : 2;
231 } else if(Sa == SPINOP_LABEL::SM or Sa == SPINOP_LABEL::QMZ) {
232 Q = Symmetry::conj(getQ(SPINOP_LABEL::SP));
233 } else if(Sa == SPINOP_LABEL::QP) {
234 Q[spin_index] = Symmetry::IS_MODULAR[spin_index] ? util::constFct::posmod<Symmetry::MOD_N[spin_index]>(4) : 4;
235 } else if(Sa == SPINOP_LABEL::QM) {
236 Q = Symmetry::conj(getQ(SPINOP_LABEL::QP));
237 }
238 }
239 return Q;
240}
241
242} // namespace Xped
243
244#endif
Definition: Qbasis.hpp:39
Definition: Spin.hpp:16
OperatorType F_1s() const
Definition: Spin.hpp:28
qType getQ(SPINOP_LABEL Sa) const
Definition: Spin.hpp:220
OperatorType Qm_1s() const
Definition: Spin.hpp:40
OperatorType Sp_1s() const
Definition: Spin.hpp:34
OperatorType Qp_1s() const
Definition: Spin.hpp:39
OperatorType exp_i_pi_Sy_1s_
Definition: Spin.hpp:81
OperatorType Qmz_1s_
Definition: Spin.hpp:78
OperatorType Qz_1s_
Definition: Spin.hpp:74
OperatorType Qz_1s() const
Definition: Spin.hpp:38
void fill_SiteOps()
Definition: Spin.hpp:96
OperatorType exp_i_pi_Sz() const
Definition: Spin.hpp:46
OperatorType exp_i_pi_Sy() const
Definition: Spin.hpp:45
OperatorType Zero_1s() const
Definition: Spin.hpp:27
OperatorType Id_1s_
Definition: Spin.hpp:62
OperatorType Sp_1s_
Definition: Spin.hpp:70
Qbasis< Symmetry, 1 > basis_1s() const
Definition: Spin.hpp:48
OperatorType Sz_1s_
Definition: Spin.hpp:69
OperatorType Sm_1s_
Definition: Spin.hpp:71
OperatorType F_1s_
Definition: Spin.hpp:64
void fill_basis()
Definition: Spin.hpp:186
OperatorType Qpz_1s() const
Definition: Spin.hpp:41
Qbasis< Symmetry, 1 > basis_1s_
Definition: Spin.hpp:59
OperatorType exp_i_pi_Sx_1s_
Definition: Spin.hpp:80
OperatorType Qpz_1s_
Definition: Spin.hpp:77
OperatorType n_1s_
Definition: Spin.hpp:66
OperatorType Qp_1s_
Definition: Spin.hpp:75
std::size_t D
Definition: Spin.hpp:51
OperatorType Sm_1s() const
Definition: Spin.hpp:35
OperatorType Id_1s() const
Definition: Spin.hpp:26
OperatorType exp_i_pi_Sz_1s_
Definition: Spin.hpp:82
Spin()
Definition: Spin.hpp:23
std::unordered_map< std::string, std::pair< qType, std::size_t > > labels
Definition: Spin.hpp:60
OperatorType Zero_1s_
Definition: Spin.hpp:63
OperatorType Qmz_1s() const
Definition: Spin.hpp:42
Spin(std::size_t D_input)
Definition: Spin.hpp:86
OperatorType Qm_1s_
Definition: Spin.hpp:76
OperatorType Sz_1s() const
Definition: Spin.hpp:33
OperatorType exp_i_pi_Sx() const
Definition: Spin.hpp:44
Definition: bench.cpp:62
void setZero()
Definition: SiteOperator.hpp:62
SiteOperator< Scalar, Symmetry > adjoint() XPED_CONST
Definition: SiteOperator.cpp:28