Xped
Loading...
Searching...
No Matches
TwoSiteObservable.hpp
Go to the documentation of this file.
1#ifndef XPED_TWO_SITE_OBSERVABLE_HPP_
2#define XPED_TWO_SITE_OBSERVABLE_HPP_
3
4#include "fmt/core.h"
5
6#include <highfive/H5DataSpace.hpp>
7
9#include "Xped/PEPS/Bonds.hpp"
10#include "Xped/PEPS/CTMOpts.hpp"
13#include "Xped/PEPS/TMatrix.hpp"
14
15namespace Xped {
16
17template <typename, typename, std::size_t, bool, Opts::CTMCheckpoint>
18class CTM;
19
20template <typename Scalar, typename Symmetry, bool HERMITIAN = true>
22{
23 using ObsScalar = std::conditional_t<HERMITIAN, typename ScalarTraits<Scalar>::Real, typename ScalarTraits<Scalar>::Comp>;
24
25 TwoSiteObservable() = default;
26
27 /*
28 x,y: O_h(x,y; x+1,y)
29 x,y: O_v(x,y; x,y+1)
30 x,y: O_d1(x,y; x+1,y+1)
31 x,y: O_d2(x,y; x-1,y+1)
32 */
33 TwoSiteObservable(const Pattern& pat, Opts::Bond bond, const std::string& name_in = "")
34 : ObservableBase(name_in)
35 , bond(bond)
36 {
40 }
44 }
48 }
52 }
53 }
54
56 {
57 if(std::all_of(charges.cbegin(), charges.cend(), [](auto c) { return c == Symmetry::qvacuum(); })) { return *this; }
59 for(int x = 0; x < data_h.pat.Lx; ++x) {
60 for(int y = 0; y < data_h.pat.Ly; ++y) {
61 if(not data_h.pat.isUnique(x, y)) { continue; }
63 // out.data_h(x, y) = data_h(x, y).template shiftQN<0, 2>(charges(x, y)).template shiftQN<1, 3>(charges(x + 1, y));
64 // out.data_h(x, y) =
65 // data_h(x, y).template shiftQN<0, 1, 2, 3>(std::array{charges(x, y), charges(x + 1, y), charges(x, y), charges(x + 1, y)});
67 c1.push_back(charges(x, y), 1);
69 c2.push_back(charges(x + 1, y), 1);
70 Tensor<Scalar, 2, 2, Symmetry> id({{c1, c2}}, {{c1, c2}});
71 id.setIdentity();
72 auto tmp = data_h(x, y).template contract<std::array{-1, -3, -5, -7}, std::array{-2, -4, -6, -8}, 4>(id);
73 Tensor<Scalar, 2, 1, Symmetry> fuser1({{data_h(x, y).uncoupledCodomain()[0], c1}},
74 {{data_h(x, y).uncoupledCodomain()[0].combine(c1).forgetHistory()}});
75 fuser1.setIdentity();
76 Tensor<Scalar, 2, 1, Symmetry> fuser2({{data_h(x, y).uncoupledCodomain()[1], c2}},
77 {{data_h(x, y).uncoupledCodomain()[1].combine(c2).forgetHistory()}});
78 fuser2.setIdentity();
79 out.data_h(x, y) =
80 tmp.template contract<std::array{-1, -2, -3, -4, 1, 2, -6, -7}, std::array{1, 2, -5}, 4>(fuser1)
81 .template contract<std::array{-1, -2, -3, -4, -5, 1, 2}, std::array{1, 2, -6}, 4>(fuser2)
82 .template contract<std::array{1, 2, -2, -3, -4, -5}, std::array{-1, 1, 2}, 3>(fuser1.adjoint().eval().twist(1).twist(2))
83 .template contract<std::array{-1, 1, 2, -3, -4}, std::array{-2, 1, 2}, 2>(fuser2.adjoint().eval().twist(1).twist(2));
84 }
86 // out.data_v(x, y) = data_v(x, y).template shiftQN<0, 2>(charges(x, y)).template shiftQN<1, 3>(charges(x, y + 1));
87 // out.data_v(x, y) =
88 // data_v(x, y).template shiftQN<0, 1, 2, 3>(std::array{charges(x, y), charges(x, y + 1), charges(x, y), charges(x, y + 1)});
90 c1.push_back(charges(x, y), 1);
92 c2.push_back(charges(x, y + 1), 1);
93 Tensor<Scalar, 2, 2, Symmetry> id({{c1, c2}}, {{c1, c2}});
94 id.setIdentity();
95 auto tmp = data_v(x, y).template contract<std::array{-1, -3, -5, -7}, std::array{-2, -4, -6, -8}, 4>(id);
96 Tensor<Scalar, 2, 1, Symmetry> fuser1({{data_v(x, y).uncoupledCodomain()[0], c1}},
97 {{data_v(x, y).uncoupledCodomain()[0].combine(c1).forgetHistory()}});
98 fuser1.setIdentity();
99 Tensor<Scalar, 2, 1, Symmetry> fuser2({{data_v(x, y).uncoupledCodomain()[1], c2}},
100 {{data_v(x, y).uncoupledCodomain()[1].combine(c2).forgetHistory()}});
101 fuser2.setIdentity();
102 out.data_v(x, y) =
103 tmp.template contract<std::array{-1, -2, -3, -4, 1, 2, -6, -7}, std::array{1, 2, -5}, 4>(fuser1)
104 .template contract<std::array{-1, -2, -3, -4, -5, 1, 2}, std::array{1, 2, -6}, 4>(fuser2)
105 .template contract<std::array{1, 2, -2, -3, -4, -5}, std::array{-1, 1, 2}, 3>(fuser1.adjoint().eval().twist(1).twist(2))
106 .template contract<std::array{-1, 1, 2, -3, -4}, std::array{-2, 1, 2}, 2>(fuser2.adjoint().eval().twist(1).twist(2));
107 }
109 // out.data_d1(x,y) = data_d1(x, y).template shiftQN<0, 1, 2, 3>(
110 // std::array{charges(x, y), charges(x + 1, y + 1), charges(x, y), charges(x + 1, y + 1)});
112 c1.push_back(charges(x, y), 1);
114 c2.push_back(charges(x + 1, y + 1), 1);
115 Tensor<Scalar, 2, 2, Symmetry> id({{c1, c2}}, {{c1, c2}});
116 id.setIdentity();
117 auto tmp = data_d1(x, y).template contract<std::array{-1, -3, -5, -7}, std::array{-2, -4, -6, -8}, 4>(id);
118 Tensor<Scalar, 2, 1, Symmetry> fuser1({{data_d1(x, y).uncoupledCodomain()[0], c1}},
119 {{data_d1(x, y).uncoupledCodomain()[0].combine(c1).forgetHistory()}});
120 fuser1.setIdentity();
121 Tensor<Scalar, 2, 1, Symmetry> fuser2({{data_d1(x, y).uncoupledCodomain()[1], c2}},
122 {{data_d1(x, y).uncoupledCodomain()[1].combine(c2).forgetHistory()}});
123 fuser2.setIdentity();
124 out.data_d1(x, y) =
125 tmp.template contract<std::array{-1, -2, -3, -4, 1, 2, -6, -7}, std::array{1, 2, -5}, 4>(fuser1)
126 .template contract<std::array{-1, -2, -3, -4, -5, 1, 2}, std::array{1, 2, -6}, 4>(fuser2)
127 .template contract<std::array{1, 2, -2, -3, -4, -5}, std::array{-1, 1, 2}, 3>(fuser1.adjoint().eval().twist(1).twist(2))
128 .template contract<std::array{-1, 1, 2, -3, -4}, std::array{-2, 1, 2}, 2>(fuser2.adjoint().eval().twist(1).twist(2));
129 }
131 // out.data_d2(x, y) = data_d2(x, y).template shiftQN<0, 1, 2, 3>(
132 // std::array{charges(x, y), charges(x - 1, y + 1), charges(x, y), charges(x - 1, y + 1)});
134 c1.push_back(charges(x, y), 1);
136 c2.push_back(charges(x - 1, y + 1), 1);
137 Tensor<Scalar, 2, 2, Symmetry> id({{c1, c2}}, {{c1, c2}});
138 id.setIdentity();
139 auto tmp = data_d2(x, y).template contract<std::array{-1, -3, -5, -7}, std::array{-2, -4, -6, -8}, 4>(id);
140 Tensor<Scalar, 2, 1, Symmetry> fuser1({{data_d2(x, y).uncoupledCodomain()[0], c1}},
141 {{data_d2(x, y).uncoupledCodomain()[0].combine(c1).forgetHistory()}});
142 fuser1.setIdentity();
143 Tensor<Scalar, 2, 1, Symmetry> fuser2({{data_d2(x, y).uncoupledCodomain()[1], c2}},
144 {{data_d2(x, y).uncoupledCodomain()[1].combine(c2).forgetHistory()}});
145 fuser2.setIdentity();
146 out.data_d2(x, y) =
147 tmp.template contract<std::array{-1, -2, -3, -4, 1, 2, -6, -7}, std::array{1, 2, -5}, 4>(fuser1)
148 .template contract<std::array{-1, -2, -3, -4, -5, 1, 2}, std::array{1, 2, -6}, 4>(fuser2)
149 .template contract<std::array{1, 2, -2, -3, -4, -5}, std::array{-1, 1, 2}, 3>(fuser1.adjoint().eval().twist(1).twist(2))
150 .template contract<std::array{-1, 1, 2, -3, -4}, std::array{-2, 1, 2}, 2>(fuser2.adjoint().eval().twist(1).twist(2));
151 }
152 }
153 }
154 return out;
155 }
156
157 void loadFromMatlab(const std::filesystem::path& p, const std::string& root_name, int qn_scale = 1)
158 {
159 HighFive::File file(p.string(), HighFive::File::ReadOnly);
160 auto root = file.getGroup(root_name);
161
162 UnitCell cell;
163 cell.loadFromMatlab(p, root_name);
164
165 // if((bond & Opts::Bond::H) == Opts::Bond::H) {
168 // }
169 // if((bond & Opts::Bond::V) == Opts::Bond::V) {
172 // }
173 // if((bond & Opts::Bond::D1) == Opts::Bond::D1) {
174 // data_d1 = TMatrix<Tensor<double, 2, 2, Symmetry, false>>(pat);
175 // obs_d1 = TMatrix<double>(pat);
176 // }
177 // if((bond & Opts::Bond::D2) == Opts::Bond::D2) {
178 // data_d2 = TMatrix<Tensor<double, 2, 2, Symmetry, false>>(pat);
179 // obs_d2 = TMatrix<double>(pat);
180 // }
181
182 for(std::size_t i = 0; i < cell.pattern.uniqueSize(); ++i) {
183 auto H_ref = root.getDataSet("H");
184 std::vector<HighFive::Reference> H;
185 H_ref.read(H);
186 auto g_Hh = H[2 * i].template dereference<HighFive::Group>(root);
187 auto g_Hv = H[2 * i + 1].template dereference<HighFive::Group>(root);
188 data_h[i] =
189 Xped::IO::loadMatlabTensor<Scalar, 4, 0, Symmetry, Xped::HeapPolicy>(g_Hh, root, std::array{false, false, true, true}, qn_scale)
190 .template permute<2, 0, 1, 2, 3>();
191 data_v[i] =
192 Xped::IO::loadMatlabTensor<Scalar, 4, 0, Symmetry, Xped::HeapPolicy>(g_Hv, root, std::array{false, false, true, true}, qn_scale)
193 .template permute<2, 0, 1, 2, 3>();
194 }
195 fmt::print("Loaded hamiltonian from matlab.\n");
196 }
197
198 virtual std::string getResString(const std::string& offset) const override
199 {
200 std::string res;
201 if((bond & Opts::Bond::H) == Opts::Bond::H) {
202 fmt::format_to(std::back_inserter(res),
203 "{}{:<10}: avg_h={:+.2f}, vals_h={::+.4f}\n",
204 offset,
205 this->name,
206 obs_h.sum() / static_cast<ObsScalar>(obs_h.size()),
208 }
209 if((bond & Opts::Bond::V) == Opts::Bond::V) {
210 fmt::format_to(std::back_inserter(res),
211 "{}{:<10}: avg_v={:+.2f}, vals_v={::+.4f}\n",
212 offset,
213 this->name,
214 obs_v.sum() / static_cast<ObsScalar>(obs_v.size()),
216 }
218 fmt::format_to(std::back_inserter(res),
219 "{}{:<10}: avg_d1={:+.2f}, vals_d1={::+.4f}\n",
220 offset,
221 this->name,
222 obs_d1.sum() / static_cast<ObsScalar>(obs_d1.size()),
224 }
226 fmt::format_to(std::back_inserter(res),
227 "{}{:<10}: avg_d2={:+.2f}, vals_d2={::+.4f}",
228 offset,
229 this->name,
230 obs_d2.sum() / static_cast<ObsScalar>(obs_d2.size()),
232 }
233 return res;
234 }
235
236 virtual void toFile(HighFive::File& file, const std::string& root = "/") const override
237 {
238 auto write_component = [&file, &root](std::string name, const auto& o) {
239 if(not file.exist(root + name)) {
240 HighFive::DataSpace dataspace = HighFive::DataSpace({0, 0}, {HighFive::DataSpace::UNLIMITED, HighFive::DataSpace::UNLIMITED});
241
242 // Use chunking
243 HighFive::DataSetCreateProps props;
244 props.add(HighFive::Chunking(std::vector<hsize_t>{2, 2}));
245
246 // Create the dataset
247 HighFive::DataSet dataset = file.createDataSet(root + name, dataspace, HighFive::create_datatype<ObsScalar>(), props);
248 }
249 auto d = file.getDataSet(root + name);
250 std::vector<std::vector<ObsScalar>> data;
251 data.push_back(o.uncompressedVector());
252 std::size_t curr_size = d.getDimensions()[0];
253 d.resize({curr_size + 1, data[0].size()});
254 d.select({curr_size, 0}, {1, data[0].size()}).write(data);
255 };
256 if((bond & Opts::Bond::H) == Opts::Bond::H) { write_component(this->name + "_h", obs_h); }
257 if((bond & Opts::Bond::V) == Opts::Bond::V) { write_component(this->name + "_v", obs_v); }
258 if((bond & Opts::Bond::D1) == Opts::Bond::D1) { write_component(this->name + "_d1", obs_d1); }
259 if((bond & Opts::Bond::D2) == Opts::Bond::D2) { write_component(this->name + "_d2", obs_d2); }
260 }
261
262 virtual void setDefaultObs() {}
263
264 virtual void computeObs(XPED_CONST CTM<double, Symmetry, 2, false, Opts::CTMCheckpoint{}>& env) {}
265 virtual void computeObs(XPED_CONST CTM<std::complex<double>, Symmetry, 2, false, Opts::CTMCheckpoint{}>& env) {}
266 virtual void computeObs(XPED_CONST CTM<double, Symmetry, 1, false, Opts::CTMCheckpoint{}>& env) {}
267
268 virtual std::string getObsString(const std::string&) const { return ""; }
269
270 virtual void obsToFile(HighFive::File&, const std::string& = "/") const {}
271
272 template <typename Ar>
273 void serialize(Ar& ar)
274 {
275 ar& YAS_OBJECT_NVP("TwoSiteobservable",
276 ("data_h", data_h),
277 ("data_v", data_v),
278 ("data_d1", data_d1),
279 ("data_d2", data_d2),
280 ("obs_h", obs_h),
281 ("obs_v", obs_v),
282 ("obs_d1", obs_d1),
283 ("obs_d2", obs_d2),
284 ("bond", bond));
285 }
286
296};
297
298} // namespace Xped
299
300#endif
Definition: CTM.hpp:62
Definition: Qbasis.hpp:39
void push_back(const qType &q, const size_t &inner_dim)
Definition: Qbasis.cpp:32
Definition: Tensor.hpp:40
Bond
Definition: Bonds.hpp:10
Definition: bench.cpp:62
Definition: ObservableBase.hpp:11
std::string name
Definition: ObservableBase.hpp:24
Definition: CTMOpts.hpp:96
Definition: Pattern.hpp:18
std::size_t uniqueSize() const
Definition: Pattern.hpp:43
Definition: ScalarTraits.hpp:10
Definition: TMatrix.hpp:13
Ttype sum() const
Definition: TMatrix.hpp:77
auto cbegin() const
Definition: TMatrix.hpp:70
std::size_t size() const
Definition: TMatrix.hpp:38
std::vector< Ttype > uncompressedVector() const
Definition: TMatrix.hpp:85
auto cend() const
Definition: TMatrix.hpp:71
Definition: TwoSiteObservable.hpp:22
virtual void computeObs(XPED_CONST CTM< double, Symmetry, 1, false, Opts::CTMCheckpoint{}> &env)
Definition: TwoSiteObservable.hpp:266
TwoSiteObservable< Scalar, Symmetry, HERMITIAN > shiftQN(const TMatrix< typename Symmetry::qType > &charges) const
Definition: TwoSiteObservable.hpp:55
TMatrix< ObsScalar > obs_d1
Definition: TwoSiteObservable.hpp:293
TMatrix< Tensor< Scalar, 2, 2, Symmetry, false > > data_h
Definition: TwoSiteObservable.hpp:287
TwoSiteObservable(const Pattern &pat, Opts::Bond bond, const std::string &name_in="")
Definition: TwoSiteObservable.hpp:33
virtual std::string getResString(const std::string &offset) const override
Definition: TwoSiteObservable.hpp:198
virtual void computeObs(XPED_CONST CTM< std::complex< double >, Symmetry, 2, false, Opts::CTMCheckpoint{}> &env)
Definition: TwoSiteObservable.hpp:265
virtual std::string getObsString(const std::string &) const
Definition: TwoSiteObservable.hpp:268
void serialize(Ar &ar)
Definition: TwoSiteObservable.hpp:273
void loadFromMatlab(const std::filesystem::path &p, const std::string &root_name, int qn_scale=1)
Definition: TwoSiteObservable.hpp:157
TMatrix< Tensor< Scalar, 2, 2, Symmetry, false > > data_v
Definition: TwoSiteObservable.hpp:288
TMatrix< Tensor< Scalar, 2, 2, Symmetry, false > > data_d1
Definition: TwoSiteObservable.hpp:289
TMatrix< ObsScalar > obs_v
Definition: TwoSiteObservable.hpp:292
Opts::Bond bond
Definition: TwoSiteObservable.hpp:295
TMatrix< ObsScalar > obs_h
Definition: TwoSiteObservable.hpp:291
std::conditional_t< HERMITIAN, typename ScalarTraits< Scalar >::Real, typename ScalarTraits< Scalar >::Comp > ObsScalar
Definition: TwoSiteObservable.hpp:23
virtual void computeObs(XPED_CONST CTM< double, Symmetry, 2, false, Opts::CTMCheckpoint{}> &env)
Definition: TwoSiteObservable.hpp:264
virtual void setDefaultObs()
Definition: TwoSiteObservable.hpp:262
TMatrix< ObsScalar > obs_d2
Definition: TwoSiteObservable.hpp:294
virtual void toFile(HighFive::File &file, const std::string &root="/") const override
Definition: TwoSiteObservable.hpp:236
virtual void obsToFile(HighFive::File &, const std::string &="/") const
Definition: TwoSiteObservable.hpp:270
TMatrix< Tensor< Scalar, 2, 2, Symmetry, false > > data_d2
Definition: TwoSiteObservable.hpp:290
Definition: UnitCell.hpp:15
Pattern pattern
Definition: UnitCell.hpp:27
void loadFromMatlab(const std::filesystem::path &p, const std::string &root_name)
Definition: UnitCell.cpp:26