1#ifndef STRAWBERRY_DMRGSOLVER_WITH_Q
2#define STRAWBERRY_DMRGSOLVER_WITH_Q
4#ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
12#include "termcolor.hpp"
15#ifdef USE_HDF5_STORAGE
16 #include <HDF5Interface.h>
19#include "LanczosSolver.h"
21#include "TerminalPlot.h"
40template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar =
double>
43 static constexpr size_t Nq = Symmetry::Nq;
44 typedef typename Symmetry::qType
qType;
53 double memory (MEMUNIT memunit=GB)
const;
56 qarray<Nq> Qtot_input, LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND,
bool USE_STATE=
false);
59 qarray<Nq> Qtot_input, LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND,
bool USE_STATE=
false);
79 LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND);
82 LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND);
92 double &time_lanczos,
double &time_sweep,
double &time_LR,
double &time_overhead);
99 double &time_lanczos,
double &time_sweep,
double &time_LR,
double &time_overhead);
107 double &time_lanczos,
double &time_sweep,
double &time_LR,
double &time_overhead);
124 #ifdef USE_HDF5_STORAGE
126 void save (
string filename)
const;
129 void load (
string filename);
156 vector<PivotMatrix1<Symmetry,Scalar,Scalar> >
Heff;
193 vector<Mps<Symmetry,Scalar> >
Psi0;
200 vector<Mpo<typename MpHamiltonian::Symmetry,typename MpHamiltonian::Scalar_>>
observables;
204 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
208 void load_pivot (
const vector<MpHamiltonian> &H);
212template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
217 ss <<
"DmrgSolver: ";
218 ss <<
"L=" << N_sites <<
", ";
219 ss <<
"Mmax=" << Mmax <<
", Dmax=" << Dmax <<
", " <<
"Nqmax=" << Nqmax <<
", ";
220 ss <<
"trunc_weight=" << totalTruncWeight <<
", ";
225template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
230 ss << termcolor::colorize << termcolor::underline <<
"half-sweeps=" << SweepStat.N_halfsweeps;
231 ss << termcolor::reset;
232 ss <<
", next algorithm=" << DynParam.iteration(SweepStat.N_halfsweeps);
234 ss <<
"err_eigval=" << err_eigval <<
", err_state=" << err_state <<
", ";
235 ss <<
"mem=" << round(memory(GB),3) <<
"GB";
239#ifdef USE_HDF5_STORAGE
240template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
242save (
string filename)
const
245 HDF5Interface target(filename, WRITE);
246 target.save_scalar(SweepStat.pivot,
"pivot");
247 target.save_scalar(SweepStat.N_halfsweeps,
"N_halfsweeps");
248 target.save_scalar(SweepStat.N_sweepsteps,
"N_sweepsteps");
249 target.save_scalar(
static_cast<int>(SweepStat.CURRENT_DIRECTION),
"direction");
250 target.save_scalar(Dmax,
"D");
251 target.save_scalar(Mmax,
"M");
252 target.save_scalar(err_eigval,
"errorE");
253 target.save_scalar(err_state,
"errorS");
256template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
258load (
string filename)
261 HDF5Interface source(filename, READ);
262 source.load_scalar(SweepStat.pivot,
"pivot");
263 source.load_scalar(SweepStat.N_halfsweeps,
"N_halfsweeps");
264 source.load_scalar(SweepStat.N_sweepsteps,
"N_sweepsteps");
266 source.load_scalar(DIR_IN_INT,
"direction");
268 source.load_scalar(err_eigval,
"errorE");
269 source.load_scalar(err_state,
"errorS");
273template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
275memory (MEMUNIT memunit)
const
278 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
279 res += Heff_curr.memory(memunit);
280 res += Heff_next.memory(memunit);
282 for (
size_t l=0; l<N_sites; ++l) res += Heff[l].memory(memunit);
287template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
291 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
306 int randomNumber = rand();
307 EnvSaveLabel = make_string(
"./tmp/EnvTmp",randomNumber);
308 lout << termcolor::green <<
"Saving environments to files starting with: " << EnvSaveLabel << termcolor::reset << endl;
311 if (CHOSEN_VERBOSITY>=2)
313 lout << endl << termcolor::colorize << termcolor::bold
314 <<
"————————————————————————————————————————————DMRG Algorithm————————————————————————————————————————————"
315 << termcolor::reset << endl;
318 N_sites = H[0].length();
319 N_phys = H[0].volume();
321 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
322 Heff_curr.Terms.resize(H.size());
323 Heff_next.Terms.resize(H.size());
324 if (Vout.state.Boundaries.IS_TRIVIAL())
326 for (
int t=0; t<H.size(); ++t)
328 Heff_curr.Terms[t].L.setVacuum();
329 Heff_curr.Terms[t].R.setTarget(
qarray3<Nq>{Qtot_input, Qtot_input, Symmetry::qvacuum()});
331 Heff_curr.Terms[t].L.save(make_string(EnvSaveLabel,
"_L_t=",t,
"_l=",0));
332 Heff_curr.Terms[t].R.save(make_string(EnvSaveLabel,
"_R_t=",t,
"_l=",N_sites-1));
337 for (
int t=0; t<H.size(); ++t)
342 Heff_curr.Terms[t].L.save(make_string(EnvSaveLabel,
"_L_t=",t,
"_l=",0));
343 Heff_curr.Terms[t].R.save(make_string(EnvSaveLabel,
"_R_t=",t,
"_l=",N_sites-1));
349 Heff.resize(N_sites);
350 for (
int l=0; l<N_sites; ++l) Heff[l].Terms.resize(H.size());
351 if (Vout.state.Boundaries.IS_TRIVIAL())
353 for (
int t=0; t<H.size(); ++t)
355 Heff[0].Terms[t].L.setVacuum();
356 Heff[N_sites-1].Terms[t].R.setTarget(
qarray3<Nq>{Qtot_input, Qtot_input, Symmetry::qvacuum()});
361 for (
int t=0; t<H.size(); ++t)
369 Stopwatch<> PrepTimer;
373 auto Boundaries_tmp = Vout.state.Boundaries;
377 Vout.state.max_Nsv = max(GlobParam.Minit, Vout.state.calc_Nqmax());
378 Vout.state.min_Nsv = DynParam.min_Nsv(0);
379 Vout.state.max_Nrich = DynParam.max_Nrich(0);
380 Vout.state.Boundaries = Boundaries_tmp;
382 if (Vout.state.Boundaries.IS_TRIVIAL()) Vout.state.Boundaries.set_open_bc(Qtot_input);
384 Vout.state.update_inbase();
385 Vout.state.update_outbase();
386 Vout.state.calc_Qlimits();
388 Vout.state.setRandom();
392 if (H[0].GOT_SEMIOPEN_LEFT or !H[0].get_boundary_condition())
394 assert(Heff[N_sites-1].Terms.size() == 1 and
"Check boundary conditions and Heff.Terms");
395 for (
size_t s=0; s<Vout.state.qloc[N_sites-1].size(); ++s)
396 for (
size_t q=0; q<Vout.state.A[N_sites-1][s].dim; ++q)
398 for (
size_t r=0; r<Heff[N_sites-1].Terms[0].R.dim; ++r)
399 for (
size_t a=0; a<Heff[N_sites-1].Terms[0].R.block[r].shape()[0]; ++a)
401 if (Heff[N_sites-1].Terms[0].R.block[r][a][0].size() != 0)
403 if (Vout.state.A[N_sites-1][s].out[q] == Heff[N_sites-1].Terms[0].R.in(r))
405 Vout.state.A[N_sites-1][s].block[q].resize(Vout.state.A[N_sites-1][s].block[q].rows(),
406 Heff[N_sites-1].Terms[0].R.block[r][a][0].rows());
407 Vout.state.A[N_sites-1][s].block[q].setRandom();
412 Vout.state.update_inbase();
413 Vout.state.update_outbase();
415 if (H[0].GOT_SEMIOPEN_RIGHT or !H[0].get_boundary_condition())
417 assert(Heff[0].Terms.size() == 1 and
"Check boundary conditions and Heff.Terms");
418 for (
size_t s=0; s<Vout.state.qloc[0].size(); ++s)
419 for (
size_t q=0; q<Vout.state.A[0][s].dim; ++q)
421 for (
size_t r=0; r<Heff[0].Terms[0].L.dim; ++r)
422 for (
size_t a=0; a<Heff[0].Terms[0].L.block[r].shape()[0]; ++a)
424 if (Heff[0].Terms[0].L.block[r][a][0].size() != 0)
426 if (Vout.state.A[0][s].in[q] == Heff[0].Terms[0].L.out(r))
428 Vout.state.A[0][s].block[q].resize(Heff[0].Terms[0].L.block[r][a][0].cols(),
429 Vout.state.A[0][s].block[q].cols());
430 Vout.state.A[0][s].block[q].setRandom();
435 Vout.state.update_inbase();
436 Vout.state.update_outbase();
452 Mmax_old = GlobParam.Minit;
456 Vout.state.max_Nsv = Vout.state.calc_Mmax();
457 Mmax_old = Vout.state.max_Nsv;
458 Vout.state.min_Nsv = DynParam.min_Nsv(0);
459 Vout.state.max_Nrich = DynParam.max_Nrich(0);
467 if (SweepStat.pivot == -1)
469 SweepStat.N_sweepsteps = SweepStat.N_halfsweeps = 0;
472 for (
int l=N_sites-1; l>0; --l)
474 if (!USE_STATE) {Vout.state.setRandom(l);}
477 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
478 Heff_curr = Heff_next;
487 for (
size_t l=0; l<N_sites-1; ++l)
489 if (!USE_STATE) {Vout.state.setRandom(l);}
492 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
493 Heff_curr = Heff_next;
498 SweepStat.pivot = N_sites-1;
505 for (
size_t l=N_sites-1; l>0; --l)
512 for (
size_t l=0; l<SweepStat.pivot; ++l)
520 for (
size_t l=0; l<N_sites-1; ++l)
527 for (
size_t l=N_sites-1; l>SweepStat.pivot; --l)
538 for (
size_t l=0; l<N_sites; ++l)
540 Heff[l].Epenalty = Epenalty;
541 Heff[l].PL.resize(Psi0.size());
542 Heff[l].PR.resize(Psi0.size());
545 for (
int t=0; t<H.size(); ++t) E0 += real(
avg(Psi0[0], H[t], Psi0[0]));
550 for (
size_t n=0; n<Psi0.size(); ++n)
552 Heff[0].PL[n].setVacuum();
553 for (
size_t l=1; l<N_sites; ++l) build_PL(H,Vout,l);
555 Heff[N_sites-1].PR[n].setTarget(Vout.state.Qtot);
556 for (
int l=N_sites-2; l>=0; --l) build_PR(H,Vout,l);
600 Eold = std::nan(
"0");
604 Vout.state.eps_svd = DynParam.eps_svd(0);
605 Vout.state.alpha_rsvd = DynParam.max_alpha_rsvd(0);
606 Vout.state.eps_truncWeight = DynParam.eps_truncWeight(0);
608 if (CHOSEN_VERBOSITY>=2)
610 lout << PrepTimer.info(
"• initial state & sweep") << endl;
611 size_t standard_precision = cout.precision();
612 lout <<
"• #MPO terms : " << H.size() << endl;
613 lout << std::setprecision(15) <<
"• initial energy : E₀=" << Eold << std::setprecision(standard_precision) << endl;
614 lout <<
"• initial state : " << Vout.state.info() << endl;
615 lout <<
"• initial fluctuation strength : α_rsvd=";
616 cout << termcolor::underline;
617 lout << Vout.state.alpha_rsvd;
618 cout << termcolor::reset;
621 lout <<
"• initial truncWeight value cutoff : ε_truncWeight=";
622 cout << termcolor::underline;
623 lout << Vout.state.eps_truncWeight;
624 cout << termcolor::reset;
627 int i_alpha_switchoff=0;
628 for (
int i=0; i<GlobParam.max_halfsweeps; ++i)
630 if (DynParam.max_alpha_rsvd(i) == 0.) {i_alpha_switchoff = i;
break;}
632 lout <<
"• fluctuations turned off after ";
633 cout << termcolor::underline;
634 lout << i_alpha_switchoff;
635 cout << termcolor::reset;
636 lout <<
" half-sweeps" << endl;
637 if (Vout.state.max_Nrich == -1)
639 lout <<
"• fluctuations use ";
640 cout << termcolor::underline;
642 cout << termcolor::reset;
643 lout <<
" additional states" << endl;
647 lout <<
"• fluctuations use ";
648 cout << termcolor::underline;
649 lout << Vout.state.max_Nrich;
650 cout << termcolor::reset;
651 lout <<
" additional states" << endl;
653 lout <<
"• initial bond dim. increase by ";
654 cout << termcolor::underline;
655 lout << static_cast<int>((DynParam.Mincr_rel(0)-1.)*100.) <<
"%";
656 cout << termcolor::reset;
657 lout <<
" and at least by ";
658 cout << termcolor::underline;
659 lout << DynParam.Mincr_abs(0);
660 cout << termcolor::reset;
662 cout << termcolor::underline;
663 lout << DynParam.Mincr_per(0);
664 cout << termcolor::reset;
665 lout <<
" half-sweeps" << endl;
667 lout <<
"• keep at least ";
668 cout << termcolor::underline;
669 lout << Vout.state.min_Nsv;
670 cout << termcolor::reset;
671 lout <<
" singular values per block" << endl;
673 lout <<
"• make between ";
674 cout << termcolor::underline;
675 lout << GlobParam.min_halfsweeps;
676 cout << termcolor::reset;
678 cout << termcolor::underline;
679 lout << GlobParam.max_halfsweeps;
680 cout << termcolor::reset;
681 lout <<
" half-sweep iterations" << endl;
682 lout <<
"• eigenvalue tolerance: ";
683 cout << termcolor::underline;
684 lout << GlobParam.tol_eigval;
685 cout << termcolor::reset;
688 lout <<
"• state tolerance: ";
689 cout << termcolor::underline;
690 lout << GlobParam.tol_state;
691 cout << termcolor::reset;
693 cout << termcolor::underline;
694 lout << GlobParam.CONVTEST;
695 cout << termcolor::reset;
698 lout <<
"• initial algorithm: ";
699 cout << termcolor::underline;
700 lout << DynParam.iteration(0);
701 cout << termcolor::reset;
702 lout <<
", initial direction: ";
703 cout << termcolor::underline;
704 lout << GlobParam.INITDIR;
705 cout << termcolor::reset;
708 lout <<
"• calculate entropy on exit: " << boolalpha;
709 cout << termcolor::underline;
710 lout << GlobParam.CALC_S_ON_EXIT;
711 cout << termcolor::reset << endl;
713 lout <<
"• calculate 2-site variance exit: " << boolalpha;
714 cout << termcolor::underline;
715 lout << GlobParam.CALC_ERR_ON_EXIT;
716 cout << termcolor::reset << endl;
718 lout <<
"• bond dim. sequence: ";
719 size_t M = Vout.state.max_Nsv;
720 if (DynParam.Mincr_per(0) == 0)
722 size_t Mnew = max(
static_cast<size_t>(DynParam.Mincr_rel(0) * M), M + DynParam.Mincr_abs(0));
723 M = min(Mnew, GlobParam.Mlimit);
724 lout << 0 <<
":" << M <<
" ";
726 for (
int j=1; j<GlobParam.max_halfsweeps; ++j)
728 if (j%DynParam.Mincr_per(j) == 0)
730 size_t Mnew = max(
static_cast<size_t>(DynParam.Mincr_rel(j) * M), M + DynParam.Mincr_abs(j));
731 M = min(Mnew, GlobParam.Mlimit);
732 lout << j <<
":" << M <<
" ";
748template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
752 Stopwatch<> HalfsweepTimer;
760 size_t halfsweepRange = (SweepStat.N_halfsweeps==0)? N_sites : N_sites-1;
762 double t_Lanczos = 0;
765 double t_overhead = 0;
772 sweep_to_edge(H,Vout,
true);
777 for (
size_t j=1; j<=halfsweepRange; ++j)
779 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
781 switch (DynParam.iteration(SweepStat.N_halfsweeps))
784 iteration_zero(H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead);
break;
787 iteration_one (H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead);
break;
798 iteration_two (H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead);
break;
801 ++SweepStat.N_sweepsteps;
803 ++SweepStat.N_halfsweeps;
805 calc_state_error(H,Vout,t_err);
810 Mmax = Vout.state.calc_Mmax();
811 Dmax = Vout.state.calc_Dmax();
812 Nqmax = Vout.state.calc_Nqmax();
813 totalTruncWeight = Vout.state.truncWeight.sum();
818 lout << eigeninfo() <<
", α=" << Vout.state.alpha_rsvd << endl;
819 size_t standard_precision = cout.precision();
820 if (EDGE == LANCZOS::EDGE::GROUND)
822 lout <<
"E₀=" << setprecision(15) << Vout.energy <<
", E₀/L=" << Vout.energy/N_phys << setprecision(standard_precision) << endl;
826 lout <<
"Eₘₐₓ=" << setprecision(15) << Vout.energy <<
", Eₘₐₓ/L=" << Vout.energy/N_phys << setprecision(standard_precision) << endl;
828 if (overlaps.rows() > 0)
830 if (gap<0) lout << termcolor::red;
831 lout <<
"gap=" << gap <<
", overlaps=" << overlaps.transpose() << endl;
832 if (gap<0) lout << termcolor::reset;
834 lout << errorCalcInfo.str();
835 lout << Vout.state.info() << endl;
836 double t_halfsweep = HalfsweepTimer.time();
837 lout << HalfsweepTimer.info(
"half-sweep")
839 <<
"Lanczos=" << round(t_Lanczos/t_halfsweep*100.,0) <<
"%"
840 <<
", sweeps=" << round(t_sweep/t_halfsweep*100.,0) <<
"%"
841 <<
", LR=" << round(t_LR/t_halfsweep*100.,0) <<
"%"
842 <<
", overhead=" << round(t_overhead/t_halfsweep*100.,0) <<
"%"
843 <<
", err=" << round(t_err/t_halfsweep*100.,0) <<
"%"
865 for (
int o=0; o<observables.size(); ++o)
867 Scalar res =
avg(Vout.state, observables[o], Vout.state);
868 lout << obs_labels[o] <<
"=" << res;
869 if (obs_labels[o] ==
"S(S+1)") lout <<
" -> Stot=" <<
calc_S_from_SSp1(real(res));
870 if (obs_normalizations[o] != 1.) lout <<
", normalized=" << res/obs_normalizations[o];
876template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
880 errorCalcInfo.clear();
881 errorCalcInfo.str(
"");
883 err_eigval_prev = err_eigval;
884 err_eigval = abs(Eold-Vout.energy)/this->N_sites;
888 Stopwatch<> ErrTimer;
889 err_state = abs(1.-abs(
dot(Vout.state,Vref)));
890 t_err += ErrTimer.time();
894 Stopwatch<> HsqTimer;
900 avgHsq = (H[0].check_power(2ul) ==
true)? real(
avg(Vout.state,H[0],Vout.state,2,DIR)) : avgHsq = real(
avg(Vout.state,H[0],H[0],Vout.state));;
904 ArrayXXd avgTerms(H.size(),H.size());
906 for (
int t1=0; t1<H.size(); ++t1)
907 for (
int t2=0; t2<H.size(); ++t2)
909 if (t1 == t2 and H[t1].check_power(2ul) ==
true)
911 avgTerms(t1,t1) = real(
avg(Vout.state,H[t1],Vout.state,2,DIR));
915 avgTerms(t1,t2) = real(
avg(Vout.state,H[t1],H[t2],Vout.state));
918 avgHsq = avgTerms.sum();
920 err_state = abs(avgHsq-pow(Vout.energy,2))/this->N_sites;
922 t_err += HsqTimer.time();
923 if (CHOSEN_VERBOSITY>=2)
925 errorCalcInfo << HsqTimer.info(
"<H^2>") << endl;
930 Stopwatch<> HsqTimer;
936 sweep_to_edge(H,Vout,
true);
937 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
941 vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > Nsaved(N_sites);
945 for (
size_t l=0; l<N_sites; ++l)
948 Stopwatch<> NspTimer;
949 Vout.state.calc_N(SweepStat.CURRENT_DIRECTION, SweepStat.pivot, Nsaved[SweepStat.pivot]);
950 t_Nsp += NspTimer.time();
953 Stopwatch<> GRALFtimer;
955 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
959 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Errt(H.size());
960 for (
size_t t=0; t<H.size(); ++t)
962 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
963 contract_GRALF (Heff_curr.Terms[t].L, Vout.state.A[SweepStat.pivot], H[t].W[SweepStat.pivot],
964 Nsaved[SweepStat.pivot], Heff_curr.Terms[t].R,
965 H[t].locBasis(SweepStat.pivot), H[t].opBasis(SweepStat.pivot), Errt[t],
966 SweepStat.CURRENT_DIRECTION);
968 contract_GRALF (Heff[SweepStat.pivot].Terms[t].L, Vout.state.A[SweepStat.pivot],
969 H[t].W[SweepStat.pivot],
970 Nsaved[SweepStat.pivot], Heff[SweepStat.pivot].Terms[t].R,
971 H[t].locBasis(SweepStat.pivot), H[t].opBasis(SweepStat.pivot), Errt[t],
972 SweepStat.CURRENT_DIRECTION);
977 for (
size_t t=1; t<H.size(); ++t) Err.
addScale(1.,Errt[t]);
978 if (H.size() > 0) Err = Err.
cleaned();
982 t_GRALF += GRALFtimer.time();
989 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot,
DMRG::BROOM::QR);
990 t_QR += QRtimer.time();
993 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_L(H,Vout,++SweepStat.pivot) : build_R(H,Vout,--SweepStat.pivot);
994 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_PL(H,Vout,SweepStat.pivot) : build_PR(H,Vout,SweepStat.pivot);
995 t_LR += LRtimer.time();
1000 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
1003 for (
size_t bond=0; bond<this->N_sites-1; ++bond)
1006 size_t loc1 = (SweepStat.CURRENT_DIRECTION==
DMRG::DIRECTION::RIGHT)? SweepStat.pivot : SweepStat.pivot-1;
1007 size_t loc2 = (SweepStat.CURRENT_DIRECTION==
DMRG::DIRECTION::RIGHT)? SweepStat.pivot+1 : SweepStat.pivot;
1010 #if defined(DMRG_SOLVER_MEMEFFICIENT_ENV)
1013 Heff_loc1.
Terms.resize(H.size());
1014 Heff_loc2.
Terms.resize(H.size());
1015 for (
size_t t=0; t<H.size(); ++t)
1017 Heff_loc1.
Terms[t].L.load(make_string(EnvSaveLabel,
"_L_t=",t,
"_l=",loc1));
1018 Heff_loc1.
Terms[t].R.load(make_string(EnvSaveLabel,
"_R_t=",t,
"_l=",loc1));
1019 Heff_loc2.
Terms[t].L.load(make_string(EnvSaveLabel,
"_L_t=",t,
"_l=",loc2));
1020 Heff_loc2.
Terms[t].R.load(make_string(EnvSaveLabel,
"_R_t=",t,
"_l=",loc2));
1025 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > N;
1032 Stopwatch<> NspTimer;
1034 t_Nsp += NspTimer.time();
1038 Stopwatch<> LRtimer1;
1039 vector<Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Yt(H.size());
1040 for (
size_t t=0; t<H.size(); ++t)
1042 #if defined(DMRG_SOLVER_MEMEFFICIENT_ENV)
1043 contract_R(Heff_loc2.
Terms[t].R, Vout.state.A[loc2], H[t].W[loc2], N, H[t].locBasis(loc2), H[t].opBasis(loc2), Yt[t]);
1045 contract_R(Heff[loc2].Terms[t].R, Vout.state.A[loc2], H[t].W[loc2], N, H[t].locBasis(loc2), H[t].opBasis(loc2), Yt[t]);
1048 t_LR += LRtimer1.time();
1058 Stopwatch<> NspTimer;
1060 t_Nsp += NspTimer.time();
1062 Stopwatch<> GRALFtimer;
1064 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Err2t(H.size());
1065 for (
size_t t=0; t<H.size(); ++t)
1067 #if defined(DMRG_SOLVER_MEMEFFICIENT_ENV)
1071 contract_GRALF (Heff[loc1].Terms[t].L, Vout.state.A[loc1], H[t].W[loc1], N, Yt[t],
1077 for (
size_t t=1; t<H.size(); ++t) Err2.
addScale(1.,Err2t[t]);
1078 if (H.size() > 0) Err2 = Err2.
cleaned();
1082 t_GRALF += GRALFtimer.time();
1086 Stopwatch<> QRtimer;
1087 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot,
DMRG::BROOM::QR);
1088 t_QR += QRtimer.time();
1091 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1095 Stopwatch<> LRtimer2;
1096 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_L(H,Vout,++SweepStat.pivot) : build_R(H,Vout,--SweepStat.pivot);
1097 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_PL(H,Vout,SweepStat.pivot) : build_PR(H,Vout,SweepStat.pivot);
1098 t_LR += LRtimer2.time();
1102 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
1103 Stopwatch<> QRtimer;
1104 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot,
DMRG::BROOM::QR);
1105 t_QR += QRtimer.time();
1106 Stopwatch<> LRtimer;
1107 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_L(H,Vout,++SweepStat.pivot) : build_R(H,Vout,--SweepStat.pivot);
1108 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_PL(H,Vout,SweepStat.pivot) : build_PR(H,Vout,SweepStat.pivot);
1109 t_LR += LRtimer.time();
1111 err_state /= this->N_sites;
1113 if (CHOSEN_VERBOSITY>=2)
1115 double t_tot = HsqTimer.time();
1117 errorCalcInfo << HsqTimer.info(
"2-site variance")
1119 <<
"GRALF=" << round(t_GRALF/t_tot*100.,0) <<
"%"
1120 <<
", LR=" << round(t_LR/t_tot*100.,0) <<
"%"
1121 <<
", Nsp=" << round(t_Nsp/t_tot*100.,0) <<
"%"
1122 <<
", QR=" << round(t_QR/t_tot*100.,0) <<
"%"
1153 assert(H.size() == 1 and
"DMRG::CONVTEST::VAR_FULL is not implemented for several terms!");
1154 Stopwatch<> HsqTimer;
1159 HxV(H[0], Psi, HxPsi,
false);
1162 ExPsi *= Vout.energy;
1165 err_state = std::real(HxPsi.
dot(HxPsi)) / this->N_sites;
1166 double t_tot = HsqTimer.time();
1168 if (CHOSEN_VERBOSITY >= 2)
1170 errorCalcInfo << HsqTimer.
info(
"‖H|Ψ>-E|Ψ>‖/L") << endl;
1177template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1180 double &time_lanczos,
double &time_sweep,
double &time_LR,
double &time_overhead)
1182 assert(H.size() == 1 and
"iteration_zero is not implemented for several terms!");
1184 double Ei = Vout.energy;
1186 Stopwatch<> OheadTimer;
1187 Eigenstate<PivotVector<Symmetry,Scalar> > g;
1188 int old_pivot = SweepStat.pivot;
1189 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? Vout.state.rightSplitStep(SweepStat.pivot,g.state.data[0]):
1190 Vout.state.leftSplitStep(SweepStat.pivot,g.state.data[0]);
1191 SweepStat.pivot = Vout.state.get_pivot();
1192 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_L(H,Vout,SweepStat.pivot) : build_R(H,Vout,SweepStat.pivot);
1198 time_overhead += OheadTimer.time();
1200 Stopwatch<> LanczosTimer;
1203 Lutz.set_efficiency(LANCZOS::EFFICIENCY::TIME);
1204 Lutz.set_dimK(min(LocParam.dimK,
dim(g.state)));
1205 Lutz.edgeState(Heff0, g, EDGE, LocParam.tol_eigval, LocParam.tol_state,
false);
1209 lout <<
"loc=" << SweepStat.pivot <<
"\t" << Lutz.info() << endl;
1210 lout << Vout.state.test_ortho() <<
", E=" << g.energy << endl;
1213 Vout.energy = g.energy;
1214 Vout.state.absorb(SweepStat.pivot, SweepStat.CURRENT_DIRECTION, g.state.data[0]);
1216 DeltaEopt = Ei-Vout.energy;
1217 time_lanczos += LanczosTimer.time();
1231 adapt_alpha_rsvd(H,Vout,EDGE);
1234template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1237 double &time_lanczos,
double &time_sweep,
double &time_LR,
double &time_overhead)
1240 double Ei = Vout.energy;
1242 Stopwatch<> OheadTimer;
1244 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1246 for (
size_t t=0; t<H.size(); ++t) Heff_curr.Terms[t].W = H[t].W[SweepStat.pivot];
1251 Vout.state.A[SweepStat.pivot], H[0].W[SweepStat.pivot], Vout.state.A[SweepStat.pivot],
1252 Heff_curr.Terms[0].R,
1253 H[0].locBasis(SweepStat.pivot), H[0].opBasis(SweepStat.pivot),
1254 Heff_curr.qlhs, Heff_curr.qrhs, Heff_curr.factor_cgcs);
1257 for (
int t=0; t<H.size(); ++t)
1259 Heff_curr.Terms[t].qloc = H[t].locBasis(SweepStat.pivot);
1260 Heff_curr.Terms[t].qOp = H[t].opBasis (SweepStat.pivot);
1263 for (
size_t t=0; t<H.size(); ++t) Heff[SweepStat.pivot].Terms[t].W = H[t].W[SweepStat.pivot];
1268 Vout.state.A[SweepStat.pivot], Heff[SweepStat.pivot].Terms[0].W, Vout.state.A[SweepStat.pivot],
1269 Heff[SweepStat.pivot].Terms[0].R,
1270 H[0].locBasis(SweepStat.pivot), H[0].opBasis(SweepStat.pivot),
1271 Heff[SweepStat.pivot].qlhs, Heff[SweepStat.pivot].qrhs, Heff[SweepStat.pivot].factor_cgcs);
1274 for (
int t=0; t<H.size(); ++t)
1276 Heff[SweepStat.pivot].Terms[t].qloc = H[t].locBasis(SweepStat.pivot);
1277 Heff[SweepStat.pivot].Terms[t].qOp = H[t].opBasis (SweepStat.pivot);
1282 if (Psi0.size() > 0)
1284 Heff[SweepStat.pivot].A0proj.resize(Psi0.size());
1285 for (
int n=0; n<Psi0.size(); ++n)
1287 Heff[SweepStat.pivot].A0proj[n].resize(Psi0[n].
A[SweepStat.pivot].size());
1290 for (
int n=0; n<Psi0.size(); ++n)
1296 Heff[SweepStat.pivot].A0proj[n] = Aout.
data;
1300 Eigenstate<PivotVector<Symmetry,Scalar> > g;
1302 g.state /= sqrt(
dot(g.state,g.state));
1303 time_overhead += OheadTimer.time();
1305 Stopwatch<> LanczosTimer;
1308 Lutz.set_efficiency(LANCZOS::EFFICIENCY::TIME);
1309 Lutz.set_dimK(min(LocParam.dimK,
dim(g.state)));
1310 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1311 Lutz.edgeState(Heff_curr, g, EDGE, LocParam.tol_eigval, LocParam.tol_state,
false);
1313 Lutz.edgeState(Heff[SweepStat.pivot], g, EDGE, LocParam.tol_eigval, LocParam.tol_state,
false);
1316 if (Psi0.size() > 0)
1325 overlaps.resize(Psi0.size());
1326 for (
int n=0; n<Psi0.size(); ++n)
1329 for (
size_t s=0; s<Heff[SweepStat.pivot].A0proj[n].size(); ++s)
1331 overlap += Heff[SweepStat.pivot].A0proj[n][s].adjoint().contract(g.state.data[s]).trace();
1333 overlaps(n) = std::abs(overlap);
1342 lout <<
"loc=" << SweepStat.pivot <<
"\t" << Lutz.info() << endl;
1343 lout << Vout.state.test_ortho() <<
", E=" << g.energy << endl;
1344 lout <<
"DmrgSolver.mem=" << round(memory(GB),3) <<
"GB" <<
", Vout.mem=" << round(Vout.state.memory(GB),3) <<
"GB" << endl;
1347 Vout.energy = g.energy;
1348 Vout.state.A[SweepStat.pivot] = g.state.data;
1349 DeltaEopt = Ei-Vout.energy;
1350 time_lanczos += LanczosTimer.time();
1353 Vout.state.min_Nsv = DynParam.min_Nsv(SweepStat.N_halfsweeps);
1354 Vout.state.max_Nrich = DynParam.max_Nrich(SweepStat.N_halfsweeps);
1355 Stopwatch<> SweepTimer;
1356 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1357 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot,
DMRG::BROOM::RICH_SVD, &Heff_curr);
1359 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot,
DMRG::BROOM::RICH_SVD, &Heff[SweepStat.pivot]);
1361 time_sweep += SweepTimer.time();
1363 Stopwatch<> LRtimer;
1364 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_L(H,Vout,++SweepStat.pivot) : build_R(H,Vout,--SweepStat.pivot);
1365 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_PL(H,Vout,SweepStat.pivot) : build_PR(H,Vout,SweepStat.pivot);
1366 time_LR += LRtimer.time();
1368 adapt_alpha_rsvd(H,Vout,EDGE);
1370 if (!Vout.state.Boundaries.IS_TRIVIAL())
1372 double norm = std::real(Vout.state.dot(Vout.state));
1373 Vout.state /= sqrt(Vout.state.dot(Vout.state));
1378#ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1379template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1383 for (
int t=0; t<H.size(); ++t)
1387 Heff_curr.Terms[t].L.load(make_string(EnvSaveLabel,
"_L_t=",t,
"_l=",SweepStat.pivot));
1391 Heff_curr.Terms[t].R.load(make_string(EnvSaveLabel,
"_R_t=",t,
"_l=",SweepStat.pivot));
1397template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1400 double &time_lanczos,
double &time_sweep,
double &time_LR,
double &time_overhead)
1403 double Ei = Vout.energy;
1405 Stopwatch<> OheadTimer;
1406 Eigenstate<PivotVector<Symmetry,Scalar> > g;
1408 Vout.state.A[loc2()], Vout.state.locBasis(loc2()),
1409 Vout.state.QoutTop[loc1()], Vout.state.QoutBot[loc1()]);
1416 Heff2.
Terms.resize(H.size());
1417 for (
int t=0; t<H.size(); ++t)
1419 Heff2.
Terms[t].L = Heff[loc1()].Terms[t].L;
1420 Heff2.
Terms[t].R = Heff[loc2()].Terms[t].R;
1421 Heff2.
Terms[t].W12 = H[t].W[loc1()];
1422 Heff2.
Terms[t].W34 = H[t].W[loc2()];
1423 Heff2.
Terms[t].qloc12 = H[t].locBasis(loc1());
1424 Heff2.
Terms[t].qloc34 = H[t].locBasis(loc2());
1425 Heff2.
Terms[t].qOp12 = H[t].opBasis(loc1());
1426 Heff2.
Terms[t].qOp34 = H[t].opBasis(loc2());
1432 H[0].locBasis(loc1()), H[0].locBasis(loc2()), H[0].opBasis(loc1()), H[0].opBasis(loc2()),
1437 if (Psi0.size() > 0)
1442 vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > A0pair(Psi0.size());
1443 for (
int n=0; n<Psi0.size(); ++n)
1446 Psi0[n].
A[loc2()], Psi0[n].locBasis(loc2()),
1450 Heff2.
A0proj.resize(Psi0.size());
1451 for (
int n=0; n<Psi0.size(); ++n) Heff2.
A0proj[n].resize(A0pair[n].size());
1453 for (
int n=0; n<Psi0.size(); ++n)
1464 time_overhead += OheadTimer.time();
1466 Stopwatch<> LanczosTimer;
1469 Lutz.set_efficiency(LANCZOS::EFFICIENCY::TIME);
1470 Lutz.set_dimK(min(LocParam.dimK,
dim(g.state)));
1471 Lutz.edgeState(Heff2, g, EDGE, LocParam.tol_eigval, LocParam.tol_state,
false);
1472 time_lanczos += LanczosTimer.time();
1474 if (Psi0.size() > 0)
1483 overlaps.resize(Psi0.size());
1484 for (
int n=0; n<Psi0.size(); ++n)
1487 for (
size_t s=0; s<Heff2.
A0proj[n].size(); ++s)
1489 overlap += Heff2.
A0proj[n][s].adjoint().contract(g.state.data[s]).trace();
1491 overlaps(n) = std::abs(overlap);
1499 lout <<
"loc=" << SweepStat.pivot <<
"\t" << Lutz.info() << endl;
1500 lout << Vout.state.test_ortho() <<
", E=" << g.energy << endl;
1501 lout <<
"DmrgSolver.mem=" << round(memory(GB),3) <<
"GB" <<
", Vout.mem=" << round(Vout.state.memory(GB),3) <<
"GB" << endl;
1504 Vout.energy = g.energy;
1505 for (
size_t s=0; s<g.state.data.size(); ++s)
1507 g.state.data[s] = g.state.data[s].cleaned();
1510 DeltaEopt = Ei-Vout.energy;
1513 Vout.state.min_Nsv = DynParam.min_Nsv(SweepStat.N_halfsweeps);
1514 Vout.state.max_Nrich = DynParam.max_Nrich(SweepStat.N_halfsweeps);
1515 Stopwatch<> SweepTimer;
1516 Vout.state.sweepStep2(SweepStat.CURRENT_DIRECTION, loc1(), g.state.data);
1517 time_sweep += SweepTimer.time();
1519 Stopwatch<> LRtimer;
1520 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_L(H,Vout,++SweepStat.pivot) : build_R(H,Vout,--SweepStat.pivot);
1521 (SweepStat.CURRENT_DIRECTION ==
DMRG::DIRECTION::RIGHT)? build_PL(H,Vout,SweepStat.pivot) : build_PR(H,Vout,SweepStat.pivot);
1522 time_LR += LRtimer.time();
1525template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1529 assert(SweepStat.pivot == 0 or SweepStat.pivot==1 or SweepStat.pivot==N_sites-2 or SweepStat.pivot==N_sites-1);
1533 if (SweepStat.pivot==1)
1536 if (MAKE_ENVIRONMENT)
1539 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1540 Heff_curr = Heff_next;
1542 SweepStat.pivot = 0;
1545 else if (SweepStat.pivot==N_sites-2)
1548 if (MAKE_ENVIRONMENT)
1550 build_L(H,Vout,N_sites-1);
1551 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1552 Heff_curr = Heff_next;
1554 SweepStat.pivot = N_sites-1;
1559template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1563 sweep_to_edge(H,Vout,
false);
1565 if (GlobParam.CALC_S_ON_EXIT)
1570 if (GlobParam.CALC_ERR_ON_EXIT)
1573 SweepStat.N_halfsweeps += GlobParam.min_halfsweeps+1;
1575 calc_state_error(H,Vout,t_err);
1576 SweepStat.N_halfsweeps = GlobParam.min_halfsweeps;
1579 lout << Timer.info(
"final err computation") <<
", err_state=" << err_state << endl;
1585 size_t standard_precision = cout.precision();
1586 string Eedge = (EDGE == LANCZOS::EDGE::GROUND)?
"Emin" :
"Emax";
1587 lout << termcolor::bold << Eedge <<
"=" << setprecision(15) << Vout.energy <<
", "
1588 << Eedge <<
"/L=" << Vout.energy/N_phys;
1589 if (Psi0.size() > 0)
1591 lout <<
", gap=" << setprecision(16) << Vout.energy-E0;
1593 lout << setprecision(standard_precision) << termcolor::reset << endl;
1594 lout << eigeninfo() << endl;
1595 lout << Vout.state.info() << endl;
1597 if (GlobParam.CALC_S_ON_EXIT)
1601 p.label =
"Entropy";
1602 if (Vout.state.entropy().rows() > 1)
1604 TerminalPlot::plot(Vout.state.entropy(),p);
1610 if (N_sites>4 and GlobParam.CALC_S_ON_EXIT)
1612 size_t l_start = N_sites%2 == 0 ? N_sites/2ul : (N_sites+1ul)/2ul;
1614 for (
size_t l=l_start; l<=l_start+1; l++)
1616 auto [qs,svs] = Vout.state.entanglementSpectrumLoc(l);
1617 ofstream Filer(make_string(
"sv_final_",l,
".dat"));
1619 for (
size_t i=0; i<svs.size(); i++)
1621 for (
size_t deg=0; deg<Symmetry::degeneracy(qs[i]); deg++)
1623 Filer << index <<
"\t" << qs[i] <<
"\t" << svs[i] << endl;
1631 if (Vout.state.calc_Nqavg() <= 1.5 and !Symmetry::IS_TRIVIAL and Vout.state.min_Nsv == 0)
1633 Vout.state.min_Nsv = 1;
1634 lout << termcolor::blue <<
"DmrgSolver::cleanup notice: Setting min_Nsv=1 do deal with small Hilbert space!" << termcolor::reset << endl;
1637 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1638 std::array<string,2> LR = {
"L",
"R"};
1639 for (
int i=0; i<2; ++i)
1640 for (
size_t t=0; t<H.size(); ++t)
1641 for (
size_t l=0; l<N_sites; ++l)
1643 std::string filename = make_string(EnvSaveLabel,
"_",LR[i],
"_t=",t,
"_l=",l,
".h5");
1649 if (remove(filename.c_str()) != 0)
1651 perror(make_string(
"Error deleting file ",filename).c_str());
1655 lout << termcolor::green <<
"File " << filename <<
" successfully deleted" << termcolor::reset << endl;
1661template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1665 edgeState(vector<MpHamiltonian>{H}, Vout, Qtot_input, EDGE, USE_STATE);
1668template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1672 prepare(H, Vout, Qtot_input, USE_STATE);
1677 Hinfo = H[0].info();
1680 for (
size_t t=0; t<H.size(); ++t)
1682 ss <<
"Term#" << t <<
":" << H[t].info() <<
";";
1686 Stopwatch<> TotalTimer;
1688 bool MESSAGE_ALPHA =
false;
1691 if (DynParam.Mincr_per(0) == 0)
1694 size_t max_Nsv_new = max(
static_cast<size_t>(DynParam.Mincr_rel(0) * Vout.state.max_Nsv),
1695 Vout.state.max_Nsv + DynParam.Mincr_abs(0));
1697 Vout.state.max_Nsv = min(max_Nsv_new, GlobParam.Mlimit);
1701 if (Vout.state.max_Nsv != Mmax_old)
1703 lout <<
"Mmax=" << Mmax_old <<
"→" << Vout.state.max_Nsv << endl;
1704 Mmax_old = Vout.state.max_Nsv;
1711 while (((err_eigval >= GlobParam.tol_eigval or err_state >= GlobParam.tol_state) and SweepStat.N_halfsweeps < GlobParam.max_halfsweeps) or
1712 SweepStat.N_halfsweeps < GlobParam.min_halfsweeps)
1715 min_alpha_rsvd = DynParam.min_alpha_rsvd(SweepStat.N_halfsweeps);
1716 max_alpha_rsvd = DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps);
1719 max_alpha_rsvd == 0. and
1720 MESSAGE_ALPHA ==
false)
1722 lout <<
"α_rsvd is turned off now!" << endl << endl;
1723 MESSAGE_ALPHA =
true;
1727 halfsweep(H,Vout,EDGE);
1731 if (DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps-1) == 0. and DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps) != 0.)
1733 Vout.state.alpha_rsvd = DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps);
1736 lout << endl <<
"α_rsvd set to: " << Vout.state.alpha_rsvd <<
" for halfsweep " << SweepStat.N_halfsweeps << endl << endl;
1740 size_t j = SweepStat.N_halfsweeps;
1742 DynParam.doSomething(j);
1745 Vout.state.eps_svd = DynParam.eps_svd(j);
1746 Vout.state.eps_truncWeight = DynParam.eps_truncWeight(j);
1748 if (j%DynParam.Mincr_per(j) == 0)
1752 size_t max_Nsv_new = max(
static_cast<size_t>(DynParam.Mincr_rel(j) * Vout.state.max_Nsv),
1753 Vout.state.max_Nsv + DynParam.Mincr_abs(j));
1755 Vout.state.max_Nsv = min(max_Nsv_new, GlobParam.Mlimit);
1760 if (Vout.state.max_Nsv != Mmax_old)
1762 lout <<
"Mmax=" << Mmax_old <<
"→" << Vout.state.max_Nsv << endl;
1763 Mmax_old = Vout.state.max_Nsv;
1768 #ifdef USE_HDF5_STORAGE
1769 if (GlobParam.savePeriod != 0 and j%GlobParam.savePeriod == 0)
1771 lout << termcolor::green <<
"saving state to: " << GlobParam.saveName << termcolor::reset << endl;
1772 Vout.state.save(GlobParam.saveName, Hinfo, Vout.energy);
1773 lout << termcolor::green <<
"saved state to: " << GlobParam.saveName <<
"!" << termcolor::reset << endl;
1778 #ifdef USE_HDF5_STORAGE
1779 if (GlobParam.savePeriod != 0)
1781 string filename = make_string(GlobParam.saveName,
"_fullMmax=",Vout.state.calc_fullMmax());
1782 lout << termcolor::green <<
"saving final state to: " << filename << termcolor::reset << endl;
1783 Vout.state.save(filename, Hinfo, Vout.energy);
1789 lout << TotalTimer.info(
"total runtime") << endl;
1791 cleanup(H,Vout,EDGE);
1794template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1798 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1803 if (Psi0.size() > 0)
1805 Heff[SweepStat.pivot].A0proj.resize(Psi0.size());
1806 for (
int n=0; n<Psi0.size(); ++n)
1808 Heff[SweepStat.pivot].A0proj[n].resize(Psi0[n].
A[SweepStat.pivot].size());
1811 for (
int n=0; n<Psi0.size(); ++n)
1812 for (
int s=0; s<Psi0[n].A[SweepStat.pivot].size(); ++s)
1818 Heff[SweepStat.pivot].A0proj[n] = Aout.
data;
1830 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1831 for (
size_t t=0; t<H.size(); ++t)
1833 Heff_curr.Terms[t].W = H[t].W[SweepStat.pivot];
1834 Heff_curr.Terms[t].qloc = H[t].locBasis(SweepStat.pivot);
1835 Heff_curr.Terms[t].qOp = H[t].opBasis (SweepStat.pivot);
1839 precalc_blockStructure (Heff_curr.Terms[0].L, Vout.state.A[SweepStat.pivot], Heff_curr.Terms[0].W, Vout.state.A[SweepStat.pivot], Heff_curr.Terms[0].R,
1840 H[0].locBasis(SweepStat.pivot), H[0].opBasis(SweepStat.pivot), Heff_curr.qlhs, Heff_curr.qrhs, Heff_curr.factor_cgcs);
1843 HxV(Heff_curr, Vtmp1, Vtmp2);
1845 for (
size_t t=0; t<H.size(); ++t)
1847 Heff[SweepStat.pivot].Terms[t].W = H[t].W[SweepStat.pivot];
1848 Heff[SweepStat.pivot].Terms[t].qloc = H[t].locBasis(SweepStat.pivot);
1849 Heff[SweepStat.pivot].Terms[t].qOp = H[t].opBasis (SweepStat.pivot);
1853 precalc_blockStructure (Heff[SweepStat.pivot].Terms[0].L, Vout.state.A[SweepStat.pivot], Heff[SweepStat.pivot].Terms[0].W, Vout.state.A[SweepStat.pivot], Heff[SweepStat.pivot].Terms[0].R,
1854 H[0].locBasis(SweepStat.pivot), H[0].opBasis(SweepStat.pivot), Heff[SweepStat.pivot].qlhs, Heff[SweepStat.pivot].qrhs, Heff[SweepStat.pivot].factor_cgcs);
1857 HxV(Heff[SweepStat.pivot], Vtmp1, Vtmp2);
1860 double DeltaEtrunc = std::real(
dot(Vtmp1,Vtmp2))-Vout.energy;
1867 double epsilon = 1e-9;
1868 if (abs(DeltaEopt) < epsilon or abs(DeltaEtrunc) < epsilon)
1870 if (abs(DeltaEtrunc) > epsilon) {f = 0.9;}
1875 double r = abs(DeltaEtrunc) / abs(DeltaEopt);
1876 if ((DeltaEtrunc < 0. and EDGE == LANCZOS::EDGE::GROUND) or
1877 (DeltaEtrunc > 0. and EDGE == LANCZOS::EDGE::ROOF)
1882 else if (r < 0.05) {f = 1.2-r;}
1883 else if (r > 0.3) {f = 1./(r+0.75);}
1887 f = max(GlobParam.falphamin,min(GlobParam.falphamax,f));
1888 Vout.state.alpha_rsvd *= f;
1893 double alpha_min = min(min_alpha_rsvd, max_alpha_rsvd);
1894 Vout.state.alpha_rsvd = max(alpha_min, min(max_alpha_rsvd, Vout.state.alpha_rsvd));
1900 lout <<
"ΔEopt=" << DeltaEopt <<
", ΔEtrunc=" << DeltaEtrunc <<
", α=" << Vout.state.alpha_rsvd << endl;
1941template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1947 for (
size_t t=0; t<H.size(); ++t)
1949 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1950 contract_L(Heff_curr.Terms[t].L, Vout.state.A[loc-1], H[t].W[loc-1], Vout.state.A[loc-1], H[t].locBasis(loc-1), H[t].opBasis(loc-1), Heff_next.Terms[t].L);
1951 Heff_next.Terms[t].L.save(make_string(EnvSaveLabel,
"_L_t=",t,
"_l=",loc));
1953 contract_L(Heff[loc-1].Terms[t].L, Vout.state.A[loc-1], H[t].W[loc-1], Vout.state.A[loc-1], H[t].locBasis(loc-1), H[t].opBasis(loc-1), Heff[loc].Terms[t].L);
1958template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1964 for (
size_t t=0; t<H.size(); ++t)
1966 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1967 contract_R(Heff_curr.Terms[t].R, Vout.state.A[loc+1], H[t].W[loc+1], Vout.state.A[loc+1], H[t].locBasis(loc+1), H[t].opBasis(loc+1), Heff_next.Terms[t].R);
1968 Heff_next.Terms[t].R.save(make_string(EnvSaveLabel,
"_R_t=",t,
"_l=",loc));
1970 contract_R(Heff[loc+1].Terms[t].R, Vout.state.A[loc+1], H[t].W[loc+1], Vout.state.A[loc+1], H[t].locBasis(loc+1), H[t].opBasis(loc+1), Heff[loc].Terms[t].R);
1975template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1979 for (
size_t n=0; n<Psi0.size(); ++n)
1982 contract_L(Heff[loc-1].PL[n], Vout.state.A[loc-1], Psi0[n].A[loc-1], H[0].locBasis(loc-1), Heff[loc].PL[n],
false,
true);
1983 Heff[loc].PL[n] = Heff[loc].PL[n].cleaned();
1987template<
typename Symmetry,
typename MpHamiltonian,
typename Scalar>
1991 for (
size_t n=0; n<Psi0.size(); ++n)
1994 contract_R(Heff[loc+1].PR[n], Vout.state.A[loc+1], Psi0[n].A[loc+1], H[0].locBasis(loc+1), Heff[loc].PR[n],
false,
true);
1995 Heff[loc].PR[n] = Heff[loc].PR[n].cleaned();
void contract_AA2(const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &A1, const vector< qarray< Symmetry::Nq > > &qloc1, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &A2, const vector< qarray< Symmetry::Nq > > &qloc2, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Apair, bool DRY=false)
void contract_GRALF(const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &L, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Aket, const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &R, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &Tout, DMRG::DIRECTION::OPTION DIR)
double calc_S_from_SSp1(double x)
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.
External functions to manipulate Mps and Mpo objects.
Scalar dot(const Mps< Symmetry, Scalar > &Vbra, const Mps< Symmetry, Scalar > &Vket)
Scalar avg(const Mps< Symmetry, Scalar > &Vbra, const Mpo< Symmetry, MpoScalar > &O, const Mps< Symmetry, Scalar > &Vket, size_t power_of_O=1ul, DMRG::DIRECTION::OPTION DIR=DMRG::DIRECTION::RIGHT, DMRG::VERBOSITY::OPTION CHOSEN_VERBOSITY=DMRG::VERBOSITY::SILENT)
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)
double norm(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
size_t dim(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
void LRxV(const PivotOverlap1< Symmetry, Scalar > &H, const PivotVector< Symmetry, Scalar > &Vin, PivotVector< Symmetry, Scalar > &Vout)
void sweep(size_t loc, DMRG::BROOM::OPTION TOOL, PivotMatrixType *H=NULL)
void build_R(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
void build_PL(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
void prepare(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, qarray< Nq > Qtot_input, bool USE_STATE=false)
void set_verbosity(DMRG::VERBOSITY::OPTION VERBOSITY)
void push_back(const Mps< Symmetry, Scalar > &Psi0_input)
void set_additional_terms(const vector< MpHamiltonian > &Hterms)
void edgeState(const MpHamiltonian &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, qarray< Nq > Qtot_input, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND, bool USE_STATE=false)
double get_errState() const
DMRG::CONTROL::LOC LocParam
DmrgSolver(DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
vector< PivotMatrix1< Symmetry, Scalar, Scalar > > Heff
stringstream errorCalcInfo
void build_PR(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
void adapt_alpha_rsvd(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE)
double get_direction() const
vector< Mpo< typename MpHamiltonian::Symmetry, typename MpHamiltonian::Scalar_ > > observables
void iteration_two(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE, double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead)
void sweep_to_edge(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, bool MAKE_ENVIRONMENT)
vector< string > obs_labels
void iteration_zero(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE, double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead)
void cleanup(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND)
void iteration_one(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE, double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead)
DMRG::CONTROL::GLOB GlobParam
void build_L(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
vector< Mps< Symmetry, Scalar > > Psi0
void halfsweep(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND)
DMRG::VERBOSITY::OPTION get_verbosity() const
void calc_state_error(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, double &t_err)
Mps< Symmetry, Scalar > Vref
static constexpr size_t Nq
vector< double > obs_normalizations
double memory(MEMUNIT memunit=GB) const
DMRG::VERBOSITY::OPTION CHOSEN_VERBOSITY
void set_observable(string label, const Mpo< typename MpHamiltonian::Symmetry, typename MpHamiltonian::Scalar_ > &Operator, double N=1.)
double get_errEigval() const
void set_SweepStatus(const SweepStatus &SweepStat_input)
DMRG::CONTROL::DYN DynParam
Scalar dot(const Mps< Symmetry, Scalar > &Vket) const
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 >, 3 > qarray3
void addScale(const Scalar &factor, const Biped< Symmetry, MatrixType_ > &Mrhs, BLOCK_POSITION BP=SAME_PLACE)
Biped< Symmetry, MatrixType_ > cleaned() const
Eigen::VectorXd squaredNorm() const
vector< PivotMatrix1Terms< Symmetry, Scalar, MpoScalar > > Terms
vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > A0proj
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
DMRG::DIRECTION::OPTION CURRENT_DIRECTION