VMPS++
Loading...
Searching...
No Matches
VumpsSolver.h
Go to the documentation of this file.
1#ifndef VANILLA_VUMPSSOLVER
2#define VANILLA_VUMPSSOLVER
3
4#ifndef LINEARSOLVER_DIMK
5#define LINEARSOLVER_DIMK 500
6#endif
7
9//#include "unsupported/Eigen/IterativeSolvers"
10#include "termcolor.hpp"
12
13#include "LanczosSolver.h" // from ALGS
14#include "GMResSolver.h" // from ALGS
15
16#include "VUMPS/Umps.h"
22
23#include "MpsBoundaries.h"
24
31template<typename Symmetry, typename MpHamiltonian, typename Scalar=double>
33{
34 typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
35 typedef Matrix<complex<Scalar>,Dynamic,Dynamic> ComplexMatrixType;
36 typedef Matrix<Scalar,Dynamic,1> VectorType;
37 typedef boost::multi_array<Scalar,4> TwoSiteHamiltonian;
38
39public:
40
42 :CHOSEN_VERBOSITY(VERBOSITY)
43 {};
44
46 inline void set_verbosity (DMRG::VERBOSITY::OPTION VERBOSITY) {CHOSEN_VERBOSITY = VERBOSITY;};
47
50
51 //call this function if you want to set the parameters for the solver by yourself
55
59
61
62 string info() const;
63
65 string eigeninfo() const;
66
68 double memory (MEMUNIT memunit=GB) const;
69
70 inline size_t iterations() {return N_iterations;};
71
80 void set_log (int N_log_input, string file_e_input, string file_err_eigval_input, string file_err_var_input, string file_err_state_input);
82
86 void edgeState (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout,
87 qarray<Symmetry::Nq> Qtot, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND, bool USE_STATE=false);
88
89 const double& errVar() {return err_var;}
90 const double& errState() {return err_state;}
91 const double& errEigval() {return err_eigval;}
92
93 bool FORCE_DO_SOMETHING = false;
94
102 Mps<Symmetry,Scalar> create_Mps (size_t Ncells, const Eigenstate<Umps<Symmetry,Scalar> > &V, const MpHamiltonian &H, size_t x0);
103
114 vector<Mps<Symmetry,Scalar>> create_Mps (size_t Ncells, const Eigenstate<Umps<Symmetry,Scalar> > &V, const MpHamiltonian &H,
115 const Mpo<Symmetry,Scalar> &O, const vector<Mpo<Symmetry,Scalar>> &Omult, double tol_OxV=2.);
116
120 Mps<Symmetry,Scalar> create_Mps (size_t Ncells, const Eigenstate<Umps<Symmetry,Scalar> > &V, const MpHamiltonian &H,
121 const Mpo<Symmetry,Scalar> &O, const Mpo<Symmetry,Scalar> &Omult, double tol_OxV=2.);
122
123 void set_boundary (const Umps<Symmetry,Scalar> &Vin, Mps<Symmetry,Scalar> &Vout, bool LEFT=false, bool RIGHT=true);
124
126 void prepare (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, qarray<Symmetry::Nq> Qtot, bool USE_STATE=false);
127
129 void build_cellEnv (const MpHamiltonian &H, const Eigenstate<Umps<Symmetry,Scalar> > &Vout, size_t power=1);
130
131 double get_err_eigval() const {return err_eigval;};
132 double get_err_state() const {return err_state;};
133 double get_err_var() const {return err_var;};
134
135//private:
136
138
139 void prepare_h2site (const TwoSiteHamiltonian &h2site, const vector<qarray<Symmetry::Nq> > &qloc_input,
140 Eigenstate<Umps<Symmetry,Scalar> > &Vout,
141 qarray<Symmetry::Nq> Qtot_input,
142 size_t M, size_t Nqmax, bool USE_STATE=false);
143
148 void iteration_h2site (Eigenstate<Umps<Symmetry,Scalar> > &Vout);
150
152
153 void iteration_parallel (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout);
154
156 void iteration_sequential (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout);
158
160
164 void iteration_idmrg (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout);
165
167 void prepare_idmrg (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, qarray<Symmetry::Nq> Qtot, bool USE_STATE=false);
168
170 double Eold = std::nan("1");
172
174
175 void build_LR (const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AL,
176 const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AR,
177 const vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > &C,
178 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
179 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
180 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
183
184 void build_R (const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AR,
185 const Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &Cintercell,
186 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
187 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
188 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
190
191 void build_L (const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AL,
192 const Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &Cintercell,
193 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
194 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
195 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
198
200
204 void expand_basis (size_t loc, size_t DeltaD, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout,
211 void expand_basis (size_t DeltaD, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout,
213
214 void expand_basis2 (size_t DeltaD, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout,
217
219
229 void calc_B2 (size_t loc, const MpHamiltonian &H, const Umps<Symmetry,Scalar> &Psi, VUMPS::TWOSITE_A::OPTION option,
234 void calc_B2 (size_t loc, const MpHamiltonian &H, const Umps<Symmetry,Scalar> &Psi,
237
239 void cleanup (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout);
240
242 size_t N_sites;
243
244 bool USER_SET_GLOBPARAM = false;
245 bool USER_SET_DYNPARAM = false;
246 bool USER_SET_LOCPARAM = false;
247
250
252 double err_eigval, err_eigval_old, err_var, err_var_old, err_state=std::nan("1"), err_state_old=std::nan("1");
253
255 vector<PivumpsMatrix1<Symmetry,Scalar,Scalar> > Heff;
256
258 vector<PivotMatrix1<Symmetry,Scalar,Scalar> > HeffA;
259
261 vector<PivotMatrix1<Symmetry,Scalar,Scalar> > HeffC;
262
264 vector<qarray<Symmetry::Nq> > qloc;
265
268
270 size_t D, M, dW, dW_singlet;
271
273 vector<pair<qarray<Symmetry::Nq>,size_t> > basis_order;
274 std::unordered_map<pair<qarray<Symmetry::Nq>,size_t>,size_t> basis_order_map;
275
277 double eL, eR, eoldR, eoldL;
278
293 size_t ab,
294 const vector<vector<Biped<Symmetry,MatrixType> > > &A,
295 const Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &Y_LR,
296 const Biped<Symmetry,MatrixType> &LReigen,
297 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
298 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
299 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
300 Scalar LRdotY,
301 const Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &LRguess,
302 Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &LRres);
303
314 const vector<vector<Biped<Symmetry,MatrixType> > > &A,
315 const Biped<Symmetry,MatrixType> &hLR,
316 const Biped<Symmetry,MatrixType> &LReigen,
317 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
318 Scalar hLRdotLR,
320
323
325 void set_LanczosTolerances (double &tolLanczosEigval, double &tolLanczosState);
326
328 void calc_errors (const MpHamiltonian &H, const Eigenstate<Umps<Symmetry,Scalar> > &Vout,
329 bool CALC_ERR_STATE=true, VUMPS::TWOSITE_A::OPTION option = VUMPS::TWOSITE_A::ALxAC);
330
333
336
338 string test_LReigen (const Eigenstate<Umps<Symmetry,Scalar> > &Vout) const;
339
341
342 size_t N_log = 0;
343
346
349
354 void write_log (bool FORCE = false);
356
369 Mps<Symmetry,Scalar> assemble_Mps (size_t Ncells,
370 const Umps<Symmetry,Scalar> &V,
371 const vector<vector<Biped<Symmetry,MatrixType> > > &AL,
372 const vector<vector<Biped<Symmetry,MatrixType> > > &AR,
373 const vector<vector<qarray<Symmetry::Nq> > > &qloc_input,
376 int x0);
377};
378
379template<typename Symmetry, typename MpHamiltonian, typename Scalar>
381info() const
382{
383 stringstream ss;
384 ss << "VumpsSolver: ";
385 ss << "L=" << N_sites << ", ";
386 ss << eigeninfo();
387 return ss.str();
388}
389
390template<typename Symmetry, typename MpHamiltonian, typename Scalar>
392eigeninfo() const
393{
394 stringstream ss;
395 ss << "iterations=" << N_iterations << ", ";
396 ss << "e0=" << setprecision(13) << min(eL,eR) << ", ";
397 ss << "err_eigval=" << setprecision(13) << err_eigval << ", err_var=" << err_var << ", ";
398 if (!isnan(err_state))
399 {
400 ss << "err_state=" << err_state << ", ";
401 }
402 ss << "mem=" << round(memory(GB),3) << "GB";
403 return ss.str();
404}
405
406template<typename Symmetry, typename MpHamiltonian, typename Scalar>
408memory (MEMUNIT memunit) const
409{
410 double res = 0.;
411// for (size_t l=0; l<N_sites; ++l)
412// {
413// res += Heff[l].L.memory(memunit);
414// res += Heff[l].R.memory(memunit);
415// for (size_t s1=0; s1<Heff[l].W.size(); ++s1)
416// for (size_t s2=0; s2<Heff[l].W[s1].size(); ++s2)
417// for (size_t k=0; k<Heff[l].W[s1][s2].size(); ++k)
418// {
419// res += calc_memory(Heff[l].W[s1][s2][k],memunit);
420// }
421// }
422 return res;
423}
424
425template<typename Symmetry, typename MpHamiltonian, typename Scalar>
427set_log (int N_log_input, string file_e_input, string file_err_eigval_input, string file_err_var_input, string file_err_state_input)
428{
429 N_log = N_log_input;
430 file_e = file_e_input;
431 file_err_eigval = file_err_eigval_input;
432 file_err_var = file_err_var_input;
433 file_err_state = file_err_state_input;
434 eL_mem.clear();
435 eR_mem.clear();
436 err_eigval_mem.clear();
437 err_var_mem.clear();
438 err_state_mem.clear();
439};
440
441template<typename Symmetry, typename MpHamiltonian, typename Scalar>
443write_log (bool FORCE)
444{
445 // save data
446 if (N_log>0 or FORCE==true)
447 {
448 eL_mem.push_back(eL);
449 eR_mem.push_back(eR);
450 err_eigval_mem.push_back(err_eigval);
451 err_var_mem.push_back(err_var);
452 err_state_mem.push_back(err_state);
453 }
454
455 if ((N_log>0 and N_iterations%N_log==0) or FORCE==true)
456 {
457 // write out energy
458 ofstream Filer(file_e);
459 for (int i=0; i<eL_mem.size(); ++i)
460 {
461 Filer << i << "\t" << setprecision(13) << min(eL_mem[i],eR_mem[i]) << "\t" << eL_mem[i] << "\t" << eR_mem[i] << endl;
462 }
463 Filer.close();
464
465 // write out energy error
466 Filer.open(file_err_eigval);
467 for (int i=0; i<err_eigval_mem.size(); ++i)
468 {
469 Filer << i << "\t" << setprecision(13) << err_eigval_mem[i] << endl;
470 }
471 Filer.close();
472
473 // write out variational error
474 Filer.open(file_err_var);
475 for (int i=0; i<err_var_mem.size(); ++i)
476 {
477 Filer << i << "\t" << setprecision(13) << err_var_mem[i] << endl;
478 }
479 Filer.close();
480
481 // write out global state error
482 Filer.open(file_err_state);
483 for (int i=0; i<err_state_mem.size(); ++i)
484 {
485 Filer << i << "\t" << setprecision(13) << err_state_mem[i] << endl;
486 }
487 Filer.close();
488 }
489}
490
491template<typename Symmetry, typename MpHamiltonian, typename Scalar>
493set_LanczosTolerances (double &tolLanczosEigval, double &tolLanczosState)
494{
495 // Set less accuracy for the first iterations
496 // tolLanczosEigval = max(max(1.e-2*err_eigval,1.e-13),1.e-13); // 1e-7
497 // tolLanczosState = max(max(1.e-2*err_var, 1.e-13),1.e-13); // 1e-4
498 tolLanczosEigval = max(max(1.e-2*err_eigval,LocParam.eps_eigval),LocParam.eps_eigval); // 1e-7
499 tolLanczosState = max(max(1.e-2*err_var, LocParam.eps_coeff) ,LocParam.eps_coeff); // 1e-4
500
501 if (std::isnan(tolLanczosEigval))
502 {
503 tolLanczosEigval = 1e-14;
504 }
505
506 if (std::isnan(tolLanczosState))
507 {
508 tolLanczosState = 1e-14;
509 }
510
511 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
512 {
513 lout << "current Lanczos tolerances: " << tolLanczosEigval << ", " << tolLanczosState << endl;
514 }
515}
516
517template<typename Symmetry, typename MpHamiltonian, typename Scalar>
519calc_errors (const MpHamiltonian &H, const Eigenstate<Umps<Symmetry,Scalar> > &Vout, bool CALC_ERR_STATE, VUMPS::TWOSITE_A::OPTION option)
520{
521 std::array<VectorXd,2> epsLRsq;
522 std::array<GAUGE::OPTION,2> gs = {GAUGE::L, GAUGE::R};
523 for (const auto &g:gs)
524 {
525 epsLRsq[g].resize(N_sites);
526 for (size_t l=0; l<N_sites; ++l)
527 {
528 epsLRsq[g](l) = std::real(Vout.state.calc_epsLRsq(g,l));
529 }
530 }
531 err_var_old = err_var;
532 err_var = max(sqrt(epsLRsq[GAUGE::L].sum()), sqrt(epsLRsq[GAUGE::R].sum()));
533
534 err_eigval_old = err_eigval;
535 err_eigval = max(abs(eoldR-eR), abs(eoldL-eL));
536 eoldR = eR;
537 eoldL = eL;
538
539 if (CALC_ERR_STATE)
540 {
541 //set the global state error to the largest norm of NAAN (=B2) in the unit cell.
542 err_state_old = err_state;
543 err_state = 0.;
544 vector<double> norm_NAAN(N_sites);
545 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
546 #pragma omp parallel for
547 #endif
548 for (size_t l=0; l<N_sites; ++l)
549 {
550 vector<Biped<Symmetry,MatrixType> > NL;
551 vector<Biped<Symmetry,MatrixType> > NR;
553 calc_B2(l, H, Vout.state, option, NAAN, NL, NR);
554 norm_NAAN[l] = sqrt(NAAN.squaredNorm().sum());
555 }
556
557 for (size_t l=0; l<N_sites; ++l)
558 {
559 if (norm_NAAN[l] > err_state) {err_state = norm_NAAN[l];}
560 }
561 }
562}
563
564template<typename Symmetry, typename MpHamiltonian, typename Scalar>
566prepare_h2site (const TwoSiteHamiltonian &h2site_input, const vector<qarray<Symmetry::Nq> > &qloc_input, Eigenstate<Umps<Symmetry,Scalar> > &Vout,
567 qarray<Symmetry::Nq> Qtot, size_t M_input, size_t Nqmax, bool USE_STATE)
568{
569 Stopwatch<> PrepTimer;
570
571 // general
572 N_sites = 1;
573 N_iterations = 0;
574 D = h2site_input.shape()[0]; // local dimension
575 M = M_input; // bond dimension
576
577 // effective and 2-site Hamiltonian
578 Heff.resize(N_sites);
579 h2site.resize(boost::extents[D][D][D][D]);
580 h2site = h2site_input;
581
582 // resize Vout
583
584 if (!USE_STATE)
585 {
586 Vout.state = Umps<Symmetry,Scalar>(qloc_input, Qtot, N_sites, M, Nqmax, GlobParam.INIT_TO_HALF_INTEGER_QN);
587 Vout.state.setRandom();
588 for (size_t l=0; l<N_sites; ++l)
589 {
590 Vout.state.svdDecompose(l);
591 }
592 }
593 Vout.state.calc_entropy((CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
594
595 // initial energy & error
596 eoldL = std::nan("");
597 eoldR = std::nan("");
598 err_eigval = 1.;
599 err_var = 1.;
600
601 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
602 {
603 lout << PrepTimer.info("prepare") << endl;
604 }
605}
606
607template<typename Symmetry, typename MpHamiltonian, typename Scalar>
609prepare (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, qarray<Symmetry::Nq> Qtot, bool USE_STATE)
610{
611 N_sites = H.length();
612 N_iterations = 0;
613 N_iterations_without_expansion = 0;
614
615 Stopwatch<> PrepTimer;
616
617 // effective Hamiltonian
618 D = H.locBasis(0).size();
619 assert(H.inBasis(0) == H.outBasis(N_sites-1) and "You've inserted a strange MPO not consistent with the unit cell");
620 dW = H.inBasis(0).size();
621 dW_singlet = H.inBasis(0).inner_dim(Symmetry::qvacuum());
622 //Basis order of the Mpo auxiliary basis which leads to a triangular Mpo form
623 basis_order = H.base_order_IBC();
624 for (size_t i=0; i<basis_order.size(); ++i)
625 {
626 basis_order_map.insert({basis_order[i],i});
627 }
628
629 // resize Vout
630 if (!USE_STATE)
631 {
632 Vout.state = Umps<Symmetry,Scalar>(H, Qtot, N_sites, GlobParam.Minit, GlobParam.Qinit, GlobParam.INIT_TO_HALF_INTEGER_QN);
633// Vout.state.graph("init");
634 Vout.state.max_Nsv = GlobParam.Mlimit;
635 // Vout.state.min_Nsv = DynParam.min_Nsv(0);
636// Vout.state.setRandom();
637// for (size_t l=0; l<N_sites; ++l)
638// {
639// Vout.state.svdDecompose(l);
640// }
641 }
642 for (size_t l=0; l<N_sites; ++l) Vout.state.calc_entropy(l,(CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
643
644 // initial energy
645 eoldL = std::nan("");
646 eoldR = std::nan("");
647 err_eigval = 1.;
648 err_var = 1.;
649
650 HeffA.clear();
651 HeffA.resize(N_sites);
652 for (int l=0; l<N_sites; ++l) HeffA[l].Terms.resize(1);
653
654 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
655 {
656 lout << PrepTimer.info("• initial decomposition") << endl;
657 lout << "• initial state : " << Vout.state.info() << endl;
658 int i_expansion_switchoff=0;
659 for (int i=0; i<GlobParam.max_iterations; ++i)
660 {
661 if (DynParam.max_deltaM(i) == 0.) {i_expansion_switchoff = i; break;}
662 }
663
664 lout << "• expansion turned off after ";
665 cout << termcolor::underline;
666 lout << i_expansion_switchoff;
667 cout << termcolor::reset;
668 lout << " iterations" << endl;
669
670 lout << "• initial bond dim. increase by ";
671 cout << termcolor::underline;
672 lout << static_cast<int>((DynParam.Mincr_rel(0)-1.)*100.) << "%";
673 cout << termcolor::reset;
674 lout << " and at least by ";
675 cout << termcolor::underline;
676 lout << DynParam.Mincr_abs(0);
677 cout << termcolor::reset << endl;
678
679 lout << "• keep at least ";
680 cout << termcolor::underline;
681 lout << Vout.state.min_Nsv;
682 cout << termcolor::reset;
683 lout << " singular values per block" << endl;
684
685 lout << "• make between ";
686 cout << termcolor::underline;
687 lout << GlobParam.min_iterations;
688 cout << termcolor::reset;
689 lout << " and ";
690 cout << termcolor::underline;
691 lout << GlobParam.max_iterations;
692 cout << termcolor::reset;
693 lout << " iterations" << endl;
694
695 bool USE_PARALLEL=false, USE_SEQUENTIAL=false, USE_DYNAMIC=false;
696 for (int i=0; i<GlobParam.max_iterations; ++i)
697 {
698 if (DynParam.iteration(i) == UMPS_ALG::PARALLEL) {USE_PARALLEL=true;}
699 if (DynParam.iteration(i) == UMPS_ALG::SEQUENTIAL) {USE_SEQUENTIAL=true;}
700 if (DynParam.iteration(i) == UMPS_ALG::DYNAMIC) {USE_DYNAMIC=true;}
701 }
702 if (USE_DYNAMIC and N_sites == 1)
703 {
704 lout << "• use the parallel algorithm" << endl;
705 }
706 else if (USE_DYNAMIC and N_sites > 1)
707 {
708 lout << "• use the sequential algorithm" << endl;
709 }
710 else if (USE_PARALLEL and USE_SEQUENTIAL)
711 {
712 lout << "• use a combination of sequential and parallel algorithm" << endl;
713 }
714 else if (USE_PARALLEL)
715 {
716 lout << "• use the parallel algorithm" << endl;
717 }
718 else if (USE_SEQUENTIAL)
719 {
720 lout << "• use the sequential algorithm" << endl;
721 }
722 lout << "• eigenvalue tolerance : ";
723 cout << termcolor::underline;
724 lout << GlobParam.tol_eigval;
725 cout << termcolor::reset;
726 lout << endl;
727 lout << "• variational tolerance: ";
728 cout << termcolor::underline;
729 lout << GlobParam.tol_var;
730 cout << termcolor::reset;
731 lout << endl;
732 lout << "• state tolerance: ";
733 cout << termcolor::underline;
734 lout << GlobParam.tol_state;
735 cout << termcolor::reset;
736 lout << endl;
737 lout << endl;
738
739// Vout.state.graph("init");
740 }
741}
742
743template<typename Symmetry, typename MpHamiltonian, typename Scalar>
745prepare_idmrg (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, qarray<Symmetry::Nq> Qtot, bool USE_STATE)
746{
747 Stopwatch<> PrepTimer;
748
749 // general
750 N_sites = 1;
751 N_iterations = 0;
752 assert(H.inBasis(0) == H.outBasis(N_sites-1) and "You insert a strange MPO not consistent with the unit cell");
753 dW = H.inBasis(0).size();
754
755 // resize Vout
756 if (!USE_STATE)
757 {
758 Vout.state = Umps<Symmetry,Scalar>(H.locBasis(0), Qtot, N_sites, GlobParam.Minit, GlobParam.Qinit, GlobParam.INIT_TO_HALF_INTEGER_QN);
759 Vout.state.max_Nsv = GlobParam.Mlimit;
760 Vout.state.setRandom();
761 for (size_t l=0; l<N_sites; ++l)
762 {
763 Vout.state.svdDecompose(l);
764 }
765 }
766 Vout.state.calc_entropy((CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
767
768 HeffA.resize(1);
769 HeffA[0].Terms.resize(1);
770 Qbasis<Symmetry> inbase;
771 inbase.pullData(Vout.state.A[GAUGE::C][0],0);
772 Qbasis<Symmetry> outbase;
773 outbase.pullData(Vout.state.A[GAUGE::C][0],1);
774 HeffA[0].Terms[0].L.setIdentity(dW, 1, inbase);
775 HeffA[0].Terms[0].R.setIdentity(dW, 1, outbase);
776
777 // initial energy & error
778 eoldL = std::nan("");
779 eoldR = std::nan("");
780 err_eigval = 1.;
781 err_var = 1.;
782
783 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
784 {
785 lout << PrepTimer.info("prepare") << endl;
786 }
787}
788
789template<typename Symmetry, typename MpHamiltonian, typename Scalar>
791build_L (const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AL,
792 const Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &Cintercell,
793 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
794 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
795 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
797{
798 Stopwatch<> GMresTimer;
799
800 auto Lguess = L;
801 L.clear();
802
803 // |R) and (L|
804 Biped<Symmetry,MatrixType> Reigen = Cintercell.contract(Cintercell.adjoint());
805
806 // |YRa) and (YLa|
807 vector<Tripod<Symmetry,MatrixType> > YL(dW);
808
809 // |Ra) and (La|
810 Qbasis<Symmetry> inbase; inbase.pullData(AL[0],0);
811 Qbasis<Symmetry> outbase; outbase.pullData(AL[0],0);
812
813 Tripod<Symmetry,MatrixType> IdL; IdL.setIdentity(dW_singlet, 1, inbase);
814 L.insert(basis_order[dW-1],IdL);
815
816 for (int b=dW-2; b>=0; --b)
817 {
818 YL[b] = make_YL(b, L, AL, W, AL, qloc, qOp, basis_order_map);
819
820 if (b > 0)
821 {
822 L.insert(basis_order[b],YL[b]);
823 }
824 else
825 {
827 Tripod<Symmetry,MatrixType> Ltmp_guess; Ltmp_guess.insert(basis_order[b],Lguess);
828 solve_linear(VMPS::DIRECTION::LEFT, b, AL, YL[b], Reigen, W, qloc, qOp, contract_LR(basis_order[b],YL[b],Reigen), Ltmp_guess, Ltmp);
829 L.insert(basis_order[b],Ltmp);
830 }
831 }
832}
833
834template<typename Symmetry, typename MpHamiltonian, typename Scalar>
836build_R (const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AR,
837 const Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &Cintercell,
838 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
839 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
840 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
842{
843 Stopwatch<> GMresTimer;
844
845 auto Rguess = R;
846 R.clear();
847
848 // |R) and (L|
849 Biped<Symmetry,MatrixType> Leigen = Cintercell.adjoint().contract(Cintercell);
850
851 // |YRa) and (YLa|
852 vector<Tripod<Symmetry,MatrixType> > YR(dW);
853
854 // |Ra) and (La|
855 Qbasis<Symmetry> inbase; inbase.pullData(AR[N_sites-1],1);
856 Qbasis<Symmetry> outbase; outbase.pullData(AR[N_sites-1],1);
857
858 Tripod<Symmetry,MatrixType> IdR; IdR.setIdentity(dW_singlet, 1, outbase);
859 R.insert(basis_order[0],IdR);
860
861 for (int a=1; a<dW; ++a)
862 {
863 YR[a] = make_YR(a, R, AR, W, AR, qloc, qOp, basis_order_map);
864
865 if (a < dW-1)
866 {
867 R.insert(basis_order[a],YR[a]);
868 }
869 else
870 {
872 Tripod<Symmetry,MatrixType> Rtmp_guess; Rtmp_guess.insert(basis_order[a],Rguess);
873 solve_linear(VMPS::DIRECTION::RIGHT, a, AR, YR[a], Leigen, W, qloc, qOp, contract_LR(basis_order[a],Leigen,YR[a]), Rtmp_guess, Rtmp);
874 R.insert(basis_order[a],Rtmp);
875 }
876 }
877}
878
879template<typename Symmetry, typename MpHamiltonian, typename Scalar>
881build_LR (const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AL,
882 const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &AR,
883 const vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > &C,
884 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
885 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
886 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
889{
890 Stopwatch<> GMresTimer;
891
892 auto Lguess = L;
893 auto Rguess = R;
894 L.clear();
895 R.clear();
896
897 // |R) and (L|
898 Biped<Symmetry,MatrixType> Reigen = C[N_sites-1].contract(C[N_sites-1].adjoint());
899 Biped<Symmetry,MatrixType> Leigen = C[N_sites-1].adjoint().contract(C[N_sites-1]);
900
901 // |YRa) and (YLa|
902 vector<Tripod<Symmetry,MatrixType> > YL(dW);
903 vector<Tripod<Symmetry,MatrixType> > YR(dW);
904
905 // |Ra) and (La|
906 Qbasis<Symmetry> inbase;
907 inbase.pullData(AL[0],0);
908 Qbasis<Symmetry> outbase;
909 outbase.pullData(AL[0],0);
910
911 Tripod<Symmetry,MatrixType> IdL; IdL.setIdentity(dW_singlet, 1, inbase); //Check correct setIdentity.
912 Tripod<Symmetry,MatrixType> IdR; IdR.setIdentity(dW_singlet, 1, outbase);
913 L.insert(basis_order[dW-1], IdL);
914 R.insert(basis_order[0], IdR);
915 // cout << "b=" << dW-1 << endl << L.print(true) << endl;
916 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
917 #pragma omp parallel sections
918 #endif
919 {
920 // Eq. C19
921 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
922 #pragma omp section
923 #endif
924 {
925 for (int b=dW-2; b>=0; --b)
926 {
927 YL[b] = make_YL(b, L, AL, W, AL, qloc, qOp, basis_order_map);
928 // cout << "b=" << b << ", Yl=" << endl << YL[b].print(true) << endl;
929 if (b > 0)
930 {
931 L.insert(basis_order[b],YL[b]);
932 }
933 else
934 {
936 // cout << "b=" << b << ", blocked=" << basis_order[b].first << "," << basis_order[b].second << endl << Lguess.print() << endl;
937 Tripod<Symmetry,MatrixType> Ltmp_guess; Ltmp_guess.insert(basis_order[b],Lguess);
938 solve_linear(VMPS::DIRECTION::LEFT, b, AL, YL[b], Reigen, W, qloc, qOp, contract_LR(basis_order[b],YL[b],Reigen), Ltmp_guess, Ltmp);
939 L.insert(basis_order[b],Ltmp);
940 // cout << "b=" << b << endl << L.print(true) << endl;
941 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE and b == 0)
942 {
943 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
944 #pragma omp critical
945 #endif
946 {
947 cout << "<L[0]|R>=" << contract_LR(basis_order[0],Ltmp,Reigen) << endl;
948 }
949 }
950 }
951 }
952 }
953
954 // Eq. C20
955 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
956 #pragma omp section
957 #endif
958 {
959 for (int a=1; a<dW; ++a)
960 {
961 YR[a] = make_YR(a, R, AR, W, AR, qloc, qOp, basis_order_map);
962
963 if (a < dW-1)
964 {
965 R.insert(basis_order[a],YR[a]);
966 }
967 else
968 {
970 Tripod<Symmetry,MatrixType> Rtmp_guess; Rtmp_guess.insert(basis_order[a],Rguess);
971 solve_linear(VMPS::DIRECTION::RIGHT, a, AR, YR[a], Leigen, W, qloc, qOp, contract_LR(basis_order[a],Leigen,YR[a]), Rtmp_guess, Rtmp);
972 R.insert(basis_order[a],Rtmp);
973
974 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE and a == dW-1)
975 {
976 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
977 #pragma omp critical
978 #endif
979 {
980 cout << "<L|R[dW-1]>=" << contract_LR(basis_order[dW-1],Leigen,Rtmp) << endl;
981 }
982 }
983 }
984 }
985 }
986 }
987
988 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
989 {
990 lout << "linear systems" << GMresTimer.info() << endl;
991 }
992
993 YLlast = YL[0];
994 YRfrst = YR[dW-1];
995
996 // Tripod<Symmetry,MatrixType> Lcheck;
997 // Tripod<Symmetry,MatrixType> Ltmp1=L;
998
999 // Tripod<Symmetry,MatrixType> Ltmp2;
1000 // for(int l=0; l<N_sites; l++)
1001 // {
1002 // contract_L(Ltmp1, AL[l], W[l], AL[l], qloc[l], qOp[l], Ltmp2);
1003 // Ltmp1.clear();
1004 // Ltmp1 = Ltmp2;
1005 // }
1006 // Lcheck = Ltmp2;
1007
1008 // Tripod<Symmetry,MatrixType> Rcheck;
1009 // Tripod<Symmetry,MatrixType> Rtmp1=R;
1010
1011 // Tripod<Symmetry,MatrixType> Rtmp2;
1012 // for(int l=N_sites-1; l>=0; l--)
1013 // {
1014 // contract_R(Rtmp1, AR[l], W[l], AR[l], qloc[l], qOp[l], Rtmp2);
1015 // Rtmp1.clear();
1016 // Rtmp1 = Rtmp2;
1017 // }
1018 // Rcheck = Rtmp2;
1019
1020 // double Lcomp = L.compare(Lcheck);
1021 // double Rcomp = R.compare(Rcheck);
1022
1023 // cout << termcolor::magenta << "CHECK=" << Lcomp << "\t" << Rcomp << termcolor::reset << endl;
1024 // cout << (L-Lcheck).print(true,13) << endl;
1025 // cout << (R-Rcheck).print(true,13) << endl;
1026}
1027
1028template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1030build_cellEnv (const MpHamiltonian &H, const Eigenstate<Umps<Symmetry,Scalar> > &Vout, size_t power)
1031{
1032 // With a unit cell, Heff is a vector for each site
1033 HeffC.clear();
1034 HeffC.resize(N_sites);
1035 for (size_t l=0; l<N_sites; ++l) HeffC[l].Terms.resize(1);
1036
1037 for (size_t l=0; l<N_sites; ++l)
1038 {
1039// HeffA[l].W = H.W[l];
1040// HeffC[l].W = H.W[l];
1041 HeffA[l].Terms[0].W = H.get_W_power(power)[l];
1042 HeffC[l].Terms[0].W = H.get_W_power(power)[l];
1043 }
1044
1045 // Make environment for the unit cell
1046// build_LR (Vout.state.A[GAUGE::L], Vout.state.A[GAUGE::R], Vout.state.C,
1047// H.W, H.locBasis(), H.opBasis(),
1048// HeffA[0].L, HeffA[N_sites-1].R);
1049 build_LR (Vout.state.A[GAUGE::L], Vout.state.A[GAUGE::R], Vout.state.C,
1050 H.get_W_power(power), H.locBasis(), H.get_qOp_power(power),
1051 HeffA[0].Terms[0].L, HeffA[N_sites-1].Terms[0].R);
1052
1053 // Make environment for each site of the unit cell
1054 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1055 #pragma omp parallel sections
1056 #endif
1057 {
1058 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1059 #pragma omp section
1060 #endif
1061 {
1062 for (size_t l=1; l<N_sites; ++l)
1063 {
1064// contract_L(HeffA[l-1].L,
1065// Vout.state.A[GAUGE::L][l-1], H.W[l-1], Vout.state.A[GAUGE::L][l-1],
1066// H.locBasis(l-1), H.opBasis(l-1),
1067// HeffA[l].L);
1068 contract_L(HeffA[l-1].Terms[0].L,
1069 Vout.state.A[GAUGE::L][l-1], H.get_W_power(power)[l-1], Vout.state.A[GAUGE::L][l-1],
1070 H.locBasis(l-1), H.get_qOp_power(power)[l-1],
1071 HeffA[l].Terms[0].L);
1072 }
1073 }
1074 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1075 #pragma omp section
1076 #endif
1077 {
1078 for (int l=N_sites-2; l>=0; --l)
1079 {
1080// contract_R(HeffA[l+1].R,
1081// Vout.state.A[GAUGE::R][l+1], H.W[l+1], Vout.state.A[GAUGE::R][l+1],
1082// H.locBasis(l+1), H.opBasis(l+1),
1083// HeffA[l].R);
1084 contract_R(HeffA[l+1].Terms[0].R,
1085 Vout.state.A[GAUGE::R][l+1], H.get_W_power(power)[l+1], Vout.state.A[GAUGE::R][l+1],
1086 H.locBasis(l+1), H.get_qOp_power(power)[l+1],
1087 HeffA[l].Terms[0].R);
1088 }
1089 }
1090 }
1091
1092 for (size_t l=0; l<N_sites; ++l)
1093 {
1094 HeffC[l].Terms[0].L = HeffA[(l+1)%N_sites].Terms[0].L;
1095 HeffC[l].Terms[0].R = HeffA[l].Terms[0].R;
1096 }
1097}
1098
1099template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1101iteration_parallel (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout)
1102{
1103 Stopwatch<> IterationTimer;
1104 double tolLanczosEigval, tolLanczosState;
1105 set_LanczosTolerances(tolLanczosEigval,tolLanczosState);
1106
1107 double t_exp = 0.;
1108 double t_trunc = 0.;
1109// cout << "N_iterations_without_expansion=" << N_iterations_without_expansion
1110// << ", max_iter_without_expansion=" << GlobParam.max_iter_without_expansion
1111// << ", min_iter_without_expansion=" << GlobParam.min_iter_without_expansion
1112// << boolalpha
1113// << ", err_var cond: " << (err_var < GlobParam.tol_var)
1114// << ", min cond: " << (N_iterations_without_expansion > GlobParam.min_iter_without_expansion)
1115// << ", max cond: " << (N_iterations_without_expansion > GlobParam.max_iter_without_expansion) << endl;
1116
1117 // If: a) err_var has converged and minimal iteration number exceeded
1118 // b) maximal iteration number exceeded
1119 if ((err_var < GlobParam.tol_var and N_iterations_without_expansion > GlobParam.min_iter_without_expansion) or
1120 N_iterations_without_expansion > GlobParam.max_iter_without_expansion
1121 )
1122 {
1123 Stopwatch<> ExpansionTimer;
1124 size_t current_M = Vout.state.calc_Mmax();
1125 size_t deltaM = min(max(static_cast<size_t>((DynParam.Mincr_rel(N_iterations)-1) * current_M), DynParam.Mincr_abs(N_iterations)),
1126 DynParam.max_deltaM(N_iterations));
1127 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
1128 {
1129 lout << termcolor::blue
1130 << "Nsv=" << current_M
1131 << ", rel=" << static_cast<size_t>(DynParam.Mincr_rel(N_iterations) * current_M-current_M)
1132 << ", abs=" << DynParam.Mincr_abs(N_iterations)
1133 << ", lim=" << DynParam.max_deltaM(N_iterations)
1134 << ", deltaM=" << deltaM
1135 << termcolor::reset << endl;
1136 }
1137
1138 //make sure to perform at least one measurement before expanding the basis
1139 FORCE_DO_SOMETHING = true;
1140 DynParam.doSomething(N_iterations);
1141 FORCE_DO_SOMETHING = false;
1142 if (Vout.state.calc_Mmax()+deltaM >= GlobParam.Mlimit) {deltaM = GlobParam.Mlimit-Vout.state.calc_Mmax();}
1143 else if (Vout.state.calc_Mmax() == GlobParam.Mlimit) {deltaM=0ul;}
1144 else if (Vout.state.calc_Mmax() > GlobParam.Mlimit) {assert(false and "Exceeded Mlimit.");}
1145
1146 VUMPS::TWOSITE_A::OPTION expand_option = VUMPS::TWOSITE_A::ALxCxAR; //static_cast<VUMPS::TWOSITE_A::OPTION>(threadSafeRandUniform<int,int>(0,2));
1147 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1148 {
1149 lout << termcolor::blue << "performing expansion with " << expand_option << termcolor::reset << endl;
1150 }
1151 expand_basis2(deltaM, H, Vout, expand_option);
1152 t_exp = ExpansionTimer.time();
1153 N_iterations_without_expansion = 0;
1154 }
1155
1156 if ((N_iterations+1)%GlobParam.truncatePeriod == 0 )
1157 {
1158 Stopwatch<> TruncationTimer;
1159 Vout.state.truncate(false);
1160 t_trunc = TruncationTimer.time();
1161 }
1162
1163 Stopwatch<> EnvironmentTimer;
1164 build_cellEnv(H,Vout);
1165 double t_env = EnvironmentTimer.time();
1166
1167 Stopwatch<> OptimizationTimer;
1168 // See Algorithm 4
1169 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1170 #pragma omp parallel for schedule(dynamic)
1171 #endif
1172 for (size_t l=0; l<N_sites; ++l)
1173 {
1174 precalc_blockStructure (HeffA[l].Terms[0].L, Vout.state.A[GAUGE::C][l], HeffA[l].Terms[0].W, Vout.state.A[GAUGE::C][l], HeffA[l].Terms[0].R,
1175 H.locBasis(l), H.opBasis(l), HeffA[l].qlhs, HeffA[l].qrhs, HeffA[l].factor_cgcs);
1176
1177 Eigenstate<PivotVector<Symmetry,Scalar> > gAC;
1178 Eigenstate<PivotVector<Symmetry,Scalar> > gC;
1179
1180 // Solve for AC
1181 gAC.state = PivotVector<Symmetry,Scalar>(Vout.state.A[GAUGE::C][l]);
1182
1183 Stopwatch<> LanczosTimer;
1184 LanczosSolver<PivotMatrix1<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz(LocParam.REORTHO);
1185 Lutz.set_dimK(min(LocParam.dimK, dim(gAC.state)));
1186 Lutz.edgeState(HeffA[l], gAC, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1187 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1188 {
1189 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1190 #pragma omp critical
1191 #endif
1192 {
1193 lout << "l=" << l << ", AC" << ", time" << LanczosTimer.info() << ", " << Lutz.info() << endl;
1194 }
1195 }
1196 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1197 {
1198 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1199 #pragma omp critical
1200 #endif
1201 {
1202 lout << "e0(AC)=" << setprecision(13) << gAC.energy << ", ratio=" << gAC.energy/Vout.energy << endl;
1203 }
1204 }
1205
1206 // Solve for C
1207 gC.state = PivotVector<Symmetry,Scalar>(Vout.state.C[l]);
1208
1209 LanczosSolver<PivotMatrix0<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lucy(LocParam.REORTHO);
1210 Lucy.set_dimK(min(LocParam.dimK, dim(gC.state)));
1211 Lucy.edgeState(PivotMatrix0(HeffC[l]), gC, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1212
1213 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1214 {
1215 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1216 #pragma omp critical
1217 #endif
1218 {
1219 lout << "l=" << l << ", C" << ", time" << LanczosTimer.info() << ", " << Lucy.info() << endl;
1220 }
1221 }
1222 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1223 {
1224 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1225 #pragma omp critical
1226 #endif
1227 {
1228 lout << "e0(C)=" << setprecision(13) << gC.energy << ", ratio=" << gC.energy/Vout.energy << endl;
1229 }
1230 }
1231
1232 Vout.state.A[GAUGE::C][l] = gAC.state.data;
1233 Vout.state.C[l] = gC.state.data[0];
1234 }
1235
1236 double t_opt = OptimizationTimer.time();
1237
1238 Stopwatch<> SweepTimer;
1239 for (size_t l=0; l<N_sites; ++l)
1240 {
1241 // Vout.state.polarDecompose(l);
1242 (err_var>0.01)? Vout.state.svdDecompose(l) : Vout.state.polarDecompose(l);
1243 }
1244 Vout.state.calc_entropy((CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
1245
1246 // // Calculate energies
1247 // Biped<Symmetry,ComplexMatrixType> Reigen_ = calc_LReigen(VMPS::DIRECTION::RIGHT, Vout.state.A[GAUGE::L], Vout.state.A[GAUGE::L],
1248 // Vout.state.outBasis(N_sites-1), Vout.state.outBasis(N_sites-1), Vout.state.qloc).state;
1249 // Biped<Symmetry,ComplexMatrixType> Leigen_ = calc_LReigen(VMPS::DIRECTION::LEFT, Vout.state.A[GAUGE::R], Vout.state.A[GAUGE::R],
1250 // Vout.state.inBasis(0), Vout.state.inBasis(0), Vout.state.qloc).state;
1251 // complex<double> eL_ = contract_LR(0, YLlast.template cast<ComplexMatrixType>(), Reigen_) / static_cast<double>(H.volume());
1252 // complex<double> eR_ = contract_LR(dW-1, Leigen_, YRfrst.template cast<ComplexMatrixType>()) / static_cast<double>(H.volume());
1255 // cout << termcolor::blue << "eL_=" << eL_ << ", eR_=" << eR_ << termcolor::reset << endl;
1256
1257 Biped<Symmetry,MatrixType> Reigen, Leigen;
1258 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1259 #pragma omp parallel sections
1260 #endif
1261 {
1262 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1263 #pragma omp section
1264 #endif
1265 {
1266 Reigen = Vout.state.C[N_sites-1].contract(Vout.state.C[N_sites-1].adjoint());
1267 eL = std::real(contract_LR(basis_order[0], YLlast, Reigen)) / H.volume(); //static_cast<Scalar>(H.volume());
1268 }
1269 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
1270 #pragma omp section
1271 #endif
1272 {
1273 Leigen = Vout.state.C[N_sites-1].adjoint().contract(Vout.state.C[N_sites-1]);
1274 eR = std::real(contract_LR(basis_order[dW-1], Leigen, YRfrst)) / H.volume(); //static_cast<Scalar>(H.volume());
1275 }
1276 }
1277 Vout.energy = min(eL,eR);
1278// lout << "e=" << Vout.energy << endl;
1279
1280// double eR2 = calc_LReigen(VMPS::DIRECTION::RIGHT,
1281// Vout.state.A[GAUGE::L],
1282// Vout.state.A[GAUGE::L],
1283// Vout.state.outBasis(N_sites-1),
1284// Vout.state.outBasis(N_sites-1),
1285// Vout.state.qloc,
1286// 100ul, 1e-12,
1287// &Reigen).energy;
1288// calc_LReigen(VMPS::DIRECTION::LEFT,
1289// Vout.state.A[GAUGE::R],
1290// Vout.state.A[GAUGE::R],
1291// Vout.state.outBasis(0),
1292// Vout.state.outBasis(0),
1293// Vout.state.qloc,
1294// 100ul, 1e-12,
1295// &Leigen).energy;
1296
1297 double t_sweep = SweepTimer.time();
1298
1299 Stopwatch<> ErrorTimer;
1300 double t_err = 0;
1301// lout << "err_state_rel=" << abs(err_state_old-err_state)/err_state << endl;
1302 if (abs(err_state_old-err_state)/err_state > 1e-3 or N_iterations_without_expansion<=1 or N_iterations<=6)
1303 {
1304 calc_errors(H, Vout, GlobParam.CALC_STATE_ERROR);
1305 t_err = ErrorTimer.time();
1306 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1307 {
1308 lout << ErrorTimer.info("error calculation") << endl;
1309 }
1310 }
1311 else
1312 {
1313 calc_errors(H, Vout, false);
1314 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1315 {
1316 lout << "State error seems converged and will not be recalculated until the next expansion!" << endl;
1317 }
1318 }
1319
1320 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1321 {
1322 lout << Vout.state.test_ortho() << endl;
1323 lout << termcolor::blue << "eL=" << eL << ", eR=" << eR << termcolor::reset << endl;
1324 lout << test_LReigen(Vout) << endl;
1325 }
1326
1327 ++N_iterations;
1328 ++N_iterations_without_expansion;
1329
1330 double t_tot = IterationTimer.time();
1331 // print stuff
1332 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1333 {
1334 size_t standard_precision = cout.precision();
1335 lout << termcolor::bold << eigeninfo() << termcolor::reset << endl;
1336
1337 lout << Vout.state.info() << endl;
1338 lout << IterationTimer.info("full parallel iteration")
1339 << " (environment=" << round(t_env/t_tot*100.,0) << "%"
1340 << ", optimization=" << round(t_opt/t_tot*100.,0) << "%"
1341 << ", sweep=" << round(t_sweep/t_tot*100.,0) << "%"
1342 << ", error=" << round(t_err/t_tot*100.,0) << "%";
1343 if (t_exp != 0.) {lout << ", basis expansion=" << round(t_exp/t_tot*100.,0) << "%";}
1344 if (t_trunc != 0) {lout << ", basis truncation=" << round(t_trunc/t_tot*100.,0) << "%";}
1345 lout << ")"<< endl;
1346 lout << endl;
1347 }
1348}
1349
1350template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1352iteration_sequential (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout)
1353{
1354 Stopwatch<> IterationTimer;
1355
1356 double tolLanczosEigval, tolLanczosState;
1357 set_LanczosTolerances(tolLanczosEigval,tolLanczosState);
1358
1359 double t_exp = 0.;
1360 double t_trunc = 0.;
1361// cout << "N_iterations_without_expansion=" << N_iterations_without_expansion
1362// << ", max_iter_without_expansion=" << GlobParam.max_iter_without_expansion
1363// << ", min_iter_without_expansion=" << GlobParam.min_iter_without_expansion
1364// << boolalpha
1365// << ", err_var cond: " << (err_var < GlobParam.tol_var)
1366// << ", min cond: " << (N_iterations_without_expansion > GlobParam.min_iter_without_expansion)
1367// << ", max cond: " << (N_iterations_without_expansion > GlobParam.max_iter_without_expansion) << endl;
1368
1369 // If: a) err_var has converged and minimal iteration number exceeded
1370 // b) maximal iteration number exceeded
1371 if ((err_var < GlobParam.tol_var and N_iterations_without_expansion > GlobParam.min_iter_without_expansion) or
1372 N_iterations_without_expansion > GlobParam.max_iter_without_expansion
1373 )
1374 {
1375 // make sure to perform at least one measurement before expanding the basis
1376 FORCE_DO_SOMETHING = true;
1377 lout << termcolor::blue << "Performing a measurement for N_iterations=" << N_iterations << termcolor::reset << endl;
1378 DynParam.doSomething(N_iterations);
1379 FORCE_DO_SOMETHING = false;
1380
1381 Stopwatch<> ExpansionTimer;
1382 size_t current_M = Vout.state.calc_Mmax();
1383 size_t deltaM = min(max(static_cast<size_t>(DynParam.Mincr_rel(N_iterations) * current_M-current_M), DynParam.Mincr_abs(N_iterations)),
1384 DynParam.max_deltaM(N_iterations));
1385 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
1386 {
1387 lout << termcolor::blue
1388 << "Nsv=" << current_M
1389 << ", rel=" << static_cast<size_t>(DynParam.Mincr_rel(N_iterations) * current_M-current_M)
1390 << ", abs=" << DynParam.Mincr_abs(N_iterations)
1391 << ", lim=" << DynParam.max_deltaM(N_iterations)
1392 << ", deltaM=" << deltaM
1393 << termcolor::reset << endl;
1394 }
1395
1396 if (Vout.state.calc_Mmax()+deltaM >= GlobParam.Mlimit) {deltaM = GlobParam.Mlimit-Vout.state.calc_Mmax();}
1397 else if (Vout.state.calc_Mmax() == GlobParam.Mlimit) {deltaM=0ul;}
1398 else if (Vout.state.calc_Mmax() > GlobParam.Mlimit) {assert(false and "Exceeded Mlimit.");}
1399
1400 VUMPS::TWOSITE_A::OPTION expand_option = VUMPS::TWOSITE_A::ALxCxAR; //static_cast<VUMPS::TWOSITE_A::OPTION>(threadSafeRandUniform<int,int>(0,2));
1401 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1402 {
1403 lout << termcolor::blue << "performing expansion with " << expand_option << termcolor::reset << endl;
1404 }
1405 expand_basis2(deltaM, H, Vout, expand_option);
1406 t_exp = ExpansionTimer.time();
1407 N_iterations_without_expansion = 0;
1408 }
1409
1410 // See Algorithm 3
1411 for (size_t l=0; l<N_sites; ++l)
1412 {
1413 build_cellEnv(H,Vout);
1414
1415 precalc_blockStructure (HeffA[l].Terms[0].L, Vout.state.A[GAUGE::C][l], HeffA[l].Terms[0].W, Vout.state.A[GAUGE::C][l], HeffA[l].Terms[0].R,
1416 H.locBasis(l), H.opBasis(l), HeffA[l].qlhs, HeffA[l].qrhs, HeffA[l].factor_cgcs);
1417
1418 Eigenstate<PivotVector<Symmetry,Scalar> > gAC;
1419 Eigenstate<PivotVector<Symmetry,Scalar> > gCR;
1420 Eigenstate<PivotVector<Symmetry,Scalar> > gCL;
1421
1422 // Solve for AC
1423 gAC.state = PivotVector<Symmetry,Scalar>(Vout.state.A[GAUGE::C][l]);
1424
1425 Stopwatch<> LanczosTimer;
1426 LanczosSolver<PivotMatrix1<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar>
1427 Lutz(LocParam.REORTHO);
1428 Lutz.set_dimK(min(LocParam.dimK, dim(gAC.state)));
1429 Lutz.edgeState(HeffA[l], gAC, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1430 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1431 {
1432 lout << "l=" << l << ", AC" << ", time" << LanczosTimer.info() << ", " << Lutz.info() << endl;
1433 }
1434 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1435 {
1436 lout << "e0(AC)=" << setprecision(13) << gAC.energy << ", ratio=" << gAC.energy/Vout.energy << endl;
1437 }
1438
1439 // Solve for CR
1440 gCR.state = PivotVector<Symmetry,Scalar>(Vout.state.C[l]);
1441
1442 LanczosSolver<PivotMatrix0<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar>
1443 Lucy(LocParam.REORTHO);
1444 Lucy.set_dimK(min(LocParam.dimK, dim(gCR.state)));
1445 Lucy.edgeState(PivotMatrix0(HeffC[l]), gCR, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1446 //ensure phase convention: real part of first element is positive
1447 if (std::real(gCR.state.data[0].block[0](0,0)) < 0.) { gCR.state.data[0] = (-1.) * gCR.state.data[0]; }
1448
1449 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1450 {
1451 lout << "l=" << l << ", CR" << ", time" << LanczosTimer.info() << ", " << Lucy.info() << endl;
1452 }
1453 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1454 {
1455 lout << "e0(C)=" << setprecision(13) << gCR.energy << ", ratio=" << gCR.energy/Vout.energy << endl;
1456 }
1457
1458 // Solve for CL
1459 size_t lC = Vout.state.minus1modL(l);
1460 gCL.state = PivotVector<Symmetry,Scalar>(Vout.state.C[lC]);
1461
1462 LanczosSolver<PivotMatrix0<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar>
1463 Luca(LocParam.REORTHO);
1464 Luca.set_dimK(min(LocParam.dimK, dim(gCL.state)));
1465 Luca.edgeState(PivotMatrix0(HeffC[lC]), gCL, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1466 //ensure phase convention: real part of first element is positive
1467 if (std::real(gCL.state.data[0].block[0](0,0)) < 0.) { gCL.state.data[0] = (-1.) * gCL.state.data[0]; }
1468
1469 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1470 {
1471 lout << "l=" << l << ", CL" << ", time" << LanczosTimer.info() << ", " << Luca.info() << endl;
1472 }
1473 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1474 {
1475 lout << "e0(C)=" << setprecision(13) << gCL.energy << ", ratio=" << gCL.energy/Vout.energy << endl;
1476 }
1477
1478 Vout.state.A[GAUGE::C][l] = gAC.state.data;
1479 Vout.state.C[lC] = gCL.state.data[0]; // C(l-1 mod L) = CL
1480 Vout.state.C[l] = gCR.state.data[0]; // C(l) = CR
1481
1482 (err_var>0.01)? Vout.state.svdDecompose(l,GAUGE::R) : Vout.state.polarDecompose(l,GAUGE::R); // AR from AC, CL
1483 (err_var>0.01)? Vout.state.svdDecompose(l,GAUGE::L) : Vout.state.polarDecompose(l,GAUGE::L); // AL from AC, CR
1484 }
1485
1486 Vout.state.calc_entropy((CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
1487
1488 // Calculate energies
1489 Biped<Symmetry,MatrixType> Reigen = Vout.state.C[N_sites-1].contract(Vout.state.C[N_sites-1].adjoint());
1490 Biped<Symmetry,MatrixType> Leigen = Vout.state.C[N_sites-1].adjoint().contract(Vout.state.C[N_sites-1]);
1491 eL = std::real(contract_LR(basis_order[0], YLlast, Reigen)) / H.volume(); //static_cast<Scalar>(H.volume());
1492 eR = std::real(contract_LR(basis_order[dW-1], Leigen, YRfrst)) / H.volume(); //static_cast<Scalar>(H.volume());
1493
1494 Vout.energy = min(eL,eR);
1495
1496 Stopwatch<> ErrorTimer;
1497 double t_err = 0;
1498 if (abs(err_state_old-err_state)/err_state_old > 0.001 or N_iterations_without_expansion<=1 or N_iterations<=6)
1499 {
1500 calc_errors(H, Vout, GlobParam.CALC_STATE_ERROR);
1501 t_err = ErrorTimer.time();
1502 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1503 {
1504 lout << ErrorTimer.info("error calculation") << endl;
1505 }
1506 }
1507 else
1508 {
1509 if (GlobParam.CALC_STATE_ERROR) {calc_errors(H, Vout, false);}
1510 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1511 {
1512 lout << "State error seems converged and will be not recalculated until the next expansion!" << endl;
1513 }
1514 }
1515
1516 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1517 {
1518 lout << Vout.state.test_ortho() << endl;
1519 lout << termcolor::blue << "eL=" << eL << ", eR=" << eR << termcolor::reset << endl;
1520 lout << test_LReigen(Vout) << endl;
1521 }
1522
1523 ++N_iterations;
1524 ++N_iterations_without_expansion;
1525
1526 // print stuff
1527 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1528 {
1529 size_t standard_precision = cout.precision();
1530 lout << Vout.state.info() << endl;
1531 lout << "S=" << Vout.state.entropy().transpose() << endl;
1532 lout << termcolor::bold << eigeninfo() << termcolor::reset << endl;
1533 lout << IterationTimer.info("full sequential iteration") << endl;
1534 lout << endl;
1535 }
1536}
1537
1538template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1540iteration_h2site (Eigenstate<Umps<Symmetry,Scalar> > &Vout)
1541{
1542 Stopwatch<> IterationTimer;
1543
1544 // |R) and (L|
1545 Biped<Symmetry,MatrixType> Reigen = Vout.state.C[N_sites-1].contract(Vout.state.C[N_sites-1].adjoint());
1546 Biped<Symmetry,MatrixType> Leigen = Vout.state.C[N_sites-1].adjoint().contract(Vout.state.C[N_sites-1]);
1547
1548 // |h_R) and (h_L|
1549 Biped<Symmetry,MatrixType> hR = make_hR(h2site, Vout.state.A[GAUGE::R][0], Vout.state.locBasis(0));
1550 Biped<Symmetry,MatrixType> hL = make_hL(h2site, Vout.state.A[GAUGE::L][0], Vout.state.locBasis(0));
1551
1552 // energies
1553 eL = std::real((Leigen.contract(hR)).trace());
1554 eR = std::real((hL.contract(Reigen)).trace());
1555
1556 // |H_R) and (H_L|
1558
1559 // Solve the linear systems in eq. 14
1560 Stopwatch<> GMresTimer;
1561 solve_linear(VMPS::DIRECTION::LEFT, Vout.state.A[GAUGE::L], hL, Reigen, Vout.state.locBasis(), eR, HL);
1562 solve_linear(VMPS::DIRECTION::RIGHT, Vout.state.A[GAUGE::R], hR, Leigen, Vout.state.locBasis(), eL, HR);
1563
1564 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1565 {
1566 lout << "linear systems" << GMresTimer.info() << endl;
1567 }
1568
1569 // Doesn't work like that!! boost::multi_array is shit!
1570// Heff[0] = PivumpsMatrix1<Symmetry,Scalar,Scalar>(HL, HR, h2site, Vout.state.A[GAUGE::L][0], Vout.state.A[GAUGE::R][0]);
1571
1572 Heff[0].h.resize(boost::extents[D][D][D][D]);
1573 Heff[0].h = h2site;
1574 Heff[0].L = HL;
1575 Heff[0].R = HR;
1576 Heff[0].AL = Vout.state.A[GAUGE::L][0];
1577 Heff[0].AR = Vout.state.A[GAUGE::R][0];
1578 Heff[0].qloc = Vout.state.locBasis(0);
1579
1580 double tolLanczosEigval, tolLanczosState;
1581 set_LanczosTolerances(tolLanczosEigval,tolLanczosState);
1582
1583 // Solve for AC (eq. 11)
1584 Eigenstate<PivotVector<Symmetry,Scalar> > gAC;
1585 gAC.state = PivotVector<Symmetry,Scalar>(Vout.state.A[GAUGE::C][0]);
1586
1587 Stopwatch<> LanczosTimer;
1588 LanczosSolver<PivumpsMatrix1<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz1(LocParam.REORTHO);
1589 Lutz1.set_dimK(min(LocParam.dimK, dim(gAC.state)));
1590 Lutz1.edgeState(Heff[0],gAC, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1591
1592 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1593 {
1594 lout << "time" << LanczosTimer.info() << ", " << Lutz1.info() << endl;
1595 }
1596 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1597 {
1598 lout << "e0(AC)=" << setprecision(13) << gAC.energy << endl;
1599 }
1600
1601 // Solve for C (eq. 16)
1602 Eigenstate<PivotVector<Symmetry,Scalar> > gC;
1603 gC.state = PivotVector<Symmetry,Scalar>(Vout.state.C[0]);
1604
1605 LanczosSolver<PivumpsMatrix0<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar> Lutz0(LocParam.REORTHO);
1606 Lutz0.set_dimK(min(LocParam.dimK, dim(gC.state)));
1607 Lutz0.edgeState(PivumpsMatrix0(Heff[0]),gC, LANCZOS::EDGE::GROUND, tolLanczosEigval,tolLanczosState, false);
1608
1609 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1610 {
1611 lout << "time" << LanczosTimer.info() << ", " << Lutz0.info() << endl;
1612 }
1613 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1614 {
1615 lout << "e0(C)=" << setprecision(13) << gC.energy << endl;
1616 }
1617
1618 // Calculate AL and AR from AC, C
1619 Vout.state.A[GAUGE::C][0] = gAC.state.data;
1620 Vout.state.C[0] = gC.state.data[0];
1621 (err_var>0.01)? Vout.state.svdDecompose(0) : Vout.state.polarDecompose(0);
1622
1623 Vout.state.calc_entropy((CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
1624
1625 // if (GlobParam.CALC_STATE_ERROR) {calc_errors(Vout);}
1626 Vout.energy = min(eL,eR);
1627
1628 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1629 {
1630 lout << Vout.state.test_ortho() << endl;
1631 lout << termcolor::blue << "eL=" << eL << ", eR=" << eR << termcolor::reset << endl;
1632 lout << test_LReigen(Vout) << endl;
1633 }
1634
1635 ++N_iterations;
1636
1637 // Print stuff
1638 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1639 {
1640 size_t standard_precision = cout.precision();
1641 lout << "S=" << Vout.state.entropy().transpose() << endl;
1642 lout << eigeninfo() << endl;
1643 lout << IterationTimer.info("full iteration") << endl;
1644 lout << endl;
1645 }
1646}
1647
1648template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1650iteration_idmrg (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout)
1651{
1652 assert(H.length() == 2);
1653 Stopwatch<> IterationTimer;
1654
1655 vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > Atmp;
1656 contract_AA (Vout.state.A[GAUGE::C][0], H.locBasis(0),
1657 Vout.state.A[GAUGE::C][0], H.locBasis(1),
1658 Vout.state.Qtop(0), Vout.state.Qbot(0),
1659 Atmp);
1660 for (size_t s=0; s<Atmp.size(); ++s)
1661 {
1662 Atmp[s] = Atmp[s].cleaned();
1663 }
1664
1665 if (HeffA[0].Terms[0].W.size() == 0)
1666 {
1667 // contract_WW<Symmetry,Scalar> (H.W_at(0), H.locBasis(0), H.opBasis(0),
1668 // H.W_at(1), H.locBasis(1), H.opBasis(1),
1669 // HeffA[0].W, HeffA[0].qloc, HeffA[0].qOp);
1670 }
1671
1672 Eigenstate<PivotVector<Symmetry,Scalar> > g;
1673 g.state = PivotVector<Symmetry,Scalar>(Atmp);
1674
1675// if (HeffA[0].qlhs.size() == 0)
1676 {
1677 HeffA[0].qlhs.clear();
1678 HeffA[0].qrhs.clear();
1679 HeffA[0].factor_cgcs.clear();
1680 precalc_blockStructure (HeffA[0].Terms[0].L, Atmp, HeffA[0].Terms[0].W, Atmp, HeffA[0].Terms[0].R,
1681 HeffA[0].Terms[0].qloc, HeffA[0].Terms[0].qOp,
1682 HeffA[0].qlhs, HeffA[0].qrhs, HeffA[0].factor_cgcs);
1683 }
1684
1685 Stopwatch<> LanczosTimer;
1686 LanczosSolver<PivotMatrix1<Symmetry,Scalar,Scalar>,PivotVector<Symmetry,Scalar>,Scalar>
1687 Lutz(LocParam.REORTHO);
1688 Lutz.set_dimK(min(LocParam.dimK, dim(g.state)));
1689 Lutz.edgeState(HeffA[0], g, LANCZOS::EDGE::GROUND, DMRG::CONTROL::DEFAULT::tol_eigval_Lanczos, DMRG::CONTROL::DEFAULT::tol_state_Lanczos, false);
1690 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1691 {
1692 lout << "time" << LanczosTimer.info() << ", " << Lutz.info() << endl;
1693 }
1694
1695 auto Cref = Vout.state.C[0];
1696
1697 // Mps<Symmetry,Scalar> Vtmp(2, H.locBasis(), Symmetry::qvacuum(), 2, Vout.state.Nqmax);
1698 // Vtmp.min_Nsv = M;
1699 // Vtmp.max_Nsv = M;
1700 // Vtmp.A[0] = Vout.state.A[GAUGE::C][0];
1701 // Vtmp.A[1] = Vout.state.A[GAUGE::C][0];
1702 // Vtmp.QinTop[0] = Vout.state.Qtop(0);
1703 // Vtmp.QinBot[0] = Vout.state.Qbot(0);
1704 // Vtmp.QoutTop[0] = Vout.state.Qtop(0);
1705 // Vtmp.QoutBot[0] = Vout.state.Qbot(0);
1706 // Vtmp.QinTop[1] = Vout.state.Qtop(1);
1707 // Vtmp.QinBot[1] = Vout.state.Qbot(1);
1708 // Vtmp.QoutTop[1] = Vout.state.Qtop(1);
1709 // Vtmp.QoutBot[1] = Vout.state.Qbot(1);
1710 // Vtmp.sweepStep2(DMRG::DIRECTION::RIGHT, 0, g.state.data,
1711 // Vout.state.A[GAUGE::L][0], Vout.state.A[GAUGE::R][0], Vout.state.C[0],
1712 // true);
1713
1714 double truncDump, Sdump;
1715
1716 split_AA(DMRG::DIRECTION::RIGHT, g.state.data,
1717 Vout.state.locBasis(0), Vout.state.A[GAUGE::L][0],
1718 Vout.state.locBasis(0), Vout.state.A[GAUGE::R][0],
1719 Vout.state.Qtop(0), Vout.state.Qbot(0),
1720 Vout.state.C[0], true, truncDump, Sdump,
1721 Vout.state.eps_svd,Vout.state.min_Nsv,Vout.state.max_Nsv);
1722 Vout.state.C[0] = 1./sqrt((Vout.state.C[0].contract(Vout.state.C[0].adjoint())).trace()) * Vout.state.C[0];
1723
1724 Vout.state.calc_entropy((CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)? true : false);
1725
1726 for (size_t s=0; s<H.locBasis(0).size(); ++s)
1727 {
1728 Vout.state.A[GAUGE::C][0][s] = Vout.state.A[GAUGE::L][0][s] *Vout.state.C[0];
1729// Vout.state.A[GAUGE::C][0][s] = Vout.state.C[0].contract(Vout.state.A[GAUGE::R][0][s]);
1730 }
1731
1732 ++N_iterations;
1733
1734 Vout.energy = 0.5*g.energy-Eold;
1735 err_eigval = abs(Vout.energy-eL); // the energy density is the contribution of the new site
1736 err_state = (Cref-Vout.state.C[0]).norm();
1737 err_var = err_state;
1738 Eold = 0.5*g.energy;
1739 eL = Vout.energy;
1740
1741 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
1742 {
1743 lout << Vout.state.test_ortho() << endl;
1744 }
1745
1747 contract_L(HeffA[0].Terms[0].L, Vout.state.A[GAUGE::L][0], H.W[0], Vout.state.A[GAUGE::L][0], H.locBasis(0), H.opBasis(0), HeffLtmp);
1748 HeffA[0].Terms[0].L = HeffLtmp;
1749 contract_R(HeffA[0].Terms[0].R, Vout.state.A[GAUGE::R][0], H.W[1], Vout.state.A[GAUGE::R][0], H.locBasis(1), H.opBasis(1), HeffRtmp);
1750 HeffA[0].Terms[0].R = HeffRtmp;
1751
1752 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1753 {
1754 size_t standard_precision = cout.precision();
1755 lout << "S=" << Vout.state.entropy().transpose() << endl;
1756 lout << termcolor::bold << eigeninfo() << termcolor::reset << endl;
1757 lout << IterationTimer.info("full iteration") << endl;
1758 lout << endl;
1759 }
1760}
1761
1762template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1764test_LReigen (const Eigenstate<Umps<Symmetry,Scalar> > &Vout) const
1765{
1766 TransferMatrix<Symmetry,Scalar> TR(VMPS::DIRECTION::RIGHT, Vout.state.A[GAUGE::R], Vout.state.A[GAUGE::R], Vout.state.qloc);
1767 TransferMatrix<Symmetry,Scalar> TL(VMPS::DIRECTION::LEFT, Vout.state.A[GAUGE::L], Vout.state.A[GAUGE::L], Vout.state.qloc);
1768
1769 Biped<Symmetry,MatrixType> Reigen = Vout.state.C[N_sites-1].contract(Vout.state.C[N_sites-1].adjoint());
1770 Biped<Symmetry,MatrixType> Leigen = Vout.state.C[N_sites-1].adjoint().contract(Vout.state.C[N_sites-1]);
1771
1774
1775 HxV(TL,PsiR);
1776 HxV(TR,PsiL);
1777
1778 stringstream ss;
1779 ss << "ReigenTest=" << (Reigen-PsiR.data).norm() << ", LeigenTest=" << (Leigen-PsiL.data).norm() << endl;
1780 return ss.str();
1781}
1782
1783template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1785edgeState (const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, qarray<Symmetry::Nq> Qtot, LANCZOS::EDGE::OPTION EDGE, bool USE_STATE)
1786{
1787 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
1788 {
1789 lout << endl << termcolor::colorize << termcolor::bold
1790 << "———————————————————————————————————————————————VUMPS algorithm—————————————————————————————————————————————————————————"
1791 << termcolor::reset << endl;
1792 }
1793
1794 if (!USER_SET_GLOBPARAM) {GlobParam = H.get_VumpsGlobParam();}
1795 if (!USER_SET_DYNPARAM) {DynParam = H.get_VumpsDynParam();}
1796
1797 if (DynParam.iteration(0) == UMPS_ALG::IDMRG)
1798 {
1799 prepare_idmrg(H, Vout, Qtot, USE_STATE);
1800 }
1801 else if (DynParam.iteration(0) == UMPS_ALG::H2SITE)
1802 {
1803 assert(H.length() == 2 and "Need L=2 for H2SITE!");
1804 for (size_t i=0; i<GlobParam.max_iterations; i++)
1805 {
1806 assert(DynParam.iteration(i) == UMPS_ALG::H2SITE and "iteration H2SITE can not be mixed with other iterations");
1807 }
1808 prepare_h2site(H.H2site(0,true), H.locBasis(0), Vout, Qtot, GlobParam.Minit, GlobParam.Qinit, USE_STATE);
1809// // if cast to complex is needed:
1810// auto H2site_tmp = H.H2site(0,true);
1811// TwoSiteHamiltonian H2site_cast;
1812// H2site_cast.resize(boost::extents[H2site_cast.shape()[0]][H2site_cast.shape()[1]][H2site_cast.shape()[2]][H2site_cast.shape()[3]]);
1813// H2site_cast = H2site_tmp;
1814// prepare_h2site(H2site_cast, H.locBasis(0), Vout, Qtot, GlobParam.Minit, GlobParam.Qinit, USE_STATE);
1815 }
1816 else
1817 {
1818 prepare(H, Vout, Qtot, USE_STATE);
1819 }
1820
1821 Stopwatch<> GlobalTimer;
1822
1823 while (((err_eigval >= GlobParam.tol_eigval or err_state >= GlobParam.tol_state) and N_iterations < GlobParam.max_iterations) or
1824 N_iterations < GlobParam.min_iterations)
1825 {
1826 if (DynParam.iteration(N_iterations) == UMPS_ALG::PARALLEL)
1827 {
1828 iteration_parallel(H,Vout);
1829 }
1830 else if (DynParam.iteration(N_iterations) == UMPS_ALG::SEQUENTIAL)
1831 {
1832 iteration_sequential(H,Vout);
1833 }
1834 else if (DynParam.iteration(N_iterations) == UMPS_ALG::IDMRG)
1835 {
1836 iteration_idmrg(H,Vout);
1837 }
1838 else if (DynParam.iteration(N_iterations) == UMPS_ALG::H2SITE)
1839 {
1840 iteration_h2site(Vout);
1841 }
1842 else // dynamical choice: L=1 parallel, L>1 sequential
1843 {
1844// if (N_sites == 1) { iteration_parallel(H,Vout); }
1845// else { iteration_sequential(H,Vout); }
1846 iteration_sequential(H,Vout);
1847 }
1848
1849 DynParam.doSomething(N_iterations);
1850
1851 write_log();
1852 #ifdef USE_HDF5_STORAGE
1853 if (GlobParam.savePeriod != 0 and N_iterations%GlobParam.savePeriod == 0 and N_iterations>GlobParam.Niter_before_save)
1854 {
1855 string filename = GlobParam.saveName;
1856 if (GlobParam.FULLMMAX_FILENAME) filename += make_string("_fullMmax=",Vout.state.calc_fullMmax());
1857 lout << termcolor::green << "saving state to: " << filename << termcolor::reset << endl;
1858 Vout.state.save(filename,H.info());
1859 }
1860 #endif
1861
1862 // if (Vout.state.calc_fullMmax() > GlobParam.fullMmaxBreakoff)
1863 // {
1864 // lout << "Terminating because the bond dimension " << Vout.state.calc_fullMmax()
1865 // << " exceeds " << GlobParam.fullMmaxBreakoff << "!" << endl;
1866 // break;
1867 // }
1868 }
1869 write_log(true); // force log on exit
1870
1871 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::ON_EXIT)
1872 {
1873 lout << GlobalTimer.info("total runtime") << endl;
1874 size_t standard_precision = cout.precision();
1875 lout << termcolor::bold << setprecision(14)
1876 << "iterations=" << N_iterations
1877 << ", e0=" << Vout.energy
1878 << ", err_eigval=" << err_eigval
1879 << ", err_var=" << err_var
1880 << ", err_state=" << err_state
1881 << setprecision(standard_precision) << termcolor::reset
1882 << endl;
1883 lout << Vout.state.info() << endl;
1884 lout << endl;
1885 }
1886
1887 if (GlobParam.CALC_S_ON_EXIT)
1888 {
1889 for (size_t l=0; l<N_sites; l++)
1890 {
1891 auto [qs,svs] = Vout.state.entanglementSpectrumLoc(l);
1892 ofstream Filer(make_string("sv_final_",l,".dat"));
1893 size_t index=0;
1894 for (size_t i=0; i<svs.size(); i++)
1895 {
1896 for (size_t deg=0; deg<Symmetry::degeneracy(qs[i]); deg++)
1897 {
1898 Filer << index << "\t" << qs[i] << "\t" << svs[i] << endl;
1899 index++;
1900 }
1901 }
1902 Filer.close();
1903 }
1904 }
1905}
1906
1907template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1910 size_t ab,
1911 const vector<vector<Biped<Symmetry,MatrixType> > > &A,
1912 const Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &Y_LR,
1913 const Biped<Symmetry,MatrixType> &LReigen,
1914 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W,
1915 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
1916 const vector<vector<qarray<Symmetry::Nq> > > &qOp,
1917 Scalar LRdotY,
1918 const Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &LRguess,
1919 Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &LRres)
1920{
1921 MpoTransferMatrix<Symmetry,Scalar> T(DIR, A, A, LReigen, W, qloc, qOp, ab, basis_order_map, basis_order);
1922 MpoTransferVector<Symmetry,Scalar> bvec(Y_LR, basis_order[ab], LRdotY); // right-hand site vector |Y_LR)-e*1
1923
1924 // Solve linear system
1925 GMResSolver<MpoTransferMatrix<Symmetry,Scalar>,MpoTransferVector<Symmetry,Scalar> > Gimli;
1926
1927 Gimli.set_dimK(min(static_cast<size_t>(LINEARSOLVER_DIMK),dim(bvec)));
1928 if (dim(bvec) == 1)
1929 {
1930 lout << termcolor::yellow << "dim(bvec)=" << dim(bvec) << termcolor::reset << endl;
1931 }
1933 Gimli.solve_linear(T, bvec, LRres_tmp, 1e-10, true);
1934 LRres = LRres_tmp.data;
1935
1936 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1937 {
1938 lout << DIR << ": " << Gimli.info() << endl;
1939 }
1940}
1941
1942template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1945 const vector<vector<Biped<Symmetry,MatrixType> > > &A,
1946 const Biped<Symmetry,MatrixType> &hLR,
1947 const Biped<Symmetry,MatrixType> &LReigen,
1948 const vector<vector<qarray<Symmetry::Nq> > > &qloc,
1949 Scalar hLRdotLR,
1951{
1952 TransferMatrix<Symmetry,Scalar> T(DIR,A,A,qloc,true);
1953 T.LReigen = LReigen;
1955
1956 for (size_t q=0; q<bvec.data.dim; ++q)
1957 {
1958 bvec.data.block[q] -= hLRdotLR * Matrix<Scalar,Dynamic,Dynamic>::Identity(bvec.data.block[q].rows(),
1959 bvec.data.block[q].cols());
1960 }
1961
1962 // Solve linear system
1963 GMResSolver<TransferMatrix<Symmetry,Scalar>,TransferVector<Symmetry,Scalar> > Gimli;
1964
1965 Gimli.set_dimK(min(static_cast<size_t>(LINEARSOLVER_DIMK),dim(bvec)));
1966 if (dim(bvec) == 1)
1967 {
1968 lout << termcolor::yellow << "dim(bvec)=" << dim(bvec) << termcolor::reset << endl;
1969 }
1971 Gimli.solve_linear(T,bvec,LRres_tmp);
1972 LRres = LRres_tmp.data;
1973
1974 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
1975 {
1976 lout << DIR << ": " << Gimli.info() << endl;
1977 }
1978}
1979
1980template<typename Symmetry, typename MpHamiltonian, typename Scalar>
1982expand_basis (size_t loc, size_t DeltaM, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, VUMPS::TWOSITE_A::OPTION option)
1983{
1984 //early return if one actually wants to do nothing.
1985 if (DeltaM == 0ul) {return;}
1986
1987 vector<Biped<Symmetry,MatrixType> > NL;
1988 vector<Biped<Symmetry,MatrixType> > NR;
1990
1991 //calculate two-site B-Tensor (double tangent space) and obtain simultaneously NL and NR (nullspaces)
1992 calc_B2(loc, H, Vout.state, option, NAAN, NL, NR);
1993
1994 // SVD-decompose NAAN
1995 double trunc;
1996 auto [U,Sigma,Vdag] = NAAN.truncateSVD(1ul,DeltaM,Vout.state.eps_svd,trunc,true); //true: PRESERVE_MULTIPLETS
1997
1998 // Biped<Symmetry,MatrixType> U, Vdag;
1999
2000 // for (size_t q=0; q<NAAN.dim; ++q)
2001 // {
2002 // #ifdef DONT_USE_BDCSVD
2003 // JacobiSVD<MatrixType> Jack; // standard SVD
2004 // #else
2005 // BDCSVD<MatrixType> Jack; // "Divide and conquer" SVD (only available in Eigen)
2006 // #endif
2007
2008 // Jack.compute(NAAN.block[q], ComputeThinU|ComputeThinV);
2009
2010 // size_t Nret = (Jack.singularValues().array() > Vout.state.eps_svd).count();
2011 // Nret = min(DeltaD, Nret);
2012 // if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE)
2013 // {
2014 // lout << "q=" << NAAN.in[q] << ": Nret=" << Nret << ", ";
2015 // }
2016 // if (Nret > 0)
2017 // {
2018 // U.push_back(NAAN.in[q], NAAN.out[q], Jack.matrixU().leftCols(Nret));
2019 // Vdag.push_back(NAAN.in[q], NAAN.out[q], Jack.matrixV().adjoint().topRows(Nret));
2020 // }
2021 // }
2022 // if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::HALFSWEEPWISE) lout << endl << endl;
2023
2024 //calc P
2025 vector<Biped<Symmetry,MatrixType> > P(Vout.state.locBasis(loc).size());
2026 for (size_t s=0; s<Vout.state.locBasis(loc).size(); ++s)
2027 {
2028 P[s] = NL[s] * U;
2029 }
2030 Vout.state.enrich(loc, GAUGE::L, P);
2031
2032 //Update the left environment if AL is involved in calculating the two site A-tensor, because we need correct environments for the effective two-site Hamiltonian.
2033 if (option == VUMPS::TWOSITE_A::ALxAC or option == VUMPS::TWOSITE_A::ALxCxAR)
2034 {
2035 contract_L(HeffA[loc].Terms[0].L,
2036 Vout.state.A[GAUGE::L][loc], H.W[loc], Vout.state.A[GAUGE::L][loc],
2037 H.locBasis(loc), H.opBasis(loc),
2038 HeffA[(loc+1)%N_sites].Terms[0].L);
2039 }
2040
2041 P.clear();
2042 P.resize(Vout.state.locBasis((loc+1)%N_sites).size());
2043 for (size_t s=0; s<Vout.state.locBasis((loc+1)%N_sites).size(); ++s)
2044 {
2045 P[s] = Vdag * NR[s];
2046 }
2047 Vout.state.enrich(loc, GAUGE::R, P);
2048
2049 //Update the right environment if AR is involved in calculating the two site A-tensor, because we need correct environments for the effective two-site Hamiltonian.
2050 //Note: maybe we only have to update the right environment if loc=0, since we need the updated environment only when loc=N_sites-1 and consequentially loc+1=0.
2051 if (option == VUMPS::TWOSITE_A::ACxAR or option == VUMPS::TWOSITE_A::ALxCxAR)
2052 {
2053 contract_R(HeffA[(loc+1)%N_sites].Terms[0].R,
2054 Vout.state.A[GAUGE::R][(loc+1)%N_sites], H.W[(loc+1)%N_sites], Vout.state.A[GAUGE::R][(loc+1)%N_sites],
2055 H.locBasis((loc+1)%N_sites), H.opBasis((loc+1)%N_sites),
2056 HeffA[loc].Terms[0].R);
2057 }
2058
2059 Vout.state.update_outbase(loc,GAUGE::L);
2060
2061 //update C with zeros
2062 Vout.state.updateC(loc);
2063
2064 //update AC with zeros at sites loc and loc+1
2065 Vout.state.updateAC(loc,GAUGE::L);
2066 Vout.state.updateAC((loc+1)%N_sites,GAUGE::L);
2067
2068 // sort
2069 Vout.state.C[loc] = Vout.state.C[loc].sorted();
2070 Vout.state.sort_A(loc, GAUGE::L, true); //true means sort all gauges, the parameter GAUGE::L has no impact here.
2071 Vout.state.sort_A((loc+1)%N_sites, GAUGE::L, true); //true means sort all gauges, the parameter GAUGE::L has no impact here.
2072}
2073
2074template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2076expand_basis (size_t DeltaM, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, VUMPS::TWOSITE_A::OPTION option)
2077{
2078 for (size_t loc=0; loc<N_sites; loc++)
2079 {
2080 cout << "loc=" << loc << endl;
2081 expand_basis(loc, DeltaM, H, Vout, option);
2082 }
2083}
2084
2085template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2087calc_B2 (size_t loc, const MpHamiltonian &H, const Umps<Symmetry,Scalar> &Psi, VUMPS::TWOSITE_A::OPTION option,
2089{
2090 Psi.calc_N(DMRG::DIRECTION::RIGHT, loc, NL);
2091 Psi.calc_N(DMRG::DIRECTION::LEFT, (loc+1)%N_sites, NR);
2092
2093 PivotMatrix2 H2(HeffA[loc].Terms[0].L, HeffA[(loc+1)%N_sites].Terms[0].R, HeffA[loc].Terms[0].W, HeffA[(loc+1)%N_sites].Terms[0].W,
2094 H.locBasis(loc), H.locBasis((loc+1)%N_sites), H.opBasis(loc), H.opBasis((loc+1)%N_sites));
2095
2096 vector<Biped<Symmetry,MatrixType> > AL;
2097 vector<Biped<Symmetry,MatrixType> > AR;
2098
2099 if (option == VUMPS::TWOSITE_A::ALxAC)
2100 {
2101 AL = Psi.A[GAUGE::L][loc];
2102 AR = Psi.A[GAUGE::C][(loc+1)%N_sites];
2103 }
2104 else if (option == VUMPS::TWOSITE_A::ACxAR)
2105 {
2106 // assert(1!=1 and "The option ACxAR causes bugs. Fix them first to use it.");
2107 AL = Psi.A[GAUGE::C][loc];
2108 AR = Psi.A[GAUGE::R][(loc+1)%N_sites];
2109 }
2110 else if (option == VUMPS::TWOSITE_A::ALxCxAR)
2111 {
2112 AL.resize(Psi.A[GAUGE::L][loc].size());
2113 //Set AL to A[GAUGE::L]*C
2114 for (size_t s=0; s<Psi.A[GAUGE::L][loc].size(); ++s)
2115 {
2116 AL[s] = Psi.A[GAUGE::L][loc][s] * Psi.C[loc];
2117 }
2118 AR = Psi.A[GAUGE::R][(loc+1)%N_sites];
2119 }
2120 else
2121 {
2122 assert(1!=1 and "You inserted an invalid value for enum VUMPS::TWOSITEA::OPTION in calc_B2 from VumpsSolver.");
2123 }
2124
2125// Psi.graph("test");
2126 PivotVector<Symmetry,Scalar> A2C(AL, H.locBasis(loc),
2127 AR, H.locBasis((loc+1)%N_sites),
2128 Psi.Qtop(loc), Psi.Qbot(loc));
2129 precalc_blockStructure (HeffA[loc].Terms[0].L, A2C.data, HeffA[loc].Terms[0].W, HeffA[(loc+1)%N_sites].Terms[0].W, A2C.data, HeffA[(loc+1)%N_sites].Terms[0].R,
2130 H.locBasis(loc), H.locBasis((loc+1)%N_sites), H.opBasis(loc), H.opBasis((loc+1)%N_sites),
2131 H2.qlhs, H2.qrhs, H2.factor_cgcs);
2132
2133 HxV(H2,A2C);
2134
2135 // split_AA(DMRG::DIRECTION::RIGHT, A2C.data, H.locBasis(loc), AL, H.locBasis((loc+1)%N_sites), AR,
2136 // Psi.Qtop(loc), Psi.Qbot(loc),
2137 // Psi.eps_svd,Psi.min_Nsv,Psi.max_Nsv);
2138 Qbasis<Symmetry> qloc_l, qloc_r;
2139 qloc_l.pullData(H.locBasis(loc)); qloc_r.pullData(H.locBasis((loc+1)%N_sites));
2140 auto combined_basis = qloc_l.combine(qloc_r);
2141
2142 split_AA2(DMRG::DIRECTION::RIGHT, combined_basis, A2C.data, H.locBasis(loc), AL, H.locBasis((loc+1)%N_sites), AR,
2143 Psi.Qtop(loc), Psi.Qbot(loc),
2144 0.,Psi.min_Nsv,std::numeric_limits<size_t>::max());
2145
2146 Qbasis<Symmetry> NRbasis; NRbasis.pullData(NR,1);
2147 Qbasis<Symmetry> NLbasis; NLbasis.pullData(NL,0);
2148 Qbasis<Symmetry> ARbasis; ARbasis.pullData(AR,1);
2149 Qbasis<Symmetry> ALbasis; ALbasis.pullData(AL,0);
2150
2151 // calculate B2 = NAAN
2152 Biped<Symmetry,MatrixType> IdL; IdL.setIdentity(NLbasis, ALbasis);
2153 Biped<Symmetry,MatrixType> IdR; IdR.setIdentity(ARbasis, NRbasis);
2154
2156 contract_L(IdL, NL, AL, H.locBasis(loc), TL);
2157 contract_R(IdR, NR, AR, H.locBasis((loc+1)%N_sites), TR);
2158 B2 = TL.contract(TR);
2159}
2160
2161template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2163calc_B2 (size_t loc, const MpHamiltonian &H, const Umps<Symmetry,Scalar> &Psi, VUMPS::TWOSITE_A::OPTION option, Biped<Symmetry,MatrixType>& B2) const
2164{
2165 vector<Biped<Symmetry,MatrixType> > NL_dump, NR_dump;
2166 calc_B2(loc,H,Psi,option,B2,NL_dump,NR_dump);
2167}
2168
2169template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2171create_Mps (size_t Ncells, const Eigenstate<Umps<Symmetry,Scalar> > &V, const MpHamiltonian &H, size_t x0)
2172{
2173 N_sites = V.state.length();
2174 size_t Lhetero = Ncells * N_sites;
2175
2176 // If ground state loaded from file, need to recalculate environments
2177 if (HeffA.size() == 0)
2178 {
2179 lout << termcolor::blue << "create_Mps(Ncells,V,H,x0): Environments are empty, recalculating!..." << termcolor::reset << endl;
2180 auto Vtmp = V;
2181 prepare(H, Vtmp, V.state.Qtarget(), true); // USE_STATE = true
2182 auto VERB_BACKUP = CHOSEN_VERBOSITY; CHOSEN_VERBOSITY = DMRG::VERBOSITY::HALFSWEEPWISE;
2183 build_cellEnv(H,V);
2184 CHOSEN_VERBOSITY = VERB_BACKUP;
2185 }
2186
2187 Mps<Symmetry,Scalar> res = assemble_Mps(Ncells, V.state, V.state.A[GAUGE::L], V.state.A[GAUGE::R], V.state.qloc,
2188 HeffA[0].Terms[0].L, HeffA[(Lhetero-1)%N_sites].Terms[0].R, x0);
2189
2190 // build environment for square:
2191// build_cellEnv(H,V,2ul);
2192// res.Boundaries.Lsq = HeffA[0].L;
2193// res.Boundaries.Rsq = HeffA[0].R;
2194 return res;
2195};
2196
2197template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2199create_Mps (size_t Ncells, const Eigenstate<Umps<Symmetry,Scalar> > &V, const MpHamiltonian &H,
2200 const Mpo<Symmetry,Scalar> &O, const vector<Mpo<Symmetry,Scalar>> &Omult, double tol_OxV)
2201{
2202 N_sites = V.state.length();
2203 size_t Lhetero = Ncells * N_sites;
2204 assert(O.length()%N_sites == 0 and "Please choose a heterogeneous region that is commensurate with the unit cell!");
2205
2208
2209 vector<vector<Biped<Symmetry,MatrixType> > > ALxO = V.state.A[GAUGE::L];
2210 vector<vector<Biped<Symmetry,MatrixType> > > ARxO = V.state.A[GAUGE::R];
2211 vector<vector<Biped<Symmetry,MatrixType> > > ACxO = V.state.A[GAUGE::C];
2212
2213// cout << O.info() << endl;
2214// cout << "V.state.locBasis(0).size()=" << V.state.locBasis(0).size() << endl;
2215// cout << "O.opBasis(O.length()-1).size()=" << O.opBasis(O.length()-1).size() << endl;
2216// cout << "O.inBasis(O.length()-1).size()=" << O.inBasis(O.length()-1).size() << endl;
2217// cout << "O.outBasis(O.length()-1).size()=" << O.outBasis(O.length()-1).size() << endl;
2218//
2219// cout << "in/outBasis at 0:" << endl;
2220// cout << O.inBasis(0).print() << endl;
2221// cout << O.outBasis(0).print() << endl;
2222// cout << "in/outBasis at 1:" << endl;
2223// cout << O.inBasis(1).print() << endl;
2224// cout << O.outBasis(1).print() << endl;
2225// cout << "in/outBasis at L-1:" << endl;
2226// cout << O.inBasis(O.length()-1).print() << endl;
2227// cout << O.outBasis(O.length()-1).print() << endl;
2228// cout << "in/outBasis at L-2:" << endl;
2229// cout << O.inBasis(O.length()-2).print() << endl;
2230// cout << O.outBasis(O.length()-2).print() << endl;
2231
2232 for (size_t l=0; l<N_sites; ++l)
2233 {
2234 Qbasis<Symmetry> inbase;
2235 Qbasis<Symmetry> outbase;
2236
2237 inbase.pullData (V.state.A[GAUGE::L][l],0);
2238 outbase.pullData(V.state.A[GAUGE::L][l],1);
2239 contract_AW(V.state.A[GAUGE::L][l], V.state.locBasis(l), O.W_at(l),
2240 O.opBasis(l), inbase, O.inBasis(l), outbase, O.outBasis(l),
2241 ALxO[l]);
2242// cout << "ALxO done!" << endl;
2243
2244 inbase.clear();
2245 outbase.clear();
2246 inbase.pullData (V.state.A[GAUGE::R][l],0);
2247 outbase.pullData(V.state.A[GAUGE::R][l],1);
2248 contract_AW(V.state.A[GAUGE::R][l], V.state.locBasis(l), O.W_at(O.length()-N_sites+l),
2249 O.opBasis(O.length()-N_sites+l), inbase, O.inBasis(O.length()-N_sites+l), outbase, O.outBasis(O.length()-N_sites+l),
2250 ARxO[l]);
2251// cout << "ARxO done!" << endl;
2252
2253 inbase.clear();
2254 outbase.clear();
2255 inbase.pullData (V.state.A[GAUGE::C][l],0);
2256 outbase.pullData(V.state.A[GAUGE::C][l],1);
2257 contract_AW(V.state.A[GAUGE::C][l], V.state.locBasis(l), O.W_at(O.length()-N_sites+l),
2258 O.opBasis(O.length()-N_sites+l), inbase, O.inBasis(O.length()-N_sites+l), outbase, O.outBasis(O.length()-N_sites+l),
2259 ACxO[l]);
2260// cout << "ACxO done!" << endl;
2261
2262// cout << "AC=" << endl;
2263// for (size_t s=0; s<ACxO[l].size(); ++s)
2264// {
2265// cout << ACxO[l][s].print() << endl;
2266// }
2267// cout << "AR=" << endl;
2268// for (size_t s=0; s<ARxO[l].size(); ++s)
2269// {
2270// cout << ARxO[l][s].print() << endl;
2271// }
2272// cout << "AL=" << endl;
2273// for (size_t s=0; s<ALxO[l].size(); ++s)
2274// {
2275// cout << ALxO[l][s].print() << endl;
2276// }
2277 }
2278
2279 // calc Cshift: q-number sectors to the right of perturbation are shifted
2280 vector<vector<Biped<Symmetry,MatrixType> > > As(N_sites);
2281 for (size_t l=0; l<N_sites; ++l) As[l] = ACxO[l];
2282
2283 auto Qt = Symmetry::reduceSilent(V.state.Qtarget(), O.Qtarget());
2284 Mps<Symmetry,Scalar> Maux(N_sites, As, V.state.locBasis(), Qt[0], N_sites);
2285 Maux.set_Qmultitarget(Qt);
2286 Maux.min_Nsv = V.state.min_Nsv;
2287
2288 auto Cshift = V.state.C[N_sites-1];
2289 Cshift.clear();
2290 Maux.rightSplitStep(N_sites-1, Cshift);
2291// double norm2 = (Cshift.contract(Cshift.adjoint())).trace();
2292 Cshift = 1./sqrt((Cshift.contract(Cshift.adjoint())).trace()) * Cshift;
2293
2294// double norm1 = (V.state.C[N_sites-1].contract(V.state.C[N_sites-1].adjoint())).trace();
2295// double norm3 = (Cshift.contract(Cshift.adjoint())).trace();
2296// cout << "norm1=" << norm1 << ", norm2=" << norm2 << ", norm3=" << norm3 << endl;
2297
2298// // test Cshift
2299// cout << Maux.test_ortho() << endl;
2300// cout << Maux.validate() << endl;
2301// cout << "V.state.C[N_sites-1]=" << endl;
2302// cout << V.state.C[N_sites-1].print(false) << endl << endl;
2303// cout << "Cshift[N_sites-1]=" << endl;
2304// cout << Cshift.print(false) << endl << endl;
2305
2306 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2307 #pragma omp parallel sections
2308 #endif
2309 {
2310 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2311 #pragma omp section
2312 #endif
2313 {
2314 build_L(ALxO, V.state.C[N_sites-1], H.W, H.locBasis(), H.opBasis(), L_with_O);
2315 }
2316 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2317 #pragma omp section
2318 #endif
2319 {
2320 build_R(ARxO, Cshift, H.W, H.locBasis(), H.opBasis(), R_with_O);
2321 }
2322 }
2323
2324 Mps<Symmetry,Scalar> Mtmp = assemble_Mps(Ncells, V.state, ALxO, ARxO, V.state.qloc, L_with_O, R_with_O, O.locality());
2325
2326 vector<Mps<Symmetry,Scalar>> Mres(Omult.size());
2327 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2328 #pragma omp parallel for
2329 #endif
2330 for (size_t l=0; l<Omult.size(); ++l)
2331 {
2333 OxV_exact(Omult[l], Mtmp, Mres[l], tol_OxV, VERB);
2334 }
2335 return Mres;
2336};
2337
2338template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2340create_Mps (size_t Ncells, const Eigenstate<Umps<Symmetry,Scalar> > &V, const MpHamiltonian &H,
2341 const Mpo<Symmetry,Scalar> &O, const Mpo<Symmetry,Scalar> &Omult, double tol_OxV)
2342{
2343 size_t Lhetero = Ncells * N_sites;
2344 assert(O.length()%N_sites == 0 and "Please choose a heterogeneous region that is commensurate with the unit cell!");
2345
2348
2349 vector<vector<Biped<Symmetry,MatrixType> > > ALxO = V.state.A[GAUGE::L];
2350 vector<vector<Biped<Symmetry,MatrixType> > > ARxO = V.state.A[GAUGE::R];
2351 vector<vector<Biped<Symmetry,MatrixType> > > ACxO = V.state.A[GAUGE::C];
2352
2353 for (size_t l=0; l<N_sites; ++l)
2354 {
2355 Qbasis<Symmetry> inbase;
2356 Qbasis<Symmetry> outbase;
2357
2358 inbase.pullData (V.state.A[GAUGE::L][l],0);
2359 outbase.pullData(V.state.A[GAUGE::L][l],1);
2360 contract_AW(V.state.A[GAUGE::L][l], V.state.locBasis(l), O.W_at(l),
2361 O.opBasis(l), inbase, O.inBasis(l), outbase, O.outBasis(l),
2362 ALxO[l]);
2363
2364 inbase.clear();
2365 outbase.clear();
2366 inbase.pullData (V.state.A[GAUGE::R][l],0);
2367 outbase.pullData(V.state.A[GAUGE::R][l],1);
2368 contract_AW(V.state.A[GAUGE::R][l], V.state.locBasis(l), O.W_at(O.length()-N_sites+l),
2369 O.opBasis(O.length()-N_sites+l), inbase, O.inBasis(O.length()-N_sites+l), outbase, O.outBasis(O.length()-N_sites+l),
2370 ARxO[l]);
2371
2372 inbase.clear();
2373 outbase.clear();
2374 inbase.pullData (V.state.A[GAUGE::C][l],0);
2375 outbase.pullData(V.state.A[GAUGE::C][l],1);
2376 contract_AW(V.state.A[GAUGE::C][l], V.state.locBasis(l), O.W_at(O.length()-N_sites+l),
2377 O.opBasis(O.length()-N_sites+l), inbase, O.inBasis(O.length()-N_sites+l), outbase, O.outBasis(O.length()-N_sites+l),
2378 ACxO[l]);
2379 }
2380
2381 // calc Cshift: q-number sectors to the right of perturbation are shifted
2382 vector<vector<Biped<Symmetry,MatrixType> > > As(N_sites);
2383 for (size_t l=0; l<N_sites; ++l) As[l] = ACxO[l];
2384
2385 auto Qt = Symmetry::reduceSilent(V.state.Qtarget(), O.Qtarget());
2386 Mps<Symmetry,Scalar> Maux(N_sites, As, V.state.locBasis(), Qt[0], N_sites);
2387 Maux.set_Qmultitarget(Qt);
2388 Maux.min_Nsv = V.state.min_Nsv;
2389
2390 auto Cshift = V.state.C[N_sites-1];
2391 Cshift.clear();
2392 Maux.rightSplitStep(N_sites-1, Cshift);
2393 Cshift = 1./sqrt((Cshift.contract(Cshift.adjoint())).trace()) * Cshift;
2394
2395 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2396 #pragma omp parallel sections
2397 #endif
2398 {
2399 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2400 #pragma omp section
2401 #endif
2402 {
2403 build_L(ALxO, V.state.C[N_sites-1], H.W, H.locBasis(), H.qOp, L_with_O);
2404 }
2405 #ifndef VUMPS_SOLVER_DONT_USE_OPENMP
2406 #pragma omp section
2407 #endif
2408 {
2409 build_R(ARxO, Cshift, H.W, H.locBasis(), H.qOp, R_with_O);
2410 }
2411 }
2412
2413 Mps<Symmetry,Scalar> Mtmp = assemble_Mps(Ncells, V.state, ALxO, ARxO, V.state.qloc, L_with_O, R_with_O, O.locality());
2414
2417 OxV_exact(Omult, Mtmp, Mres, tol_OxV, VERB);
2418 return Mres;
2419};
2420
2421template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2423assemble_Mps (size_t Ncells,
2424 const Umps<Symmetry,Scalar> &V,
2425 const vector<vector<Biped<Symmetry,MatrixType> > > &AL,
2426 const vector<vector<Biped<Symmetry,MatrixType> > > &AR,
2427 const vector<vector<qarray<Symmetry::Nq> > > &qloc_input,
2430 int x0)
2431{
2432 size_t Lhetero = Ncells * AL.size();
2433
2434 vector<vector<Biped<Symmetry,MatrixType>>> As(Lhetero);
2435 // variant 1: put pivot at x0
2436 for (size_t l=0; l<x0; ++l)
2437 {
2438 As[l] = V.A[GAUGE::L][l%N_sites];
2439 }
2440 As[x0] = V.A[GAUGE::C][x0%N_sites];
2441 for (size_t l=x0+1; l<Lhetero; ++l)
2442 {
2443 As[l] = V.A[GAUGE::R][l%N_sites];
2444 }
2445 // variant 2: put pivot at Lhetero-1
2446// for (size_t l=0; l<Lhetero-1; ++l)
2447// {
2448// As[l] = V.A[GAUGE::L][l%N_sites];
2449// }
2450// As[Lhetero-1] = V.A[GAUGE::C][(Lhetero-1)%N_sites];
2451
2452 vector<vector<qarray<Symmetry::Nq>>> qloc(Lhetero);
2453 for (size_t l=0; l<Lhetero; ++l)
2454 {
2455 qloc[l] = qloc_input[l%N_sites];
2456 }
2457
2458 Mps<Symmetry,Scalar> Mout(Lhetero, As, qloc, Symmetry::qvacuum(), Lhetero);
2459 Mout.set_pivot(x0);
2460
2461 Mout.Boundaries = MpsBoundaries<Symmetry,Scalar>(L,R,AL,AR,qloc_input);
2462
2463 Mout.update_inbase();
2464 Mout.update_outbase();
2465 Mout.calc_Qlimits();
2466
2467 return Mout;
2468}
2469
2470template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2472set_boundary (const Umps<Symmetry,Scalar> &Vin, Mps<Symmetry,Scalar> &Vout, bool LEFT, bool RIGHT)
2473{
2474 if (LEFT or RIGHT)
2475 {
2476 Vout.Boundaries.TRIVIAL_BOUNDARIES = false;
2477
2478 if (LEFT)
2479 {
2480 Vout.Boundaries.L = HeffA[0].Terms[0].L;
2481 }
2482 else
2483 {
2484 Vout.Boundaries.L.clear();
2485 Vout.Boundaries.L.setVacuum();
2486 }
2487 if (RIGHT)
2488 {
2489 Vout.Boundaries.R = HeffA[N_sites-1].Terms[0].R;
2490 }
2491 else
2492 {
2493 Vout.Boundaries.R.clear();
2494 Vout.Boundaries.R.setTarget(qarray3<Symmetry::Nq>{Vin.Qtarget(), Vin.Qtarget(), Symmetry::qvacuum()});
2495 }
2496
2497 Vout.Boundaries.A[0] = Vin.A[GAUGE::L];
2498 Vout.Boundaries.A[1] = Vin.A[GAUGE::R];
2499 Vout.Boundaries.A[2] = Vin.A[GAUGE::C];
2500
2501 Vout.Boundaries.qloc = Vin.qloc;
2502 Vout.Boundaries.N_sites = Vin.qloc.size();
2503
2504// Vout.update_inbase();
2505// Vout.update_outbase();
2506// Vout.calc_Qlimits();
2507 }
2508}
2509
2510//*******************************************************************************************************************************************************************************
2511//This function is expand_basis for the whole unit cell, but with updating AC only at the end.
2512//This could be slightly more efficient than the variant used above, so if you want you can try this function.
2513//It is basically the same code as in expand_basis (size_t loc, size_t DeltaM, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, VUMPS::TWOSITE_A::OPTION option)
2514//but without updating AC. This is here done after the loop over the unit cell.
2515//*******************************************************************************************************************************************************************************
2516
2517template<typename Symmetry, typename MpHamiltonian, typename Scalar>
2519expand_basis2 (size_t DeltaM, const MpHamiltonian &H, Eigenstate<Umps<Symmetry,Scalar> > &Vout, VUMPS::TWOSITE_A::OPTION option)
2520{
2521 if (DeltaM == 0) {return;} //early exit if the dimension to increase is zero.
2522 auto state_ref = Vout.state; //save a copy of the currrent state.
2523
2524 for(size_t loc=0; loc<N_sites; loc++)
2525 {
2526 vector<Biped<Symmetry,MatrixType> > NL;
2527 vector<Biped<Symmetry,MatrixType> > NR;
2529 //calculate two-site B-Tensor (double tangent space) and obtain simultaneously NL and NR (nullspaces)
2530 calc_B2(loc, H, state_ref, option, NAAN, NL, NR);
2531
2532 if (CHOSEN_VERBOSITY >= DMRG::VERBOSITY::STEPWISE)
2533 {
2534 lout << "l=" << loc << ", norm(NAAN)=" << sqrt(NAAN.squaredNorm().sum()) << endl;
2535 }
2536
2537 // SVD-decompose NAAN
2538 double trunc;
2539 auto [U,Sigma,Vdag] = NAAN.truncateSVD(1ul,DeltaM,state_ref.eps_svd,trunc,false); //true: PRESERVE_MULTIPLETS
2540 // cout << "U:" << endl << U.print(false) << endl << "Sigma:" << endl << Sigma.print(false) << "Vdag:" << Vdag.print(false) << endl;
2541
2542 //calc P
2543 vector<Biped<Symmetry,MatrixType> > P(Vout.state.locBasis(loc).size());
2544 for (size_t s=0; s<Vout.state.locBasis(loc).size(); ++s)
2545 {
2546 P[s] = NL[s] * U;
2547 }
2548
2549 // cout << "before enrich, AL:" << endl;
2550 // for (size_t s=0; s<Vout.state.locBasis(loc).size(); s++)
2551 // {
2552 // cout << "s=" << s << endl << Vout.state.A[GAUGE::L][loc][s].print(true) << endl;
2553 // }
2554 Vout.state.enrich(loc, GAUGE::L, P);
2555 // cout << "after enrich, AL:" << endl;
2556 // for (size_t s=0; s<Vout.state.locBasis(loc).size(); s++)
2557 // {
2558 // cout << "s=" << s << endl << Vout.state.A[GAUGE::L][loc][s].print(true) << endl;
2559 // }
2560 //Update the left environment if AL is involved in calculating the two site A-tensor, because we need correct environments for the effective two-site Hamiltonian.
2561 // if (option == VUMPS::TWOSITE_A::ALxAC or option == VUMPS::TWOSITE_A::ALxCxAR)
2562 // {
2563 // contract_L(HeffA[loc].L,
2564 // Vout.state.A[GAUGE::L][loc], H.W[loc], Vout.state.A[GAUGE::L][loc],
2565 // H.locBasis(loc), H.opBasis(loc),
2566 // HeffA[(loc+1)%N_sites].L);
2567 // }
2568
2569 P.clear();
2570 P.resize(Vout.state.locBasis((loc+1)%N_sites).size());
2571 for (size_t s=0; s<Vout.state.locBasis((loc+1)%N_sites).size(); ++s)
2572 {
2573 P[s] = Vdag * NR[s];
2574 }
2575
2576 // cout << "before enrich, AR:" << endl;
2577 // for (size_t s=0; s<Vout.state.locBasis(loc).size(); s++)
2578 // {
2579 // cout << "s=" << s << endl << Vout.state.A[GAUGE::R][loc][s].print(true) << endl;
2580 // }
2581 Vout.state.enrich(loc, GAUGE::R, P);
2582 // cout << "after enrich, AR:" << endl;
2583 // for (size_t s=0; s<Vout.state.locBasis(loc).size(); s++)
2584 // {
2585 // cout << "s=" << s << endl << Vout.state.A[GAUGE::R][loc][s].print(true) << endl;
2586 // }
2587 //Update the right environment if AR is involved in calculating the two site A-tensor, because we need correct environments for the effective two-site Hamiltonian.
2588 //Note: maybe we only have to update the right environment if loc=0, since we need the updated environment only when loc=N_sites-1 and consequentially loc+1=0.
2589 // if (option == VUMPS::TWOSITE_A::ACxAR or option == VUMPS::TWOSITE_A::ALxCxAR)
2590 // {
2591 // contract_R(HeffA[(loc+1)%N_sites].R,
2592 // Vout.state.A[GAUGE::R][(loc+1)%N_sites], H.W[(loc+1)%N_sites], Vout.state.A[GAUGE::R][(loc+1)%N_sites],
2593 // H.locBasis((loc+1)%N_sites), H.opBasis((loc+1)%N_sites),
2594 // HeffA[loc].R);
2595 // }
2596
2597 Vout.state.update_outbase(loc,GAUGE::L);
2598
2599 //update C with zeros
2600 Vout.state.updateC(loc);
2601
2602 // sort
2603 Vout.state.sort_A(loc, GAUGE::L);
2604 Vout.state.sort_A((loc+1)%N_sites, GAUGE::R);
2605 Vout.state.C[loc] = Vout.state.C[loc].sorted();
2606 }
2607
2608 // update AC with zeros and sort
2609 for (size_t loc=0; loc<N_sites; loc++)
2610 {
2611 Vout.state.updateAC(loc,GAUGE::L);
2612 Vout.state.sort_A(loc, GAUGE::L, true); //true means sort all gauges, the parameter GAUGE::L has no impact here.
2613 Vout.state.C[loc] = Vout.state.C[loc].sorted();
2614 }
2615 Vout.state.update_inbase();
2616 Vout.state.update_outbase();
2617}
2618
2619#endif
void contract_AA(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, const qarray< Symmetry::Nq > &Qtop, const qarray< Symmetry::Nq > &Qbot, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Apair, bool DRY=false)
void contract_AW(const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Ain, const vector< qarray< Symmetry::Nq > > &qloc, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< qarray< Symmetry::Nq > > &qOp, const Qbasis< Symmetry > &qauxAl, const Qbasis< Symmetry > &qauxWl, const Qbasis< Symmetry > &qauxAr, const Qbasis< Symmetry > &qauxWr, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Aout, bool FORCE_QTOT=false, qarray< Symmetry::Nq > Qtot=Symmetry::qvacuum())
void split_AA2(DMRG::DIRECTION::OPTION DIR, const Qbasis< Symmetry > &locBasis, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Apair, const vector< qarray< Symmetry::Nq > > &qloc_l, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Al, const vector< qarray< Symmetry::Nq > > &qloc_r, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Ar, const qarray< Symmetry::Nq > &qtop, const qarray< Symmetry::Nq > &qbot, double eps_svd, size_t min_Nsv, size_t max_Nsv)
void split_AA(DMRG::DIRECTION::OPTION DIR, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Apair, const vector< qarray< Symmetry::Nq > > &qloc_l, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Al, const vector< qarray< Symmetry::Nq > > &qloc_r, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Ar, const qarray< Symmetry::Nq > &qtop, const qarray< Symmetry::Nq > &qbot, double eps_svd, size_t min_Nsv, size_t max_Nsv)
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)
Hamiltonian sum(const Hamiltonian &H1, const Hamiltonian &H2, DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
void OxV_exact(const Mpo< Symmetry, MpoScalar > &O, const Mps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, double tol_compr=1e-7, DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::HALFSWEEPWISE, int max_halfsweeps=200, int min_halfsweeps=1, int Minit=-1, DMRG::BROOM::OPTION BROOMOPTION=DMRG::BROOM::QR)
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)
@ A
Definition: DmrgTypedefs.h:130
Tripod< Symmetry, MatrixType > make_YL(size_t b, const Tripod< Symmetry, MatrixType > &Lold, const vector< vector< Biped< Symmetry, MatrixType > > > &Abra, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< MpoScalar > > > > > > &W, const vector< vector< Biped< Symmetry, MatrixType > > > &Aket, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map)
Tripod< Symmetry, MatrixType > make_YR(size_t a, const Tripod< Symmetry, MatrixType > &Rold, const vector< vector< Biped< Symmetry, MatrixType > > > &Abra, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< MpoScalar > > > > > > &W, const vector< vector< Biped< Symmetry, MatrixType > > > &Aket, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map)
Biped< Symmetry, MatrixType > make_hR(const boost::multi_array< MpoScalar, 4 > &H2site, const vector< Biped< Symmetry, MatrixType > > &AR, const vector< qarray< Symmetry::Nq > > &qloc)
Biped< Symmetry, MatrixType > make_hL(const boost::multi_array< MpoScalar, 4 > &H2site, const vector< Biped< Symmetry, MatrixType > > &AL, const vector< qarray< Symmetry::Nq > > &qloc)
‍**Calculates the tensor (eq. (12)) from the explicit 4-legged 2-site Hamiltonian and ....
#define LINEARSOLVER_DIMK
Definition: VumpsSolver.h:5
void set_pivot(int pivot_input)
Definition: DmrgJanitor.h:104
size_t length() const
Definition: DmrgJanitor.h:92
size_t min_Nsv
Definition: DmrgJanitor.h:98
const Qbasis< Symmetry > & outBasis(const std::size_t loc) const
Definition: MpoTerms.h:708
const std::vector< std::vector< std::vector< Biped< Symmetry, MatrixType > > > > & W_at(const std::size_t loc) const
Definition: MpoTerms.h:699
const Qbasis< Symmetry > & inBasis(const std::size_t loc) const
Definition: MpoTerms.h:707
const std::vector< std::vector< qType > > & opBasis() const
Definition: MpoTerms.h:710
const qType & Qtarget() const
Definition: MpoTerms.h:713
Definition: Mpo.h:40
std::size_t length() const
Definition: Mpo.h:112
int locality() const
Definition: Mpo.h:124
Definition: Mps.h:39
void set_Qmultitarget(const vector< qarray< Nq > > &Qmulti_input)
Definition: Mps.h:206
void rightSplitStep(size_t loc, Biped< Symmetry, MatrixType > &C)
void calc_Qlimits()
MpsBoundaries< Symmetry, Scalar > Boundaries
Definition: Mps.h:481
void update_inbase(size_t loc)
void update_outbase(size_t loc)
Definition: Qbasis.h:39
Qbasis< Symmetry > combine(const Qbasis< Symmetry > &other, bool FLIP=false) const
Definition: Qbasis.h:686
void pullData(const vector< Biped< Symmetry, MatrixType > > &A, const Eigen::Index &leg)
Definition: Qbasis.h:486
void clear()
Definition: Qbasis.h:147
Definition: Umps.h:42
qarray< Symmetry::Nq > Qtop(size_t loc) const
Definition: Umps.h:542
qarray< Symmetry::Nq > Qbot(size_t loc) const
Definition: Umps.h:549
vector< vector< qarray< Symmetry::Nq > > > qloc
Definition: Umps.h:365
void calc_N(DMRG::DIRECTION::OPTION DIR, size_t loc, vector< Biped< Symmetry, MatrixType > > &N) const
Definition: Umps.h:1782
size_t min_Nsv
Definition: Umps.h:350
qarray< Nq > Qtarget() const
Definition: Umps.h:211
std::array< vector< vector< Biped< Symmetry, MatrixType > > >, 3 > A
Definition: Umps.h:368
vector< Biped< Symmetry, MatrixType > > C
Definition: Umps.h:371
Matrix< Scalar, Dynamic, Dynamic > MatrixType
Definition: VumpsSolver.h:34
VUMPS::CONTROL::LOC LocParam
Definition: VumpsSolver.h:58
Matrix< Scalar, Dynamic, 1 > VectorType
Definition: VumpsSolver.h:36
double get_err_state() const
Definition: VumpsSolver.h:132
double eoldL
Definition: VumpsSolver.h:277
void set_boundary(const Umps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, bool LEFT=false, bool RIGHT=true)
Definition: VumpsSolver.h:2472
double err_eigval
Definition: VumpsSolver.h:252
DMRG::VERBOSITY::OPTION get_verbosity()
Definition: VumpsSolver.h:49
Mps< Symmetry, Scalar > create_Mps(size_t Ncells, const Eigenstate< Umps< Symmetry, Scalar > > &V, const MpHamiltonian &H, size_t x0)
Definition: VumpsSolver.h:2171
string test_LReigen(const Eigenstate< Umps< Symmetry, Scalar > > &Vout) const
Definition: VumpsSolver.h:1764
vector< qarray< Symmetry::Nq > > qloc
Definition: VumpsSolver.h:264
void userSetGlobParam()
Definition: VumpsSolver.h:52
std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > basis_order_map
Definition: VumpsSolver.h:274
size_t N_iterations
Definition: VumpsSolver.h:249
size_t N_iterations_without_expansion
Definition: VumpsSolver.h:249
void expand_basis2(size_t DeltaD, const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout, VUMPS::TWOSITE_A::OPTION option=VUMPS::TWOSITE_A::ALxAC)
Definition: VumpsSolver.h:2519
size_t iterations()
Definition: VumpsSolver.h:70
void edgeState(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout, qarray< Symmetry::Nq > Qtot, LANCZOS::EDGE::OPTION EDGE=LANCZOS::EDGE::GROUND, bool USE_STATE=false)
Definition: VumpsSolver.h:1785
size_t N_log
Definition: VumpsSolver.h:342
string file_err_var
Definition: VumpsSolver.h:345
void set_LanczosTolerances(double &tolLanczosEigval, double &tolLanczosState)
Definition: VumpsSolver.h:493
void calc_B2(size_t loc, const MpHamiltonian &H, const Umps< Symmetry, Scalar > &Psi, VUMPS::TWOSITE_A::OPTION option, Biped< Symmetry, MatrixType > &B2, vector< Biped< Symmetry, MatrixType > > &NL, vector< Biped< Symmetry, MatrixType > > &NR) const
Definition: VumpsSolver.h:2087
double memory(MEMUNIT memunit=GB) const
Definition: VumpsSolver.h:408
vector< double > err_state_mem
Definition: VumpsSolver.h:348
void prepare_h2site(const TwoSiteHamiltonian &h2site, const vector< qarray< Symmetry::Nq > > &qloc_input, Eigenstate< Umps< Symmetry, Scalar > > &Vout, qarray< Symmetry::Nq > Qtot_input, size_t M, size_t Nqmax, bool USE_STATE=false)
Definition: VumpsSolver.h:566
VUMPS::CONTROL::DYN DynParam
Definition: VumpsSolver.h:57
void set_log(int N_log_input, string file_e_input, string file_err_eigval_input, string file_err_var_input, string file_err_state_input)
Definition: VumpsSolver.h:427
DMRG::VERBOSITY::OPTION CHOSEN_VERBOSITY
Definition: VumpsSolver.h:322
VumpsSolver(DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
Definition: VumpsSolver.h:41
string file_e
Definition: VumpsSolver.h:345
void iteration_sequential(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout)
Definition: VumpsSolver.h:1352
VUMPS::CONTROL::GLOB GlobParam
Definition: VumpsSolver.h:56
void iteration_h2site(Eigenstate< Umps< Symmetry, Scalar > > &Vout)
Definition: VumpsSolver.h:1540
string eigeninfo() const
Definition: VumpsSolver.h:392
void build_cellEnv(const MpHamiltonian &H, const Eigenstate< Umps< Symmetry, Scalar > > &Vout, size_t power=1)
Definition: VumpsSolver.h:1030
void iteration_idmrg(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout)
Definition: VumpsSolver.h:1650
void calc_errors(const MpHamiltonian &H, const Eigenstate< Umps< Symmetry, Scalar > > &Vout, bool CALC_ERR_STATE=true, VUMPS::TWOSITE_A::OPTION option=VUMPS::TWOSITE_A::ALxAC)
Definition: VumpsSolver.h:519
TwoSiteHamiltonian h2site
Definition: VumpsSolver.h:267
string file_err_state
Definition: VumpsSolver.h:345
vector< PivumpsMatrix1< Symmetry, Scalar, Scalar > > Heff
Definition: VumpsSolver.h:255
double err_var
Definition: VumpsSolver.h:252
bool USER_SET_DYNPARAM
Definition: VumpsSolver.h:245
double get_err_eigval() const
Definition: VumpsSolver.h:131
Tripod< Symmetry, MatrixType > YLlast
Definition: VumpsSolver.h:332
void userSetLocParam()
Definition: VumpsSolver.h:54
void build_R(const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &AR, const Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &Cintercell, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< Scalar > > > > > > &W, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, Tripod< Symmetry, MatrixType > &R)
Definition: VumpsSolver.h:836
double Eold
Definition: VumpsSolver.h:170
const double & errState()
Definition: VumpsSolver.h:90
void iteration_parallel(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout)
Definition: VumpsSolver.h:1101
Tripod< Symmetry, MatrixType > YRfrst
Definition: VumpsSolver.h:335
size_t N_sites
Definition: VumpsSolver.h:242
void build_L(const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &AL, const Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &Cintercell, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< Scalar > > > > > > &W, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, Tripod< Symmetry, MatrixType > &L)
Definition: VumpsSolver.h:791
double eoldR
Definition: VumpsSolver.h:277
void build_LR(const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &AL, const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &AR, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &C, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< Scalar > > > > > > &W, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, Tripod< Symmetry, MatrixType > &L, Tripod< Symmetry, MatrixType > &R)
Definition: VumpsSolver.h:881
bool FORCE_DO_SOMETHING
Definition: VumpsSolver.h:93
vector< PivotMatrix1< Symmetry, Scalar, Scalar > > HeffC
Definition: VumpsSolver.h:261
size_t dW_singlet
Definition: VumpsSolver.h:270
vector< pair< qarray< Symmetry::Nq >, size_t > > basis_order
Definition: VumpsSolver.h:273
const double & errEigval()
Definition: VumpsSolver.h:91
vector< PivotMatrix1< Symmetry, Scalar, Scalar > > HeffA
Definition: VumpsSolver.h:258
double err_eigval_old
Definition: VumpsSolver.h:252
vector< double > err_var_mem
Definition: VumpsSolver.h:348
string info() const
Definition: VumpsSolver.h:381
Mps< Symmetry, Scalar > assemble_Mps(size_t Ncells, const Umps< Symmetry, Scalar > &V, const vector< vector< Biped< Symmetry, MatrixType > > > &AL, const vector< vector< Biped< Symmetry, MatrixType > > > &AR, const vector< vector< qarray< Symmetry::Nq > > > &qloc_input, const Tripod< Symmetry, MatrixType > &L, const Tripod< Symmetry, MatrixType > &R, int x0)
Definition: VumpsSolver.h:2423
vector< double > eL_mem
Definition: VumpsSolver.h:348
boost::multi_array< Scalar, 4 > TwoSiteHamiltonian
Definition: VumpsSolver.h:37
void prepare_idmrg(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout, qarray< Symmetry::Nq > Qtot, bool USE_STATE=false)
Definition: VumpsSolver.h:745
bool USER_SET_LOCPARAM
Definition: VumpsSolver.h:246
void expand_basis(size_t loc, size_t DeltaD, const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout, VUMPS::TWOSITE_A::OPTION option=VUMPS::TWOSITE_A::ALxAC)
Definition: VumpsSolver.h:1982
void cleanup(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout)
double get_err_var() const
Definition: VumpsSolver.h:133
double err_state
Definition: VumpsSolver.h:252
vector< double > eR_mem
Definition: VumpsSolver.h:348
double err_state_old
Definition: VumpsSolver.h:252
void write_log(bool FORCE=false)
Definition: VumpsSolver.h:443
void solve_linear(VMPS::DIRECTION::OPTION gauge, size_t ab, const vector< vector< Biped< Symmetry, MatrixType > > > &A, const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &Y_LR, const Biped< Symmetry, MatrixType > &LReigen, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< Scalar > > > > > > &W, const vector< vector< qarray< Symmetry::Nq > > > &qloc, const vector< vector< qarray< Symmetry::Nq > > > &qOp, Scalar LRdotY, const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &LRguess, Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &LRres)
Definition: VumpsSolver.h:1909
const double & errVar()
Definition: VumpsSolver.h:89
bool USER_SET_GLOBPARAM
Definition: VumpsSolver.h:244
vector< double > err_eigval_mem
Definition: VumpsSolver.h:348
void userSetDynParam()
Definition: VumpsSolver.h:53
void set_verbosity(DMRG::VERBOSITY::OPTION VERBOSITY)
Definition: VumpsSolver.h:46
Matrix< complex< Scalar >, Dynamic, Dynamic > ComplexMatrixType
Definition: VumpsSolver.h:35
void prepare(const MpHamiltonian &H, Eigenstate< Umps< Symmetry, Scalar > > &Vout, qarray< Symmetry::Nq > Qtot, bool USE_STATE=false)
Definition: VumpsSolver.h:609
double err_var_old
Definition: VumpsSolver.h:252
string file_err_eigval
Definition: VumpsSolver.h:345
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={})
Scalar contract_LR(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)
std::array< qarray< Nq >, 3 > qarray3
Definition: qarray.h:52
Definition: Biped.h:64
Biped< Symmetry, MatrixType_ > adjoint() const
Definition: Biped.h:630
std::vector< MatrixType_ > block
Definition: Biped.h:96
Biped< Symmetry, MatrixType_ > contract(const Biped< Symmetry, MatrixType_ > &A, const contract::MODE MODE=contract::MODE::UNITY) const
Definition: Biped.h:976
tuple< Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ > > truncateSVD(size_t minKeep, size_t maxKeep, EpsScalar eps_svd, double &truncWeight, double &entropy, map< qarray< Symmetry::Nq >, Eigen::ArrayXd > &SVspec, bool PRESERVE_MULTIPLETS=true, bool RETURN_SPEC=true) const
Definition: Biped.h:744
std::size_t dim
Definition: Biped.h:82
Eigen::VectorXd squaredNorm() const
Definition: Biped.h:520
void setIdentity(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
Definition: Biped.h:358
static constexpr double tol_eigval_Lanczos
Definition: DmrgTypedefs.h:371
static constexpr double tol_state_Lanczos
Definition: DmrgTypedefs.h:372
Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > data
void clear()
Definition: Multipede.h:409
void insert(std::pair< qType, size_t > ab, const Multipede< Nlegs, Symmetry, MatrixType > &Trhs)
Definition: Multipede.h:556
void setIdentity(size_t Drows, size_t Dcols, size_t amax=1, size_t bmax=1)
Definition: Multipede.h:509
vector< vector< std::array< size_t, 12 > > > qrhs
vector< std::array< size_t, 2 > > qlhs
vector< vector< Scalar > > factor_cgcs
vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > data
Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > data
Definition: qarray.h:26