Xped
Loading...
Searching...
No Matches
SpinBase.hpp
Go to the documentation of this file.
1#ifndef XPED_SPINBASE_HPP_
2#define XPED_SPINBASE_HPP_
3
9
10#include "Xped/Util/Constfct.hpp" // for posmod
11
12namespace Xped {
13
14// Note: Don't put a name in this documentation with \class .. because doxygen gets confused with template symbols
21template <typename Symmetry_, std::size_t order = 0>
22class SpinBase : public Spin<Symmetry_, order>
23{
24 using Scalar = double;
25
26public:
27 using Symmetry = Symmetry_;
30 using qType = typename Symmetry::qType;
31
32 SpinBase() = default;
33
38 SpinBase(std::size_t L_input, std::size_t D_input);
39
41 inline std::size_t dim() const { return N_states; }
42
44 inline std::size_t orbitals() const { return N_orbitals; }
45
47 inline std::size_t get_D() const { return this->D; }
48
54 OperatorType sign(std::size_t orb1 = 0, std::size_t orb2 = 0) const;
55
60 template <class Dummy = Symmetry>
61 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type n(std::size_t orbital = 0) const;
62
64
68 template <class Dummy = Symmetry>
69 typename std::enable_if<Dummy::IS_SPIN_SU2(), OperatorType>::type S(std::size_t orbital = 0) const;
70
75 template <class Dummy = Symmetry>
76 typename std::enable_if<Dummy::IS_SPIN_SU2(), OperatorType>::type Sdag(std::size_t orbital = 0) const;
77
78 template <class Dummy = Symmetry>
79 typename std::enable_if<Dummy::IS_SPIN_SU2(), OperatorType>::type Q(std::size_t orbital = 0) const;
80
81 template <class Dummy = Symmetry>
82 typename std::enable_if<Dummy::IS_SPIN_SU2(), OperatorType>::type Qdag(std::size_t orbital = 0) const;
83
84 template <class Dummy = Symmetry>
85 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Qz(std::size_t orbital = 0) const;
86
87 template <class Dummy = Symmetry>
88 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Qp(std::size_t orbital = 0) const;
89
90 template <class Dummy = Symmetry>
91 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Qm(std::size_t orbital = 0) const;
92
93 template <class Dummy = Symmetry>
94 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Qpz(std::size_t orbital = 0) const;
95
96 template <class Dummy = Symmetry>
97 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Qmz(std::size_t orbital = 0) const;
98
99 template <class Dummy = Symmetry>
100 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Sz(std::size_t orbital = 0) const;
101
102 template <class Dummy = Symmetry>
103 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Sp(std::size_t orbital = 0) const;
104
105 template <class Dummy = Symmetry>
106 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Sm(std::size_t orbital = 0) const;
107
108 template <class Dummy = Symmetry>
109 typename std::enable_if<Dummy::NO_SPIN_SYM(), OperatorType>::type Sx(std::size_t orbital = 0) const;
110
111 template <class Dummy = Symmetry>
112 typename std::enable_if<Dummy::NO_SPIN_SYM(), OperatorTypeC>::type Sy(std::size_t orbital = 0) const;
113
114 template <class Dummy = Symmetry>
115 typename std::enable_if<Dummy::NO_SPIN_SYM(), OperatorType>::type iSy(std::size_t orbital = 0) const;
116
117 template <class Dummy = Symmetry>
118 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Scomp(SPINOP_LABEL Sa, int orbital = 0) const
119 {
120 assert(Sa != SPINOP_LABEL::SY and Sa != SPINOP_LABEL::QP and Sa != SPINOP_LABEL::QM and Sa != SPINOP_LABEL::QPZ and Sa != SPINOP_LABEL::QMZ);
121 OperatorType out = Zero();
122 if constexpr(Dummy::NO_SPIN_SYM()) {
123 if(Sa == SPINOP_LABEL::SX) {
124 out = Sx(orbital);
125 } else if(Sa == SPINOP_LABEL::iSY) {
126 out = iSy(orbital);
127 } else if(Sa == SPINOP_LABEL::SZ) {
128 out = Sz(orbital);
129 } else if(Sa == SPINOP_LABEL::SP) {
130 out = Sp(orbital);
131 } else if(Sa == SPINOP_LABEL::SM) {
132 out = Sm(orbital);
133 }
134 } else {
135 assert(Sa != SPINOP_LABEL::SX and Sa != SPINOP_LABEL::iSY);
136 if(Sa == SPINOP_LABEL::SZ) {
137 out = Sz(orbital);
138 } else if(Sa == SPINOP_LABEL::SP) {
139 out = Sp(orbital);
140 } else if(Sa == SPINOP_LABEL::SM) {
141 out = Sm(orbital);
142 }
143 }
144 return out;
145 };
146
147 template <class Dummy = Symmetry>
148 typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type Qcomp(SPINOP_LABEL Sa, int orbital = 0) const
149 {
150 assert(Sa != SPINOP_LABEL::SX and Sa != SPINOP_LABEL::SY and Sa != SPINOP_LABEL::iSY and Sa != SPINOP_LABEL::SZ and Sa != SPINOP_LABEL::SP and
151 Sa != SPINOP_LABEL::SM);
152 OperatorType out;
153 if(Sa == SPINOP_LABEL::QZ) {
154 out = Qz(orbital);
155 } else if(Sa == SPINOP_LABEL::QP) {
156 out = Qp(orbital);
157 } else if(Sa == SPINOP_LABEL::QM) {
158 out = Qm(orbital);
159 } else if(Sa == SPINOP_LABEL::QPZ) {
160 out = Qpz(orbital);
161 } else if(Sa == SPINOP_LABEL::QMZ) {
162 out = Qmz(orbital);
163 }
164 return out;
165 };
167
168 // template <class Dummy = Symmetry>
169 // typename std::enable_if < !Dummy::IS_SPIN_SU2(),
170 // SiteOperator<Scalar, Symmetry>::type Rcomp(SPINOP_LABEL Sa, int orbital = 0) const;
171
172 // template <class Dummy = Symmetry>
173 // typename std::enable_if<Dummy::IS_SPIN_SU2(), OperatorType>::type bead(STRING STR, std::size_t orbital = 0) const;
174
175 // template <class Dummy = Symmetry>
176 // typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type bead(STRING STR, std::size_t orbital = 0) const;
177
179 OperatorType Id(std::size_t orbital = 0) const;
180
182 OperatorType Zero(std::size_t orbital = 0) const;
183
184 // /**Returns an array of size dim() with zeros.*/
185 // ArrayXd ZeroField() const { return ArrayXd::Zero(N_orbitals); }
186
187 // /**Returns an array of size dim()xdim() with zeros.*/
188 // ArrayXXd ZeroHopping() const { return ArrayXXd::Zero(N_orbitals, N_orbitals); }
189
201 // template <typename Scalar_>
202 // SiteOperatorQ<Symmetry_, Eigen::Matrix<Scalar_, -1, -1>> HeisenbergHamiltonian(const Array<Scalar_, Dynamic, Dynamic>& J) const;
203
204 // template <typename Dummy = Symmetry>
205 // typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type
206 // HeisenbergHamiltonian(const ArrayXXd& Jxy, const ArrayXXd& Jz, const ArrayXd& Bz, const ArrayXd& mu, const ArrayXd& nu, const ArrayXd& Kz)
207 // const;
208
209 // template <typename Dummy = Symmetry>
210 // typename std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType>::type HeisenbergHamiltonian(const ArrayXXcd& Jxy, const ArrayXXcd& Jz) const;
211
223 // template <typename Dummy = Symmetry>
224 // typename std::enable_if<Dummy::NO_SPIN_SYM(), OperatorType>::type HeisenbergHamiltonian(const ArrayXXd& Jxy,
225 // const ArrayXXd& Jz,
226 // const ArrayXd& Bz,
227 // const ArrayXd& Bx,
228 // const ArrayXd& mu,
229 // const ArrayXd& nu,
230 // const ArrayXd& Kz,
231 // const ArrayXd& Kx,
232 // const ArrayXXd& Dy) const;
240 // template <typename Dummy = Symmetry>
241 // typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<complex<double>, -1, -1>>>::type
242 // HeisenbergHamiltonian(const std::array<ArrayXXd, 3>& J,
243 // const std::array<ArrayXd, 3>& B,
244 // const std::array<ArrayXd, 3>& K,
245 // const std::array<ArrayXXd, 3>& D) const;
246 // template <typename Scalar_, typename Dummy = Symmetry>
247 // typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<Scalar_, -1, -1>>>::type
248 // coupling_Bx(const Array<double, Dynamic, 1>& Bx) const;
249
250 // template <typename Dummy = Symmetry>
251 // typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<complex<double>, -1, -1>>>::type
252 // coupling_By(const Array<double, Dynamic, 1>& By) const;
253
255 Qbasis<Symmetry, 1> get_basis() const { return TensorBasis; }
256
257private:
258 OperatorType make_operator(const OperatorType& Op_1s, std::size_t orbital = 0, std::string label = "") const;
259 std::size_t N_orbitals;
260 std::size_t N_states;
261
262 Qbasis<Symmetry, 1> TensorBasis; // Final basis for N_orbital sites
263};
264
265template <typename Symmetry_, std::size_t order>
266SpinBase<Symmetry_, order>::SpinBase(std::size_t L_input, std::size_t D_input)
267 : Spin<Symmetry, order>(D_input)
268 , N_orbitals(L_input)
269{
270 // create basis for spin 0
271 typename Symmetry::qType Q = Symmetry::qvacuum();
272 Eigen::Index inner_dim = 1;
274 vacuum.push_back(Q, inner_dim);
275
276 // // create operators for zero orbitals
277 // Zero_vac = OperatorType(Symmetry::qvacuum(), vacuum);
278 // Zero_vac.setZero();
279 // Id_vac = OperatorType(Symmetry::qvacuum(), vacuum);
280 // Id_vac.setIdentity();
281
282 // create basis for N_orbitals fermionic sites
283 if(N_orbitals == 1) {
284 TensorBasis = this->basis_1s();
285 } else if(N_orbitals == 0) {
286 TensorBasis = vacuum;
287 } else {
288 TensorBasis = this->basis_1s().combine(this->basis_1s()).forgetHistory();
289 for(std::size_t o = 2; o < N_orbitals; o++) { TensorBasis = TensorBasis.combine(this->basis_1s()).forgetHistory(); }
290 }
291
292 N_states = TensorBasis.dim();
293}
294
295template <typename Symmetry_, std::size_t order>
296SiteOperator<double, Symmetry_> SpinBase<Symmetry_, order>::make_operator(const OperatorType& Op_1s, std::size_t orbital, std::string label) const
297{
298 OperatorType out;
299 if(N_orbitals == 1) {
300 out = Op_1s;
301 out.label() = label;
302 return out;
303 } else {
304 OperatorType stringOp = this->Id_1s();
305 ;
306 bool TOGGLE = false;
307 if(orbital == 0) {
308 out = OperatorType::outerprod(Op_1s, this->Id_1s(), Op_1s.Q);
309 TOGGLE = true;
310 } else {
311 if(orbital == 1) {
312 out = OperatorType::outerprod(stringOp, Op_1s, Op_1s.Q);
313 TOGGLE = true;
314 } else {
315 out = OperatorType::outerprod(stringOp, stringOp, Symmetry_::qvacuum());
316 }
317 }
318 for(std::size_t o = 2; o < N_orbitals; o++) {
319 if(orbital == o) {
320 out = OperatorType::outerprod(out, Op_1s, Op_1s.Q);
321 TOGGLE = true;
322 } else if(TOGGLE == false) {
323 out = OperatorType::outerprod(out, stringOp, Symmetry_::qvacuum());
324 } else if(TOGGLE == true) {
325 out = OperatorType::outerprod(out, this->Id_1s(), Op_1s.Q);
326 }
327 }
328 out.label() = label;
329 return out;
330 }
331}
332
333template <typename Symmetry_, std::size_t order>
335{
336 OperatorType Oout;
337 if(N_orbitals == 1) {
338 Oout = this->F_1s();
339 Oout.label() = "sign";
340 return Oout;
341 } else {
342 Oout = Id();
343 for(int i = orb1; i < N_orbitals; ++i) { Oout = Oout * (2. * Sz(i)); }
344 for(int i = 0; i < orb2; ++i) { Oout = Oout * (2. * Sz(i)); }
345 Oout.label() = "sign";
346 return Oout;
347 }
348}
349
350template <typename Symmetry_, std::size_t order>
351template <typename Dummy>
352typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::n(std::size_t orbital) const
353{
354 OperatorType Oout = 0.5 * Id() - Sz(orbital);
355 Oout.label() = "n";
356 return Oout;
357}
358
359// template <typename Symmetry_, std::size_t order>
360// template <typename Dummy>
361// typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type
362// SpinBase<Symmetry_, order>::bead(STRING STR, std::size_t orbital) const
363// {
364// if(STR == STRINGZ) {
365// if(this->D % 2 == 0) { lout << termcolor::red << "Warning: exp(iπSz) is not correct for half-integer S!" << termcolor::reset << endl; }
366// return make_operator(this->exp_i_pi_Sz(), orbital, "exp(iπSz)");
367// } else if(STR == STRINGX) {
368// if(this->D % 2 == 0) { lout << termcolor::red << "Warning: exp(iπSx) is not correct for half-integer S!" << termcolor::reset << endl; }
369// return make_operator(this->exp_i_pi_Sx(), orbital, "exp(iπSx)");
370// } else {
371// if(this->D % 2 == 0) { lout << termcolor::red << "Warning: exp(iπSy) is not correct for half-integer S!" << termcolor::reset << endl; }
372// return make_operator(this->exp_i_pi_Sy(), orbital, "exp(iπSy)");
373// }
374// }
375
376// template <typename Symmetry_, std::size_t order>
377// template <typename Dummy>
378// typename std::enable_if<Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type
379// SpinBase<Symmetry_, order>::bead(STRING STR, std::size_t orbital) const
380// {
381// lout << termcolor::red << "Warning: returning Id instead of exp(iπSa) with SU(2) symmetry!" << termcolor::reset << endl;
382// return make_operator(this->Id_1s(), orbital, "Id");
383// }
384
385template <typename Symmetry_, std::size_t order>
386template <typename Dummy>
387typename std::enable_if<Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::S(std::size_t orbital) const
388{
389 return make_operator(this->S_1s(), orbital, "S");
390}
391
392template <typename Symmetry_, std::size_t order>
393template <typename Dummy>
394typename std::enable_if<Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Sdag(std::size_t orbital) const
395{
396 return S(orbital).adjoint();
397}
398
399template <typename Symmetry_, std::size_t order>
400template <typename Dummy>
401typename std::enable_if<Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Q(std::size_t orbital) const
402{
403 return make_operator(this->Q_1s(), orbital, "Q");
404}
405
406template <typename Symmetry_, std::size_t order>
407template <typename Dummy>
408typename std::enable_if<Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Qdag(std::size_t orbital) const
409{
410 return Q(orbital).adjoint();
411}
412
413template <typename Symmetry_, std::size_t order>
414template <typename Dummy>
415typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Qz(std::size_t orbital) const
416{
417 return make_operator(this->Qz_1s(), orbital, "Qz");
418}
419
420template <typename Symmetry_, std::size_t order>
421template <typename Dummy>
422typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Qp(std::size_t orbital) const
423{
424 return make_operator(this->Qp_1s(), orbital, "Qp");
425}
426
427template <typename Symmetry_, std::size_t order>
428template <typename Dummy>
429typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Qm(std::size_t orbital) const
430{
431 return make_operator(this->Qm_1s(), orbital, "Qm");
432}
433
434template <typename Symmetry_, std::size_t order>
435template <typename Dummy>
436typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Qpz(std::size_t orbital) const
437{
438 return make_operator(this->Qpz_1s(), orbital, "Qpz");
439}
440
441template <typename Symmetry_, std::size_t order>
442template <typename Dummy>
443typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Qmz(std::size_t orbital) const
444{
445 return make_operator(this->Qmz_1s(), orbital, "Qmz");
446}
447
448template <typename Symmetry_, std::size_t order>
449template <typename Dummy>
450typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Sz(std::size_t orbital) const
451{
452 return make_operator(this->Sz_1s(), orbital, "Sz");
453}
454
455template <typename Symmetry_, std::size_t order>
456template <typename Dummy>
457typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Sp(std::size_t orbital) const
458{
459 return make_operator(this->Sp_1s(), orbital, "Sp");
460}
461
462template <typename Symmetry_, std::size_t order>
463template <typename Dummy>
464typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Sm(std::size_t orbital) const
465{
466 return make_operator(this->Sm_1s(), orbital, "Sm");
467}
468
469template <typename Symmetry_, std::size_t order>
470template <typename Dummy>
471typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::Sx(std::size_t orbital) const
472{
473 OperatorType out = 0.5 * (Sp(orbital) + Sm(orbital));
474 out.label() = "Sx";
475 return out;
476}
477
478template <typename Symmetry, std::size_t order>
479template <typename Dummy>
480typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperator<std::complex<double>, Symmetry>>::type
481SpinBase<Symmetry, order>::Sy(std::size_t orbital) const
482{
483 using namespace std::complex_literals;
484 OperatorTypeC out = -1i * 0.5 * (Sp(orbital) - Sm(orbital));
485 out.label() = "Sy";
486 return out;
487}
488
489template <typename Symmetry_, std::size_t order>
490template <typename Dummy>
491typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperator<double, Symmetry_>>::type SpinBase<Symmetry_, order>::iSy(std::size_t orbital) const
492{
493 OperatorType out = 0.5 * (Sp(orbital) - Sm(orbital));
494 out.label() = "iSy";
495 return out;
496}
497
498template <typename Symmetry_, std::size_t order>
500{
501 return make_operator(this->Id_1s(), orbital, "Id");
502}
503
504template <typename Symmetry_, std::size_t order>
506{
507 return make_operator(this->Zero_1s(), orbital, "Zero");
508}
509
510// template <typename Symmetry_, std::size_t order>
511// template <typename Scalar_>
512// SiteOperatorQ<Symmetry_, Eigen::Matrix<Scalar_, Eigen::Dynamic, Eigen::Dynamic>>
513// SpinBase<Symmetry_, order>::HeisenbergHamiltonian(const Array<Scalar_, Dynamic, Dynamic>& J) const
514// {
515// SiteOperatorQ<Symmetry_, Eigen::Matrix<Scalar_, Eigen::Dynamic, Eigen::Dynamic>> Oout(Symmetry::qvacuum(), TensorBasis);
516
517// for(int i = 0; i < N_orbitals; ++i)
518// for(int j = 0; j < N_orbitals; ++j) {
519// if(J(i, j) != 0.) {
520// if constexpr(Symmetry::IS_SPIN_SU2()) {
521// Oout += J(i, j) * std::sqrt(3.) * (OperatorType::prod(Sdag(i), S(j), Symmetry::qvacuum())).template cast<Scalar_>();
522// } else {
523// Oout += J(i, j) * (OperatorType::prod(Sz(i), Sz(j), Symmetry::qvacuum())).template cast<Scalar_>();
524// Oout += 0.5 * J(i, j) *
525// (OperatorType::prod(Sp(i), Sm(j), Symmetry::qvacuum()) + OperatorType::prod(Sm(i), Sp(j), Symmetry::qvacuum()))
526// .template cast<Scalar_>();
527// }
528// }
529// }
530
531// Oout.label() = "Hloc";
532// return Oout;
533// }
534
535// template <typename Symmetry_, std::size_t order>
536// template <typename Dummy>
537// typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperatorQ<Symmetry_, Eigen::Matrix<double, -1, -1>>>::type
538// SpinBase<Symmetry_, order>::HeisenbergHamiltonian(const ArrayXXd& Jxy,
539// const ArrayXXd& Jz,
540// const ArrayXd& Bz,
541// const ArrayXd& mu,
542// const ArrayXd& nu,
543// const ArrayXd& Kz) const
544// {
545// assert(Bz.rows() == N_orbitals and Kz.rows() == N_orbitals);
546
547// OperatorType Mout(Symmetry::qvacuum(), TensorBasis);
548
549// for(int i = 0; i < N_orbitals; ++i)
550// for(int j = 0; j < N_orbitals; ++j) {
551// if(Jxy(i, j) != 0.) { Mout += 0.5 * Jxy(i, j) * (Scomp(SP, i) * Scomp(SM, j) + Scomp(SM, i) * Scomp(SP, j)); }
552// if(Jz(i, j) != 0.) { Mout += Jz(i, j) * Scomp(SZ, i) * Scomp(SZ, j); }
553// }
554
555// for(int i = 0; i < N_orbitals; ++i) {
556// if(Bz(i) != 0.) { Mout -= Bz(i) * Scomp(SZ, i); }
557// }
558// for(int i = 0; i < N_orbitals; ++i) {
559// if(mu(i) != 0.) { Mout += mu(i) * (Scomp(SZ, i) - 0.5 * Id()); } // for Kitaev chain: -mu*n = -mu*(1/2-Sz) = mu*(Sz-1/2)
560// }
561// for(int i = 0; i < N_orbitals; ++i) {
562// if(nu(i) != 0.) { Mout += nu(i) * (Scomp(SZ, i) + 0.5 * Id()); }
563// }
564// for(int i = 0; i < N_orbitals; ++i) {
565// if(Kz(i) != 0.) { Mout += Kz(i) * Scomp(SZ, i) * Scomp(SZ, i); }
566// }
567// Mout.label() = "Hloc";
568// return Mout;
569// }
570
571// template <typename Symmetry_, std::size_t order>
572// template <typename Dummy>
573// typename std::enable_if<!Dummy::IS_SPIN_SU2(), SiteOperatorQ<Symmetry_, Eigen::Matrix<double, -1, -1>>>::type
574// SpinBase<Symmetry_, order>::HeisenbergHamiltonian(const ArrayXXcd& Jxy, const ArrayXXcd& Jz) const
575// {
576// OperatorType Mout(Symmetry::qvacuum(), TensorBasis);
577
578// for(int i = 0; i < N_orbitals; ++i)
579// for(int j = 0; j < N_orbitals; ++j) {
580// if(abs(Jxy(i, j)) != 0.) { Mout += 0.5 * (Jxy(i, j) * Scomp(SP, i) * Scomp(SM, j) + conj(Jxy(i, j)) * Scomp(SM, i) * Scomp(SP, j)); }
581// if(abs(Jz(i, j)) != 0.) { Mout += Jz(i, j) * Scomp(SZ, i) * Scomp(SZ, j); }
582// }
583// Mout.label() = "Hloc";
584// return Mout;
585// }
586
587// template <typename Symmetry_, std::size_t order>
588// template <typename Dummy>
589// typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<double, -1, -1>>>::type
590// SpinBase<Symmetry_, order>::HeisenbergHamiltonian(const ArrayXXd& Jxy,
591// const ArrayXXd& Jz,
592// const ArrayXd& Bz,
593// const ArrayXd& Bx,
594// const ArrayXd& mu,
595// const ArrayXd& nu,
596// const ArrayXd& Kz,
597// const ArrayXd& Kx,
598// const ArrayXXd& Dy) const
599// {
600// assert(Bz.rows() == N_orbitals and Bx.rows() == N_orbitals and Kz.rows() == N_orbitals and Kx.rows() == N_orbitals);
601
602// OperatorType Mout = HeisenbergHamiltonian(Jxy, Jz, Bz, mu, nu, Kz);
603
604// for(int i = 0; i < N_orbitals; ++i)
605// for(int j = 0; j < i; ++j) {
606// if(Dy(i, j) != 0.) { Mout += Dy(i, j) * (Scomp(SX, i) * Scomp(SZ, j) - Scomp(SZ, i) * Scomp(SX, j)); }
607// }
608// for(int i = 0; i < N_orbitals; ++i) {
609// if(Bx(i) != 0.) { Mout -= Bx(i) * Scomp(SX, i); }
610// }
611// for(int i = 0; i < N_orbitals; ++i) {
612// if(Kx(i) != 0.) { Mout += Kx(i) * Scomp(SX, i) * Scomp(SX, i); }
613// }
614
615// return Mout;
616// }
617
618// template <typename Symmetry_, std::size_t order>
619// template <typename Scalar_, typename Dummy>
620// typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<Scalar_, -1, -1>>>::type
621// SpinBase<Symmetry_, order>::coupling_Bx(const Array<double, Dynamic, 1>& Bx) const
622// {
623// SiteOperatorQ<Symmetry_, Eigen::Matrix<Scalar_, -1, -1>> Mout(Symmetry::qvacuum(), TensorBasis);
624// for(int i = 0; i < N_orbitals; ++i) {
625// if(Bx(i) != 0.) { Mout -= Bx(i) * Sx(i).template cast<Scalar_>(); }
626// }
627// return Mout;
628// }
629
630// template <typename Symmetry_, std::size_t order>
631// template <typename Dummy>
632// typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<complex<double>, -1, -1>>>::type
633// SpinBase<Symmetry_, order>::coupling_By(const Array<double, Dynamic, 1>& By) const
634// {
635// SiteOperatorQ<Symmetry_, Eigen::Matrix<complex<double>, -1, -1>> Mout(Symmetry::qvacuum(), TensorBasis);
636// for(int i = 0; i < N_orbitals; ++i) {
637// if(By(i) != 0.) { Mout -= -1i * By(i) * iSy(i).template cast<complex<double>>(); }
638// }
639// return Mout;
640// }
641
642// template <typename Symmetry_, std::size_t order>
643// template <typename Dummy>
644// typename std::enable_if<Dummy::NO_SPIN_SYM(), SiteOperatorQ<Symmetry_, Eigen::Matrix<complex<double>, -1, -1>>>::type
645// SpinBase<Symmetry_, order>::HeisenbergHamiltonian(const std::array<ArrayXXd, 3>& J,
646// const std::array<ArrayXd, 3>& B,
647// const std::array<ArrayXd, 3>& K,
648// const std::array<ArrayXXd, 3>& D) const
649// {
650// SiteOperatorQ<Symmetry_, Eigen::Matrix<complex<double>, -1, -1>> Mout(Symmetry::qvacuum(), TensorBasis);
651// for(int i = 0; i < N_orbitals; ++i)
652// for(int j = 0; j < N_orbitals; ++j) {
653// // J
654// if(J[0](i, j) != 0.) { Mout += J[0](i, j) * (Sx(i) * Sx(j)).template cast<complex<double>>(); }
655// if(J[1](i, j) != 0.) { Mout += -J[1](i, j) * (iSy(i) * iSy(j)).template cast<complex<double>>(); }
656// if(J[2](i, j) != 0.) { Mout += J[2](i, j) * (Sz(i) * Sz(j)).template cast<complex<double>>(); }
657
658// // D
659// if(D[0](i, j) != 0.) { Mout += D[0](i, j) * (-1.i) * (iSy(i) * Sz(j) - Sz(i) * iSy(j)).template cast<complex<double>>(); }
660// if(D[1](i, j) != 0.) { Mout += D[1](i, j) * (Sx(i) * Sz(j) - Sz(i) * Sx(j)).template cast<complex<double>>(); }
661// if(D[2](i, j) != 0.) { Mout += D[2](i, j) * (-1.i) * (Sx(i) * iSy(j) - iSy(i) * Sx(j)).template cast<complex<double>>(); }
662// }
663
664// for(int i = 0; i < N_orbitals; ++i) {
665// // B
666// if(B[0](i) != 0.) { Mout -= B[0](i) * Sx(i).template cast<complex<double>>(); }
667// if(B[1](i) != 0.) { Mout -= B[1](i) * (-1.i) * iSy(i).template cast<complex<double>>(); }
668// if(B[2](i) != 0.) { Mout -= B[2](i) * Sz(i).template cast<complex<double>>(); }
669
670// // K
671// if(K[0](i) != 0.) { Mout += K[0](i) * (Sx(i) * Sx(i)).template cast<complex<double>>(); }
672// if(K[1](i) != 0.) { Mout -= K[1](i) * (iSy(i) * iSy(i)).template cast<complex<double>>(); }
673// if(K[2](i) != 0.) { Mout += K[2](i) * (Sz(i) * Sz(i)).template cast<complex<double>>(); }
674// }
675// Mout.label() = "Hloc";
676// return Mout;
677// }
678
679} // namespace Xped
680#endif
Definition: Qbasis.hpp:39
void push_back(const qType &q, const size_t &inner_dim)
Definition: Qbasis.cpp:32
Qbasis< Symmetry, depth+1, AllocationPolicy > combine(const Qbasis< Symmetry, 1, AllocationPolicy > &other, bool CONJ=false) const
Definition: Qbasis.cpp:439
std::size_t dim() const
Definition: Qbasis.hpp:75
Definition: SpinBase.hpp:23
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Qp(std::size_t orbital=0) const
Definition: SpinBase.hpp:422
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Qm(std::size_t orbital=0) const
Definition: SpinBase.hpp:429
SpinBase()=default
std::enable_if< Dummy::IS_SPIN_SU2(), OperatorType >::type Q(std::size_t orbital=0) const
Definition: SpinBase.hpp:401
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Qcomp(SPINOP_LABEL Sa, int orbital=0) const
Definition: SpinBase.hpp:148
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Qz(std::size_t orbital=0) const
Definition: SpinBase.hpp:415
OperatorType Zero(std::size_t orbital=0) const
Definition: SpinBase.hpp:505
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Scomp(SPINOP_LABEL Sa, int orbital=0) const
Definition: SpinBase.hpp:118
std::enable_if< Dummy::IS_SPIN_SU2(), OperatorType >::type S(std::size_t orbital=0) const
Definition: SpinBase.hpp:387
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Sz(std::size_t orbital=0) const
Definition: SpinBase.hpp:450
std::size_t dim() const
Definition: SpinBase.hpp:41
std::size_t orbitals() const
Definition: SpinBase.hpp:44
std::size_t get_D() const
Definition: SpinBase.hpp:47
Symmetry_ Symmetry
Definition: SpinBase.hpp:27
std::enable_if< Dummy::IS_SPIN_SU2(), OperatorType >::type Qdag(std::size_t orbital=0) const
Definition: SpinBase.hpp:408
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Qmz(std::size_t orbital=0) const
Definition: SpinBase.hpp:443
std::enable_if< Dummy::NO_SPIN_SYM(), OperatorTypeC >::type Sy(std::size_t orbital=0) const
Definition: SpinBase.hpp:481
typename Symmetry::qType qType
Definition: SpinBase.hpp:30
std::enable_if< Dummy::NO_SPIN_SYM(), OperatorType >::type iSy(std::size_t orbital=0) const
Definition: SpinBase.hpp:491
OperatorType Id(std::size_t orbital=0) const
Definition: SpinBase.hpp:499
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Qpz(std::size_t orbital=0) const
Definition: SpinBase.hpp:436
std::enable_if< Dummy::NO_SPIN_SYM(), OperatorType >::type Sx(std::size_t orbital=0) const
Definition: SpinBase.hpp:471
OperatorType sign(std::size_t orb1=0, std::size_t orb2=0) const
Definition: SpinBase.hpp:334
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Sp(std::size_t orbital=0) const
Definition: SpinBase.hpp:457
SiteOperator< Scalar, Symmetry > OperatorType
Definition: SpinBase.hpp:28
SpinBase(std::size_t L_input, std::size_t D_input)
Definition: SpinBase.hpp:266
Qbasis< Symmetry, 1 > get_basis() const
Definition: SpinBase.hpp:255
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type n(std::size_t orbital=0) const
Definition: SpinBase.hpp:352
std::enable_if< Dummy::IS_SPIN_SU2(), OperatorType >::type Sdag(std::size_t orbital=0) const
Definition: SpinBase.hpp:394
std::enable_if<!Dummy::IS_SPIN_SU2(), OperatorType >::type Sm(std::size_t orbital=0) const
Definition: SpinBase.hpp:464
Definition: Spin.hpp:16
Qbasis< Symmetry, 1 > basis_1s() const
Definition: Spin.hpp:48
std::size_t D
Definition: Spin.hpp:51
Definition: bench.cpp:62
std::string & label()
Definition: SiteOperator.hpp:85