VMPS++
Loading...
Searching...
No Matches
DoubleHeisenbergObservables.h
Go to the documentation of this file.
1#ifndef DOUBLEHEISENBERGOBSERVABLES
2#define DOUBLEHEISENBERGOBSERVABLES
3
4#include "Mpo.h"
5#include "ParamHandler.h" // from HELPERS
6#include "bases/SpinBase.h"
7//include "DmrgLinearAlgebra.h"
8//include "DmrgExternal.h"
9
10template<typename Symmetry>
12{
14
15public:
16
19 DoubleHeisenbergObservables (const size_t &L); // for inheritance purposes
20 DoubleHeisenbergObservables (const size_t &L, const vector<Param> &params, const std::map<string,std::any> &defaults);
22
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;
27
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;
31
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;
35
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;
39
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;
43
44 template<size_t order = 0ul, typename Dummy = Symmetry>
45 typename std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type
46 Scomp (SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const;
47
48 template<size_t order = 0ul, typename Dummy = Symmetry>
49 typename std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type
50 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;
52
53protected:
54
55 Mpo<Symmetry> make_local (size_t locx, size_t locy,
56 const OperatorType &Op,
57 double factor =1.,
58 bool HERMITIAN=false) const;
59 template<size_t order=0ul> Mpo<Symmetry> make_localSum (const vector<OperatorType> &Op, vector<double> factor, bool HERMITIAN) const;
60 template<size_t order=0ul> Mpo<Symmetry> make_corr (size_t locx1, size_t locx2, size_t locy1, size_t locy2,
61 const OperatorType &Op1, const OperatorType &Op2, qarray<Symmetry::Nq> Qtot,
62 double factor, bool HERMITIAN) const;
63
64// Mpo<Symmetry,complex<double> >
65// make_FourierYSum (string name, const vector<OperatorType> &Ops, double factor, bool HERMITIAN, const vector<complex<double> > &phases) const;
66//
67// typename Symmetry::qType getQ_ScompScomp(SPINOP_LABEL Sa1, SPINOP_LABEL Sa2) const;
68
69 vector<SpinBase<Symmetry,0ul>> B0;
70 vector<SpinBase<Symmetry,1ul>> B1;
71};
72
73template<typename Symmetry>
75DoubleHeisenbergObservables (const size_t &L)
76{
77 B0.resize(L);
78 B1.resize(L);
79}
80
81template<typename Symmetry>
83DoubleHeisenbergObservables (const size_t &L, const vector<Param> &params, const std::map<string,std::any> &defaults)
84{
85 ParamHandler P(params,defaults);
86 size_t Lcell = P.size();
87 B0.resize(L);
88 B1.resize(L);
89
90 for (size_t l=0; l<L; ++l)
91 {
92 B0[l] = SpinBase<Symmetry,0ul>(P.get<size_t>("Ly",l%Lcell), P.get<size_t>("D",l%Lcell));
93 B1[l] = SpinBase<Symmetry,1ul>(P.get<size_t>("Ly",l%Lcell), P.get<size_t>("D",l%Lcell));
94 }
95}
96
97template<typename Symmetry>
99make_local (size_t locx, size_t locy, const OperatorType &Op, double factor, bool HERMITIAN) const
100{
101 assert(locx<B0.size() and locy<B0[locx].dim());
102 stringstream ss;
103 ss << Op.label() << "(" << locx << "," << locy;
104 if (factor != 1.) ss << ",factor=" << factor;
105 ss << ")";
106
107 Mpo<Symmetry> Mout(B0.size(), Op.Q(), ss.str(), HERMITIAN);
108 for (size_t l=0; l<B0.size(); ++l) {Mout.setLocBasis(B0[l].get_basis().combine(B1[l].get_basis()).qloc(),l);}
109
110 Mout.setLocal(locx, (factor * Op).template plain<double>());
111
112 return Mout;
113}
114
115template<typename Symmetry>
116template<size_t order>
118make_localSum (const vector<OperatorType> &Op, vector<double> factor, bool HERMITIAN) const
119{
120 assert(Op.size()==B0.size() and factor.size()==B0.size());
121 stringstream ss;
122 ss << Op[0].label() << "localSum";
123
124 vector<OperatorType> OpExt(Op.size());
125 for (int i=0; i<Op.size(); ++i)
126 {
127 if (order == 0ul)
128 {
129 OpExt[i] = kroneckerProduct(Op[i], B1[i].Id());
130 }
131 else if (order == 1ul)
132 {
133 OpExt[i] = kroneckerProduct(B0[i].Id(), Op[i]);
134 }
135 }
136
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);}
139
140 vector<SiteOperator<Symmetry,double>> Op_plain;
141 for (int i=0; i<Op.size(); ++i)
142 {
143 Op_plain.push_back(OpExt[i].template plain<double>());
144 }
145 Mout.setLocalSum(Op_plain, factor);
146
147 return Mout;
148}
149
150template<typename Symmetry>
151template<size_t order>
153make_corr (size_t locx1, size_t locx2, size_t locy1, size_t locy2,
154 const OperatorType &Op1, const OperatorType &Op2,
156 double factor, bool HERMITIAN) const
157{
158 assert(locx1<B0.size() and locy1<B0[locx1].dim());
159 assert(locx2<B0.size() and locy2<B0[locx2].dim());
160
161 stringstream ss;
162 ss << Op1.label() << "(" << locx1 << "," << locy1 << ")"
163 << Op2.label() << "(" << locx2 << "," << locy2 << ")";
164
165 Mpo<Symmetry> Mout(B0.size(), Qtot, ss.str(), HERMITIAN);
166 for (size_t l=0; l<B0.size(); ++l) {Mout.setLocBasis(B0[l].get_basis().combine(B1[l].get_basis()).qloc(),l);}
167
168 OperatorType Op1Ext;
169 OperatorType Op2Ext;
170
171 if (order == 0ul)
172 {
173 Op1Ext = kroneckerProduct(Op1, B1[locx1].Id());
174 Op2Ext = kroneckerProduct(Op2, B1[locx2].Id());
175 }
176 else if (order == 1ul)
177 {
178 Op1Ext = kroneckerProduct(B0[locx1].Id(), Op1);
179 Op2Ext = kroneckerProduct(B0[locx2].Id(), Op2);
180 }
181
182 if (locx1 == locx2)
183 {
184 auto product = factor * OperatorType::prod(Op1Ext, Op2Ext, Qtot);
185 Mout.setLocal(locx1, product.template plain<double>());
186 }
187 else
188 {
189 Mout.setLocal({locx1, locx2}, {(factor*Op1Ext).template plain<double>(), Op2Ext.template plain<double>()});
190 }
191
192 return Mout;
193}
194
195template<typename Symmetry>
196template<size_t order, typename Dummy>
197typename std::enable_if<Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type DoubleHeisenbergObservables<Symmetry>::
198S (size_t locx, size_t locy, double factor) const
199{
200 return (order==0ul)?
201 make_local(locx,locy, kroneckerProduct(B0[locx].S(locy),B1[locx].Id()), factor, PROP::NON_HERMITIAN):
202 make_local(locx,locy, kroneckerProduct(B0[locx].Id(),B1[locx].S(locy)), factor, PROP::NON_HERMITIAN);
203}
204
205template<typename Symmetry>
206template<size_t order, typename Dummy>
207typename std::enable_if<Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type DoubleHeisenbergObservables<Symmetry>::
208Sdag (size_t locx, size_t locy, double factor) const
209{
210 return (order==0ul)?
211 make_local(locx,locy, kroneckerProduct(B0[locx].Sdag(locy),B1[locx].Id()), factor, PROP::NON_HERMITIAN):
212 make_local(locx,locy, kroneckerProduct(B1[locx].Id(),B0[locx].Sdag(locy)), factor, PROP::NON_HERMITIAN);
213}
214
215template<typename Symmetry>
216template<size_t order, typename Dummy>
217typename std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type DoubleHeisenbergObservables<Symmetry>::
218Scomp (SPINOP_LABEL Sa, size_t locx, size_t locy, double factor) const
219{
220 bool HERMITIAN = (Sa==SX or Sa==SZ)? true:false;
221 return (order==0ul)?
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);
224}
225
226template<typename Symmetry>
227template<size_t order, typename Dummy>
228typename std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type DoubleHeisenbergObservables<Symmetry>::
229ScompScomp (SPINOP_LABEL Sa1, SPINOP_LABEL Sa2, size_t locx1, size_t locx2, size_t locy1, size_t locy2, double fac) const
230{
231 return (order==0ul)?
232 make_corr<order>(locx1,locx2,locy1,locy2,
233 B0[locx1].Scomp(Sa1,locy1), B0[locx2].Scomp(Sa2,locy2),
234 Symmetry::qvacuum(), fac, PROP::HERMITIAN):
235 make_corr<order>(locx1,locx2,locy1,locy2,
236 B1[locx1].Scomp(Sa1,locy1), B1[locx2].Scomp(Sa2,locy2),
237 Symmetry::qvacuum(), fac, PROP::HERMITIAN);
238}
239
240template<typename Symmetry>
241template<size_t order, typename Dummy>
242typename std::conditional<Dummy::IS_SPIN_SU2(), Mpo<Symmetry>, vector<Mpo<Symmetry> > >::type DoubleHeisenbergObservables<Symmetry>::
243SdagS (size_t locx1, size_t locx2, size_t locy1, size_t locy2) const
244{
245 if constexpr (Symmetry::IS_SPIN_SU2())
246 {
247 return (order==0ul)?
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);
250 }
251 else
252 {
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);
257 return out;
258 }
259}
260
261template<typename Symmetry>
262template<size_t order, typename Dummy>
263typename std::enable_if<Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type DoubleHeisenbergObservables<Symmetry>::
264Stot (size_t locy, double factor) const
265{
266 vector<OperatorType> Ops(B0.size());
267 vector<double> factors(B0.size());
268 for (int l=0; l<B0.size(); ++l)
269 {
270 if (order==0)
271 {
272 Ops[l] = B0[l].S(locy);
273 }
274 else
275 {
276 Ops[l] = B1[l].S(locy);
277 }
278 factors[l] = factor;
279 }
280 return make_localSum<order>(Ops, factors, PROP::NON_HERMITIAN);
281}
282
283template<typename Symmetry>
284template<size_t order, typename Dummy>
285typename std::enable_if<Dummy::IS_SPIN_SU2(), Mpo<Symmetry> >::type DoubleHeisenbergObservables<Symmetry>::
286Sdagtot (size_t locy, double factor) const
287{
288 vector<OperatorType> Ops(B0.size());
289 vector<double> factors(B0.size());
290 for (int l=0; l<B0.size(); ++l)
291 {
292 if (order==0)
293 {
294 Ops[l] = B0[l].Sdag(locy);
295 }
296 else
297 {
298 Ops[l] = B1[l].Sdag(locy);
299 }
300 factors[l] = factor;
301 }
302 return make_localSum<order>(Ops, factors, PROP::NON_HERMITIAN);
303}
304
305#endif
SPINOP_LABEL
Definition: DmrgTypedefs.h:60
@ SZ
Definition: DmrgTypedefs.h:60
@ SP
Definition: DmrgTypedefs.h:60
@ SX
Definition: DmrgTypedefs.h:60
@ SM
Definition: DmrgTypedefs.h:60
SiteOperator< Symmetry, Scalar_ > kroneckerProduct(const SiteOperator< Symmetry, Scalar_ > &O1, const SiteOperator< Symmetry, Scalar_ > &O2)
Definition: SiteOperator.h:164
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
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 > &params, 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
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)
Definition: MpoTerms.h:715
Definition: Mpo.h:40
void setLocal(std::size_t loc, const OperatorType &op)
void setLocalSum(const OperatorType &op, Scalar(*f)(int)=localSumTrivial)
std::string & label()
const bool NON_HERMITIAN
Definition: DmrgTypedefs.h:493
const bool HERMITIAN
Definition: DmrgTypedefs.h:492
Definition: qarray.h:26