1#ifndef VANILLA_VUMPSCONTRACTIONS
2#define VANILLA_VUMPSCONTRACTIONS
5#include "boost/multi_array.hpp"
12#include "ArnoldiSolver.h"
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,
24 double tol_input = 1e-12,
25 Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > *LReigenTop= NULL)
29 if (LReigenTop != NULL)
31 T.TopEigvec = *LReigenTop;
33 T.PROJECT_OUT_TOPEIGVEC =
true;
47 assert(1==0 and
"Unknown VMPS::DIRECTION::OPTION in calc_LReigen!");
54 Arnie.calc_dominant(T,LRtmp);
55 complex<double> lambda = Arnie.get_lambda(0);
57 if (abs(lambda.imag()) > tol_input)
59 lout << Arnie.info() << endl;
60 lout << termcolor::red <<
"Non-zero imaginary part of dominant eigenvalue λ=" << lambda <<
", |λ|=" << abs(lambda) << termcolor::reset << endl;
63 Eigenstate<Biped<Symmetry,Matrix<complex<Scalar>,Dynamic,Dynamic> > > out;
64 out.energy = abs(lambda);
65 out.state = LRtmp.
data;
71template<
typename Symmetry,
typename MatrixType,
typename MpoScalar>
77 size_t D = qloc.
size();
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)
85 auto A1ins = Symmetry::reduceSilent(AL[s3].in[q3], Symmetry::flip(qloc[s1]));
86 for (
const auto &A1in : A1ins)
89 if (it1 != AL[s1].dict.end())
91 auto A2outs = Symmetry::reduceSilent(AL[s1].in[it1->second], qloc[s2]);
92 for (
const auto &A2out : A2outs)
95 if (it2 != AL[s2].dict.end())
97 auto A4outs = Symmetry::reduceSilent(AL[s2].out[it2->second], qloc[s4]);
98 for (
const auto &A4out : A4outs)
101 if (it4 != AL[s4].dict.end())
104 if (H2site[s1][s2][s3][s4] != 0.)
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],
114 if (Mtmp.size() != 0)
117 assert(quple[0] == quple[1]);
118 auto it = Mout.
dict.find(quple);
120 if (it != Mout.
dict.end())
122 if (Mout.
block[it->second].rows() != Mtmp.rows() and
123 Mout.
block[it->second].cols() != Mtmp.cols())
125 Mout.
block[it->second] = Mtmp;
129 Mout.
block[it->second] += Mtmp;
149template<
typename Symmetry,
typename MatrixType,
typename MpoScalar>
155 size_t D = qloc.
size();
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)
163 auto A4outs = Symmetry::reduceSilent(AR[s2].out[q2], qloc[s4]);
164 for (
const auto &A4out : A4outs)
167 if (it4 != AR[s4].dict.end())
169 auto A3ins = Symmetry::reduceSilent(AR[s4].out[it4->second], Symmetry::flip(qloc[s3]));
170 for (
const auto &A3in : A3ins)
173 if (it3 != AR[s3].dict.end())
175 auto A1ins = Symmetry::reduceSilent(AR[s3].in[it3->second], Symmetry::flip(qloc[s1]));
176 for (
const auto &A1in : A1ins)
179 if (it1 != AR[s1].dict.end())
182 if (H2site[s1][s2][s3][s4] != 0.)
186 AR[s4].block[it4->second],
187 AR[s3].block[it3->second].adjoint(),
188 AR[s1].block[it1->second].adjoint(),
192 if (Mtmp.size() != 0)
195 assert(quple[0] == quple[1]);
196 auto it = Mout.
dict.find(quple);
198 if (it != Mout.
dict.end())
200 if (Mout.
block[it->second].rows() != Mtmp.rows() and
201 Mout.
block[it->second].cols() != Mtmp.cols())
203 Mout.
block[it->second] = Mtmp;
207 Mout.
block[it->second] += Mtmp;
227template<
typename Symmetry,
typename MatrixType,
typename MpoScalar>
231 const vector<vector<vector<vector<
Biped<Symmetry,SparseMatrix<MpoScalar> > > > > > &W,
237 size_t Lcell = Abra.size();
240 for (
size_t l=0; l<Lcell; ++l)
244 contract_L(L, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Lnext,
false, make_pair(
FIXED_COLS,b), basis_order_map);
248 contract_L(L, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Lnext,
false, make_pair(
TRIANGULAR,b), basis_order_map);
252 contract_L(L, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Lnext,
false, make_pair(
FULL,0), basis_order_map);
262template<
typename Symmetry,
typename MatrixType,
typename MpoScalar>
266 const vector<vector<vector<vector<
Biped<Symmetry,SparseMatrix<MpoScalar> > > > > > &W,
272 size_t Lcell = Abra.size();
275 for (
int l=Lcell-1; l>=0; --l)
279 contract_R(R, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Rnext,
false, make_pair(
FIXED_ROWS,a), basis_order_map);
283 contract_R(R, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Rnext,
false, make_pair(
TRIANGULAR,a), basis_order_map);
287 contract_R(R, Abra[l], W[l], Aket[l], qloc[l], qOp[l], Rnext,
false, make_pair(
FULL,0), basis_order_map);
296template<
typename Symmetry,
typename MpoScalar>
297void contract_WW (
const vector<vector<vector<SparseMatrix<MpoScalar> > > > &W12,
300 const vector<vector<vector<SparseMatrix<MpoScalar> > > > &W34,
303 vector<vector<vector<SparseMatrix<MpoScalar> > > > &W,
311 qOp = Symmetry::reduceSilent(qOp12, qOp34,
true);
312 auto tensor_basis = Symmetry::tensorProd(qloc12, qloc34);
314 qloc.resize(tensor_basis.size());
315 for (
size_t q=0; q<tensor_basis.size(); ++q)
317 qloc[q] = get<4>(tensor_basis[q]);
320 W.resize(tensor_basis.size());
321 for (
size_t s1s3=0; s1s3<tensor_basis.size(); ++s1s3)
323 W[s1s3].resize(tensor_basis.size());
324 for (
size_t s2s4=0; s2s4<tensor_basis.size(); ++s2s4)
326 W[s1s3][s2s4].resize(qOp.size());
330 for (
size_t s1=0; s1<qloc12.size(); ++s1)
331 for (
size_t s3=0; s3<qloc34.size(); ++s3)
333 auto qmerges13 = Symmetry::reduceSilent(qloc12[s1], qloc34[s3]);
335 for (
const auto &qmerge13:qmerges13)
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));
340 for (
size_t s2=0; s2<qloc12.size(); ++s2)
341 for (
size_t s4=0; s4<qloc34.size(); ++s4)
343 auto qmerges24 = Symmetry::reduceSilent(qloc12[s2], qloc34[s4]);
345 for (
const auto &qmerge24:qmerges24)
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));
350 for (
size_t k12=0; k12<qOp12.size(); ++k12)
351 for (
size_t k34=0; k34<qOp34.size(); ++k34)
353 auto kmerges = Symmetry::reduceSilent(qOp12[k12], qOp34[k34]);
355 for (
const auto &kmerge:kmerges)
359 auto k = distance(qOp.begin(), find(qOp.begin(), qOp.end(), kmerge));
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)
366 MpoScalar val = iW12.value() * iW34.value();
368 if (iW12.col() == iW34.row() and abs(val) > 0.)
370 if (W[s1s3][s2s4][k].size() == 0)
372 W[s1s3][s2s4][k].resize(W12[s1][s2][k12].rows(), W34[s3][s4][k34].cols());
375 W[s1s3][s2s4][k].coeffRef(iW12.row(),iW34.col()) += val;
void optimal_multiply(Scalar alpha, const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, MatrixTypeR &result, bool DEBUG=false)
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 ....
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
std::array< qarray< Nq >, 3 > qarray3
std::unordered_map< std::array< qType, 2 >, std::size_t > dict
std::vector< MatrixType_ > block
void push_back(qType qin, qType qout, const MatrixType_ &M)
void setIdentity(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > data