5#include "LanczosPropagator.h"
11#include <gsl/gsl_math.h>
13template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
22 double memory (MEMUNIT memunit=GB)
const;
23 double overhead (MEMUNIT memunit=GB)
const;
25 void t_step (
const Hamiltonian &H,
const VectorType &Vin, VectorType &Vout, TimeScalar dt,
int N_stages=1,
double tol_Lanczos=1e-8);
27 void t_step (
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
int N_stages=1,
double tol_Lanczos=1e-8);
28 void t_step0 (
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
int N_stages=1,
double tol_Lanczos=1e-8);
30 void t_step_adaptive (
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
const vector<bool> &TWO_STEP_AT,
int N_stages=1,
double tol_Lanczos=1e-8);
40 void t_step_pivot (
double x,
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
double tol_Lanczos=1e-8);
41 void t0_step_pivot (
bool BACK,
double x,
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
double tol_Lanczos=1e-8,
bool TURN_FIRST=
true);
47 vector<PivotMatrix1<Symmetry,TimeScalar,MpoScalar> >
Heff;
51 double x (
int alg,
size_t l,
int N_stages);
53 void set_blocks (
const Hamiltonian &H, VectorType &Vinout);
59 void build_L (
const Hamiltonian &H,
const VectorType &Vinout,
int loc);
60 void build_R (
const Hamiltonian &H,
const VectorType &Vinout,
int loc);
79template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
84 ss <<
"TDVPPropagator: ";
85 ss <<
" dt=" << last_dt;
86 ss <<
", max(dist)=" << dist_max <<
", ";
88 if (dimK2_log.size() > 0)
90 ss <<
"dimK2=" << *min_element(dimK2_log.begin(), dimK2_log.end()) <<
"~" << *max_element(dimK2_log.begin(), dimK2_log.end()) <<
", ";
92 if (dimK1_log.size() > 0)
94 ss <<
"dimK1=" << *min_element(dimK1_log.begin(), dimK1_log.end()) <<
"~" << *max_element(dimK1_log.begin(), dimK1_log.end()) <<
", ";
96 if (dimK0_log.size() > 0)
98 ss <<
"dimK0=" << *min_element(dimK0_log.begin(), dimK0_log.end()) <<
"~" << *max_element(dimK0_log.begin(), dimK0_log.end()) <<
", ";
102 ss <<
"δE@edge: L=" << deltaE(0) <<
", R=" << deltaE(deltaE.rows()-1) <<
", ";
103 ss <<
"overhead=" << round(overhead(MB),3) <<
"MB, ";
104 ss <<
"t[s]=" << t_tot <<
", "
105 <<
"t0=" << round(t_0site/t_tot*100.,0) <<
"%, "
106 <<
"t1=" << round(t_1site/t_tot*100.) <<
"%, "
107 <<
"t2=" << round(t_2site/t_tot*100.) <<
"%, "
108 <<
"t_ohead=" << round(t_ohead/t_tot*100.) <<
"%, "
109 <<
"t_contr=" << round(t_contr/t_tot*100.) <<
"%";
114template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
116memory (MEMUNIT memunit)
const
132template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
147template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
151 set_blocks(H,Vinout);
152 assert(H.HAS_TWO_SITE_DATA() and
"You need to call H.precalc_TwoSiteData() before dynamics!");
155template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
157set_blocks (
const Hamiltonian &H, VectorType &Vinout)
159 N_sites = H.length();
163 Heff.resize(N_sites);
166 for (
int l=0; l<N_sites; ++l) Heff[l].Terms.resize(1);
170 for (
size_t l=0; l<N_sites; ++l)
172 Heff[l].Terms[0].W = H.W[l];
180 for (
size_t l=N_sites-1; l>0; --l)
183 build_R(H,Vinout,l-1);
190 double overlap =
isReal(Vtmp.dot(Vinout));
191 if (GSL_SIGN(overlap) == -1)
194 lout << termcolor::yellow <<
"dot=" << overlap <<
", minus overlap, compensating..." << termcolor::reset << endl;
198 deltaE.resize(N_sites);
210template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
212x (
int alg,
size_t l,
int N_stages)
215 int N_updates = (alg==2)? N_sites-1 : N_sites;
221 else if (N_stages == 2)
223 if (l<N_updates) {out = 0.25;}
224 else if (l>=N_updates and l<2*N_updates) {out = 0.25;}
225 else if (l>=2*N_updates and l<3*N_updates) {out = 0.25;}
226 else if (l>=3*N_updates) {out = 0.25;}
228 else if (N_stages == 3)
230 double tripleJump1 = 1./(2.-pow(2.,1./3.));
231 double tripleJump2 = 1.-2.*tripleJump1;
233 if (l< 2*N_updates) {out = 0.5*tripleJump1;}
234 else if (l>=2*N_updates and l<4*N_updates) {out = 0.5*tripleJump2;}
235 else if (l>=4*N_updates) {out = 0.5*tripleJump1;}
240template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
242t_step (
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
int N_stages,
double tol_Lanczos)
245 assert(N_stages==1 or N_stages==2 or N_stages==3 and
"Only N_stages=1,2,3 implemented for TDVPPropagator::t_step!");
248 N_stages_last = N_stages;
263 for (
size_t l=0; l<2*N_stages*(N_sites-1); ++l)
266 turnaround(pivot, N_sites, CURRENT_DIRECTION);
275 Vinout.A[loc2], Vinout.locBasis(loc2),
276 Vinout.QoutTop[loc1], Vinout.QoutBot[loc1]);
277 t_contr += Wc.time(SECONDS);
279 H.W_at(loc1), H.W_at(loc2),
280 H.locBasis(loc1), H.locBasis(loc2),
281 H.opBasis(loc1), H.opBasis(loc2));
290 H.locBasis(loc1), H.locBasis(loc2), H.opBasis(loc1), H.opBasis(loc2),
292 t_ohead += Woh2.time(SECONDS);
298 Lutz2.t_step(Heff2, Apair, x(2,l,N_stages)*dt);
300 t_2site += W2.time(SECONDS);
302 dimK2_log.push_back(Lutz2.get_dimK());
303 if (Lutz2.get_dist() > dist_max) {dist_max = Lutz2.get_dist();}
304 if (Lutz2.get_dimK() > dimK_max) {dimK_max = Lutz2.get_dimK();}
307 Vinout.sweepStep2(CURRENT_DIRECTION, loc1, Apair.
data);
308 t_contr += Ws.time(SECONDS);
310 pivot = Vinout.get_pivot();
317 precalc_blockStructure (Heff[pivot].Terms[0].L, Vinout.A[pivot], Heff[pivot].Terms[0].W, Vinout.A[pivot], Heff[pivot].Terms[0].R,
318 H.locBasis(pivot), H.opBasis(pivot),
319 Heff[pivot].qlhs, Heff[pivot].qrhs, Heff[pivot].factor_cgcs);
320 t_ohead += Woh1.time(SECONDS);
329 Lutz.t_step(Heff[pivot], Asingle, -x(2,l,N_stages)*dt);
331 t_1site += W1.time(SECONDS);
333 dimK1_log.push_back(Lutz2.get_dimK());
334 if (Lutz.get_dist() > dist_max) {dist_max = Lutz2.get_dist();}
335 if (Lutz.get_dimK() > dimK_max) {dimK_max = Lutz2.get_dimK();}
337 Vinout.A[pivot] = Asingle.
data;
343 t_tot = Wtot.time(SECONDS);
449template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
451t_step0 (
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
int N_stages,
double tol_Lanczos)
456 N_stages_last = N_stages;
473 for (
size_t l=0; l<2*N_stages*N_sites; ++l)
475 turnaround(pivot, N_sites, CURRENT_DIRECTION);
480 precalc_blockStructure (Heff[pivot].Terms[0].L, Vinout.A[pivot], Heff[pivot].Terms[0].W, Vinout.A[pivot], Heff[pivot].Terms[0].R,
481 H.locBasis(pivot), H.opBasis(pivot), Heff[pivot].qlhs, Heff[pivot].qrhs, Heff[pivot].factor_cgcs);
482 t_ohead += Woh1.time(SECONDS);
489 Lutz.t_step(Heff[pivot], Asingle, x(1,l,N_stages)*dt);
490 t_1site += W1.time(SECONDS);
492 dimK1_log.push_back(Lutz.get_dimK());
493 if (Lutz.get_dist() > dist_max) {dist_max = Lutz.get_dist();}
494 if (Lutz.get_dimK() > dimK_max) {dimK_max = Lutz.get_dimK();}
495 Vinout.A[pivot] = Asingle.
data;
498 if ((l+1)%N_sites != 0)
501 int old_pivot = pivot;
503 pivot = Vinout.get_pivot();
523 Lutz0.t_step(Heff0, Azero, -x(1,l,N_stages)*dt);
524 t_0site += W0.time(SECONDS);
526 dimK0_log.push_back(Lutz0.get_dimK());
527 if (Lutz0.get_dist() > dist_max) {dist_max = Lutz0.get_dist();}
528 if (Lutz0.get_dimK() > dimK_max) {dimK_max = Lutz0.get_dimK();}
530 Vinout.absorb(pivot, CURRENT_DIRECTION, Azero.
data[0]);
536 t_tot = Wtot.time(SECONDS);
549template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
551t_step (
const Hamiltonian &H,
const VectorType &Vin, VectorType &Vout, TimeScalar dt,
int N_stages,
double tol_Lanczos)
555 t_step(H,Vout,dt,N_stages,tol_Lanczos);
558template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
560t_step_pivot (
double x,
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
double tol_Lanczos)
563 turnaround(pivot, N_sites, CURRENT_DIRECTION);
572 Vinout.A[loc2], Vinout.locBasis(loc2),
573 Vinout.QoutTop[loc1], Vinout.QoutBot[loc1]);
574 t_contr += Wc.time(SECONDS);
576 H.W_at(loc1), H.W_at(loc2),
577 H.locBasis(loc1), H.locBasis(loc2),
578 H.opBasis(loc1), H.opBasis(loc2));
587 H.locBasis(loc1), H.locBasis(loc2), H.opBasis(loc1), H.opBasis(loc2),
589 t_ohead += Woh2.time(SECONDS);
594 Lutz2.t_step(Heff2, Apair, x*dt);
596 t_2site += W2.time(SECONDS);
598 dimK2_log.push_back(Lutz2.get_dimK());
599 if (Lutz2.get_dist() > dist_max) {dist_max = Lutz2.get_dist();}
600 if (Lutz2.get_dimK() > dimK_max) {dimK_max = Lutz2.get_dimK();}
603 Vinout.sweepStep2(CURRENT_DIRECTION, loc1, Apair.
data);
604 t_contr += Ws.time(SECONDS);
607 pivot = Vinout.get_pivot();
614 precalc_blockStructure (Heff[pivot].Terms[0].L, Vinout.A[pivot], Heff[pivot].Terms[0].W, Vinout.A[pivot], Heff[pivot].Terms[0].R,
615 H.locBasis(pivot), H.opBasis(pivot),
616 Heff[pivot].qlhs, Heff[pivot].qrhs, Heff[pivot].factor_cgcs);
617 t_ohead += Woh1.time(SECONDS);
626 Lutz.t_step(Heff[pivot], Asingle, -x*dt);
627 deltaE(pivot) = Lutz.get_deltaE();
629 t_1site += W1.time(SECONDS);
631 dimK1_log.push_back(Lutz.get_dimK());
632 if (Lutz.get_dist() > dist_max) {dist_max = Lutz2.get_dist();}
633 if (Lutz.get_dimK() > dimK_max) {dimK_max = Lutz2.get_dimK();}
635 Vinout.A[pivot] = Asingle.
data;
639template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
641t0_step_pivot (
bool BACK,
double x,
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
double tol_Lanczos,
bool TURN_FIRST)
644 if (TURN_FIRST)
turnaround(pivot, N_sites, CURRENT_DIRECTION);
649 precalc_blockStructure (Heff[pivot].Terms[0].L, Vinout.A[pivot], Heff[pivot].Terms[0].W, Vinout.A[pivot], Heff[pivot].Terms[0].R,
650 H.locBasis(pivot), H.opBasis(pivot),
651 Heff[pivot].qlhs, Heff[pivot].qrhs, Heff[pivot].factor_cgcs);
652 t_ohead += Woh1.time(SECONDS);
661 Lutz.t_step(Heff[pivot], Asingle, x*dt);
662 deltaE(pivot) = Lutz.get_deltaE();
663 t_1site += W1.time(SECONDS);
665 dimK1_log.push_back(Lutz.get_dimK());
666 if (Lutz.get_dist() > dist_max) {dist_max = Lutz.get_dist();}
667 if (Lutz.get_dimK() > dimK_max) {dimK_max = Lutz.get_dimK();}
668 Vinout.A[pivot] = Asingle.
data;
674 int old_pivot = pivot;
678 Vinout.rightSplitStep(pivot,Azero.
data[0]);
683 Vinout.leftSplitStep(pivot,Azero.
data[0]);
685 pivot = Vinout.get_pivot();
688 if (old_pivot+1 == N_sites)
690 build_L(H,Vinout,N_sites);
694 build_L(H,Vinout,pivot);
699 if (old_pivot-1 == -1)
701 build_R(H,Vinout,-1);
705 build_R(H,Vinout,pivot);
722 if (old_pivot+1 == N_sites)
733 if (old_pivot-1 == -1)
745 Lutz0.t_step(Heff0, Azero, -x*dt);
747 t_0site += W0.time(SECONDS);
749 dimK0_log.push_back(Lutz0.get_dimK());
750 if (Lutz0.get_dist() > dist_max) {dist_max = Lutz0.get_dist();}
751 if (Lutz0.get_dimK() > dimK_max) {dimK_max = Lutz0.get_dimK();}
753 if (!TURN_FIRST)
turnaround(pivot, N_sites, CURRENT_DIRECTION);
756 Vinout.absorb(pivot, CURRENT_DIRECTION, Azero.
data[0]);
760template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
762t_step_adaptive (
const Hamiltonian &H, VectorType &Vinout, TimeScalar dt,
const vector<bool> &TWO_STEP_AT,
int N_stages,
double tol_Lanczos)
765 assert(N_stages==1 and
"Only N_stages=1 implemented for TDVPPropagator::t_step_adaptive!");
768 N_stages_last = N_stages;
783 for (
size_t l=0; l<N_sites-1; ++l)
785 if (TWO_STEP_AT[l] ==
true)
787 t_step_pivot(x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
791 t0_step_pivot(
true,x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
795 if (TWO_STEP_AT[N_sites-2])
797 t_step_pivot(x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
805 t0_step_pivot(
false,x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
806 t0_step_pivot(
true,x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
816 for (
int l=N_sites-3; l>=0; --l)
818 if (TWO_STEP_AT[l] ==
true)
820 t_step_pivot(x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
824 t0_step_pivot(
true,x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
832 t0_step_pivot(
false,x(1,0,N_stages),H,Vinout,dt,tol_Lanczos);
842 t_tot = Wtot.time(SECONDS);
845template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
849 if (pivot == 0 or pivot == N_sites-1)
854 HxV(Heff[pivot],V,HV);
855 double res = abs(
dot(HV,HV).real()-pow(
dot(V,HV).real(),2));
868template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
870build_L (
const Hamiltonian &H,
const VectorType &Vinout,
int loc)
876 contract_L(Heff[loc-1].Terms[0].L, Vinout.A[loc-1], H.W[loc-1], Vinout.A[loc-1], H.locBasis(loc-1), H.opBasis(loc-1), HeffLast.Terms[0].L);
880 contract_L(Heff[loc-1].Terms[0].L, Vinout.A[loc-1], H.W[loc-1], Vinout.A[loc-1], H.locBasis(loc-1), H.opBasis(loc-1), Heff[loc].Terms[0].L);
885template<
typename Hamiltonian,
typename Symmetry,
typename MpoScalar,
typename TimeScalar,
typename VectorType>
887build_R (
const Hamiltonian &H,
const VectorType &Vinout,
int loc)
889 if (loc != N_sites-1)
893 contract_R(Heff[loc+1].Terms[0].R, Vinout.A[loc+1], H.W[loc+1], Vinout.A[loc+1], H.locBasis(loc+1), H.opBasis(loc+1), HeffFrst.Terms[0].R);
897 contract_R(Heff[loc+1].Terms[0].R, Vinout.A[loc+1], H.W[loc+1], Vinout.A[loc+1], H.locBasis(loc+1), H.opBasis(loc+1), Heff[loc].Terms[0].R);
void precalc_blockStructure(const Tripod< Symmetry, Eigen::Matrix< Scalar, Dynamic, Dynamic > > &L, const vector< Biped< Symmetry, Eigen::Matrix< Scalar, Dynamic, Dynamic > > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, Eigen::Matrix< Scalar, Dynamic, Dynamic > > > &Aket, const Tripod< Symmetry, Eigen::Matrix< Scalar, Dynamic, Dynamic > > &R, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, vector< std::array< size_t, 2 > > &qlhs, vector< vector< std::array< size_t, 6 > > > &qrhs, vector< vector< Scalar > > &factor_cgcs)
void turnaround(int pivot, size_t L, DMRG::DIRECTION::OPTION &DIR)
Flips the sweep direction when the edge is reached.
Scalar dot(const Mps< Symmetry, Scalar > &Vbra, const Mps< Symmetry, Scalar > &Vket)
void HxV(const Mpo< Symmetry, MpoScalar > &H, const Mps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, bool VERBOSE=true, double tol_compr=1e-4, int Mincr=100, int Mlimit=10000, int max_halfsweeps=100)
void normalize(PivotVector< Symmetry, Scalar_ > &V)
VectorXd get_deltaE() const
DMRG::DIRECTION::OPTION CURRENT_DIRECTION
void t_step_pivot(double x, const Hamiltonian &H, VectorType &Vinout, TimeScalar dt, double tol_Lanczos=1e-8)
void t_step0(const Hamiltonian &H, VectorType &Vinout, TimeScalar dt, int N_stages=1, double tol_Lanczos=1e-8)
vector< size_t > get_dimK0_log() const
void t_step(const Hamiltonian &H, const VectorType &Vin, VectorType &Vout, TimeScalar dt, int N_stages=1, double tol_Lanczos=1e-8)
void build_R(const Hamiltonian &H, const VectorType &Vinout, int loc)
double memory(MEMUNIT memunit=GB) const
double x(int alg, size_t l, int N_stages)
void build_L(const Hamiltonian &H, const VectorType &Vinout, int loc)
double overhead(MEMUNIT memunit=GB) const
PivotMatrix1< Symmetry, TimeScalar, MpoScalar > HeffFrst
void test_edge_eigenvector(const PivotVector< Symmetry, TimeScalar > &Asingle)
vector< size_t > get_dimK2_log() const
vector< PivotMatrix1< Symmetry, TimeScalar, MpoScalar > > Heff
void t_step_adaptive(const Hamiltonian &H, VectorType &Vinout, TimeScalar dt, const vector< bool > &TWO_STEP_AT, int N_stages=1, double tol_Lanczos=1e-8)
void set_blocks(const Hamiltonian &H, VectorType &Vinout)
vector< size_t > dimK2_log
void t0_step_pivot(bool BACK, double x, const Hamiltonian &H, VectorType &Vinout, TimeScalar dt, double tol_Lanczos=1e-8, bool TURN_FIRST=true)
PivotMatrix1< Symmetry, TimeScalar, MpoScalar > HeffLast
vector< size_t > dimK0_log
vector< size_t > get_dimK1_log() const
vector< size_t > dimK1_log
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={})
vector< vector< std::array< size_t, 12 > > > qrhs
vector< std::array< size_t, 2 > > qlhs
vector< vector< Scalar > > factor_cgcs
vector< PivotMatrix2Terms< Symmetry, Scalar, MpoScalar > > Terms
vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > data