1#ifndef STRAWBERRY_DMRGEXTERNAL_WITH_Q
2#define STRAWBERRY_DMRGEXTERNAL_WITH_Q
4#ifndef OXV_EXACT_INIT_M
5#define OXV_EXACT_INIT_M 100
13#include "ParamHandler.h"
23template<
typename Symmetry,
typename Scalar>
26 return Vbra.
dot(Vket);
35template<
typename Symmetry,
typename Scalar>
40 return Vbra.
dot(Vket);
50 Vketl.elongate_hetero(abs(Ncellshift),0);
54 Vbral.elongate_hetero(abs(Ncellshift),0);
55 Vketl.elongate_hetero(0,abs(Ncellshift));
59 return Vbral.dot(Vketl);
64template<
typename Symmetry,
typename Scalar>
70template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
76 size_t power_of_O = 1)
88 vector<qarray3<Symmetry::Nq> > Qt;
93 for (
int l=iR; l>=iL; --l)
120template<
typename Symmetry,
typename Scalar>
148template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
152 size_t power_of_O = 1ul,
164 vector<qarray3<Symmetry::Nq> > Qt;
172 for (
size_t l=0; l<O.
length(); ++l)
179 if (CHOSEN_VERBOSITY>=2)
181 lout <<
"avg <Ψ|O|Ψ> L→R, l=" << l <<
", mem=" << round(
B.memory(GB),3) <<
"GB, " << Timer.info(
"time") << endl;
191 vector<qarray3<Symmetry::Nq> > Qt;
201 for (
size_t l=O.
length()-1; l!=-1; --l)
208 if (CHOSEN_VERBOSITY>=2)
210 lout <<
"avg <Ψ|O|Ψ> R→L, l=" << l <<
", mem=" << round(
B.memory(GB),3) <<
"GB, " << Timer.info(
"time") << endl;
286template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
290 bool USE_BOUNDARY =
false,
300 assert(O.
Qtarget() == Symmetry::qvacuum() and
"Can only do avg_hetero with vacuum targets. Try OxV_exact followed by dot instead.");
308 for (
size_t l=0; l<O.
length(); ++l)
364template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
369 typename Symmetry::qType Qtarget = Symmetry::qvacuum(),
375 if constexpr (Symmetry::NON_ABELIAN)
381 vector<qarray3<Symmetry::Nq> > Qt;
389 for (
size_t l=O1.
length()-1; l!=-1; --l)
399 if (CHOSEN_VERBOSITY>=2)
401 lout <<
"avg <Ψ|O·O|Ψ> L→R, l=" << l <<
", mem=" << round(
B.memory(GB),3) <<
"GB, " << Timer.info(
"time") << endl;
408 return B.block[0][0][0].trace();
415 lout <<
"Warning: Result of contraction in <φ|O1·O2|ψ> has " <<
B.dim <<
" blocks, returning 0!" << endl;
416 lout <<
"MPS in question: " << Vket.
info() << endl;
417 lout <<
"MPO1 in question: " << O1.
info() << endl;
418 lout <<
"MPO2 in question: " << O2.
info() << endl;
430 for (
size_t l=0; l<O2.
length(); ++l)
440 return B.block[0][0][0].trace();
446 lout <<
"Warning: Result of contraction in <φ|O1·O2|ψ> has " <<
B.dim <<
" blocks, returning 0!" << endl;
447 lout <<
"MPS in question: " << Vket.
info() << endl;
448 lout <<
"MPO1 in question: " << O1.
info() << endl;
449 lout <<
"MPO2 in question: " << O2.
info() << endl;
456template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
460 size_t usePower = 1ul,
465 for (
int i=0; i<O.
size(); ++i)
467 out +=
avg(Vbra, O[i], Vket, usePower, DIR, CHOSEN_VERBOSITY);
472template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
477 typename Symmetry::qType Qtarget = Symmetry::qvacuum(),
478 size_t usePower1 = 1ul,
479 size_t usePower2 = 1ul,
484 for (
int i=0; i<O1.
size(); ++i)
485 for (
int j=0; j<O2.
size(); ++j)
487 out +=
avg(Vbra, O1[i], O2[j], Vket, Qtarget, usePower1, usePower2, WARN, CHOSEN_VERBOSITY);
499template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
501 bool VERBOSE=
true,
double tol_compr=1e-4,
int Mincr=100,
int Mlimit=10000,
int max_halfsweeps=100)
525 lout << Chronos.info(
"HxV") << endl;
526 lout <<
"Vout: " << Vout.
info() << endl << endl;
530template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
534 HxV(H,Vinout,Vtmp,VERBOSE,tol_compr,Mincr,Mlimit,max_halfsweeps);
549template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
563 lout << Compadre.
info() << endl;
564 lout << termcolor::bold << Chronos.info(make_string(
"polyIter B=",polyB)) << termcolor::reset << endl;
565 lout <<
"Vout: " << Vout.
info() << endl;
569template<
typename Symmetry,
typename Scalar,
typename OtherScalar>
576 vector<Mps<Symmetry,Scalar> > V(2);
586 lout << Compadre.
info() << endl;
587 lout << Chronos.info(
"V+V") << endl;
588 lout <<
"Vout: " << Vout.
info() << endl << endl;
592template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
593void OxV (
const Mpo<Symmetry,MpoScalar> &H,
const Mpo<Symmetry,MpoScalar> &Hdag,
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,
int min_halfsweeps=1,
bool MEASURE_DISTANCE=
true)
606 Compadre.
prodCompress(H, Hdag, Vin, Vout, Vin.
Qtarget(), Vin.
calc_Mmax(), Mincr, Mlimit, tol_compr, max_halfsweeps, min_halfsweeps, 0,
"backup", MEASURE_DISTANCE);
616 lout << Chronos.info(
"OxV") << endl;
617 lout <<
"Vout: " << Vout.
info() << endl << endl;
621template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
622void OxV (
const Mpo<Symmetry,MpoScalar> &H,
const Mpo<Symmetry,MpoScalar> &Hdag,
Mps<Symmetry,Scalar> &Vinout,
bool VERBOSE=
true,
double tol_compr=1e-4,
int Mincr=100,
int Mlimit=10000,
int max_halfsweeps=100,
int min_halfsweeps=1,
bool MEASURE_DISTANCE=
true)
625 OxV(H,Hdag,Vinout,Vtmp,VERBOSE,tol_compr,Mincr,Mlimit,max_halfsweeps,min_halfsweeps,MEASURE_DISTANCE);
721template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
724 int max_halfsweeps = 200,
int min_halfsweeps = 1,
int Minit=-1,
729 bool TRIVIAL_BOUNDARIES =
false;
730 if (Vin.
Boundaries.IS_TRIVIAL()) {TRIVIAL_BOUNDARIES =
true;}
754 for (
size_t l=0; l<L; ++l)
756 bool FORCE_QTOT = (l!=L-1 or TRIVIAL_BOUNDARIES==
false)?
false:
true;
768 string input_info, exact_info, swept_info, compressed_info, Compressor_info;
774 input_info = Vin.
info();
775 exact_info = Vout.
info();
784 Compadre.
stateCompress(Vout, Vtmp, (Minit==-1)?Vin.
calc_Mmax():Minit, 100, 10000, tol_compr, max_halfsweeps, min_halfsweeps);
790 lout << termcolor::red <<
"Warning: OxV compression failed, returning exact result!" << termcolor::reset << endl;
791 Vout.
sweep(0,BROOMOPTION);
803 compressed_info = Vout.
info();
804 Compressor_info = Compadre.
info();
814 Vout.
sweep(0,BROOMOPTION);
819 swept_info = Vout.
info();
828 lout << termcolor::bold <<
"OxV_exact" << termcolor::reset << endl;
829 lout <<
"input:\t" << input_info << endl;
830 lout <<
"oper.:\t" << O.
info() << endl;
831 lout <<
"exact:\t" << exact_info << endl;
834 lout <<
"compr.:\t" << compressed_info << endl;
835 lout <<
"\t" << Compressor_info << endl;
839 lout <<
"swept:\t" << swept_info << endl;
846 Symmetry::IS_TRIVIAL ==
false and
850 lout << termcolor::blue <<
"Warning: Setting min_Nsv=1 to deal with small Hilbert space after OxV_exact!" << termcolor::reset << endl;
854template<
typename Symmetry,
typename MpoScalar,
typename Scalar>
857 int max_halfsweeps = 200,
int min_halfsweeps = 1,
int Minit=-1,
861 OxV_exact(O,Vinout,Vtmp,tol_compr,VERBOSITY,max_halfsweeps,min_halfsweeps,Minit,BROOMOPTION);
865template<
typename Hamiltonian,
typename Scalar>
874 vector<Param> params;
875 Hamiltonian Hres(Sum_asMpo,params);
879template<
typename Hamiltonian,
typename Scalar>
888 vector<Param> params;
889 Hamiltonian Hres(Prod_asMpo,params);
893template<
typename Symmetry,
typename Scalar=
double>
898 else if (!H1.
HAS_W() and H2.
HAS_W()) res = H2;
913template<
typename Symmetry,
typename Scalar=
double>
941template<
typename Symmetry,
typename Scalar=
double>
953template<
typename Symmetry,
typename MpsScalar=
double,
typename MpoScalar=
double>
956 assert(Os.size() > 0);
958 std::size_t Minit = Minit_in;
963 assert(Os[0].IS_UNITARY() and
"Unitarity is needed for this method");
965 Compadre.
prodCompress(Os[0], Os[0], v_in, v_other, Symmetry::qvacuum(), Minit, Mincr, Mlimit, tol_compr, max_halfsweeps, min_halfsweeps);
966 for (std::size_t k=1; k<Os.size(); ++k)
975 assert(Os[k].IS_UNITARY() and
"Unitarity is needed for this method");
977 Compadre.
prodCompress(Os[k], Os[k], v_old, v_new, Symmetry::qvacuum(), Minit, Mincr, Mlimit, tol_compr, max_halfsweeps, min_halfsweeps);
979 if(Os.size() % 2 == 1)
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())
Scalar dot(const Mps< Symmetry, Scalar > &Vbra, const Mps< Symmetry, Scalar > &Vket)
void polyIter(const Mpo< Symmetry, MpoScalar > &H, const Mps< Symmetry, Scalar > &Vin1, double polyB, const Mps< Symmetry, Scalar > &Vin2, Mps< Symmetry, Scalar > &Vout, bool VERBOSE=true)
void addScale(const OtherScalar alpha, const Mps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
Array< Scalar, Dynamic, 1 > dot_green(const Mps< Symmetry, Scalar > &V1, const Mps< Symmetry, Scalar > &V2)
Hamiltonian sum(const Hamiltonian &H1, const Hamiltonian &H2, DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
void OxV(const Mpo< Symmetry, MpoScalar > &H, const Mpo< Symmetry, MpoScalar > &Hdag, 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, int min_halfsweeps=1, bool MEASURE_DISTANCE=true)
Hamiltonian prod(const Hamiltonian &H1, const Hamiltonian &H2, const qarray< Hamiltonian::Symmetry::Nq > &Qtot=Hamiltonian::Symmetry::qvacuum(), DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
void swap(Mps< Symmetry, Scalar > &V1, Mps< Symmetry, Scalar > &V2)
Scalar avg_hetero(const Mps< Symmetry, Scalar > &Vbra, const Mpo< Symmetry, MpoScalar > &O, const Mps< Symmetry, Scalar > &Vket, bool USE_BOUNDARY=false, size_t usePower=1ul, const qarray< Symmetry::Nq > &Qmid=Symmetry::qvacuum())
Scalar dot_hetero(const Mps< Symmetry, Scalar > &Vbra, const Mps< Symmetry, Scalar > &Vket, int Ncellshift=0)
void OvecxV(const std::vector< Mpo< Symmetry, MpoScalar > > &Os, Mps< Symmetry, MpsScalar > &v_in, std::size_t Minit_in=0ul, std::size_t Mincr=100ul, std::size_t Mlimit=10000ul, double tol_compr=1e-5, std::size_t max_halfsweeps=24ul, std::size_t min_halfsweeps=1ul)
Scalar avg(const Mps< Symmetry, Scalar > &Vbra, const Mpo< Symmetry, MpoScalar > &O, const Mps< Symmetry, Scalar > &Vket, size_t power_of_O=1ul, DMRG::DIRECTION::OPTION DIR=DMRG::DIRECTION::RIGHT, DMRG::VERBOSITY::OPTION CHOSEN_VERBOSITY=DMRG::VERBOSITY::SILENT)
void 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)
Array< Scalar, Dynamic, 1 > matrix_element(int iL, int iR, const Mps< Symmetry, Scalar > &Vbra, const Mpo< Symmetry, MpoScalar > &O, const Mps< Symmetry, Scalar > &Vket, size_t power_of_O=1)
Mpo< Symmetry, Scalar > diff(const Mpo< Symmetry, Scalar > &H1, const Mpo< Symmetry, Scalar > &H2, DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
void HxV(const Mpo< Symmetry, MpoScalar > &H, const Mps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, bool VERBOSE=true, double tol_compr=1e-4, int Mincr=100, int Mlimit=10000, int max_halfsweeps=100)
void sweep(size_t loc, DMRG::BROOM::OPTION TOOL, PivotMatrixType *H=NULL)
static MpoTerms< Symmetry, Scalar > prod(const MpoTerms< Symmetry, Scalar > &top, const MpoTerms< Symmetry, Scalar > &bottom, const qType &qTot, const double tolerance=::mynumeric_limits< double >::epsilon())
const Qbasis< Symmetry > & outBasis(const std::size_t loc) const
void set_verbosity(const DMRG::VERBOSITY::OPTION VERB_in)
const std::vector< std::vector< std::vector< Biped< Symmetry, MatrixType > > > > & W_at(const std::size_t loc) const
void scale(const Scalar factor, const Scalar offset=0., const std::size_t power=0ul, const double tolerance=1.e-14)
static MpoTerms< Symmetry, Scalar > sum(const MpoTerms< Symmetry, Scalar > &top, const MpoTerms< Symmetry, Scalar > &bottom, const double tolerance=::mynumeric_limits< double >::epsilon())
const std::vector< std::vector< qType > > & locBasis() const
void calc(const std::size_t power)
const Qbasis< Symmetry > & inBasis(const std::size_t loc) const
const std::vector< std::vector< std::vector< std::vector< Biped< Symmetry, MatrixType > > > > > & get_W_power(std::size_t power) const
const std::vector< std::vector< qType > > & get_qOp_power(std::size_t power) const
const std::vector< std::vector< qType > > & opBasis() const
const qType & Qtarget() const
const std::vector< Qbasis< Symmetry > > & auxBasis() const
std::size_t volume() const
std::size_t length() const
std::string info(bool REDUCED=false) const
void prodCompress(const MpOperator &H, const MpOperator &Hdag, const Mps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, qarray< Symmetry::Nq > Qtot_input, size_t Minit, size_t Mincr=100, size_t Mlimit=10000, double tol=1e-4, size_t max_halfsweeps=100, size_t min_halfsweeps=1, std::size_t savePeriod=0, std::string saveName="backup", bool MEASURE_DISTANCE=true, const MpOperator *HdagH=NULL)
void lincomboCompress(const vector< Mps< Symmetry, Scalar > > &Vin, const vector< Scalar > &factors, Mps< Symmetry, Scalar > &Vout, const Mps< Symmetry, Scalar > &Vguess, size_t Minit, size_t Mincr=100, size_t Mlimit=10000, double tol=1e-4, size_t max_halfsweeps=40, size_t min_halfsweeps=1)
void polyCompress(const MpOperator &H, const Mps< Symmetry, Scalar > &Vin1, double polyB, const Mps< Symmetry, Scalar > &Vin2, Mps< Symmetry, Scalar > &Vout, size_t Minit, size_t Mincr=100, size_t Mlimit=10000, double tol=DMRG_POLYCOMPRESS_TOL, size_t max_halfsweeps=DMRG_POLYCOMPRESS_MAX, size_t min_halfsweeps=DMRG_POLYCOMPRESS_MIN)
void stateCompress(const Mps< Symmetry, Scalar > &Vin, Mps< Symmetry, Scalar > &Vout, size_t Minit, size_t Mincr=100, size_t Mlimit=10000, double tol=1e-4, size_t max_halfsweeps=40, size_t min_halfsweeps=1)
vector< qarray< Nq > > locBasis(size_t loc) const
void elongate_hetero(size_t Nleft=0, size_t Nright=0)
void set_Qmultitarget(const vector< qarray< Nq > > &Qmulti_input)
Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > get_boundaryTensor(DMRG::DIRECTION::OPTION DIR, size_t usePower=1ul) const
Scalar dot(const Mps< Symmetry, Scalar > &Vket) const
const vector< Biped< Symmetry, MatrixType > > & A_at(size_t loc) const
double calc_Nqavg() const
MpsBoundaries< Symmetry, Scalar > Boundaries
void update_inbase(size_t loc)
void update_outbase(size_t loc)
Qbasis< Symmetry > inBasis(size_t loc) const
void swap(Mps< Symmetry, Scalar > &V)
vector< qarray< Nq > > Qmultitarget() const
Qbasis< Symmetry > outBasis(size_t loc) const
qarray< Nq > Qtarget() const
void contract_R(const Tripod< Symmetry, MatrixType2 > &Rold, const vector< Biped< Symmetry, MatrixType > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, MatrixType > > &Aket, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Tripod< Symmetry, MatrixType2 > &Rnew, bool RANDOMIZE=false, tuple< CONTRACT_LR_MODE, size_t > MODE_input=make_pair(FULL, 0), const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map={})
void contract_L(const Tripod< Symmetry, MatrixType2 > &Lold, const vector< Biped< Symmetry, MatrixType > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, MatrixType > > &Aket, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Tripod< Symmetry, MatrixType2 > &Lnew, bool RANDOMIZE=false, tuple< CONTRACT_LR_MODE, size_t > MODE_input=make_pair(FULL, 0), const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map={})
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
void setTarget(std::array< qType, Nlegs > Q)
void push_back(std::array< qType, Nlegs > quple, const boost::multi_array< MatrixType, LEGLIMIT > &M)
void setIdentity(size_t Drows, size_t Dcols, size_t amax=1, size_t bmax=1)