1#ifndef DOUBLEHEISENBERGOBSERVABLES
2#define DOUBLEHEISENBERGOBSERVABLES
5#include "ParamHandler.h"
10template<
typename Symmetry>
24 template<
size_t order = 0ul,
typename Dummy = Symmetry>
25 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry> >::type
26 S (
size_t locx,
size_t locy=0,
double factor=1.)
const;
28 template<
size_t order = 0ul,
typename Dummy = Symmetry>
29 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry> >::type
30 Sdag (
size_t locx,
size_t locy=0,
double factor=std::sqrt(3.))
const;
32 template<
size_t order = 0ul,
typename Dummy = Symmetry>
33 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry> >::type
34 Stot (
size_t locy=0,
double factor=1.)
const;
36 template<
size_t order = 0ul,
typename Dummy = Symmetry>
37 typename std::enable_if<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry> >::type
38 Sdagtot (
size_t locy=0,
double factor=1.)
const;
40 template<
size_t order = 0ul,
typename Dummy = Symmetry>
41 typename std::conditional<Dummy::IS_SPIN_SU2(),
Mpo<Symmetry>, vector<Mpo<Symmetry> > >::type
42 SdagS (
size_t locx1,
size_t locx2,
size_t locy1=0,
size_t locy2=0)
const;
44 template<
size_t order = 0ul,
typename Dummy = Symmetry>
45 typename std::enable_if<!Dummy::IS_SPIN_SU2(),
Mpo<Symmetry> >::type
48 template<
size_t order = 0ul,
typename Dummy = Symmetry>
49 typename std::enable_if<!Dummy::IS_SPIN_SU2(),
Mpo<Symmetry> >::type
58 bool HERMITIAN=
false)
const;
62 double factor,
bool HERMITIAN)
const;
69 vector<SpinBase<Symmetry,0ul>>
B0;
70 vector<SpinBase<Symmetry,1ul>>
B1;
73template<
typename Symmetry>
81template<
typename Symmetry>
85 ParamHandler P(params,defaults);
86 size_t Lcell = P.size();
90 for (
size_t l=0; l<L; ++l)
97template<
typename Symmetry>
101 assert(locx<B0.size() and locy<B0[locx].dim());
103 ss << Op.
label() <<
"(" << locx <<
"," << locy;
104 if (factor != 1.) ss <<
",factor=" << factor;
108 for (
size_t l=0; l<B0.size(); ++l) {Mout.
setLocBasis(B0[l].get_basis().combine(B1[l].get_basis()).qloc(),l);}
110 Mout.
setLocal(locx, (factor * Op).
template plain<double>());
115template<
typename Symmetry>
116template<
size_t order>
118make_localSum (
const vector<OperatorType> &Op, vector<double> factor,
bool HERMITIAN)
const
120 assert(Op.size()==B0.size() and factor.size()==B0.size());
122 ss << Op[0].label() <<
"localSum";
124 vector<OperatorType> OpExt(Op.size());
125 for (
int i=0; i<Op.size(); ++i)
131 else if (order == 1ul)
137 Mpo<Symmetry> Mout(B0.size(), OpExt[0].Q(), ss.str(), HERMITIAN);
138 for (
size_t l=0; l<B0.size(); ++l) {Mout.
setLocBasis(B0[l].get_basis().combine(B1[l].get_basis()).qloc(),l);}
140 vector<SiteOperator<Symmetry,double>> Op_plain;
141 for (
int i=0; i<Op.size(); ++i)
143 Op_plain.push_back(OpExt[i].
template plain<double>());
150template<
typename Symmetry>
151template<
size_t order>
153make_corr (
size_t locx1,
size_t locx2,
size_t locy1,
size_t locy2,
156 double factor,
bool HERMITIAN)
const
158 assert(locx1<B0.size() and locy1<B0[locx1].dim());
159 assert(locx2<B0.size() and locy2<B0[locx2].dim());
162 ss << Op1.
label() <<
"(" << locx1 <<
"," << locy1 <<
")"
163 << Op2.
label() <<
"(" << locx2 <<
"," << locy2 <<
")";
166 for (
size_t l=0; l<B0.size(); ++l) {Mout.
setLocBasis(B0[l].get_basis().combine(B1[l].get_basis()).qloc(),l);}
176 else if (order == 1ul)
184 auto product = factor * OperatorType::prod(Op1Ext, Op2Ext, Qtot);
185 Mout.
setLocal(locx1, product.template plain<double>());
189 Mout.
setLocal({locx1, locx2}, {(factor*Op1Ext).
template plain<double>(), Op2Ext.template plain<double>()});
195template<
typename Symmetry>
196template<
size_t order,
typename Dummy>
198S (
size_t locx,
size_t locy,
double factor)
const
205template<
typename Symmetry>
206template<
size_t order,
typename Dummy>
208Sdag (
size_t locx,
size_t locy,
double factor)
const
215template<
typename Symmetry>
216template<
size_t order,
typename Dummy>
220 bool HERMITIAN = (Sa==
SX or Sa==
SZ)?
true:
false;
222 make_local(locx,locy,
kroneckerProduct(B0[locx].Scomp(Sa,locy), B1[locx].Id()), factor, HERMITIAN):
223 make_local(locx,locy,
kroneckerProduct(B0[locx].Id(), B1[locx].Scomp(Sa,locy)), factor, HERMITIAN);
226template<
typename Symmetry>
227template<
size_t order,
typename Dummy>
232 make_corr<order>(locx1,locx2,locy1,locy2,
233 B0[locx1].Scomp(Sa1,locy1), B0[locx2].Scomp(Sa2,locy2),
235 make_corr<order>(locx1,locx2,locy1,locy2,
236 B1[locx1].Scomp(Sa1,locy1), B1[locx2].Scomp(Sa2,locy2),
240template<
typename Symmetry>
241template<
size_t order,
typename Dummy>
243SdagS (
size_t locx1,
size_t locx2,
size_t locy1,
size_t locy2)
const
245 if constexpr (Symmetry::IS_SPIN_SU2())
248 make_corr<order>(locx1, locx2, locy1, locy2, B0[locx1].Sdag(locy1), B0[locx2].S(locy2), Symmetry::qvacuum(), sqrt(3.),
PROP::HERMITIAN):
249 make_corr<order>(locx1, locx2, locy1, locy2, B1[locx1].Sdag(locy1), B1[locx2].S(locy2), Symmetry::qvacuum(), sqrt(3.),
PROP::HERMITIAN);
253 vector<Mpo<Symmetry> > out(3);
254 out[0] = ScompScomp<order>(
SZ,
SZ,locx1,locx2,locy1,locy2,1.0);
255 out[1] = ScompScomp<order>(
SP,
SM,locx1,locx2,locy1,locy2,0.5);
256 out[2] = ScompScomp<order>(
SM,
SP,locx1,locx2,locy1,locy2,0.5);
261template<
typename Symmetry>
262template<
size_t order,
typename Dummy>
264Stot (
size_t locy,
double factor)
const
266 vector<OperatorType> Ops(B0.size());
267 vector<double> factors(B0.size());
268 for (
int l=0; l<B0.size(); ++l)
272 Ops[l] = B0[l].S(locy);
276 Ops[l] = B1[l].S(locy);
283template<
typename Symmetry>
284template<
size_t order,
typename Dummy>
286Sdagtot (
size_t locy,
double factor)
const
288 vector<OperatorType> Ops(B0.size());
289 vector<double> factors(B0.size());
290 for (
int l=0; l<B0.size(); ++l)
294 Ops[l] = B0[l].Sdag(locy);
298 Ops[l] = B1[l].Sdag(locy);
SiteOperator< Symmetry, Scalar_ > kroneckerProduct(const SiteOperator< Symmetry, Scalar_ > &O1, const SiteOperator< Symmetry, Scalar_ > &O2)
Mpo< Symmetry > make_local(size_t locx, size_t locy, const OperatorType &Op, double factor=1., bool HERMITIAN=false) const
vector< SpinBase< Symmetry, 0ul > > B0
SiteOperatorQ< Symmetry, Eigen::MatrixXd > OperatorType
Mpo< Symmetry > 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) const
DoubleHeisenbergObservables()
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry > >::type S(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry > >::type Sdagtot(size_t locy=0, double factor=1.) const
DoubleHeisenbergObservables(const size_t &L, const vector< Param > ¶ms, const std::map< string, std::any > &defaults)
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry > >::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
DoubleHeisenbergObservables(const size_t &L)
Mpo< Symmetry > make_localSum(const vector< OperatorType > &Op, vector< double > factor, bool HERMITIAN) const
std::conditional< Dummy::IS_SPIN_SU2(), Mpo< Symmetry >, vector< Mpo< Symmetry > > >::type SdagS(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry > >::type Stot(size_t locy=0, double factor=1.) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Symmetry > >::type Scomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Symmetry, 1ul > > B1
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Symmetry > >::type Sdag(size_t locx, size_t locy=0, double factor=std::sqrt(3.)) const
void setLocBasis(const std::vector< std::vector< qType > > &q)
void setLocal(std::size_t loc, const OperatorType &op)
void setLocalSum(const OperatorType &op, Scalar(*f)(int)=localSumTrivial)