1#ifndef HEISENBERGOBSERVABLES
2#define HEISENBERGOBSERVABLES
5#include "ParamHandler.h"
9#include "Permutations.h"
11template<
typename Symmetry,
typename Scalar=
double>
21 HeisenbergObservables (
const size_t &L,
const vector<Param> ¶ms,
const std::map<string,std::any> &defaults);
25 template<
typename Dummy = Symmetry>
26 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
S (
size_t locx,
size_t locy=0,
double factor=1.)
const;
27 template<
typename Dummy = Symmetry>
28 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
Sdag (
size_t locx,
size_t locy=0,
double factor=std::sqrt(3.))
const;
29 template<
typename Dummy = Symmetry>
31 template<
typename Dummy = Symmetry>
33 template<
typename Dummy = Symmetry>
35 template<
typename Dummy = Symmetry>
37 template<
typename Dummy = Symmetry>
39 template<
typename Dummy = Symmetry>
41 template<
typename Dummy = Symmetry>
43 template<
typename Dummy = Symmetry>
45 template<
typename Dummy = Symmetry>
47 template<
typename Dummy = Symmetry>
49 template<
typename Dummy = Symmetry>
50 typename std::enable_if<!Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
SpSm (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0,
double fac=1.)
const {
return ScompScomp(
SP,
SM,locx1,locx2,locy1,locy2,fac);}
51 template<
typename Dummy = Symmetry>
52 typename std::enable_if<!Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
SmSp (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0,
double fac=1.)
const {
return ScompScomp(
SM,
SP,locx1,locx2,locy1,locy2,fac);}
53 template<
typename Dummy = Symmetry>
54 typename std::enable_if<!Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
SzSz (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0)
const {
return ScompScomp(
SZ,
SZ,locx1,locx2,locy1,locy2,1.);}
55 template<
typename Dummy = Symmetry>
56 typename std::enable_if<Dummy::NO_SPIN_SYM(),
Mpo<Symmetry,Scalar> >::type
SxSx (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0)
const {
return ScompScomp(
SX,
SX,locx1,locx2,locy1,locy2,1.);}
57 template<
typename Dummy = Symmetry>
58 typename std::conditional<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar>, vector<Mpo<Symmetry,Scalar> > >::type
SdagS (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0,
double factor=1.)
const;
59 template<
typename Dummy = Symmetry>
60 typename std::conditional<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar>, vector<Mpo<Symmetry,Scalar> > >::type
QdagQ (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0)
const;
61 template<
typename Dummy = Symmetry>
62 typename std::conditional<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar>, vector<Mpo<Symmetry,Scalar> > >::type
SdagSxS (
size_t locx1,
size_t locx2,
size_t locx3,
size_t locy1=0,
size_t locy2=0,
size_t locy3=0)
const;
63 template<
typename Dummy = Symmetry>
64 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
Stot (
size_t locy1=0,
double factor=1.,
int dLphys=1)
const;
65 template<
typename Dummy = Symmetry>
66 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
Sdagtot (
size_t locy1=0,
double factor=std::sqrt(3.),
int dLphys=1)
const;
67 template<
typename Dummy = Symmetry>
70 template<
typename Dummy = Symmetry>
71 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
Q (
size_t locx,
size_t locy=0,
double factor=1.)
const;
72 template<
typename Dummy = Symmetry>
73 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry,Scalar> >::type
Qdag (
size_t locx,
size_t locy=0,
double factor=std::sqrt(5.))
const;
75 template<
typename Dummy = Symmetry>
96 template<
typename Dummy = Symmetry>
98 template<
typename Dummy = Symmetry>
100 template<
typename Dummy = Symmetry>
104 template<
typename Dummy = Symmetry>
107 template<
typename Dummy = Symmetry>
150 bool HERMITIAN=
false,
155 double factor,
bool HERMITIAN,
159 vector<SpinBase<Symmetry> >
B;
162template<
typename Symmetry,
typename Scalar>
169template<
typename Symmetry,
typename Scalar>
171HeisenbergObservables (
const size_t &L,
const vector<Param> ¶ms,
const std::map<string,std::any> &defaults)
173 ParamHandler P(params,defaults);
174 size_t Lcell = P.size();
177 for (
size_t l=0; l<L; ++l)
179 B[l] =
SpinBase<Symmetry>(P.get<
size_t>(
"Ly",l%Lcell), P.get<
size_t>(
"D",l%Lcell), P.get<
int>(
"mfactor",l%Lcell));
183template<
typename Symmetry,
typename Scalar>
187 assert(locx<
B.size() and locy<
B[locx].dim());
189 ss << Op.
label() <<
"(" << locx <<
"," << locy;
190 if (factor != 1.) ss <<
",factor=" << factor;
194 for (
size_t l=0; l<
B.size(); ++l) {Mout.
setLocBasis(
B[l].get_basis().qloc(),l);}
198 Mout.
setLocal(locx, (factor * Op).
template cast<Scalar>().
template plain<Scalar>());
209template<
typename Symmetry,
typename Scalar>
211make_localSum (
const vector<OperatorType> &Op, vector<Scalar> factor,
bool HERMITIAN)
const
213 assert(Op.size()==
B.size() and factor.size()==
B.size());
215 ss << Op[0].label() <<
"localSum";
218 for (
size_t l=0; l<
B.size(); ++l) {Mout.
setLocBasis(
B[l].get_basis().qloc(),l);}
220 vector<SiteOperator<Symmetry,Scalar>> Op_plain;
221 for (
int i=0; i<Op.size(); ++i)
223 Op_plain.push_back(Op[i].
template cast<Scalar>().
template plain<Scalar>());
230template<
typename Symmetry,
typename Scalar>
232make_corr (
size_t locx1,
size_t locx2,
size_t locy1,
size_t locy2,
235 double factor,
bool HERMITIAN,
238 assert(locx1<
B.size() and locy1<
B[locx1].dim());
239 assert(locx2<
B.size() and locy2<
B[locx2].dim());
242 ss << Op1.
label() <<
"(" << locx1 <<
"," << locy1 <<
")"
243 << Op2.
label() <<
"(" << locx2 <<
"," << locy2;
244 if (factor != 1.) {ss <<
",fac=" << factor;}
248 for (
size_t l=0; l<
B.size(); ++l) {Mout.
setLocBasis(
B[l].get_basis().qloc(),l);}
252 auto product = factor*OperatorType::prod(Op1, Op2, Qtot);
253 Mout.
setLocal(locx1, product.template cast<Scalar>().template plain<Scalar>());
260 if (
int(locx2)-
int(locx1)-1 != 0)
262 vector<SiteOperator<Symmetry,Scalar> > dummySign(max(locx1,locx2)-min(locx1,locx2)-1);
263 for (
int i=0; i<dummySign.size(); ++i)
265 dummySign[i] =
B[min(locx1,locx2)+i+1].Id().template cast<Scalar>().template plain<Scalar>();
267 Mout.
setLocal(vector<size_t>{locx1, locx2},
268 vector<SiteOperator<Symmetry,Scalar> >{
269 (factor*Op1).
template cast<Scalar>().template plain<Scalar>(),
270 Op2 .template cast<Scalar>().template plain<Scalar>()},
275 Mout.
setLocal(vector<size_t>{locx1, locx2},
276 vector<SiteOperator<Symmetry,Scalar> >{
277 (factor*Op1).
template cast<Scalar>().template plain<Scalar>(),
278 Op2 .template cast<Scalar>().template plain<Scalar>()});
292template<
typename Symmetry,
typename Scalar>
295 double factor,
bool HERMITIAN,
const vector<complex<double> > &phases)
const
298 ss << name <<
"_ky(";
299 for (
int l=0; l<phases.size(); ++l)
302 if (l!=phases.size()-1) {ss <<
",";}
308 for (
size_t l=0; l<
B.size(); ++l) {Mout.
setLocBasis(
B[l].get_basis().qloc(),l);}
310 vector<complex<double> > phases_x_factor = phases;
311 for (
int l=0; l<phases.size(); ++l)
313 phases_x_factor[l] = phases[l] * factor;
316 vector<SiteOperator<Symmetry,complex<double> > > OpsPlain(Ops.size());
317 for (
int l=0; l<OpsPlain.size(); ++l)
319 OpsPlain[l] = Ops[l].template cast<complex<double> >().
template plain<complex<double> >();
329template<
typename Symmetry,
typename Scalar>
330template<
typename Dummy>
334 bool HERMITIAN = (Sa==
SX or Sa==
SZ)?
true:
false;
335 return make_local(locx,locy,
B[locx].Scomp(Sa,locy).
template cast<Scalar>(), factor, HERMITIAN);
338template<
typename Symmetry,
typename Scalar>
339template<
typename Dummy>
343 bool HERMITIAN = (Sa==
QZ)?
true:
false;
344 return make_local(locx,locy,
B[locx].Qcomp(Sa,locy).
template cast<Scalar>(), factor, HERMITIAN);
347template<
typename Symmetry,
typename Scalar>
348template<
typename Dummy>
355 ss <<
"exp[2Ï€" << Sa <<
"(" << locx <<
"," << locy <<
")]";
359 ss <<
"exp[2Ï€i" << Sa <<
"(" << locx <<
"," << locy <<
")]";
362 auto Op =
B[locx].Rcomp(Sa,locy).template plain<complex<double> >();
365 for (
size_t l=0; l<
B.size(); ++l) {Mout.setLocBasis(
B[l].get_basis().qloc(),l);}
367 Mout.setLocal(locx, Op);
372template<
typename Symmetry,
typename Scalar>
373template<
typename Dummy>
377 bool HERMITIAN =
false;
378 if ((Sa1 ==
SZ and Sa2 ==
SZ) or (Sa1 ==
SX and Sa2 ==
SX)) HERMITIAN =
true;
379 auto Qtot =
B[locx1].Scomp(Sa1,locy1).Q() +
B[locx2].Scomp(Sa2,locy2).Q();
380 return make_corr(locx1,locx2,locy1,locy2,
B[locx1].Scomp(Sa1,locy1).
template cast<Scalar>(),
B[locx2].Scomp(Sa2,locy2).
template cast<Scalar>(), Qtot, fac, HERMITIAN);
383template<
typename Symmetry,
typename Scalar>
384template<
typename Dummy>
388 bool HERMITIAN =
false;
389 if (Sa1 ==
QZ and Sa2 ==
QZ) HERMITIAN =
true;
390 auto Qtot =
B[locx1].Qcomp(Sa1,locy1).Q() +
B[locx2].Qcomp(Sa2,locy2).Q();
391 return make_corr(locx1,locx2,locy1,locy2,
B[locx1].Qcomp(Sa1,locy1).
template cast<Scalar>(),
B[locx2].Qcomp(Sa2,locy2).
template cast<Scalar>(), Qtot, fac, HERMITIAN);
394template<
typename Symmetry,
typename Scalar>
395template<
typename Dummy>
397S (
size_t locx,
size_t locy,
double factor)
const
402template<
typename Symmetry,
typename Scalar>
403template<
typename Dummy>
405Sdag (
size_t locx,
size_t locy,
double factor)
const
410template<
typename Symmetry,
typename Scalar>
411template<
typename Dummy>
413Q (
size_t locx,
size_t locy,
double factor)
const
418template<
typename Symmetry,
typename Scalar>
419template<
typename Dummy>
421Qdag (
size_t locx,
size_t locy,
double factor)
const
426template<
typename Symmetry,
typename Scalar>
427template<
typename Dummy>
429Sz (
size_t locx,
size_t locy)
const
431 return Scomp(
SZ,locx,locy);
434template<
typename Symmetry,
typename Scalar>
435template<
typename Dummy>
437exp_ipiSz (
size_t locx,
size_t locy,
double factor)
const
439 bool HERMITIAN =
false;
441 assert(locx<
B.size() and locy<
B[locx].dim());
443 ss <<
B[locx].exp_ipiSz(locy).label() <<
"(" << locx <<
"," << locy;
444 if (factor != 1.) ss <<
",factor=" << factor;
448 for (
size_t l=0; l<
B.size(); ++l) Mout.
setLocBasis(
B[l].get_basis().qloc(),l);
450 Mout.
setLocal(locx, (factor *
B[locx].exp_ipiSz(locy)).
template plain<complex<double> >().
template cast<complex<double> >());
455template<
typename Symmetry,
typename Scalar>
456template<
typename Dummy>
460 vector<OperatorType> Ops(
B.size());
461 vector<Scalar> factors(
B.size());
462 for (
int l=0; l<
B.size(); ++l)
464 Ops[l] =
B[l].Scomp(Sa,locy).template cast<Scalar>();
467 for (
int l=0; l<
B.size(); l+=dLphys)
474template<
typename Symmetry,
typename Scalar>
475template<
typename Dummy>
477Stot (
size_t locy,
double factor,
int dLphys)
const
479 vector<OperatorType> Ops(
B.size());
480 vector<Scalar> factors(
B.size());
481 for (
int l=0; l<
B.size(); ++l)
483 Ops[l] =
B[l].S(locy).template cast<Scalar>();
486 for (
int l=0; l<
B.size(); l+=dLphys)
493template<
typename Symmetry,
typename Scalar>
494template<
typename Dummy>
496Sdagtot (
size_t locy,
double factor,
int dLphys)
const
498 vector<OperatorType> Ops(
B.size());
499 vector<double> factors(
B.size());
500 for (
int l=0; l<
B.size(); ++l)
502 Ops[l] =
B[l].Sdag(locy);
505 for (
int l=0; l<
B.size(); l+=dLphys)
512template<
typename Symmetry,
typename Scalar>
513template<
typename Dummy>
515SdagS (
size_t locx1,
size_t locx2,
size_t locy1,
size_t locy2,
double factor)
const
517 if constexpr (Symmetry::IS_SPIN_SU2())
519 return make_corr(locx1, locx2, locy1, locy2,
B[locx1].Sdag(locy1),
B[locx2].S(locy2), Symmetry::qvacuum(), factor*sqrt(3.),
PROP::HERMITIAN);
523 vector<Mpo<Symmetry,Scalar> > out(3);
524 out[0] = SzSz(locx1,locx2,locy1,locy2);
525 out[1] = SpSm(locx1,locx2,locy1,locy2,0.5);
526 out[2] = SmSp(locx1,locx2,locy1,locy2,0.5);
531template<
typename Symmetry,
typename Scalar>
532template<
typename Dummy>
534QdagQ (
size_t locx1,
size_t locx2,
size_t locy1,
size_t locy2)
const
536 if constexpr (Symmetry::IS_SPIN_SU2())
538 return make_corr(locx1, locx2, locy1, locy2,
B[locx1].Qdag(locy1),
B[locx2].Q(locy2), Symmetry::qvacuum(), sqrt(5.),
PROP::HERMITIAN);
542 vector<Mpo<Symmetry,Scalar> > out(5);
543 out[0] = QcompQcomp(
QZ,
QZ,locx1,locx2,locy1,locy2);
544 out[1] = QcompQcomp(
QP,
QM,locx1,locx2,locy1,locy2,0.5);
545 out[2] = QcompQcomp(
QM,
QP,locx1,locx2,locy1,locy2,0.5);
546 out[3] = QcompQcomp(
QPZ,
QMZ,locx1,locx2,locy1,locy2,0.5);
547 out[4] = QcompQcomp(
QMZ,
QPZ,locx1,locx2,locy1,locy2,0.5);
552template<
typename Symmetry,
typename Scalar>
553template<
typename Dummy>
555SdagSxS (
size_t locx1,
size_t locx2,
size_t locx3,
size_t locy1,
size_t locy2,
size_t locy3)
const
557 if constexpr (Symmetry::IS_SPIN_SU2())
560 for (
size_t l=0; l<
B.size(); ++l) {Mout.
setLocBasis(
B[l].get_basis().qloc(),l);}
562 std::vector<typename Symmetry::qType> qList(
B.size()+1);
563 std::vector<SiteOperator<Symmetry,double>> opList(
B.size());
565 for (
int i=0; i<qList.size(); ++i) {qList[i] = Symmetry::qvacuum();}
566 for (
int i=0; i<opList.size(); ++i) {opList[i] =
B[i].Id().template plain<double>();}
568 for (
int i=0; i<
B.size(); ++i)
570 if (i>=locx1 and i<locx3)
575 opList[i] = (
B[i].S(i)).
template plain<double>();
579 opList[i] = (
B[i].S(i)).
template plain<double>();
584 opList[i] = (
B[i].S(i)).
template plain<double>();
588 for (
int i=0; i<qList.size(); ++i)
590 cout <<
"i=" << i <<
", q=" << qList[i] << endl;
603 lout <<
"SdagSxS is not implemented for this symmetry!" << endl;
608template<
typename Symmetry,
typename Scalar>
609template<
typename Dummy>
611S_ky (vector<complex<double> > phases)
const
613 vector<OperatorType> Ops(
B.size());
614 for (
size_t l=0; l<
B.size(); ++l)
618 return make_FourierYSum(
"S", Ops, 1.,
false, phases);
621template<
typename Symmetry,
typename Scalar>
622template<
typename Dummy>
624Sdag_ky (vector<complex<double> > phases,
double factor)
const
626 vector<OperatorType> Ops(
B.size());
627 for (
size_t l=0; l<
B.size(); ++l)
629 Ops[l] =
B[l].Sdag(0);
631 return make_FourierYSum(
"S†", Ops, 1.,
false, phases);
634template<
typename Symmetry,
typename Scalar>
635template<
typename Dummy>
639 return make_local(locx, locy,
B[locx].Scomp(
STRING_TO_SPINOP(STR),locy), 1.,
false, STR);
642template<
typename Symmetry,
typename Scalar>
643template<
typename Dummy>
645StringCorr (
STRING STR,
size_t locx1,
size_t locx2,
size_t locy1,
size_t locy2)
const
648 auto Qtot =
B[locx1].Scomp(Sa,locy1).Q() +
B[locx2].Scomp(Sa,locy2).Q();
650 return make_corr(locx1, locx2, locy1, locy2,
B[locx1].Scomp(Sa,locy1),
B[locx2].Scomp(Sa,locy2), Qtot, -1.,
false, STR);
745template<
typename Symmetry,
typename Scalar>
749 auto check_locs = [
this](std::size_t& locx1, std::size_t& locx2, std::size_t& locy1, std::size_t& locy2)
751 assert(locx1 <
B.size() and locx2 <
B.size());
752 assert(locy1 <
B[locx1].
dim() and locy2 <
B[locx2].
dim());
753 assert(locx1 != locx2 or locy1 != locy2);
756 std::swap(locx1,locx2);
757 std::swap(locy1,locy2);
760 std::size_t D =
B[0].get_D();
761 assert(D == 2ul or D == 3ul);
762 for (
size_t loc=0; loc<
B.size(); ++loc)
764 assert(
B[loc].get_D() == D);
767 std::vector<std::vector<Transposition>> transpositions = permutations.independentTranspositions();
768 std::size_t divisions = transpositions.size();
769 std::vector<Mpo<Symmetry,Scalar>> Mout(divisions);
770 for(std::size_t div=0; div<divisions; ++div)
772 std::size_t locx1 = transpositions[div][0].source;
773 std::size_t locx2 = transpositions[div][0].target;
774 std::size_t locy1 = 0ul;
775 std::size_t locy2 = 0ul;
776 check_locs(locx1,locx2,locy1,locy2);
777 MpoTerms<Symmetry,double> terms = (D == 2ul ? spin_swap_operator_D2(locx1,locx2,locy1,locy2) : spin_swap_operator_D3(locx1,locx2,locy1,locy2));
778 for (std::size_t t=1; t<transpositions[div].size(); ++t)
780 std::size_t locx1 = transpositions[div][t].source;
781 std::size_t locx2 = transpositions[div][t].target;
782 std::size_t locy1 = 0ul;
783 std::size_t locy2 = 0ul;
784 check_locs(locx1,locx2,locy1,locy2);
785 terms = (D == 2ul ?
MpoTerms<Symmetry,double>::prod(spin_swap_operator_D2(locx1,locx2,locy1,locy2),terms,Symmetry::qvacuum()) :
MpoTerms<Symmetry,double>::prod(spin_swap_operator_D3(locx1,locx2,locy1,locy2),terms,Symmetry::qvacuum()));
787 std::stringstream ss;
788 ss <<
"Spin permutation";
791 ss <<
" " << div+1 <<
"/" << divisions;
796 Mout[div].UNITARY =
true;
798 lout <<
"Construction of spin permutation operator: " << watch.
info(
"Time") << std::endl;
802template<
typename Symmetry,
typename Scalar>
804spin_swap_operator_D2 (
const std::size_t locx1,
const std::size_t locx2,
const std::size_t locy1,
const std::size_t locy2)
const
807 for (
size_t loc=0; loc<
B.size(); ++loc)
814 Tout.
push(locx1,{identity},0.5);
815 if constexpr (Symmetry::IS_SPIN_SU2())
818 Tout.
push(locx1,{SdagS},2.*std::sqrt(3.));
825 Tout.
push(locx1,{SzSz},2.);
826 Tout.
push(locx1,{SpSm},1.);
827 Tout.
push(locx1,{SmSp},1.);
832 std::vector<SiteOperator<Symmetry,double>> opList(locx2-locx1+1);
833 for(
int j=0; j<-1+locx2-locx1; ++j)
835 opList[j+1] = (
B[j].Id().template plain<double>());
839 first_op =
B[locx1].Id().template plain<double>();
840 last_op =
B[locx2].Id().template plain<double>();
841 Tout.
push(locx1,opList,0.5);
843 if constexpr (Symmetry::IS_SPIN_SU2())
845 first_op = (
B[locx1].Sdag(locy1).template plain<double>());
846 last_op = (
B[locx2].S(locy2).template plain<double>());
847 Tout.
push(locx1,opList,2.*std::sqrt(3));
851 first_op = (
B[locx1].Sz(locy1).template plain<double>());
852 last_op = (
B[locx2].Sz(locy2).template plain<double>());
853 Tout.
push(locx1,opList,2.);
855 first_op = (
B[locx1].Sp(locy1).template plain<double>());
856 last_op = (
B[locx2].Sm(locy2).template plain<double>());
857 Tout.
push(locx1,opList,1.);
859 first_op = (
B[locx1].Sm(locy1).template plain<double>());
860 last_op = (
B[locx2].Sp(locy2).template plain<double>());
861 Tout.
push(locx1,opList,1.);
865 std::stringstream ss;
866 ss <<
"(" << locx1 <<
"<->" << locx2 <<
")";
871template<
typename Symmetry,
typename Scalar>
873Psinglet (
const std::size_t locx1,
const std::size_t locx2,
const std::size_t locy1,
const std::size_t locy2)
const
876 for (
size_t loc=0; loc<
B.size(); ++loc)
883 Tout.
push(locx1,{identity},0.25);
884 if constexpr (Symmetry::IS_SPIN_SU2())
887 Tout.
push(locx1,{SdagS},-1.*std::sqrt(3.));
894 Tout.
push(locx1,{SzSz},-1.);
895 Tout.
push(locx1,{SpSm},-0.5);
896 Tout.
push(locx1,{SmSp},-0.5);
901 std::vector<SiteOperator<Symmetry,double>> opList(locx2-locx1+1);
902 for(
int j=0; j<-1+locx2-locx1; ++j)
904 opList[j+1] = (
B[j].Id().template plain<double>());
908 first_op =
B[locx1].Id().template plain<double>();
909 last_op =
B[locx2].Id().template plain<double>();
910 Tout.
push(locx1,opList,0.25);
912 if constexpr (Symmetry::IS_SPIN_SU2())
914 first_op = (
B[locx1].Sdag(locy1).template plain<double>());
915 last_op = (
B[locx2].S(locy2).template plain<double>());
916 Tout.
push(locx1,opList,-1.*std::sqrt(3));
920 first_op = (
B[locx1].Sz(locy1).template plain<double>());
921 last_op = (
B[locx2].Sz(locy2).template plain<double>());
922 Tout.
push(locx1,opList,-1.);
924 first_op = (
B[locx1].Sp(locy1).template plain<double>());
925 last_op = (
B[locx2].Sm(locy2).template plain<double>());
926 Tout.
push(locx1,opList,-0.5);
928 first_op = (
B[locx1].Sm(locy1).template plain<double>());
929 last_op = (
B[locx2].Sp(locy2).template plain<double>());
930 Tout.
push(locx1,opList,-0.5);
934 std::stringstream ss;
935 ss <<
"Psinglet(" << locx1 <<
"," << locx2 <<
")";
940template<
typename Symmetry,
typename Scalar>
942spin_swap_operator_D3 (
const std::size_t locx1,
const std::size_t locx2,
const std::size_t locy1,
const std::size_t locy2)
const
945 for (
size_t loc=0; loc<
B.size(); ++loc)
952 Tout.
push(locx1,{identity},-1.);
953 if constexpr (Symmetry::IS_SPIN_SU2())
956 Tout.
push(locx1,{SdagS},std::sqrt(3.));
958 OperatorType SdagSdag_singl = OperatorType::prod(
B[locx1].Sdag(locy1),
B[locx1].Sdag(locy1), {1});
959 OperatorType SS_singl = OperatorType::prod(
B[locx2].S(locy2),
B[locx2].S(locy2), {1});
961 Tout.
push(locx1,{SdagSdagSS_singl},1.);
963 OperatorType SdagSdag_tripl = OperatorType::prod(
B[locx1].Sdag(locy1),
B[locx1].Sdag(locy1), {3});
964 OperatorType SS_tripl = OperatorType::prod(
B[locx2].S(locy2),
B[locx2].S(locy2), {3});
966 Tout.
push(locx1,{SdagSdagSS_tripl},std::sqrt(3.));
968 OperatorType SdagSdag_quint = OperatorType::prod(
B[locx1].Sdag(locy1),
B[locx1].Sdag(locy1), {5});
969 OperatorType SS_quint = OperatorType::prod(
B[locx2].S(locy2),
B[locx2].S(locy2), {5});
971 Tout.
push(locx1,{SdagSdagSS_quint},std::sqrt(5.));
978 Tout.
push(locx1,{SzSz},1.);
979 Tout.
push(locx1,{SpSm},0.5);
980 Tout.
push(locx1,{SmSp},0.5);
982 OperatorType SzSz_1 = OperatorType::prod(
B[locx1].Sz(locy1),
B[locx1].Sz(locy1), {0});
983 OperatorType SzSp_1 = OperatorType::prod(
B[locx1].Sz(locy1),
B[locx1].Sp(locy1), {2});
984 OperatorType SzSm_1 = OperatorType::prod(
B[locx1].Sz(locy1),
B[locx1].Sm(locy1), {-2});
985 OperatorType SpSz_1 = OperatorType::prod(
B[locx1].Sp(locy1),
B[locx1].Sz(locy1), {2});
986 OperatorType SpSp_1 = OperatorType::prod(
B[locx1].Sp(locy1),
B[locx1].Sp(locy1), {4});
987 OperatorType SpSm_1 = OperatorType::prod(
B[locx1].Sp(locy1),
B[locx1].Sm(locy1), {0});
988 OperatorType SmSz_1 = OperatorType::prod(
B[locx1].Sm(locy1),
B[locx1].Sz(locy1), {-2});
989 OperatorType SmSp_1 = OperatorType::prod(
B[locx1].Sm(locy1),
B[locx1].Sp(locy1), {0});
990 OperatorType SmSm_1 = OperatorType::prod(
B[locx1].Sm(locy1),
B[locx1].Sm(locy1), {-4});
991 OperatorType SzSz_2 = OperatorType::prod(
B[locx2].Sz(locy2),
B[locx2].Sz(locy2), {0});
992 OperatorType SzSp_2 = OperatorType::prod(
B[locx2].Sz(locy2),
B[locx2].Sp(locy2), {2});
993 OperatorType SzSm_2 = OperatorType::prod(
B[locx2].Sz(locy2),
B[locx2].Sm(locy2), {-2});
994 OperatorType SpSz_2 = OperatorType::prod(
B[locx2].Sp(locy2),
B[locx2].Sz(locy2), {2});
995 OperatorType SpSp_2 = OperatorType::prod(
B[locx2].Sp(locy2),
B[locx2].Sp(locy2), {4});
996 OperatorType SpSm_2 = OperatorType::prod(
B[locx2].Sp(locy2),
B[locx2].Sm(locy2), {0});
997 OperatorType SmSz_2 = OperatorType::prod(
B[locx2].Sm(locy2),
B[locx2].Sz(locy2), {-2});
998 OperatorType SmSp_2 = OperatorType::prod(
B[locx2].Sm(locy2),
B[locx2].Sp(locy2), {0});
999 OperatorType SmSm_2 = OperatorType::prod(
B[locx2].Sm(locy2),
B[locx2].Sm(locy2), {-4});
1011 Tout.
push(locx1,{SzSzSzSz},1.);
1012 Tout.
push(locx1,{SzSpSzSm},0.5);
1013 Tout.
push(locx1,{SzSmSzSp},0.5);
1014 Tout.
push(locx1,{SpSzSmSz},0.5);
1015 Tout.
push(locx1,{SmSzSpSz},0.5);
1016 Tout.
push(locx1,{SpSmSmSp},0.25);
1017 Tout.
push(locx1,{SmSpSpSm},0.25);
1018 Tout.
push(locx1,{SpSpSmSm},0.25);
1019 Tout.
push(locx1,{SmSmSpSp},0.25);
1024 std::vector<SiteOperator<Symmetry,double>> opList(locx2-locx1+1);
1025 for(
int j=0; j<-1+locx2-locx1; ++j)
1027 opList[j+1] = (
B[j].Id().template plain<double>());
1031 first_op =
B[locx1].Id().template plain<double>();
1032 last_op =
B[locx2].Id().template plain<double>();
1033 Tout.
push(locx1,opList,-1.);
1035 if constexpr (Symmetry::IS_SPIN_SU2())
1037 first_op = (
B[locx1].Sdag(locy1).template plain<double>());
1038 last_op = (
B[locx2].S(locy2).template plain<double>());
1039 Tout.
push(locx1,opList,std::sqrt(3.));
1041 first_op = (OperatorType::prod(
B[locx1].Sdag(locy1),
B[locx1].Sdag(locy1), {1})).template plain<double>();
1042 last_op = (OperatorType::prod(
B[locx2].S(locy2),
B[locx2].S(locy2), {1})).template plain<double>();
1043 Tout.
push(locx1,opList,1.);
1045 first_op = (OperatorType::prod(
B[locx1].Sdag(locy1),
B[locx1].Sdag(locy1), {3})).template plain<double>();
1046 last_op = (OperatorType::prod(
B[locx2].S(locy2),
B[locx2].S(locy2), {3})).template plain<double>();
1047 Tout.
push(locx1,opList,std::sqrt(3.));
1049 first_op = (OperatorType::prod(
B[locx1].Sdag(locy1),
B[locx1].Sdag(locy1), {5})).template plain<double>();
1050 last_op = (OperatorType::prod(
B[locx2].S(locy2),
B[locx2].S(locy2), {5})).template plain<double>();
1051 Tout.
push(locx1,opList,std::sqrt(5.));
1055 first_op = (
B[locx1].Sz(locy1).template plain<double>());
1056 last_op = (
B[locx2].Sz(locy2).template plain<double>());
1057 Tout.
push(locx1,opList,1.);
1059 first_op = (
B[locx1].Sp(locy1).template plain<double>());
1060 last_op = (
B[locx2].Sm(locy2).template plain<double>());
1061 Tout.
push(locx1,opList,0.5);
1063 first_op = (
B[locx1].Sm(locy1).template plain<double>());
1064 last_op = (
B[locx2].Sp(locy2).template plain<double>());
1065 Tout.
push(locx1,opList,0.5);
1067 first_op = (OperatorType::prod(
B[locx1].Sz(locy1),
B[locx1].Sz(locy1), {0})).template plain<double>();
1068 last_op = (OperatorType::prod(
B[locx2].Sz(locy2),
B[locx2].Sz(locy2), {0})).template plain<double>();
1069 Tout.
push(locx1,opList,1.);
1071 first_op = (OperatorType::prod(
B[locx1].Sz(locy1),
B[locx1].Sp(locy1), {2})).template plain<double>();
1072 last_op = (OperatorType::prod(
B[locx2].Sz(locy2),
B[locx2].Sm(locy2), {-2})).template plain<double>();
1073 Tout.
push(locx1,opList,0.5);
1075 first_op = (OperatorType::prod(
B[locx1].Sz(locy1),
B[locx1].Sm(locy1), {-2})).template plain<double>();
1076 last_op = (OperatorType::prod(
B[locx2].Sz(locy2),
B[locx2].Sp(locy2), {2})).template plain<double>();
1077 Tout.
push(locx1,opList,0.5);
1079 first_op = (OperatorType::prod(
B[locx1].Sp(locy1),
B[locx1].Sz(locy1), {2})).template plain<double>();
1080 last_op = (OperatorType::prod(
B[locx2].Sm(locy2),
B[locx2].Sz(locy2), {-2})).template plain<double>();
1081 Tout.
push(locx1,opList,0.5);
1083 first_op = (OperatorType::prod(
B[locx1].Sp(locy1),
B[locx1].Sp(locy1), {4})).template plain<double>();
1084 last_op = (OperatorType::prod(
B[locx2].Sm(locy2),
B[locx2].Sm(locy2), {-4})).template plain<double>();
1085 Tout.
push(locx1,opList,0.25);
1087 first_op = (OperatorType::prod(
B[locx1].Sp(locy1),
B[locx1].Sm(locy1), {0})).template plain<double>();
1088 last_op = (OperatorType::prod(
B[locx2].Sm(locy2),
B[locx2].Sp(locy2), {0})).template plain<double>();
1089 Tout.
push(locx1,opList,0.25);
1091 first_op = (OperatorType::prod(
B[locx1].Sm(locy1),
B[locx1].Sz(locy1), {-2})).template plain<double>();
1092 last_op = (OperatorType::prod(
B[locx2].Sp(locy2),
B[locx2].Sz(locy2), {2})).template plain<double>();
1093 Tout.
push(locx1,opList,0.5);
1095 first_op = (OperatorType::prod(
B[locx1].Sm(locy1),
B[locx1].Sp(locy1), {0})).template plain<double>();
1096 last_op = (OperatorType::prod(
B[locx2].Sp(locy2),
B[locx2].Sm(locy2), {0})).template plain<double>();
1097 Tout.
push(locx1,opList,0.25);
1099 first_op = (OperatorType::prod(
B[locx1].Sm(locy1),
B[locx1].Sm(locy1), {-4})).template plain<double>();
1100 last_op = (OperatorType::prod(
B[locx2].Sp(locy2),
B[locx2].Sp(locy2), {4})).template plain<double>();
1101 Tout.
push(locx1,opList,0.25);
1105 std::stringstream ss;
1106 ss <<
"(" << locx1 <<
"<->" << locx2 <<
")";
size_t dim(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
SPINOP_LABEL STRING_TO_SPINOP(STRING STR)
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Q(size_t locx, size_t locy=0, double factor=1.) const
Mpo< Symmetry, Scalar > make_localSum(const vector< OperatorType > &Op, vector< Scalar > factor, bool HERMITIAN) const
HeisenbergObservables(const size_t &L)
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type String(STRING STR, size_t locx, size_t locy=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Qcomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type QcompQcomp(SPINOP_LABEL Sa1, SPINOP_LABEL Sa2, size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0, double fac=1.) const
std::vector< Mpo< Symmetry, Scalar > > make_spinPermutation(const Permutation &permutations) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type iSy(size_t locx, size_t locy=0) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Qdag(size_t locx, size_t locy=0, double factor=std::sqrt(5.)) const
vector< SpinBase< Symmetry > > B
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, complex< double > > >::type S_ky(vector< complex< double > > phases) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, complex< double > > >::type Sa_ky(SPINOP_LABEL Sa, vector< complex< double > > phases) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Sm(size_t locx, size_t locy=0) const
Mpo< Symmetry, complex< double > > make_FourierYSum(string name, const vector< OperatorType > &Ops, double factor, bool HERMITIAN, const vector< complex< double > > &phases) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Sp(size_t locx, size_t locy=0) const
std::enable_if< Dummy::NO_SPIN_SYM(), Mpo< Symmetry, Scalar > >::type SxSx(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type ScompScomp(SPINOP_LABEL Sa1, SPINOP_LABEL Sa2, size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0, double fac=1.) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type SmSp(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0, double fac=1.) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type SpSm(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0, double fac=1.) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Sdag(size_t locx, size_t locy=0, double factor=std::sqrt(3.)) const
std::conditional< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar >, vector< Mpo< Symmetry, Scalar > > >::type SdagS(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0, double factor=1.) const
std::conditional< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar >, vector< Mpo< Symmetry, Scalar > > >::type SdagSxS(size_t locx1, size_t locx2, size_t locx3, size_t locy1=0, size_t locy2=0, size_t locy3=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type SzSz(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Sx(size_t locx, size_t locy=0) const
Mpo< Symmetry, Scalar > make_local(size_t locx, size_t locy, const OperatorType &Op, double factor=1., bool HERMITIAN=false, STRING STR=NOSTRING) const
MpoTerms< Symmetry, double > spin_swap_operator_D2(const std::size_t locx1, const std::size_t locx2, const std::size_t locy1=0ul, const std::size_t locy2=0ul) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, complex< double > > >::type exp_ipiSz(size_t locx, size_t locy=0, double factor=1.) const
Mpo< Symmetry, Scalar > make_corr(size_t locx1, size_t locx2, size_t locy1, size_t locy2, const OperatorType &Op1, const OperatorType &Op2, qarray< Symmetry::Nq > Qtot, double factor, bool HERMITIAN, STRING STR=NOSTRING) const
SiteOperatorQ< Symmetry, Eigen::Matrix< Scalar, Dynamic, Dynamic > > OperatorType
HeisenbergObservables(const size_t &L, const vector< Param > ¶ms, const std::map< string, std::any > &defaults)
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type StringCorr(STRING STR, size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Scomptot(SPINOP_LABEL Sa, size_t locy1=0, double factor=1., int dLphys=1) const
std::conditional< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar >, vector< Mpo< Symmetry, Scalar > > >::type QdagQ(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Scomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const
MpoTerms< Symmetry, double > Psinglet(const std::size_t locx1, const std::size_t locx2, const std::size_t locy1=0ul, const std::size_t locy2=0ul) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type S(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Stot(size_t locy1=0, double factor=1., int dLphys=1) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, complex< double > > >::type Rcomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Sz(size_t locx, size_t locy=0) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, Scalar > >::type Sdagtot(size_t locy1=0, double factor=std::sqrt(3.), int dLphys=1) const
MpoTerms< Symmetry, double > spin_swap_operator_D3(const std::size_t locx1, const std::size_t locx2, const std::size_t locy1=0ul, const std::size_t locy2=0ul) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry, complex< double > > >::type Sdag_ky(vector< complex< double > > phases, double factor=sqrt(3.)) const
static MpoTerms< Symmetry, Scalar > prod(const MpoTerms< Symmetry, Scalar > &top, const MpoTerms< Symmetry, Scalar > &bottom, const qType &qTot, const double tolerance=::mynumeric_limits< double >::epsilon())
std::vector< std::vector< std::string > > info
void finalize(const bool COMPRESS=true, const std::size_t power=1, const double tolerance=::mynumeric_limits< double >::epsilon())
void setLocBasis(const std::vector< std::vector< qType > > &q)
virtual void push(const std::size_t loc, const std::vector< OperatorType > &opList, const std::vector< qType > &qList, const Scalar lambda=1.0)
const std::string get_name() const
void set_name(const std::string &label_in)
void setLocal(std::size_t loc, const OperatorType &op)
void setLocalSum(const OperatorType &op, Scalar(*f)(int)=localSumTrivial)
void precalc_TwoSiteData(bool FORCE=false)
void push_qpath(const std::size_t loc, const std::vector< OperatorType > &opList, const std::vector< qType > &qList, const Scalar lambda=1.0)