VMPS++
Loading...
Searching...
No Matches
DmrgSolver.h
Go to the documentation of this file.
1#ifndef STRAWBERRY_DMRGSOLVER_WITH_Q
2#define STRAWBERRY_DMRGSOLVER_WITH_Q
3
4#ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
5#include <cstdlib> // For rand() and srand()
6#include <ctime> // For time()
7#include <cstdio> // For file access
8//#include <filesystem>
9#endif
10
12#include "termcolor.hpp" //from https://github.com/ikalnytskyi/termcolor
14
15#ifdef USE_HDF5_STORAGE
16 #include <HDF5Interface.h> // from TOOLS
17#endif
18
19#include "LanczosSolver.h" // from ALGS
20#include "Stopwatch.h" // from TOOLS
21#include "TerminalPlot.h"
22
23#include "Mps.h"
24#include "Mpo.h"
25#include "DmrgLinearAlgebra.h" // for avg()
27
28//include "solvers/MpsCompressor.h"
29//include "tensors/DmrgContractions.h"
30//include "Mpo.h"
31
33{
34 int pivot = -1;
36 size_t N_sweepsteps = 0;
37 size_t N_halfsweeps = 0;
38};
39
40template<typename Symmetry, typename MpHamiltonian, typename Scalar = double>
42{
43 static constexpr size_t Nq = Symmetry::Nq;
44 typedef typename Symmetry::qType qType;
45public:
46
48 :CHOSEN_VERBOSITY(VERBOSITY)
49 {};
50
51 string info() const;
52 string eigeninfo() const;
53 double memory (MEMUNIT memunit=GB) const;
54
55 void edgeState (const MpHamiltonian &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout,
56 qarray<Nq> Qtot_input, LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND, bool USE_STATE=false);
57
58 void edgeState (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout,
59 qarray<Nq> Qtot_input, LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND, bool USE_STATE=false);
60
61 //call this function if you want to set the parameters for the solver by yourself
65
69
70 inline void set_verbosity (DMRG::VERBOSITY::OPTION VERBOSITY) {CHOSEN_VERBOSITY = VERBOSITY;};
72
73 void set_additional_terms (const vector<MpHamiltonian> &Hterms);
74
75 void prepare (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout,
76 qarray<Nq> Qtot_input, bool USE_STATE=false);
77
78 void halfsweep (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout,
79 LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND);
80
81 void cleanup (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout,
82 LANCZOS::EDGE::OPTION EDGE = LANCZOS::EDGE::GROUND);
83
85
91 void iteration_zero (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE,
92 double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead);
98 void iteration_one (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE,
99 double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead);
106 void iteration_two (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE,
107 double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead);
109
111 inline double get_errEigval() const {return err_eigval;};
112
114 inline double get_errState() const {return err_state;};
115
117 inline double get_pivot() const {return SweepStat.pivot;};
118
120 inline double get_direction() const {return SweepStat.CURRENT_DIRECTION;};
121
122 void push_back (const Mps<Symmetry,Scalar> &Psi0_input) {Psi0.push_back(Psi0_input);};
123
124 #ifdef USE_HDF5_STORAGE
126 void save (string filename) const;
127
129 void load (string filename);
130 #endif
131
133 double Epenalty = 1e4;
134
135 inline void set_SweepStatus (const SweepStatus &SweepStat_input)
136 {
137 SweepStat = SweepStat_input;
138 }
139
142 {
143 obs_labels.push_back(label);
144 obs_normalizations.push_back(N);
145 observables.push_back(Operator);
146 }
147
148private:
149
151 size_t Dmax, Mmax, Nqmax;
153 size_t Mmax_old;
155
156 vector<PivotMatrix1<Symmetry,Scalar,Scalar> > Heff; // Scalar = MpoScalar for ground state
157
158 double Eold;
159
160 double DeltaEopt;
162
163 bool USER_SET_GLOBPARAM = false;
164 bool USER_SET_DYNPARAM = false;
165 bool USER_SET_LOCPARAM = false;
166
168
169 stringstream errorCalcInfo;
171 void calc_state_error (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, double &t_err);
172
175
176 // Not used anymore (?):
177 //void LanczosStep (const MpHamiltonian &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE);
178
179 void sweep_to_edge (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, bool MAKE_ENVIRONMENT);
180
182 void build_L (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc);
183
185 void build_R (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc);
186
187 void build_PL (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc);
188 void build_PR (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc);
189
190 void adapt_alpha_rsvd (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE);
191
193 vector<Mps<Symmetry,Scalar> > Psi0;
194 double E0;
195 VectorXd overlaps;
196 double gap;
197
199
200 vector<Mpo<typename MpHamiltonian::Symmetry,typename MpHamiltonian::Scalar_>> observables;
201 vector<string> obs_labels;
202 vector<double> obs_normalizations;
203
204 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
205 string EnvSaveLabel;
208 void load_pivot (const vector<MpHamiltonian> &H);
209 #endif
210};
211
212template<typename Symmetry, typename MpHamiltonian, typename Scalar>
214info() const
215{
216 stringstream ss;
217 ss << "DmrgSolver: ";
218 ss << "L=" << N_sites << ", ";
219 ss << "Mmax=" << Mmax << ", Dmax=" << Dmax << ", " << "Nqmax=" << Nqmax << ", ";
220 ss << "trunc_weight=" << totalTruncWeight << ", ";
221 ss << eigeninfo();
222 return ss.str();
223}
224
225template<typename Symmetry, typename MpHamiltonian, typename Scalar>
227eigeninfo() const
228{
229 stringstream ss;
230 ss << termcolor::colorize << termcolor::underline << "half-sweeps=" << SweepStat.N_halfsweeps;
231 ss << termcolor::reset;
232 ss << ", next algorithm=" << DynParam.iteration(SweepStat.N_halfsweeps);
233 ss << ", ";
234 ss << "err_eigval=" << err_eigval << ", err_state=" << err_state << ", ";
235 ss << "mem=" << round(memory(GB),3) << "GB";
236 return ss.str();
237}
238
239#ifdef USE_HDF5_STORAGE
240template<typename Symmetry, typename MpHamiltonian, typename Scalar>
242save (string filename) const
243{
244 filename+=".h5";
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");
254}
255
256template<typename Symmetry, typename MpHamiltonian, typename Scalar>
258load (string filename)
259{
260 filename+=".h5";
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");
265 int DIR_IN_INT;
266 source.load_scalar(DIR_IN_INT,"direction");
267 SweepStat.CURRENT_DIRECTION = static_cast<DMRG::DIRECTION::OPTION>(DIR_IN_INT);
268 source.load_scalar(err_eigval,"errorE");
269 source.load_scalar(err_state,"errorS");
270}
271#endif
272
273template<typename Symmetry, typename MpHamiltonian, typename Scalar>
275memory (MEMUNIT memunit) const
276{
277 double res = 0.;
278 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
279 res += Heff_curr.memory(memunit);
280 res += Heff_next.memory(memunit);
281 #else
282 for (size_t l=0; l<N_sites; ++l) res += Heff[l].memory(memunit);
283 #endif
284 return res;
285}
286
287template<typename Symmetry, typename MpHamiltonian, typename Scalar>
289prepare (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, qarray<Nq> Qtot_input, bool USE_STATE)
290{
291 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
292 srand(time(0));
293// std::filesystem::path folderPath = "./tmp";
294// if (!std::filesystem::exists(folderPath))
295// {
296// // Create the folder if it doesn't exist
297// if (std::filesystem::create_directory(folderPath))
298// {
299// lout << "Folder ./tmp created successfully." << endl;
300// }
301// else
302// {
303// cerr << "Failed to create folder ./tmp !" << endl;
304// }
305// }
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;
309 #endif
310
311 if (CHOSEN_VERBOSITY>=2)
312 {
313 lout << endl << termcolor::colorize << termcolor::bold
314 << "————————————————————————————————————————————DMRG Algorithm————————————————————————————————————————————"
315 << termcolor::reset << endl;
316 }
317
318 N_sites = H[0].length();
319 N_phys = H[0].volume();
320
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())
325 {
326 for (int t=0; t<H.size(); ++t)
327 {
328 Heff_curr.Terms[t].L.setVacuum();
329 Heff_curr.Terms[t].R.setTarget(qarray3<Nq>{Qtot_input, Qtot_input, Symmetry::qvacuum()});
330
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));
333 }
334 }
335 else
336 {
337 for (int t=0; t<H.size(); ++t)
338 {
339 Heff_curr.Terms[t].L = Vout.state.get_boundaryTensor(DMRG::DIRECTION::LEFT);
340 Heff_curr.Terms[t].R = Vout.state.get_boundaryTensor(DMRG::DIRECTION::RIGHT);
341
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));
344 }
345 }
346 #else
347 // set edges
348 Heff.clear();
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())
352 {
353 for (int t=0; t<H.size(); ++t)
354 {
355 Heff[0].Terms[t].L.setVacuum();
356 Heff[N_sites-1].Terms[t].R.setTarget(qarray3<Nq>{Qtot_input, Qtot_input, Symmetry::qvacuum()});
357 }
358 }
359 else
360 {
361 for (int t=0; t<H.size(); ++t)
362 {
363 Heff[0].Terms[t].L = Vout.state.get_boundaryTensor(DMRG::DIRECTION::LEFT);
364 Heff[N_sites-1].Terms[t].R = Vout.state.get_boundaryTensor(DMRG::DIRECTION::RIGHT);
365 }
366 }
367 #endif
368
369 Stopwatch<> PrepTimer;
370 if (!USE_STATE)
371 {
372 // resize Vout
373 auto Boundaries_tmp = Vout.state.Boundaries; // save to temporary, otherwise reset in the following constructor
374 Vout.state = Mps<Symmetry,Scalar>(H[0], GlobParam.Minit, Qtot_input, GlobParam.Qinit);
375// Vout.state.graph("init");
376 // reset stuff after constructor:
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;
381 // If boundaries not pre-set, set them to trivial now:
382 if (Vout.state.Boundaries.IS_TRIVIAL()) Vout.state.Boundaries.set_open_bc(Qtot_input);
383
384 Vout.state.update_inbase();
385 Vout.state.update_outbase();
386 Vout.state.calc_Qlimits();
387
388 Vout.state.setRandom();
389
390 // adjust corners for IBC
391 // ONLY IMPLEMENTED FOR ONE TERM
392 if (H[0].GOT_SEMIOPEN_LEFT or !H[0].get_boundary_condition())
393 {
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)
397 {
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)
400 {
401 if (Heff[N_sites-1].Terms[0].R.block[r][a][0].size() != 0)
402 {
403 if (Vout.state.A[N_sites-1][s].out[q] == Heff[N_sites-1].Terms[0].R.in(r))
404 {
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();
408 }
409 }
410 }
411 }
412 Vout.state.update_inbase();
413 Vout.state.update_outbase();
414 }
415 if (H[0].GOT_SEMIOPEN_RIGHT or !H[0].get_boundary_condition())
416 {
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)
420 {
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)
423 {
424 if (Heff[0].Terms[0].L.block[r][a][0].size() != 0)
425 {
426 if (Vout.state.A[0][s].in[q] == Heff[0].Terms[0].L.out(r))
427 {
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();
431 }
432 }
433 }
434 }
435 Vout.state.update_inbase();
436 Vout.state.update_outbase();
437 }
438
439 // leads to segfault with local basis:
440// if (!H.GOT_OPEN_BC)
441// {
442// for (int l=0; l<N_sites-1; ++l)
443// {
444// Vout.state.A[l] = Vout.state.Boundaries.A[0][l%Vout.state.Boundaries.length()];
445// }
446// Vout.state.A[N_sites-1] = Vout.state.Boundaries.A[2][(N_sites-1)%Vout.state.Boundaries.length()];
447//
448// Vout.state.update_inbase();
449// Vout.state.update_outbase();
450// }
451
452 Mmax_old = GlobParam.Minit;
453 }
454 else
455 {
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);
460// cout << termcolor::blue << "Vout.state.max_Nsv=" << Vout.state.max_Nsv << ", Mmax_old=" << Mmax_old << termcolor::reset << endl;
461 }
462
463// Vout.state.graph("ginit");
464
465 //if the SweepStatus is default initialized (pivot==-1), one initial sweep from right-to-left and N_halfsweeps = N_sweepsteps = 0,
466 //otherwise prepare for continuing at the given SweepStatus.
467 if (SweepStat.pivot == -1)
468 {
469 SweepStat.N_sweepsteps = SweepStat.N_halfsweeps = 0;
470 if (GlobParam.INITDIR == DMRG::DIRECTION::RIGHT)
471 {
472 for (int l=N_sites-1; l>0; --l)
473 {
474 if (!USE_STATE) {Vout.state.setRandom(l);} // Don't set random for loaded states.
475 Vout.state.sweepStep(DMRG::DIRECTION::LEFT, l, DMRG::BROOM::QR);
476 build_R(H,Vout,l-1);
477 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
478 Heff_curr = Heff_next;
479 #endif
480 }
481 Vout.state.sweepStep(DMRG::DIRECTION::LEFT, 0, DMRG::BROOM::QR, NULL, true); // removes large numbers from matrix
482 SweepStat.CURRENT_DIRECTION = DMRG::DIRECTION::RIGHT;
483 SweepStat.pivot = 0;
484 }
485 else
486 {
487 for (size_t l=0; l<N_sites-1; ++l)
488 {
489 if (!USE_STATE) {Vout.state.setRandom(l);} // Don't set random for loaded states.
490 Vout.state.sweepStep(DMRG::DIRECTION::RIGHT, l, DMRG::BROOM::QR);
491 build_L(H,Vout,l+1);
492 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
493 Heff_curr = Heff_next;
494 #endif
495 }
496 Vout.state.sweepStep(DMRG::DIRECTION::RIGHT, N_sites-1, DMRG::BROOM::QR, NULL, true); // removes large numbers from matrix
497 SweepStat.CURRENT_DIRECTION = DMRG::DIRECTION::LEFT;
498 SweepStat.pivot = N_sites-1;
499 }
500 }
501 else
502 {
503 if (SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT)
504 {
505 for (size_t l=N_sites-1; l>0; --l)
506 {
507 Vout.state.sweepStep(DMRG::DIRECTION::LEFT, l, DMRG::BROOM::QR);
508 build_R(H,Vout,l-1);
509 }
510 Vout.state.sweepStep(DMRG::DIRECTION::LEFT, 0, DMRG::BROOM::QR); // removes large numbers from first matrix
511
512 for (size_t l=0; l<SweepStat.pivot; ++l)
513 {
514 Vout.state.sweepStep(DMRG::DIRECTION::RIGHT, l, DMRG::BROOM::QR);
515 build_L(H,Vout,l+1);
516 }
517 }
518 else if (SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::LEFT)
519 {
520 for (size_t l=0; l<N_sites-1; ++l)
521 {
522 Vout.state.sweepStep(DMRG::DIRECTION::RIGHT, l, DMRG::BROOM::QR);
523 build_L(H,Vout,l+1);
524 }
525 Vout.state.sweepStep(DMRG::DIRECTION::RIGHT, N_sites-1, DMRG::BROOM::QR); // removes large numbers from first matrix
526
527 for (size_t l=N_sites-1; l>SweepStat.pivot; --l)
528 {
529 Vout.state.sweepStep(DMRG::DIRECTION::LEFT, l, DMRG::BROOM::QR);
530 build_R(H,Vout,l-1);
531 }
532 }
533 }
534
535 // resize environments for projected-out states
536 if (Psi0.size() > 0)
537 {
538 for (size_t l=0; l<N_sites; ++l)
539 {
540 Heff[l].Epenalty = Epenalty;
541 Heff[l].PL.resize(Psi0.size());
542 Heff[l].PR.resize(Psi0.size());
543 }
544 E0 = 0; //isReal(avg(Psi0[0], H, Psi0[0]));
545 for (int t=0; t<H.size(); ++t) E0 += real(avg(Psi0[0], H[t], Psi0[0]));
546 }
547
548 // build environments for projected-out states
549 // convention: Psi0 ist ket, current Psi is bra
550 for (size_t n=0; n<Psi0.size(); ++n)
551 {
552 Heff[0].PL[n].setVacuum();
553 for (size_t l=1; l<N_sites; ++l) build_PL(H,Vout,l);
554
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);
557 }
558
559 // initial energy
560 // NOT DONE FOR TERMS
561// if (SweepStat.pivot == 0)
562// {
563// Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > Rtmp;
564// contract_R(Heff[0].R, Vout.state.A[0], H.W[0], Vout.state.A[0], H.locBasis(0), H.opBasis(0), Rtmp);
565// if (Rtmp.dim == 0)
566// {
567// Eold = 0;
568// }
569// else
570// {
571// assert(Rtmp.dim == 1 and
572// Rtmp.block[0][0][0].rows() == 1 and
573// Rtmp.block[0][0][0].cols() == 1 and
574// "Result of contraction <ψ|H|ψ> in DmrgSolver::prepare is not a scalar!");
575// Eold = isReal(Rtmp.block[0][0][0](0,0));
576// }
577// }
578// else if (SweepStat.pivot == N_sites-1)
579// {
580// Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > Ltmp;
581// contract_L(Heff[N_sites-1].L, Vout.state.A[N_sites-1], H.W[N_sites-1], Vout.state.A[N_sites-1], H.locBasis(N_sites-1), H.opBasis(N_sites-1), Ltmp);
582// if (Ltmp.dim == 0)
583// {
584// Eold = 0;
585// }
586// else
587// {
588// assert(Ltmp.dim == 1 and
589// Ltmp.block[0][0][0].rows() == 1 and
590// Ltmp.block[0][0][0].cols() == 1 and
591// "Result of contraction <ψ|H|ψ> in DmrgSolver::prepare is not a scalar!");
592// Eold = isReal(Ltmp.block[0][0][0](0,0));
593// }
594// }
595// else
596// {
597// Eold = std::real(avg(Vout.state,H,Vout.state));
598// }
599// Vout.energy = Eold;
600 Eold = std::nan("0");
601 Vout.energy = Eold;
602
603 // initial cutoffs
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);
607
608 if (CHOSEN_VERBOSITY>=2)
609 {
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;
619 lout << endl;
620
621 lout << "• initial truncWeight value cutoff : ε_truncWeight=";
622 cout << termcolor::underline;
623 lout << Vout.state.eps_truncWeight;
624 cout << termcolor::reset;
625 lout << endl;
626
627 int i_alpha_switchoff=0;
628 for (int i=0; i<GlobParam.max_halfsweeps; ++i)
629 {
630 if (DynParam.max_alpha_rsvd(i) == 0.) {i_alpha_switchoff = i; break;}
631 }
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)
638 {
639 lout << "• fluctuations use ";
640 cout << termcolor::underline;
641 lout << "all";
642 cout << termcolor::reset;
643 lout << " additional states" << endl;
644 }
645 else
646 {
647 lout << "• fluctuations use ";
648 cout << termcolor::underline;
649 lout << Vout.state.max_Nrich;
650 cout << termcolor::reset;
651 lout << " additional states" << endl;
652 }
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;
661 lout << " every ";
662 cout << termcolor::underline;
663 lout << DynParam.Mincr_per(0);
664 cout << termcolor::reset;
665 lout << " half-sweeps" << endl;
666
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;
672
673 lout << "• make between ";
674 cout << termcolor::underline;
675 lout << GlobParam.min_halfsweeps;
676 cout << termcolor::reset;
677 lout << " and ";
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;
686 lout << endl;
687
688 lout << "• state tolerance: ";
689 cout << termcolor::underline;
690 lout << GlobParam.tol_state;
691 cout << termcolor::reset;
692 lout << " using ";
693 cout << termcolor::underline;
694 lout << GlobParam.CONVTEST;
695 cout << termcolor::reset;
696 lout << endl;
697
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;
706 lout << endl;
707
708 lout << "• calculate entropy on exit: " << boolalpha;
709 cout << termcolor::underline;
710 lout << GlobParam.CALC_S_ON_EXIT;
711 cout << termcolor::reset << endl;
712
713 lout << "• calculate 2-site variance exit: " << boolalpha;
714 cout << termcolor::underline;
715 lout << GlobParam.CALC_ERR_ON_EXIT;
716 cout << termcolor::reset << endl;
717
718 lout << "• bond dim. sequence: ";
719 size_t M = Vout.state.max_Nsv;
720 if (DynParam.Mincr_per(0) == 0)
721 {
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 << " ";
725 }
726 for (int j=1; j<GlobParam.max_halfsweeps; ++j)
727 {
728 if (j%DynParam.Mincr_per(j) == 0)
729 {
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 << " ";
733 }
734 }
735 lout << endl;
736
737 lout << endl;
738
739// Vout.state.graph("init");
740 }
741
742 err_eigval = 1.;
743 err_state = 1.;
744
745// Vout.state.graph("init");
746}
747
748template<typename Symmetry, typename MpHamiltonian, typename Scalar>
750halfsweep (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE)
751{
752 Stopwatch<> HalfsweepTimer;
753
754 // save state for reference
755 if (GlobParam.CONVTEST == DMRG::CONVTEST::NORM_TEST)
756 {
757 Vref = Vout.state;
758 }
759
760 size_t halfsweepRange = (SweepStat.N_halfsweeps==0)? N_sites : N_sites-1; // one extra step on 1st iteration
761
762 double t_Lanczos = 0;
763 double t_sweep = 0;
764 double t_LR = 0;
765 double t_overhead = 0;
766 double t_err = 0;
767
768 // If the next sweep is a 2-site or a 0-site sweep, move pivot back to edge. not sure if this is necessary for a 0-site sweep...
769 if (DynParam.iteration(SweepStat.N_halfsweeps) == DMRG::ITERATION::TWO_SITE or
770 DynParam.iteration(SweepStat.N_halfsweeps) == DMRG::ITERATION::ZERO_SITE)
771 {
772 sweep_to_edge(H,Vout,true); // build_LR = true
773 }
774
775 Eold = Vout.energy;
776
777 for (size_t j=1; j<=halfsweepRange; ++j)
778 {
779 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
780
781 switch (DynParam.iteration(SweepStat.N_halfsweeps))
782 {
784 iteration_zero(H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead); break;
785
787 iteration_one (H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead); break;
788
790 //if (err_eigval < GlobParam.tol_eigval and
791 // err_eigval_prev < GlobParam.tol_eigval and
792 // Vout.state.calc_Mmax() == GlobParam.Mlimit)
793 //{
794 // iteration_one (H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead); break;
795 //}
796 //else
797 //{
798 iteration_two (H, Vout, EDGE, t_Lanczos, t_sweep, t_LR, t_overhead); break;
799 //}
800 }
801 ++SweepStat.N_sweepsteps;
802 }
803 ++SweepStat.N_halfsweeps;
804
805 calc_state_error(H,Vout,t_err);
806
807 if (GlobParam.CONVTEST == DMRG::CONVTEST::NORM_TEST) Vref = Vout.state;
808
809 // calculate stats
810 Mmax = Vout.state.calc_Mmax();
811 Dmax = Vout.state.calc_Dmax();
812 Nqmax = Vout.state.calc_Nqmax();
813 totalTruncWeight = Vout.state.truncWeight.sum();
814
815 // print stuff
816 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
817 {
818 lout << eigeninfo() << ", α=" << Vout.state.alpha_rsvd << endl;
819 size_t standard_precision = cout.precision();
820 if (EDGE == LANCZOS::EDGE::GROUND)
821 {
822 lout << "E₀=" << setprecision(15) << Vout.energy << ", E₀/L=" << Vout.energy/N_phys << setprecision(standard_precision) << endl;
823 }
824 else
825 {
826 lout << "Eₘₐₓ=" << setprecision(15) << Vout.energy << ", Eₘₐₓ/L=" << Vout.energy/N_phys << setprecision(standard_precision) << endl;
827 }
828 if (overlaps.rows() > 0)
829 {
830 if (gap<0) lout << termcolor::red;
831 lout << "gap=" << gap << ", overlaps=" << overlaps.transpose() << endl;
832 if (gap<0) lout << termcolor::reset;
833 }
834 lout << errorCalcInfo.str();
835 lout << Vout.state.info() << endl;
836 double t_halfsweep = HalfsweepTimer.time();
837 lout << HalfsweepTimer.info("half-sweep")
838 << " ("
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) << "%"
844 << ")"
845 << endl;
846
847// // check qmid:
848// for (size_t l=0; l<N_sites; ++l)
849// {
850// set<qarray<Nq> > qmids;
851// for (size_t q=0; q<Heff[l].L.dim; ++q)
852// {
853// qmids.insert(Heff[l].L.mid(q));
854// }
855//
856// cout << "l=" << l << endl;
857// for (const auto &qmid:qmids)
858// {
859// cout << qmid << " ";
860// }
861// cout << endl;
862// }
863
864 // check some observables
865 for (int o=0; o<observables.size(); ++o)
866 {
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];
871 lout << endl;
872 }
873 }
874}
875
876template<typename Symmetry, typename MpHamiltonian, typename Scalar>
878calc_state_error (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, double &t_err)
879{
880 errorCalcInfo.clear();
881 errorCalcInfo.str("");
882
883 err_eigval_prev = err_eigval;
884 err_eigval = abs(Eold-Vout.energy)/this->N_sites;
885
886 if (GlobParam.CONVTEST == DMRG::CONVTEST::NORM_TEST and SweepStat.N_halfsweeps > GlobParam.min_halfsweeps)
887 {
888 Stopwatch<> ErrTimer;
889 err_state = abs(1.-abs(dot(Vout.state,Vref)));
890 t_err += ErrTimer.time();
891 }
892 else if (GlobParam.CONVTEST == DMRG::CONVTEST::VAR_HSQ and SweepStat.N_halfsweeps > GlobParam.min_halfsweeps)
893 {
894 Stopwatch<> HsqTimer;
895 DMRG::DIRECTION::OPTION DIR = (SweepStat.N_halfsweeps%2==0) ? DMRG::DIRECTION::RIGHT : DMRG::DIRECTION::LEFT;
896
897 double avgHsq = 0.;
898 if (H.size() == 1)
899 {
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));;
901 }
902 else
903 {
904 ArrayXXd avgTerms(H.size(),H.size());
905 avgTerms.setZero();
906 for (int t1=0; t1<H.size(); ++t1)
907 for (int t2=0; t2<H.size(); ++t2)
908 {
909 if (t1 == t2 and H[t1].check_power(2ul) == true)
910 {
911 avgTerms(t1,t1) = real(avg(Vout.state,H[t1],Vout.state,2,DIR));
912 }
913 else
914 {
915 avgTerms(t1,t2) = real(avg(Vout.state,H[t1],H[t2],Vout.state));
916 }
917 }
918 avgHsq = avgTerms.sum();
919 }
920 err_state = abs(avgHsq-pow(Vout.energy,2))/this->N_sites;
921
922 t_err += HsqTimer.time();
923 if (CHOSEN_VERBOSITY>=2)
924 {
925 errorCalcInfo << HsqTimer.info("<H^2>") << endl;
926 }
927 }
928 else if (GlobParam.CONVTEST == DMRG::CONVTEST::VAR_2SITE and SweepStat.N_halfsweeps > GlobParam.min_halfsweeps)
929 {
930 Stopwatch<> HsqTimer;
931 double t_LR = 0;
932 double t_Nsp = 0;
933 double t_QR = 0;
934 double t_GRALF = 0;
935
936 sweep_to_edge(H,Vout,true);
937 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
938
939 err_state = 0.;
940
941 vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > Nsaved(N_sites);
942 DMRG::DIRECTION::OPTION DIR_N = SweepStat.CURRENT_DIRECTION;
943
944 // one-site variance
945 for (size_t l=0; l<N_sites; ++l)
946 {
947 // calculate the nullspace tensor F/G
948 Stopwatch<> NspTimer;
949 Vout.state.calc_N(SweepStat.CURRENT_DIRECTION, SweepStat.pivot, Nsaved[SweepStat.pivot]);
950 t_Nsp += NspTimer.time();
951
952 // contract Fig. 4 top from Hubig, Haegeman, Schollwöck (PRB 97, 2018), arXiv:1711.01104
953 Stopwatch<> GRALFtimer;
954
955 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
956 load_pivot(H);
957 #endif
958
959 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Errt(H.size());
960 for (size_t t=0; t<H.size(); ++t)
961 {
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);
967 #else
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);
973 #endif
974 }
975
977 for (size_t t=1; t<H.size(); ++t) Err.addScale(1.,Errt[t]);
978 if (H.size() > 0) Err = Err.cleaned();
979
980 err_state += Err.squaredNorm().sum();
981
982 t_GRALF += GRALFtimer.time();
983
984 // sweep to next site
985 if ((l<N_sites-1 and DIR_N == DMRG::DIRECTION::RIGHT) or
986 (l>0 and DIR_N == DMRG::DIRECTION::LEFT))
987 {
988 Stopwatch<> QRtimer;
989 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot, DMRG::BROOM::QR);
990 t_QR += QRtimer.time();
991
992 Stopwatch<> LRtimer;
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();
996 }
997 }
998
999 //sweep_to_edge(H,Vout,true); // not necessary
1000 turnaround(SweepStat.pivot, N_sites, SweepStat.CURRENT_DIRECTION);
1001
1002 // two-site variance
1003 for (size_t bond=0; bond<this->N_sites-1; ++bond)
1004 {
1005 {
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;
1008
1009 // mem-efficient: load Heff[loc1] and Heff[loc2] from file
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)
1016 {
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));
1021 }
1022 #endif
1023
1024 // calculate the nullspace tensor F/G with QR_NULL
1025 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > N;
1026 if (DIR_N == DMRG::DIRECTION::LEFT)
1027 {
1028 N = Nsaved[loc2];
1029 }
1030 else
1031 {
1032 Stopwatch<> NspTimer;
1033 Vout.state.calc_N(DMRG::DIRECTION::LEFT, loc2, N);
1034 t_Nsp += NspTimer.time();
1035 }
1036
1037 // pre-contract the right site
1038 Stopwatch<> LRtimer1;
1039 vector<Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Yt(H.size());
1040 for (size_t t=0; t<H.size(); ++t)
1041 {
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]);
1044 #else
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]);
1046 #endif
1047 }
1048 t_LR += LRtimer1.time();
1049
1050 // complete the contraction in Fig. 4 bottom from Hubig, Haegeman, Schollwöck (PRB 97, 2018), arXiv:1711.01104
1051 N.clear();
1052 if (DIR_N == DMRG::DIRECTION::RIGHT)
1053 {
1054 N = Nsaved[loc1];
1055 }
1056 else
1057 {
1058 Stopwatch<> NspTimer;
1059 Vout.state.calc_N(DMRG::DIRECTION::RIGHT, loc1, N);
1060 t_Nsp += NspTimer.time();
1061 }
1062 Stopwatch<> GRALFtimer;
1063
1064 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Err2t(H.size());
1065 for (size_t t=0; t<H.size(); ++t)
1066 {
1067 #if defined(DMRG_SOLVER_MEMEFFICIENT_ENV)
1068 contract_GRALF (Heff_loc1.Terms[t].L, Vout.state.A[loc1], H[t].W[loc1], N, Yt[t],
1069 H[t].locBasis(loc1), H[t].opBasis(loc1), Err2t[t], DMRG::DIRECTION::RIGHT);
1070 #else
1071 contract_GRALF (Heff[loc1].Terms[t].L, Vout.state.A[loc1], H[t].W[loc1], N, Yt[t],
1072 H[t].locBasis(loc1), H[t].opBasis(loc1), Err2t[t], DMRG::DIRECTION::RIGHT);
1073 #endif
1074 }
1075
1077 for (size_t t=1; t<H.size(); ++t) Err2.addScale(1.,Err2t[t]);
1078 if (H.size() > 0) Err2 = Err2.cleaned();
1079
1080 err_state += Err2.squaredNorm().sum();
1081
1082 t_GRALF += GRALFtimer.time();
1083 }
1084
1085 // sweep to next site
1086 Stopwatch<> QRtimer;
1087 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot, DMRG::BROOM::QR);
1088 t_QR += QRtimer.time();
1089
1090 // A bit ugly: Must reload for correct save
1091 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1092 load_pivot(H);
1093 #endif
1094
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();
1099 }
1100
1101 // sweep back to the beginning (one site away from the edge)
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();
1110
1111 err_state /= this->N_sites;
1112
1113 if (CHOSEN_VERBOSITY>=2)
1114 {
1115 double t_tot = HsqTimer.time();
1116 t_err += t_tot;
1117 errorCalcInfo << HsqTimer.info("2-site variance")
1118 << " ("
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) << "%"
1123 << ")"
1124 << endl;
1125 }
1126
1127// Mps<Symmetry,Scalar> HxPsi;
1128// Mps<Symmetry,Scalar> Psi = Vout.state; Psi.sweep(0,DMRG::BROOM::QR);
1129// HxV(H,Psi,HxPsi,DMRG::VERBOSITY::HALFSWEEPWISE);
1130// Mps<Symmetry,Scalar> ExPsi = Vout.state;
1131// ExPsi *= Vout.energy;
1132// cout << HxPsi.validate("HxPsi") << ", " << HxPsi.info() << endl;
1133// cout << ExPsi.validate("ExPsi") << ", " << ExPsi.info() << endl;
1134// HxPsi -= ExPsi;
1135// cout << HxPsi.validate("res") << ", " << HxPsi.info() << endl;
1136// double err_exact_ = HxPsi.dot(HxPsi) / this->N_sites;
1137//
1138// Stopwatch<> HsqTimer_;
1139// double PsixHxHxPsi = (H.check_power(2ul)==true)? isReal(avg(Vout.state,H,Vout.state,2)) : isReal(avg(Vout.state,H,H,Vout.state));
1140// double PsixPsi = dot(Vout.state,Vout.state);
1141// double PsixHxPsi = isReal(avg(Vout.state,H,Vout.state));
1142// double err_exact = (PsixHxHxPsi + pow(Vout.energy,2)*PsixPsi - 2.*Vout.energy*PsixHxPsi) / this->N_sites;
1143// cout << sqrt(PsixHxHxPsi) << ", " << Vout.energy << ", " << PsixHxPsi << ", " << PsixPsi << endl;
1144//
1145// cout << TCOLOR(RED) << "err_state=" << err_state << ", err_exact=" << err_exact
1146// << ", " << err_exact_
1147// << ", diff=" << abs(err_state-err_exact)
1148// << ", ratio=" << err_state/err_exact
1149// << ", " << HsqTimer_.info("‖H|Ψ>-E|Ψ>‖") << TCOLOR(BLACK) << endl;
1150 }
1151 else if (GlobParam.CONVTEST == DMRG::CONVTEST::VAR_FULL and SweepStat.N_halfsweeps > GlobParam.min_halfsweeps) // full variance: for testing purposes only
1152 {
1153 assert(H.size() == 1 and "DMRG::CONVTEST::VAR_FULL is not implemented for several terms!");
1154 Stopwatch<> HsqTimer;
1155
1157 Mps<Symmetry,Scalar> Psi = Vout.state;
1158 Psi.sweep(0,DMRG::BROOM::QR);
1159 HxV(H[0], Psi, HxPsi, false);
1160
1161 Mps<Symmetry,Scalar> ExPsi = Vout.state;
1162 ExPsi *= Vout.energy;
1163 HxPsi -= ExPsi;
1164
1165 err_state = std::real(HxPsi.dot(HxPsi)) / this->N_sites;
1166 double t_tot = HsqTimer.time();
1167
1168 if (CHOSEN_VERBOSITY >= 2)
1169 {
1170 errorCalcInfo << HsqTimer.info("‖H|Ψ>-E|Ψ>‖/L") << endl;
1171 }
1172
1173 t_err += t_tot;
1174 }
1175}
1176
1177template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1179iteration_zero (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE,
1180 double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead)
1181{
1182 assert(H.size() == 1 and "iteration_zero is not implemented for several terms!");
1183 //*********************************************************LanczosStep******************************************************
1184 double Ei = Vout.energy;
1185
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);
1193
1195 (SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT)?
1196 Heff0 = PivotMatrix0<Symmetry,Scalar,Scalar>(Heff[old_pivot+1].Terms[0].L, Heff[old_pivot].Terms[0].R):
1197 Heff0 = PivotMatrix0<Symmetry,Scalar,Scalar>(Heff[old_pivot].Terms[0].L, Heff[old_pivot-1].Terms[0].R);
1198 time_overhead += OheadTimer.time();
1199
1200 Stopwatch<> LanczosTimer;
1201 LanczosSolver<PivotMatrix0<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz(LocParam.REORTHO);
1202
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);
1206
1207 if (CHOSEN_VERBOSITY == DMRG::VERBOSITY::STEPWISE)
1208 {
1209 lout << "loc=" << SweepStat.pivot << "\t" << Lutz.info() << endl;
1210 lout << Vout.state.test_ortho() << ", E=" << g.energy << endl;
1211 }
1212
1213 Vout.energy = g.energy;
1214 Vout.state.absorb(SweepStat.pivot, SweepStat.CURRENT_DIRECTION, g.state.data[0]);
1215
1216 DeltaEopt = Ei-Vout.energy;
1217 time_lanczos += LanczosTimer.time();
1218 //**************************************************************************************************************************
1219
1220 // Vout.state.min_Nsv = DynParam.min_Nsv(SweepStat.N_halfsweeps);
1221 // Vout.state.max_Nrich = DynParam.max_Nrich(SweepStat.N_halfsweeps);
1222 // Stopwatch<> SweepTimer;
1223 // Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot, DMRG::BROOM::RICH_SVD, &Heff[SweepStat.pivot]);
1224 // time_sweep += SweepTimer.time();
1225
1226 // Stopwatch<> LRtimer;
1227 // (SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT)? build_L(H,Vout,++SweepStat.pivot) : build_R(H,Vout,--SweepStat.pivot);
1228 // (SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT)? build_PL(H,Vout,SweepStat.pivot) : build_PR(H,Vout,SweepStat.pivot);
1229 // time_LR += LRtimer.time();
1230
1231 adapt_alpha_rsvd(H,Vout,EDGE);
1232}
1233
1234template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1236iteration_one (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE,
1237 double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead)
1238{
1239 //*********************************************************LanczosStep******************************************************
1240 double Ei = Vout.energy;
1241
1242 Stopwatch<> OheadTimer;
1243
1244 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1245 load_pivot(H);
1246 for (size_t t=0; t<H.size(); ++t) Heff_curr.Terms[t].W = H[t].W[SweepStat.pivot];
1247
1248 if (H.size() == 1)
1249 {
1250 precalc_blockStructure (Heff_curr.Terms[0].L,
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);
1255 }
1256
1257 for (int t=0; t<H.size(); ++t)
1258 {
1259 Heff_curr.Terms[t].qloc = H[t].locBasis(SweepStat.pivot);
1260 Heff_curr.Terms[t].qOp = H[t].opBasis (SweepStat.pivot);
1261 }
1262 #else
1263 for (size_t t=0; t<H.size(); ++t) Heff[SweepStat.pivot].Terms[t].W = H[t].W[SweepStat.pivot];
1264
1265 if (H.size() == 1)
1266 {
1267 precalc_blockStructure (Heff[SweepStat.pivot].Terms[0].L,
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);
1272 }
1273
1274 for (int t=0; t<H.size(); ++t)
1275 {
1276 Heff[SweepStat.pivot].Terms[t].qloc = H[t].locBasis(SweepStat.pivot);
1277 Heff[SweepStat.pivot].Terms[t].qOp = H[t].opBasis (SweepStat.pivot);
1278 }
1279 #endif
1280
1281 // contract environment for excited states
1282 if (Psi0.size() > 0)
1283 {
1284 Heff[SweepStat.pivot].A0proj.resize(Psi0.size());
1285 for (int n=0; n<Psi0.size(); ++n)
1286 {
1287 Heff[SweepStat.pivot].A0proj[n].resize(Psi0[n].A[SweepStat.pivot].size());
1288 }
1289
1290 for (int n=0; n<Psi0.size(); ++n)
1291 {
1292 PivotOverlap1<Symmetry,Scalar> PO(Heff[SweepStat.pivot].PL[n], Heff[SweepStat.pivot].PR[n], Psi0[n].locBasis(SweepStat.pivot));
1293 PivotVector<Symmetry,Scalar> Ain = PivotVector<Symmetry,Scalar>(Psi0[n].A[SweepStat.pivot]);
1295 LRxV(PO,Ain,Aout);
1296 Heff[SweepStat.pivot].A0proj[n] = Aout.data;
1297 }
1298 }
1299
1300 Eigenstate<PivotVector<Symmetry,Scalar> > g;
1301 g.state = PivotVector<Symmetry,Scalar>(Vout.state.A[SweepStat.pivot]);
1302 g.state /= sqrt(dot(g.state,g.state));
1303 time_overhead += OheadTimer.time();
1304
1305 Stopwatch<> LanczosTimer;
1306 LanczosSolver<PivotMatrix1<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz(LocParam.REORTHO);
1307
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);
1312 #else
1313 Lutz.edgeState(Heff[SweepStat.pivot], g, EDGE, LocParam.tol_eigval, LocParam.tol_state, false);
1314 #endif
1315
1316 if (Psi0.size() > 0)
1317 {
1318 // STEPWISE: print always, HALFSWEEPWISE: print after every halfsweep
1319 if (CHOSEN_VERBOSITY == DMRG::VERBOSITY::STEPWISE or
1320 CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE and
1321 ((loc1()==0 and SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT) or
1322 (loc2()==N_sites-1) and SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::LEFT)
1323 )
1324 {
1325 overlaps.resize(Psi0.size());
1326 for (int n=0; n<Psi0.size(); ++n)
1327 {
1328 Scalar overlap = 0;
1329 for (size_t s=0; s<Heff[SweepStat.pivot].A0proj[n].size(); ++s)
1330 {
1331 overlap += Heff[SweepStat.pivot].A0proj[n][s].adjoint().contract(g.state.data[s]).trace();
1332 }
1333 overlaps(n) = std::abs(overlap);
1334 //lout << "pivot=" << SweepStat.pivot << ", n=" << n << ", |overlap|=" << std::abs(overlap) << endl;
1335 }
1336 gap = g.energy-E0;
1337 //if (CHOSEN_VERBOSITY > DMRG::VERBOSITY::SILENT) lout << setprecision(16) << "gap=" << g.energy-E0 << ", |overlap|=" << overlaps.transpose() << setprecision(6) << endl;
1338 }
1339 }
1340 if (CHOSEN_VERBOSITY == DMRG::VERBOSITY::STEPWISE)
1341 {
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;
1345 }
1346
1347 Vout.energy = g.energy;
1348 Vout.state.A[SweepStat.pivot] = g.state.data;
1349 DeltaEopt = Ei-Vout.energy;
1350 time_lanczos += LanczosTimer.time();
1351 //**************************************************************************************************************************
1352
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);
1358 #else
1359 Vout.state.sweepStep(SweepStat.CURRENT_DIRECTION, SweepStat.pivot, DMRG::BROOM::RICH_SVD, &Heff[SweepStat.pivot]);
1360 #endif
1361 time_sweep += SweepTimer.time();
1362
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();
1367
1368 adapt_alpha_rsvd(H,Vout,EDGE);
1369
1370 if (!Vout.state.Boundaries.IS_TRIVIAL())
1371 {
1372 double norm = std::real(Vout.state.dot(Vout.state));
1373 Vout.state /= sqrt(Vout.state.dot(Vout.state));
1374// cout << Vout.state.test_ortho() << ", old_dot=" << norm << ", dot=" << Vout.state.dot(Vout.state) << endl;
1375 }
1376}
1377
1378#ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1379template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1381load_pivot (const vector<MpHamiltonian> &H)
1382{
1383 for (int t=0; t<H.size(); ++t)
1384 {
1385 //if (SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT)
1386 {
1387 Heff_curr.Terms[t].L.load(make_string(EnvSaveLabel,"_L_t=",t,"_l=",SweepStat.pivot));
1388 }
1389 //else
1390 {
1391 Heff_curr.Terms[t].R.load(make_string(EnvSaveLabel,"_R_t=",t,"_l=",SweepStat.pivot));
1392 }
1393 }
1394}
1395#endif
1396
1397template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1399iteration_two (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE,
1400 double &time_lanczos, double &time_sweep, double &time_LR, double &time_overhead)
1401{
1402 //*********************************************************LanczosStep******************************************************
1403 double Ei = Vout.energy;
1404
1405 Stopwatch<> OheadTimer;
1406 Eigenstate<PivotVector<Symmetry,Scalar> > g;
1407 g.state = PivotVector<Symmetry,Scalar>(Vout.state.A[loc1()], Vout.state.locBasis(loc1()),
1408 Vout.state.A[loc2()], Vout.state.locBasis(loc2()),
1409 Vout.state.QoutTop[loc1()], Vout.state.QoutBot[loc1()]);
1410
1411// PivotMatrix2<Symmetry,Scalar,Scalar> Heff2(Heff[loc1()].L, Heff[loc2()].R,
1412// H.W[loc1()], H.W[loc2()],
1413// H.locBasis(loc1()), H.locBasis(loc2()),
1414// H.opBasis (loc1()), H.opBasis (loc2()));
1416 Heff2.Terms.resize(H.size());
1417 for (int t=0; t<H.size(); ++t)
1418 {
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());
1427 }
1428
1429 if (H.size() == 1)
1430 {
1431 precalc_blockStructure (Heff2.Terms[0].L, g.state.data, Heff2.Terms[0].W12, Heff2.Terms[0].W34, g.state.data, Heff2.Terms[0].R,
1432 H[0].locBasis(loc1()), H[0].locBasis(loc2()), H[0].opBasis(loc1()), H[0].opBasis(loc2()),
1433 Heff2.qlhs, Heff2.qrhs, Heff2.factor_cgcs);
1434 }
1435
1436 // excited states projection stuff
1437 if (Psi0.size() > 0)
1438 {
1439 Heff2.Epenalty = Epenalty;
1440
1441 // contract A0pair
1442 vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > A0pair(Psi0.size());
1443 for (int n=0; n<Psi0.size(); ++n)
1444 {
1445 contract_AA2(Psi0[n].A[loc1()], Psi0[n].locBasis(loc1()),
1446 Psi0[n].A[loc2()], Psi0[n].locBasis(loc2()),
1447 A0pair[n]);
1448 }
1449
1450 Heff2.A0proj.resize(Psi0.size());
1451 for (int n=0; n<Psi0.size(); ++n) Heff2.A0proj[n].resize(A0pair[n].size());
1452
1453 for (int n=0; n<Psi0.size(); ++n)
1454 {
1455 PivotOverlap2<Symmetry,Scalar> PO(Heff[loc1()].PL[n], Heff[loc2()].PR[n], Psi0[n].locBasis(loc1()), Psi0[n].locBasis(loc2()));
1458 LRxV(PO,Ain,Aout);
1459// for (int s=0; s<Aout.data.size(); ++s) Aout.data[s] = Aout.data[s].cleaned();
1460 Heff2.A0proj[n] = Aout.data;
1461 }
1462 }
1463
1464 time_overhead += OheadTimer.time();
1465
1466 Stopwatch<> LanczosTimer;
1467 LanczosSolver<PivotMatrix2<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz(LocParam.REORTHO);
1468
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();
1473
1474 if (Psi0.size() > 0)
1475 {
1476 // STEPWISE: print always, HALFSWEEPWISE: print after every halfsweep
1477 if (CHOSEN_VERBOSITY == DMRG::VERBOSITY::STEPWISE or
1478 CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE and
1479 ((loc1()==0 and SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::RIGHT) or
1480 (loc2()==N_sites-1) and SweepStat.CURRENT_DIRECTION == DMRG::DIRECTION::LEFT)
1481 )
1482 {
1483 overlaps.resize(Psi0.size());
1484 for (int n=0; n<Psi0.size(); ++n)
1485 {
1486 Scalar overlap = 0;
1487 for (size_t s=0; s<Heff2.A0proj[n].size(); ++s)
1488 {
1489 overlap += Heff2.A0proj[n][s].adjoint().contract(g.state.data[s]).trace();
1490 }
1491 overlaps(n) = std::abs(overlap);
1492 }
1493 gap = g.energy-E0;
1494 //lout << setprecision(16) << "gap=" << g.energy-E0 << ", |overlap|=" << overlaps.transpose() << setprecision(6) << endl;
1495 }
1496 }
1497 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1498 {
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;
1502 }
1503
1504 Vout.energy = g.energy;
1505 for (size_t s=0; s<g.state.data.size(); ++s)
1506 {
1507 g.state.data[s] = g.state.data[s].cleaned();
1508 }
1509
1510 DeltaEopt = Ei-Vout.energy;
1511 //**************************************************************************************************************************
1512
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();
1518
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();
1523}
1524
1525template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1527sweep_to_edge (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, bool MAKE_ENVIRONMENT)
1528{
1529 assert(SweepStat.pivot == 0 or SweepStat.pivot==1 or SweepStat.pivot==N_sites-2 or SweepStat.pivot==N_sites-1);
1530
1531 // assert(SweepStat.pivot==1 or SweepStat.pivot==N_sites-2);
1532
1533 if (SweepStat.pivot==1)
1534 {
1535 Vout.state.sweepStep(DMRG::DIRECTION::LEFT, 1, DMRG::BROOM::QR);
1536 if (MAKE_ENVIRONMENT)
1537 {
1538 build_R(H,Vout,0);
1539 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1540 Heff_curr = Heff_next;
1541 #endif
1542 SweepStat.pivot = 0;
1543 }
1544 }
1545 else if (SweepStat.pivot==N_sites-2)
1546 {
1547 Vout.state.sweepStep(DMRG::DIRECTION::RIGHT, N_sites-2, DMRG::BROOM::QR);
1548 if (MAKE_ENVIRONMENT)
1549 {
1550 build_L(H,Vout,N_sites-1);
1551 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1552 Heff_curr = Heff_next;
1553 #endif
1554 SweepStat.pivot = N_sites-1;
1555 }
1556 }
1557}
1558
1559template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1561cleanup (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE)
1562{
1563 sweep_to_edge(H,Vout,false);
1564
1565 if (GlobParam.CALC_S_ON_EXIT)
1566 {
1567 Vout.state.skim(DMRG::BROOM::SVD,NULL);
1568 }
1569
1570 if (GlobParam.CALC_ERR_ON_EXIT)
1571 {
1572 double t_err = 0.;
1573 SweepStat.N_halfsweeps += GlobParam.min_halfsweeps+1; // set to this value to force error calculation
1574 Stopwatch<> Timer;
1575 calc_state_error(H,Vout,t_err);
1576 SweepStat.N_halfsweeps = GlobParam.min_halfsweeps; // reset back
1577 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1578 {
1579 lout << Timer.info("final err computation") << ", err_state=" << err_state << endl;
1580 }
1581 }
1582
1583 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
1584 {
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)
1590 {
1591 lout << ", gap=" << setprecision(16) << Vout.energy-E0;
1592 }
1593 lout << setprecision(standard_precision) << termcolor::reset << endl;
1594 lout << eigeninfo() << endl;
1595 lout << Vout.state.info() << endl;
1596
1597 if (GlobParam.CALC_S_ON_EXIT)
1598 {
1599 // size_t standard_precision = cout.precision();
1600 PlotParams p;
1601 p.label = "Entropy";
1602 if (Vout.state.entropy().rows() > 1)
1603 {
1604 TerminalPlot::plot(Vout.state.entropy(),p);
1605 }
1606 // lout << setprecision(2) << "S=" << Vout.state.entropy().transpose() << setprecision(standard_precision) << endl;
1607 }
1608 }
1609
1610 if (N_sites>4 and GlobParam.CALC_S_ON_EXIT)
1611 {
1612 size_t l_start = N_sites%2 == 0 ? N_sites/2ul : (N_sites+1ul)/2ul;
1613
1614 for (size_t l=l_start; l<=l_start+1; l++)
1615 {
1616 auto [qs,svs] = Vout.state.entanglementSpectrumLoc(l);
1617 ofstream Filer(make_string("sv_final_",l,".dat"));
1618 size_t index=0;
1619 for (size_t i=0; i<svs.size(); i++)
1620 {
1621 for (size_t deg=0; deg<Symmetry::degeneracy(qs[i]); deg++)
1622 {
1623 Filer << index << "\t" << qs[i] << "\t" << svs[i] << endl;
1624 index++;
1625 }
1626 }
1627 Filer.close();
1628 }
1629 }
1630
1631 if (Vout.state.calc_Nqavg() <= 1.5 and !Symmetry::IS_TRIVIAL and Vout.state.min_Nsv == 0)
1632 {
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;
1635 }
1636
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)
1642 {
1643 std::string filename = make_string(EnvSaveLabel,"_",LR[i],"_t=",t,"_l=",l,".h5");
1644
1645 //if (i==0 and l==0) {continue;}
1646 //if (i==1 and l==N_sites-1) {continue;}
1647
1648 // Delete the file using c_str() to convert std::string to const char*
1649 if (remove(filename.c_str()) != 0)
1650 {
1651 perror(make_string("Error deleting file ",filename).c_str());
1652 }
1653 else
1654 {
1655 lout << termcolor::green << "File " << filename << " successfully deleted" << termcolor::reset << endl;
1656 }
1657 }
1658 #endif
1659}
1660
1661template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1663edgeState (const MpHamiltonian &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, qarray<Nq> Qtot_input, LANCZOS::EDGE::OPTION EDGE, bool USE_STATE)
1664{
1665 edgeState(vector<MpHamiltonian>{H}, Vout, Qtot_input, EDGE, USE_STATE);
1666}
1667
1668template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1670edgeState (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, qarray<Nq> Qtot_input, LANCZOS::EDGE::OPTION EDGE, bool USE_STATE)
1671{
1672 prepare(H, Vout, Qtot_input, USE_STATE);
1673
1674 string Hinfo;
1675 if (H.size() == 1)
1676 {
1677 Hinfo = H[0].info();
1678 }
1679 stringstream ss;
1680 for (size_t t=0; t<H.size(); ++t)
1681 {
1682 ss << "Term#" << t << ":" << H[t].info() << ";";
1683 }
1684 Hinfo = ss.str();
1685
1686 Stopwatch<> TotalTimer;
1687
1688 bool MESSAGE_ALPHA = false;
1689
1690 //----<increase before first sweep, useful when state is loaded>----
1691 if (DynParam.Mincr_per(0) == 0)
1692 {
1693 // increase by Mincr_abs for small Mmax and by Mincr_rel for large Mmax(e.g. add 10% of current Mmax)
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));
1696 // do not increase beyond Mlimit
1697 Vout.state.max_Nsv = min(max_Nsv_new, GlobParam.Mlimit);
1698
1699 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1700 {
1701 if (Vout.state.max_Nsv != Mmax_old)
1702 {
1703 lout << "Mmax=" << Mmax_old << "→" << Vout.state.max_Nsv << endl;
1704 Mmax_old = Vout.state.max_Nsv;
1705 }
1706 lout << endl;
1707 }
1708 }
1709 //----</increase before first sweep, useful when state is loaded>----
1710
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)
1713 {
1714 // Set limits for alpha for the upcoming halfsweep
1715 min_alpha_rsvd = DynParam.min_alpha_rsvd(SweepStat.N_halfsweeps);
1716 max_alpha_rsvd = DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps);
1717
1718 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE and
1719 max_alpha_rsvd == 0. and
1720 MESSAGE_ALPHA == false)
1721 {
1722 lout << "α_rsvd is turned off now!" << endl << endl;
1723 MESSAGE_ALPHA = true;
1724 }
1725
1726 // sweep
1727 halfsweep(H,Vout,EDGE); //SweepStat.N_halfsweeps gets incremented by 1!
1728// Vout.state.graph(make_string("sweep",SweepStat.N_halfsweeps));
1729
1730 // overwrite if alpha_rsvd was switched on
1731 if (DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps-1) == 0. and DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps) != 0.)
1732 {
1733 Vout.state.alpha_rsvd = DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps);
1734 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1735 {
1736 lout << endl << "α_rsvd set to: " << Vout.state.alpha_rsvd << " for halfsweep " << SweepStat.N_halfsweeps << endl << endl;
1737 }
1738 }
1739
1740 size_t j = SweepStat.N_halfsweeps;
1741
1742 DynParam.doSomething(j);
1743
1744 // If truncated weight too large, increase upper limit per subspace by 10%, but at least by dimqlocAvg, overall never larger than Mlimit
1745 Vout.state.eps_svd = DynParam.eps_svd(j);
1746 Vout.state.eps_truncWeight = DynParam.eps_truncWeight(j);
1747// cout << "j=" << j << ", Vout.state.eps_svd=" << Vout.state.eps_svd << endl;
1748 if (j%DynParam.Mincr_per(j) == 0)
1749 //and (totalTruncWeight >= Vout.state.eps_svd or err_state > 10.*GlobParam.tol_state)
1750 {
1751 // increase by Mincr_abs for small Mmax and by Mincr_rel for large Mmax(e.g. add 10% of current Mmax)
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));
1754 // do not increase beyond Mlimit
1755 Vout.state.max_Nsv = min(max_Nsv_new, GlobParam.Mlimit);
1756 }
1757
1758 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1759 {
1760 if (Vout.state.max_Nsv != Mmax_old)
1761 {
1762 lout << "Mmax=" << Mmax_old << "→" << Vout.state.max_Nsv << endl;
1763 Mmax_old = Vout.state.max_Nsv;
1764 }
1765 lout << endl;
1766 }
1767
1768 #ifdef USE_HDF5_STORAGE
1769 if (GlobParam.savePeriod != 0 and j%GlobParam.savePeriod == 0)
1770 {
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;
1774 }
1775 #endif
1776 }
1777
1778 #ifdef USE_HDF5_STORAGE
1779 if (GlobParam.savePeriod != 0)
1780 {
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);
1784 }
1785 #endif
1786
1787 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
1788 {
1789 lout << TotalTimer.info("total runtime") << endl;
1790 }
1791 cleanup(H,Vout,EDGE);
1792}
1793
1794template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1796adapt_alpha_rsvd (const vector<MpHamiltonian> &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE)
1797{
1798 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1799 load_pivot(H);
1800 #endif
1801
1802 // adapt alpha
1803 if (Psi0.size() > 0)
1804 {
1805 Heff[SweepStat.pivot].A0proj.resize(Psi0.size());
1806 for (int n=0; n<Psi0.size(); ++n)
1807 {
1808 Heff[SweepStat.pivot].A0proj[n].resize(Psi0[n].A[SweepStat.pivot].size());
1809 }
1810
1811 for (int n=0; n<Psi0.size(); ++n)
1812 for (int s=0; s<Psi0[n].A[SweepStat.pivot].size(); ++s)
1813 {
1814 PivotOverlap1<Symmetry,Scalar> PO(Heff[SweepStat.pivot].PL[n], Heff[SweepStat.pivot].PR[n], Psi0[n].locBasis(SweepStat.pivot));
1815 PivotVector<Symmetry,Scalar> Ain = PivotVector<Symmetry,Scalar>(Psi0[n].A[SweepStat.pivot]);
1817 LRxV(PO,Ain,Aout);
1818 Heff[SweepStat.pivot].A0proj[n] = Aout.data;
1819 }
1820 }
1821
1822 PivotVector<Symmetry,Scalar> Vtmp1(Vout.state.A[SweepStat.pivot]);
1824// Heff[SweepStat.pivot].W = H.W[SweepStat.pivot];
1825// Heff[SweepStat.pivot].qloc = H.locBasis(SweepStat.pivot);
1826// Heff[SweepStat.pivot].qOp = H.opBasis(SweepStat.pivot);
1827// precalc_blockStructure (Heff[SweepStat.pivot].L, Vout.state.A[SweepStat.pivot], Heff[SweepStat.pivot].W, Vout.state.A[SweepStat.pivot], Heff[SweepStat.pivot].R,
1828// H.locBasis(SweepStat.pivot), H.opBasis(SweepStat.pivot), Heff[SweepStat.pivot].qlhs, Heff[SweepStat.pivot].qrhs, Heff[SweepStat.pivot].factor_cgcs);
1829
1830 #ifdef DMRG_SOLVER_MEMEFFICIENT_ENV
1831 for (size_t t=0; t<H.size(); ++t)
1832 {
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);
1836 }
1837 if (H.size() == 1)
1838 {
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);
1841 }
1842
1843 HxV(Heff_curr, Vtmp1, Vtmp2);
1844 #else
1845 for (size_t t=0; t<H.size(); ++t)
1846 {
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);
1850 }
1851 if (H.size() == 1)
1852 {
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);
1855 }
1856
1857 HxV(Heff[SweepStat.pivot], Vtmp1, Vtmp2);
1858 #endif
1859
1860 double DeltaEtrunc = std::real(dot(Vtmp1,Vtmp2))-Vout.energy;
1861
1862// if (DeltaEtrunc < 0.3*DeltaEopt) {Vout.state.alpha_rsvd *= sqrt(10.);}
1863// else {Vout.state.alpha_rsvd /= sqrt(10.);}
1864// Vout.state.alpha_rsvd = min(Vout.state.alpha_rsvd, max_alpha_rsvd);
1865
1866 double f;
1867 double epsilon = 1e-9;
1868 if (abs(DeltaEopt) < epsilon or abs(DeltaEtrunc) < epsilon)
1869 {
1870 if (abs(DeltaEtrunc) > epsilon) {f = 0.9;}
1871 else {f = 1.001;}
1872 }
1873 else
1874 {
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)
1878 )
1879 {
1880 f = 2.*(r+1.);
1881 }
1882 else if (r < 0.05) {f = 1.2-r;}
1883 else if (r > 0.3) {f = 1./(r+0.75);}
1884 }
1885 //f = max(0.1,min(2.,f)); // limit between [0.1,2]
1886 //f = max(0.99,min(1.01,f));
1887 f = max(GlobParam.falphamin,min(GlobParam.falphamax,f));
1888 Vout.state.alpha_rsvd *= f;
1889 // limit between [min_alpha_rsvd,max_alpha_rsvd]:
1890 // double alpha_min = min(DynParam.min_alpha_rsvd(SweepStat.N_halfsweeps),
1891 // DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps)); // for the accidental case alpha_min > alpha_max
1892 // Vout.state.alpha_rsvd = max(alpha_min, min(DynParam.max_alpha_rsvd(SweepStat.N_halfsweeps), Vout.state.alpha_rsvd));
1893 double alpha_min = min(min_alpha_rsvd, max_alpha_rsvd); // for the accidental case alpha_min > alpha_max
1894 Vout.state.alpha_rsvd = max(alpha_min, min(max_alpha_rsvd, Vout.state.alpha_rsvd));
1895
1896// cout << "ΔEopt=" << DeltaEopt << ", ΔEtrunc=" << DeltaEtrunc << ", f=" << f << ", alpha=" << Vout.state.alpha_rsvd << endl;
1897
1898 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1899 {
1900 lout << "ΔEopt=" << DeltaEopt << ", ΔEtrunc=" << DeltaEtrunc << ", α=" << Vout.state.alpha_rsvd << endl;
1901 }
1902}
1903
1904// NOT USED ANYMORE (?):
1905//template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1906//void DmrgSolver<Symmetry,MpHamiltonian,Scalar>::
1907//LanczosStep (const MpHamiltonian &H, Eigenstate<Mps<Symmetry,Scalar> > &Vout, LANCZOS::EDGE::OPTION EDGE)
1908//{
1909// double Ei = Vout.energy;
1910//
1912// {
1913// Heff[SweepStat.pivot].W = H.W[SweepStat.pivot];
1914// precalc_blockStructure (Heff[SweepStat.pivot].L, Vout.state.A[SweepStat.pivot],
1915// Heff[SweepStat.pivot].W, Vout.state.A[SweepStat.pivot], Heff[SweepStat.pivot].R,
1916// H.locBasis(SweepStat.pivot), H.opBasis(SweepStat.pivot), Heff[SweepStat.pivot].qlhs, Heff[SweepStat.pivot].qrhs,
1917// Heff[SweepStat.pivot].factor_cgcs);
1918// Heff[SweepStat.pivot].qloc = H.locBasis(SweepStat.pivot);
1919// Heff[SweepStat.pivot].qOp = H.opBasis(SweepStat.pivot);
1920// }
1921//
1922// Eigenstate<PivotVector<Symmetry,Scalar> > g;
1923// g.state = PivotVector<Symmetry,Scalar>(Vout.state.A[SweepStat.pivot]);
1924// LanczosSolver<PivotMatrix1<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz(LocParam.REORTHO);
1925//
1926// Lutz.set_efficiency(LANCZOS::EFFICIENCY::TIME);
1927// Lutz.set_dimK(min(LocParam.dimK, dim(g.state)));
1928// Lutz.edgeState(Heff[SweepStat.pivot],g, EDGE, LocParam.tol_eigval, LocParam.tol_state, false);
1929//
1930// if (CHOSEN_VERBOSITY == DMRG::VERBOSITY::STEPWISE)
1931// {
1932// lout << "loc=" << SweepStat.pivot << "\t" << Lutz.info() << endl;
1933// lout << Vout.state.test_ortho() << ", " << g.energy << endl;
1934// }
1935//
1936// Vout.energy = g.energy;
1937// Vout.state.A[SweepStat.pivot] = g.state.data;
1938// DeltaEopt = Ei-Vout.energy;
1939//}
1940
1941template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1943build_L (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc)
1944{
1945 //contract_L(Heff[loc-1].L, Vout.state.A[loc-1], H.W[loc-1], Vout.state.A[loc-1], H.locBasis(loc-1), H.opBasis(loc-1), Heff[loc].L);
1946
1947 for (size_t t=0; t<H.size(); ++t)
1948 {
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));
1952 #else
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);
1954 #endif
1955 }
1956}
1957
1958template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1960build_R (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc)
1961{
1962 //contract_R(Heff[loc+1].R, Vout.state.A[loc+1], H.W[loc+1], Vout.state.A[loc+1], H.locBasis(loc+1), H.opBasis(loc+1), Heff[loc].R);
1963
1964 for (size_t t=0; t<H.size(); ++t)
1965 {
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));
1969 #else
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);
1971 #endif
1972 }
1973}
1974
1975template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1977build_PL (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc)
1978{
1979 for (size_t n=0; n<Psi0.size(); ++n)
1980 {
1981 // Note: Should be the same local basis for all terms
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();
1984 }
1985}
1986
1987template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1989build_PR (const vector<MpHamiltonian> &H, const Eigenstate<Mps<Symmetry,Scalar> > &Vout, size_t loc)
1990{
1991 for (size_t n=0; n<Psi0.size(); ++n)
1992 {
1993 // Note: Should be the same local basis for all terms
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();
1996 }
1997}
1998
1999#endif
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)
Definition: DmrgExternal.h:283
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.
Definition: DmrgJanitor.h:7
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)
@ A
Definition: DmrgTypedefs.h:130
void sweep(size_t loc, DMRG::BROOM::OPTION TOOL, PivotMatrixType *H=NULL)
Definition: DmrgJanitor.h:198
void build_R(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
Definition: DmrgSolver.h:1960
void build_PL(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
Definition: DmrgSolver.h:1977
void prepare(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, qarray< Nq > Qtot_input, bool USE_STATE=false)
Definition: DmrgSolver.h:289
void set_verbosity(DMRG::VERBOSITY::OPTION VERBOSITY)
Definition: DmrgSolver.h:70
void push_back(const Mps< Symmetry, Scalar > &Psi0_input)
Definition: DmrgSolver.h:122
void userSetDynParam()
Definition: DmrgSolver.h:63
string info() const
Definition: DmrgSolver.h:214
double max_alpha_rsvd
Definition: DmrgSolver.h:161
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)
Definition: DmrgSolver.h:1663
double err_state
Definition: DmrgSolver.h:154
double get_errState() const
Definition: DmrgSolver.h:114
DMRG::CONTROL::LOC LocParam
Definition: DmrgSolver.h:68
SweepStatus SweepStat
Definition: DmrgSolver.h:167
size_t loc2() const
Definition: DmrgSolver.h:174
DmrgSolver(DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
Definition: DmrgSolver.h:47
vector< PivotMatrix1< Symmetry, Scalar, Scalar > > Heff
Definition: DmrgSolver.h:156
VectorXd overlaps
Definition: DmrgSolver.h:195
stringstream errorCalcInfo
Definition: DmrgSolver.h:169
double get_pivot() const
Definition: DmrgSolver.h:117
size_t Nqmax
Definition: DmrgSolver.h:151
bool USER_SET_DYNPARAM
Definition: DmrgSolver.h:164
void build_PR(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
Definition: DmrgSolver.h:1989
string eigeninfo() const
Definition: DmrgSolver.h:227
void adapt_alpha_rsvd(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE)
Definition: DmrgSolver.h:1796
double get_direction() const
Definition: DmrgSolver.h:120
vector< Mpo< typename MpHamiltonian::Symmetry, typename MpHamiltonian::Scalar_ > > observables
Definition: DmrgSolver.h:200
double Eold
Definition: DmrgSolver.h:158
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)
Definition: DmrgSolver.h:1399
void sweep_to_edge(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, bool MAKE_ENVIRONMENT)
Definition: DmrgSolver.h:1527
vector< string > obs_labels
Definition: DmrgSolver.h:201
size_t Mmax
Definition: DmrgSolver.h:151
size_t Dmax
Definition: DmrgSolver.h:151
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)
Definition: DmrgSolver.h:1179
bool USER_SET_GLOBPARAM
Definition: DmrgSolver.h:163
size_t loc1() const
Definition: DmrgSolver.h:173
double E0
Definition: DmrgSolver.h:194
double Epenalty
Definition: DmrgSolver.h:133
double gap
Definition: DmrgSolver.h:196
void cleanup(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND)
Definition: DmrgSolver.h:1561
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)
Definition: DmrgSolver.h:1236
size_t N_sites
Definition: DmrgSolver.h:150
DMRG::CONTROL::GLOB GlobParam
Definition: DmrgSolver.h:66
void build_L(const vector< MpHamiltonian > &H, const Eigenstate< Mps< Symmetry, Scalar > > &Vout, size_t loc)
Definition: DmrgSolver.h:1943
vector< Mps< Symmetry, Scalar > > Psi0
Definition: DmrgSolver.h:193
void halfsweep(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND)
Definition: DmrgSolver.h:750
size_t N_phys
Definition: DmrgSolver.h:150
DMRG::VERBOSITY::OPTION get_verbosity() const
Definition: DmrgSolver.h:71
bool USER_SET_LOCPARAM
Definition: DmrgSolver.h:165
void calc_state_error(const vector< MpHamiltonian > &H, Eigenstate< Mps< Symmetry, Scalar > > &Vout, double &t_err)
Definition: DmrgSolver.h:878
Mps< Symmetry, Scalar > Vref
Definition: DmrgSolver.h:170
void userSetLocParam()
Definition: DmrgSolver.h:64
static constexpr size_t Nq
Definition: DmrgSolver.h:43
void userSetGlobParam()
Definition: DmrgSolver.h:62
double DeltaEopt
Definition: DmrgSolver.h:160
vector< double > obs_normalizations
Definition: DmrgSolver.h:202
double memory(MEMUNIT memunit=GB) const
Definition: DmrgSolver.h:275
DMRG::VERBOSITY::OPTION CHOSEN_VERBOSITY
Definition: DmrgSolver.h:198
double min_alpha_rsvd
Definition: DmrgSolver.h:161
double totalTruncWeight
Definition: DmrgSolver.h:152
void set_observable(string label, const Mpo< typename MpHamiltonian::Symmetry, typename MpHamiltonian::Scalar_ > &Operator, double N=1.)
Definition: DmrgSolver.h:141
size_t Mmax_old
Definition: DmrgSolver.h:153
double err_eigval
Definition: DmrgSolver.h:154
double get_errEigval() const
Definition: DmrgSolver.h:111
void set_SweepStatus(const SweepStatus &SweepStat_input)
Definition: DmrgSolver.h:135
DMRG::CONTROL::DYN DynParam
Definition: DmrgSolver.h:67
Symmetry::qType qType
Definition: DmrgSolver.h:44
double err_eigval_prev
Definition: DmrgSolver.h:154
Definition: Mpo.h:40
Definition: Mps.h:39
Scalar dot(const Mps< Symmetry, Scalar > &Vket) const
string info() 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
Definition: qarray.h:52
Definition: Biped.h:64
void addScale(const Scalar &factor, const Biped< Symmetry, MatrixType_ > &Mrhs, BLOCK_POSITION BP=SAME_PLACE)
Definition: Biped.h:1295
Biped< Symmetry, MatrixType_ > cleaned() const
Definition: Biped.h:597
Eigen::VectorXd squaredNorm() const
Definition: Biped.h:520
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
size_t N_halfsweeps
Definition: DmrgSolver.h:37
size_t N_sweepsteps
Definition: DmrgSolver.h:36
DMRG::DIRECTION::OPTION CURRENT_DIRECTION
Definition: DmrgSolver.h:35
Definition: qarray.h:26