VMPS++
Loading...
Searching...
No Matches
VumpsContractions.h
Go to the documentation of this file.
1#ifndef VANILLA_VUMPSCONTRACTIONS
2#define VANILLA_VUMPSCONTRACTIONS
3
5#include "boost/multi_array.hpp"
7
9//include "VUMPS/Umps.h"
11//include "Mpo.h"
12#include "ArnoldiSolver.h" // from ALGS
13#include "Mpo.h"
14
15template<typename Symmetry, typename Scalar>
16Eigenstate<Biped<Symmetry,Matrix<complex<Scalar>,Dynamic,Dynamic> > >
18 const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &Abra,
19 const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &Aket,
20 const Qbasis<Symmetry> &basisBra,
21 const Qbasis<Symmetry> &basisKet,
22 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
23 size_t dimK = 100ul,
24 double tol_input = 1e-12,
25 Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > *LReigenTop= NULL)
26{
27 TransferMatrix<Symmetry,Scalar> T(DIR, Abra, Aket, qloc);
28
29 if (LReigenTop != NULL)
30 {
31 T.TopEigvec = *LReigenTop;
32 T.TopEigval = 1.;
33 T.PROJECT_OUT_TOPEIGVEC = true;
34 }
35
37 if (DIR == VMPS::DIRECTION::LEFT)
38 {
39 LRtmp.data.setIdentity(basisBra,basisKet); // For contract_L: bra is in, ket is out
40 }
41 else if (DIR == VMPS::DIRECTION::RIGHT)
42 {
43 LRtmp.data.setIdentity(basisKet,basisBra); // For contract_R: bra is out, ket is in
44 }
45 else
46 {
47 assert(1==0 and "Unknown VMPS::DIRECTION::OPTION in calc_LReigen!");
48 }
49
50 ArnoldiSolver<TransferMatrix<Symmetry,double>,TransferVector<Symmetry,complex<double> > > Arnie(1,tol_input);
51 Arnie.set_dimK(dimK);
52
53 //Arnie.calc_dominant(T,LRtmp,lambda,tol_input);
54 Arnie.calc_dominant(T,LRtmp);
55 complex<double> lambda = Arnie.get_lambda(0);
56
57 if (abs(lambda.imag()) > tol_input)
58 {
59 lout << Arnie.info() << endl;
60 lout << termcolor::red << "Non-zero imaginary part of dominant eigenvalue λ=" << lambda << ", |λ|=" << abs(lambda) << termcolor::reset << endl;
61 }
62
63 Eigenstate<Biped<Symmetry,Matrix<complex<Scalar>,Dynamic,Dynamic> > > out;
64 out.energy = abs(lambda);
65 out.state = LRtmp.data;
66
67 return out;
68}
69
71template<typename Symmetry, typename MatrixType, typename MpoScalar>
72Biped<Symmetry,MatrixType> make_hL (const boost::multi_array<MpoScalar,4> &H2site,
73 const vector<Biped<Symmetry,MatrixType> > &AL,
74 const vector<qarray<Symmetry::Nq> > &qloc)
75{
77 size_t D = qloc.size();
78
79 for (size_t s1=0; s1<D; ++s1)
80 for (size_t s2=0; s2<D; ++s2)
81 for (size_t s3=0; s3<D; ++s3)
82 for (size_t s4=0; s4<D; ++s4)
83 for (size_t q3=0; q3<AL[s3].dim; ++q3)
84 {
85 auto A1ins = Symmetry::reduceSilent(AL[s3].in[q3], Symmetry::flip(qloc[s1]));
86 for (const auto &A1in : A1ins)
87 {
88 auto it1 = AL[s1].dict.find(qarray2<Symmetry::Nq>{A1in, AL[s3].in[q3]});
89 if (it1 != AL[s1].dict.end())
90 {
91 auto A2outs = Symmetry::reduceSilent(AL[s1].in[it1->second], qloc[s2]);
92 for (const auto &A2out : A2outs)
93 {
94 auto it2 = AL[s2].dict.find(qarray2<Symmetry::Nq>{AL[s1].in[it1->second], A2out});
95 if (it2 != AL[s2].dict.end())
96 {
97 auto A4outs = Symmetry::reduceSilent(AL[s2].out[it2->second], qloc[s4]);
98 for (const auto &A4out : A4outs)
99 {
100 auto it4 = AL[s4].dict.find(qarray2<Symmetry::Nq>{AL[s2].out[it2->second], A4out});
101 if (it4 != AL[s4].dict.end())
102 {
103 MatrixType Mtmp;
104 if (H2site[s1][s2][s3][s4] != 0.)
105 {
106 optimal_multiply(H2site[s1][s2][s3][s4],
107 AL[s3].block[q3].adjoint(),
108 AL[s1].block[it1->second].adjoint(),
109 AL[s2].block[it2->second],
110 AL[s4].block[it4->second],
111 Mtmp);
112 }
113
114 if (Mtmp.size() != 0)
115 {
116 qarray2<Symmetry::Nq> quple = {AL[s3].out[q3], AL[s4].out[it4->second]};
117 assert(quple[0] == quple[1]);
118 auto it = Mout.dict.find(quple);
119
120 if (it != Mout.dict.end())
121 {
122 if (Mout.block[it->second].rows() != Mtmp.rows() and
123 Mout.block[it->second].cols() != Mtmp.cols())
124 {
125 Mout.block[it->second] = Mtmp;
126 }
127 else
128 {
129 Mout.block[it->second] += Mtmp;
130 }
131 }
132 else
133 {
134 Mout.push_back(quple, Mtmp);
135 }
136 }
137 }
138 }
139 }
140 }
141 }
142 }
143 }
144
145 return Mout;
146}
147
149template<typename Symmetry, typename MatrixType, typename MpoScalar>
150Biped<Symmetry,MatrixType> make_hR (const boost::multi_array<MpoScalar,4> &H2site,
151 const vector<Biped<Symmetry,MatrixType> > &AR,
152 const vector<qarray<Symmetry::Nq> > &qloc)
153{
155 size_t D = qloc.size();
156
157 for (size_t s1=0; s1<D; ++s1)
158 for (size_t s2=0; s2<D; ++s2)
159 for (size_t s3=0; s3<D; ++s3)
160 for (size_t s4=0; s4<D; ++s4)
161 for (size_t q2=0; q2<AR[s2].dim; ++q2)
162 {
163 auto A4outs = Symmetry::reduceSilent(AR[s2].out[q2], qloc[s4]);
164 for (const auto &A4out : A4outs)
165 {
166 auto it4 = AR[s4].dict.find(qarray2<Symmetry::Nq>{AR[s2].out[q2], A4out});
167 if (it4 != AR[s4].dict.end())
168 {
169 auto A3ins = Symmetry::reduceSilent(AR[s4].out[it4->second], Symmetry::flip(qloc[s3]));
170 for (const auto &A3in : A3ins)
171 {
172 auto it3 = AR[s3].dict.find(qarray2<Symmetry::Nq>{A3in, AR[s4].out[it4->second]});
173 if (it3 != AR[s3].dict.end())
174 {
175 auto A1ins = Symmetry::reduceSilent(AR[s3].in[it3->second], Symmetry::flip(qloc[s1]));
176 for (const auto &A1in : A1ins)
177 {
178 auto it1 = AR[s1].dict.find(qarray2<Symmetry::Nq>{A1in, AR[s3].in[it3->second]});
179 if (it1 != AR[s1].dict.end())
180 {
181 MatrixType Mtmp;
182 if (H2site[s1][s2][s3][s4] != 0.)
183 {
184 optimal_multiply(H2site[s1][s2][s3][s4],
185 AR[s2].block[q2],
186 AR[s4].block[it4->second],
187 AR[s3].block[it3->second].adjoint(),
188 AR[s1].block[it1->second].adjoint(),
189 Mtmp);
190 }
191
192 if (Mtmp.size() != 0)
193 {
194 qarray2<Symmetry::Nq> quple = {AR[s2].in[q2], AR[s1].in[it1->second]};
195 assert(quple[0] == quple[1]);
196 auto it = Mout.dict.find(quple);
197
198 if (it != Mout.dict.end())
199 {
200 if (Mout.block[it->second].rows() != Mtmp.rows() and
201 Mout.block[it->second].cols() != Mtmp.cols())
202 {
203 Mout.block[it->second] = Mtmp;
204 }
205 else
206 {
207 Mout.block[it->second] += Mtmp;
208 }
209 }
210 else
211 {
212 Mout.push_back(quple, Mtmp);
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220 }
221 }
222
223 return Mout;
224}
225
227template<typename Symmetry, typename MatrixType, typename MpoScalar>
229 const Tripod<Symmetry,MatrixType> &Lold,
230 const vector<vector<Biped<Symmetry,MatrixType> > > &Abra,
231 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<MpoScalar> > > > > > &W,
232 const vector<vector<Biped<Symmetry,MatrixType> > > &Aket,
233 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
234 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
235 const std::unordered_map<pair<qarray<Symmetry::Nq>,size_t>,size_t> &basis_order_map)
236{
237 size_t Lcell = Abra.size();
240 for (size_t l=0; l<Lcell; ++l)
241 {
242 if (l==Lcell-1)
243 {
244 contract_L(L, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Lnext, false, make_pair(FIXED_COLS,b), basis_order_map);
245 }
246 else if (l==0)
247 {
248 contract_L(L, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Lnext, false, make_pair(TRIANGULAR,b), basis_order_map);
249 }
250 else
251 {
252 contract_L(L, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Lnext, false, make_pair(FULL,0), basis_order_map);
253 }
254 L.clear();
255 L = Lnext;
256 Lnext.clear();
257 }
258 return L;
259}
260
262template<typename Symmetry, typename MatrixType, typename MpoScalar>
264 const Tripod<Symmetry,MatrixType> &Rold,
265 const vector<vector<Biped<Symmetry,MatrixType> > > &Abra,
266 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<MpoScalar> > > > > > &W,
267 const vector<vector<Biped<Symmetry,MatrixType> > > &Aket,
268 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
269 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
270 const std::unordered_map<pair<qarray<Symmetry::Nq>,size_t>,size_t> &basis_order_map)
271{
272 size_t Lcell = Abra.size();
275 for (int l=Lcell-1; l>=0; --l)
276 {
277 if (l==0)
278 {
279 contract_R(R, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Rnext, false, make_pair(FIXED_ROWS,a), basis_order_map);
280 }
281 else if (l==Lcell-1)
282 {
283 contract_R(R, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Rnext, false, make_pair(TRIANGULAR,a), basis_order_map);
284 }
285 else
286 {
287 contract_R(R, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Rnext, false, make_pair(FULL,0), basis_order_map);
288 }
289 R.clear();
290 R = Rnext;
291 Rnext.clear();
292 }
293 return R;
294}
295
296template<typename Symmetry, typename MpoScalar>
297void contract_WW (const vector<vector<vector<SparseMatrix<MpoScalar> > > > &W12,
298 const vector<qarray<Symmetry::Nq> > &qloc12,
299 const vector<qarray<Symmetry::Nq> > &qOp12,
300 const vector<vector<vector<SparseMatrix<MpoScalar> > > > &W34,
301 const vector<qarray<Symmetry::Nq> > &qloc34,
302 const vector<qarray<Symmetry::Nq> > &qOp34,
303 vector<vector<vector<SparseMatrix<MpoScalar> > > > &W,
304 vector<qarray<Symmetry::Nq> > &qloc,
305 vector<qarray<Symmetry::Nq> > &qOp)
306{
307 W.clear();
308 qloc.clear();
309 qOp.clear();
310
311 qOp = Symmetry::reduceSilent(qOp12, qOp34, true);
312 auto tensor_basis = Symmetry::tensorProd(qloc12, qloc34);
313
314 qloc.resize(tensor_basis.size());
315 for (size_t q=0; q<tensor_basis.size(); ++q)
316 {
317 qloc[q] = get<4>(tensor_basis[q]);
318 }
319
320 W.resize(tensor_basis.size());
321 for (size_t s1s3=0; s1s3<tensor_basis.size(); ++s1s3)
322 {
323 W[s1s3].resize(tensor_basis.size());
324 for (size_t s2s4=0; s2s4<tensor_basis.size(); ++s2s4)
325 {
326 W[s1s3][s2s4].resize(qOp.size());
327 }
328 }
329
330 for (size_t s1=0; s1<qloc12.size(); ++s1)
331 for (size_t s3=0; s3<qloc34.size(); ++s3)
332 {
333 auto qmerges13 = Symmetry::reduceSilent(qloc12[s1], qloc34[s3]);
334
335 for (const auto &qmerge13:qmerges13)
336 {
337 auto qtensor13 = make_tuple(qloc12[s1], s1, qloc34[s3], s3, qmerge13);
338 auto s1s3 = distance(tensor_basis.begin(), find(tensor_basis.begin(), tensor_basis.end(), qtensor13));
339
340 for (size_t s2=0; s2<qloc12.size(); ++s2)
341 for (size_t s4=0; s4<qloc34.size(); ++s4)
342 {
343 auto qmerges24 = Symmetry::reduceSilent(qloc12[s2], qloc34[s4]);
344
345 for (const auto &qmerge24:qmerges24)
346 {
347 auto qtensor24 = make_tuple(qloc12[s2], s2, qloc34[s4], s4, qmerge24);
348 auto s2s4 = distance(tensor_basis.begin(), find(tensor_basis.begin(), tensor_basis.end(), qtensor24));
349
350 for (size_t k12=0; k12<qOp12.size(); ++k12)
351 for (size_t k34=0; k34<qOp34.size(); ++k34)
352 {
353 auto kmerges = Symmetry::reduceSilent(qOp12[k12], qOp34[k34]);
354
355 for (const auto &kmerge:kmerges)
356 {
357 if (!Symmetry::validate(qarray3<Symmetry::Nq>{qmerge24,kmerge,qmerge13})) {continue;}
358
359 auto k = distance(qOp.begin(), find(qOp.begin(), qOp.end(), kmerge));
360
361 for (int r12=0; r12<W12[s1][s2][k12].outerSize(); ++r12)
362 for (typename SparseMatrix<MpoScalar>::InnerIterator iW12(W12[s1][s2][k12],r12); iW12; ++iW12)
363 for (int r34=0; r34<W34[s3][s4][k34].outerSize(); ++r34)
364 for (typename SparseMatrix<MpoScalar>::InnerIterator iW34(W34[s3][s4][k34],r34); iW34; ++iW34)
365 {
366 MpoScalar val = iW12.value() * iW34.value();
367
368 if (iW12.col() == iW34.row() and abs(val) > 0.)
369 {
370 if (W[s1s3][s2s4][k].size() == 0)
371 {
372 W[s1s3][s2s4][k].resize(W12[s1][s2][k12].rows(), W34[s3][s4][k34].cols());
373 }
374
375 W[s1s3][s2s4][k].coeffRef(iW12.row(),iW34.col()) += val;
376 }
377 }
378 }
379 }
380 }
381 }
382 }
383 }
384}
385
386#endif
@ FIXED_ROWS
@ FIXED_COLS
@ TRIANGULAR
@ FULL
void optimal_multiply(Scalar alpha, const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, MatrixTypeR &result, bool DEBUG=false)
Definition: DmrgExternal.h:191
void contract_WW(const vector< vector< vector< SparseMatrix< MpoScalar > > > > &W12, const vector< qarray< Symmetry::Nq > > &qloc12, const vector< qarray< Symmetry::Nq > > &qOp12, const vector< vector< vector< SparseMatrix< MpoScalar > > > > &W34, const vector< qarray< Symmetry::Nq > > &qloc34, const vector< qarray< Symmetry::Nq > > &qOp34, vector< vector< vector< SparseMatrix< MpoScalar > > > > &W, vector< qarray< Symmetry::Nq > > &qloc, vector< qarray< Symmetry::Nq > > &qOp)
Tripod< Symmetry, MatrixType > make_YL(size_t b, const Tripod< Symmetry, MatrixType > &Lold, const vector< vector< Biped< Symmetry, MatrixType > > > &Abra, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< MpoScalar > > > > > > &W, const vector< vector< Biped< Symmetry, MatrixType > > > &Aket, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map)
Tripod< Symmetry, MatrixType > make_YR(size_t a, const Tripod< Symmetry, MatrixType > &Rold, const vector< vector< Biped< Symmetry, MatrixType > > > &Abra, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< MpoScalar > > > > > > &W, const vector< vector< Biped< Symmetry, MatrixType > > > &Aket, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map)
Biped< Symmetry, MatrixType > make_hR(const boost::multi_array< MpoScalar, 4 > &H2site, const vector< Biped< Symmetry, MatrixType > > &AR, const vector< qarray< Symmetry::Nq > > &qloc)
Eigenstate< Biped< Symmetry, Matrix< complex< Scalar >, Dynamic, Dynamic > > > calc_LReigen(VMPS::DIRECTION::OPTION DIR, const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &Abra, const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &Aket, const Qbasis< Symmetry > &basisBra, const Qbasis< Symmetry > &basisKet, const vector< vector< qarray< Symmetry::Nq > > > &qloc, size_t dimK=100ul, double tol_input=1e-12, Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > *LReigenTop=NULL)
Biped< Symmetry, MatrixType > make_hL(const boost::multi_array< MpoScalar, 4 > &H2site, const vector< Biped< Symmetry, MatrixType > > &AL, const vector< qarray< Symmetry::Nq > > &qloc)
‍**Calculates the tensor (eq. (12)) from the explicit 4-legged 2-site Hamiltonian and ....
Definition: Qbasis.h:39
void contract_R(const Tripod< Symmetry, MatrixType2 > &Rold, const vector< Biped< Symmetry, MatrixType > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, MatrixType > > &Aket, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Tripod< Symmetry, MatrixType2 > &Rnew, bool RANDOMIZE=false, tuple< CONTRACT_LR_MODE, size_t > MODE_input=make_pair(FULL, 0), const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map={})
void contract_L(const Tripod< Symmetry, MatrixType2 > &Lold, const vector< Biped< Symmetry, MatrixType > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, MatrixType > > &Aket, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Tripod< Symmetry, MatrixType2 > &Lnew, bool RANDOMIZE=false, tuple< CONTRACT_LR_MODE, size_t > MODE_input=make_pair(FULL, 0), const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map={})
std::array< qarray< Nq >, 2 > qarray2
Definition: qarray.h:51
std::array< qarray< Nq >, 3 > qarray3
Definition: qarray.h:52
Definition: Biped.h:64
std::unordered_map< std::array< qType, 2 >, std::size_t > dict
Definition: Biped.h:104
std::vector< MatrixType_ > block
Definition: Biped.h:96
std::size_t size() const
Definition: Biped.h:83
void push_back(qType qin, qType qout, const MatrixType_ &M)
Definition: Biped.h:529
void setIdentity(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
Definition: Biped.h:358
void clear()
Definition: Multipede.h:409
Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > data
Definition: qarray.h:26