VMPS++
Loading...
Searching...
No Matches
VumpsPivotMatrices.h
Go to the documentation of this file.
1#ifndef VUMPSPIVOTSTUFF
2#define VUMPSPIVOTSTUFF
3
5//include "tensors/Biped.h"
6
7
8//-----------<definitions>-----------
9
13template<typename Symmetry, typename Scalar, typename MpoScalar=double>
15{
17
18 // Produces an error with boost::multi_array!
19// PivumpsMatrix (const Matrix<Scalar,Dynamic,Dynamic> &L_input,
20// const Matrix<Scalar,Dynamic,Dynamic> &R_input,
21// const boost::multi_array<MpoScalar,4> &h_input,
22// const vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > &AL_input,
23// const vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > &AR_input)
24// :L(L_input), R(R_input), AL(AL_input), AR(AR_input)
25// {
26// size_t D = h_input.shape()[0];
27// h.resize(boost::extents[D][D][D][D]);
28// h = h_input;
29// }
30
33
34 boost::multi_array<MpoScalar,4> h;
35
36 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > AL;
37 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > AR;
38
39 vector<qarray<Symmetry::Nq> > qloc;
40};
41
45template<typename Symmetry, typename Scalar, typename MpoScalar=double>
47{
49
51 :L(H.L), R(H.R), h(H.h), AL(H.AL), AR(H.AR), qloc(H.qloc)
52 {}
53
56
57 boost::multi_array<MpoScalar,4> h;
58
59 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > AL;
60 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > AR;
61
62 vector<qarray<Symmetry::Nq> > qloc;
63};
64//-----------</definitions>-----------
65
67template<typename Symmetry, typename Scalar, typename MpoScalar>
69{
70 size_t D = H.h.shape()[0];
71
72 Vout.outerResize(Vin);
73 Vout.setZero();
74
75 // term 1 AL
76 for (size_t s1=0; s1<D; ++s1)
77 for (size_t s2=0; s2<D; ++s2)
78 for (size_t s3=0; s3<D; ++s3)
79 for (size_t s4=0; s4<D; ++s4)
80 {
81 if (H.h[s1][s2][s3][s4] != 0.)
82 {
83 for (size_t q1=0; q1<H.AL[s1].dim; ++q1)
84 {
85 auto A2outs = Symmetry::reduceSilent(H.AL[s1].in[q1], H.qloc[s2]);
86 for (const auto &A2out : A2outs)
87 {
88 auto it2 = H.AL[s2].dict.find(qarray2<Symmetry::Nq>{H.AL[s1].in[q1], A2out});
89 if (it2 != H.AL[s2].dict.end())
90 {
91 auto A4outs = Symmetry::reduceSilent(H.AL[s2].out[it2->second], H.qloc[s4]);
92 for (const auto &A4out : A4outs)
93 {
94 auto it4 = Vin.data[s4].dict.find(qarray2<Symmetry::Nq>{H.AL[s2].out[it2->second], A4out});
95 if (it4 != H.AL[s4].dict.end())
96 {
97 Matrix<Scalar,Dynamic,Dynamic> Mtmp;
98 optimal_multiply(H.h[s1][s2][s3][s4],
99 H.AL[s1].block[q1].adjoint(),
100 H.AL[s2].block[it2->second],
101 Vin.data[s4].block[it4->second],
102 Mtmp
103 );
104
105 if (Mtmp.size() != 0)
106 {
107 qarray2<Symmetry::Nq> quple = {H.AL[s1].out[q1], H.AL[s4].out[it4->second]};
108 auto it = Vout.data[s3].dict.find(quple);
109
110 if (it != Vout.data[s3].dict.end())
111 {
112 if (Vout.data[s3].block[it->second].rows() != Mtmp.rows() and
113 Vout.data[s3].block[it->second].cols() != Mtmp.cols())
114 {
115 Vout.data[s3].block[it->second] = Mtmp;
116 }
117 else
118 {
119 Vout.data[s3].block[it->second] += Mtmp;
120 }
121 }
122 else
123 {
124 cout << termcolor::red << "pushback that shouldn't be: PivumpsMatrix1 term 1" << termcolor::reset << endl;
125 Vout.data[s3].push_back(quple, Mtmp);
126 }
127 }
128 }
129 }
130 }
131 }
132 }
133 }
134 }
135
136 // term 2 AR
137 for (size_t s1=0; s1<D; ++s1)
138 for (size_t s2=0; s2<D; ++s2)
139 for (size_t s3=0; s3<D; ++s3)
140 for (size_t s4=0; s4<D; ++s4)
141 {
142 if (H.h[s1][s2][s3][s4] != 0.)
143 {
144 for (size_t q2=0; q2<Vin.data[s2].dim; ++q2)
145 {
146 auto A4outs = Symmetry::reduceSilent(Vin.data[s2].out[q2], H.qloc[s4]);
147 for (const auto &A4out : A4outs)
148 {
149 auto it4 = H.AR[s4].dict.find(qarray2<Symmetry::Nq>{Vin.data[s2].out[q2], A4out});
150 if (it4 != H.AR[s4].dict.end())
151 {
152 auto A3ins = Symmetry::reduceSilent(H.AR[s4].out[it4->second], Symmetry::flip(H.qloc[s3]));
153 for (const auto &A3in : A3ins)
154 {
155 auto it3 = H.AR[s3].dict.find(qarray2<Symmetry::Nq>{A3in, H.AR[s4].out[it4->second]});
156 if (it3 != H.AR[s3].dict.end())
157 {
158 Matrix<Scalar,Dynamic,Dynamic> Mtmp;
159 optimal_multiply(H.h[s1][s2][s3][s4],
160 Vin.data[s2].block[q2],
161 H.AR[s4].block[it4->second],
162 H.AR[s3].block[it3->second].adjoint(),
163 Mtmp
164 );
165
166 if (Mtmp.size() != 0)
167 {
168 qarray2<Symmetry::Nq> quple = {Vin.data[s2].in[q2], H.AR[s3].in[it3->second]};
169 auto it = Vout.data[s1].dict.find(quple);
170
171 if (it != Vout.data[s1].dict.end())
172 {
173 if (Vout.data[s1].block[it->second].rows() != Mtmp.rows() and
174 Vout.data[s1].block[it->second].cols() != Mtmp.cols())
175 {
176 Vout.data[s1].block[it->second] = Mtmp;
177 }
178 else
179 {
180 Vout.data[s1].block[it->second] += Mtmp;
181 }
182 }
183 else
184 {
185 cout << termcolor::red << "pushback that shouldn't be: PivumpsMatrix1 term 2" << termcolor::reset << endl;
186 Vout.data[s1].push_back(quple, Mtmp);
187 }
188 }
189 }
190 }
191 }
192 }
193 }
194 }
195 }
196
197 for (size_t s=0; s<D; ++s)
198 {
199 auto Vtmp = H.L.contract(Vin.data[s]);
200 Vout[s] += Vtmp;
201
202 Vtmp.clear();
203 Vtmp = Vin.data[s].contract(H.R);
204 Vout[s] += Vtmp;
205 }
206}
207
209template<typename Symmetry, typename Scalar, typename MpoScalar>
211{
213 HxV(H,Vinout,Vtmp);
214 Vinout = Vtmp;
215}
216
218template<typename Symmetry, typename Scalar, typename MpoScalar>
220{
221 size_t D = H.h.shape()[0];
222
223 Vout.outerResize(Vin);
224 Vout.setZero();
225
226 // term 1
227 for (size_t s1=0; s1<D; ++s1)
228 for (size_t s2=0; s2<D; ++s2)
229 for (size_t s3=0; s3<D; ++s3)
230 for (size_t s4=0; s4<D; ++s4)
231 {
232 if (H.h[s1][s2][s3][s4] != 0.)
233 {
234 for (size_t q1=0; q1<H.AL[s1].dim; ++q1)
235 {
236 auto A2outs = Symmetry::reduceSilent(H.AL[s1].in[q1], H.qloc[s2]);
237 for (const auto &A2out : A2outs)
238 {
239 qarray2<Symmetry::Nq> qupleC = {A2out, A2out};
240 auto itC = Vin.data[0].dict.find(qupleC);
241 auto it2 = H.AL[s2].dict.find(qarray2<Symmetry::Nq>{H.AL[s1].in[q1], A2out});
242
243 if (it2 != H.AL[s2].dict.end() and itC != Vin.data[0].dict.end())
244 {
245 auto A4outs = Symmetry::reduceSilent(H.AL[s2].out[it2->second], H.qloc[s4]);
246 for (const auto &A4out : A4outs)
247 {
248 auto it4 = H.AR[s4].dict.find(qarray2<Symmetry::Nq>{H.AL[s2].out[it2->second], A4out});
249 if (it4 != H.AR[s4].dict.end())
250 {
251 auto A3ins = Symmetry::reduceSilent(H.AR[s4].out[it4->second], Symmetry::flip(H.qloc[s3]));
252 for (const auto &A3in : A3ins)
253 {
254 auto it3 = H.AR[s3].dict.find(qarray2<Symmetry::Nq>{A3in, H.AR[s4].out[it4->second]});
255 if (it3 != H.AR[s3].dict.end())
256 {
257 Matrix<Scalar,Dynamic,Dynamic> Mtmp;
258 Mtmp = H.h[s1][s2][s3][s4] *
259 H.AL[s1].block[q1].adjoint() *
260 H.AL[s2].block[it2->second] *
261 Vin.data[0].block[itC->second] *
262 H.AR[s4].block[it4->second] *
263 H.AR[s3].block[it3->second].adjoint();
264
265 if (Mtmp.size() != 0)
266 {
267 qarray2<Symmetry::Nq> quple = {H.AL[s1].out[q1], H.AR[s3].in[it3->second]};
268 auto it = Vout.data[0].dict.find(quple);
269
270 if (it != Vout.data[0].dict.end())
271 {
272 if (Vout.data[0].block[it->second].rows() != Mtmp.rows() and
273 Vout.data[0].block[it->second].cols() != Mtmp.cols())
274 {
275 Vout.data[0].block[it->second] = Mtmp;
276 }
277 else
278 {
279 Vout.data[0].block[it->second] += Mtmp;
280 }
281 }
282 else
283 {
284 cout << termcolor::red << "pushback that shouldn't be: HxC term 1" << termcolor::reset << endl;
285 cout << "q=" << quple[0] << ", " << quple[1] << endl;
286 Vout.data[0].push_back(quple, Mtmp);
287 }
288 }
289 }
290 }
291 }
292 }
293 }
294 }
295 }
296 }
297 }
298
299 // term 2 HL
300 auto Vtmp = H.L.contract(Vin.data[0]);
301 Vout.data[0] += Vtmp;
302
303 // term 2 HR
304 Vtmp.clear();
305 Vtmp = Vin.data[0].contract(H.R);
306 Vout.data[0] += Vtmp;
307}
308
310template<typename Symmetry, typename Scalar, typename MpoScalar>
312{
314 HxV(H,Vinout,Vtmp);
315 Vinout = Vtmp;
316}
317
318template<typename Symmetry, typename Scalar, typename MpoScalar>
320{
321 return 0;
322}
323
324// How to calculate the Frobenius norm of this?
325template<typename Symmetry, typename Scalar, typename MpoScalar>
327{
328 return 0;
329}
330
331template<typename Symmetry, typename Scalar, typename MpoScalar>
333{
334 return 0;
335}
336
337// How to calculate the Frobenius norm of this?
338template<typename Symmetry, typename Scalar, typename MpoScalar>
340{
341 return 0;
342}
343
344#endif
void optimal_multiply(Scalar alpha, const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, MatrixTypeR &result, bool DEBUG=false)
Definition: DmrgExternal.h:191
double norm(const PivumpsMatrix1< Symmetry, Scalar, MpoScalar > &H)
void HxV(const PivumpsMatrix1< Symmetry, Scalar, MpoScalar > &H, const PivotVector< Symmetry, Scalar > &Vin, PivotVector< Symmetry, Scalar > &Vout)
size_t dim(const PivumpsMatrix1< Symmetry, Scalar, MpoScalar > &H)
std::array< qarray< Nq >, 2 > qarray2
Definition: qarray.h:51
Definition: Biped.h:64
Biped< Symmetry, MatrixType_ > contract(const Biped< Symmetry, MatrixType_ > &A, const contract::MODE MODE=contract::MODE::UNITY) const
Definition: Biped.h:976
void outerResize(const PivotVector &Vrhs)
vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > data
vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > AR
boost::multi_array< MpoScalar, 4 > h
vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > AL
PivumpsMatrix0(const PivumpsMatrix1< Symmetry, Scalar, MpoScalar > &H)
vector< qarray< Symmetry::Nq > > qloc
Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > R
Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > L
vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > AR
Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > R
Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > L
boost::multi_array< MpoScalar, 4 > h
vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > AL
vector< qarray< Symmetry::Nq > > qloc