27 #ifndef APP_DMRG_TEVOL_NN_SIM_H
28 #define APP_DMRG_TEVOL_NN_SIM_H
39 template<
class Matrix,
class SymmGroup>
41 typedef std::vector<long>
idx_t;
42 typedef std::vector<block_matrix<Matrix, SymmGroup> >
vgates_t;
71 os <<
"Second order Trotter decomposition";
74 os <<
"Fourth order Trotter decomposition";
77 os <<
"uknown Trotter decomposition";
84 template <
class Matrix,
class SymmGroup>
95 , trotter_order(parse_trotter_order((*parms)[
"te_order"]))
98 maquis::cout <<
"Using nearest-neighbors time evolution." << std::endl;
99 maquis::cout <<
"Using " << trotter_order << std::endl;
100 maquis::cout <<
"Time evolution optimization is "
101 << (((*parms)[
"te_optim"]) ?
"enabled" :
"disabled")
105 switch (trotter_order){
108 gates_coeff.push_back(std::make_pair(0,0.5));
109 gates_coeff.push_back(std::make_pair(1,1.));
115 if ((*parms)[
"te_optim"])
117 gates_coeff.push_back(std::make_pair(0,1.));
119 Useq_bmeas.push_back(0);
120 Useq_bmeas.push_back(1);
121 Useq_bmeas.push_back(2);
123 Useq_double.push_back(1);
124 Useq_double.push_back(2);
126 Useq_ameas.push_back(1);
127 Useq_ameas.push_back(0);
130 maquis::cout <<
"Sequence initialized with " << Useq.size() <<
" terms." << std::endl;
135 double alpha_1=1./(4.0-pow(4.0,0.33333));
136 double alpha_3=1.-4.0*alpha_1;
138 gates_coeff.push_back(std::make_pair(0,alpha_1*0.5));
139 gates_coeff.push_back(std::make_pair(1,alpha_1));
140 gates_coeff.push_back(std::make_pair(0,alpha_3*0.5));
141 gates_coeff.push_back(std::make_pair(1,alpha_3));
159 if ((*parms)[
"te_optim"])
161 gates_coeff.push_back(std::make_pair(0,alpha_1));
162 gates_coeff.push_back(std::make_pair(0,alpha_3*0.5+alpha_1*0.5));
164 Useq_bmeas.push_back(0);
165 Useq_bmeas.push_back(1);
166 Useq_bmeas.push_back(4);
167 Useq_bmeas.push_back(1);
168 Useq_bmeas.push_back(5);
169 Useq_bmeas.push_back(3);
170 Useq_bmeas.push_back(5);
171 Useq_bmeas.push_back(1);
172 Useq_bmeas.push_back(4);
173 Useq_bmeas.push_back(1);
174 Useq_bmeas.push_back(4);
176 Useq_double.push_back(1);
177 Useq_double.push_back(4);
178 Useq_double.push_back(1);
179 Useq_double.push_back(5);
180 Useq_double.push_back(3);
181 Useq_double.push_back(5);
182 Useq_double.push_back(1);
183 Useq_double.push_back(4);
184 Useq_double.push_back(1);
185 Useq_double.push_back(4);
187 Useq_ameas.push_back(1);
188 Useq_ameas.push_back(4);
189 Useq_ameas.push_back(1);
190 Useq_ameas.push_back(5);
191 Useq_ameas.push_back(3);
192 Useq_ameas.push_back(5);
193 Useq_ameas.push_back(1);
194 Useq_ameas.push_back(4);
195 Useq_ameas.push_back(1);
196 Useq_ameas.push_back(0);
198 maquis::cout <<
"Sequence initialized with " << Useq.size() <<
" terms." << std::endl;
204 throw std::runtime_error(
"uknown Trotter decomposition");
216 double dt = (*parms)[
"dt"];
217 typename Matrix::value_type I;
218 if (sweep < (*parms)[
"nsweeps_img"])
222 typename Matrix::value_type alpha = -I * dt;
225 for (
size_t i=0; i<gates_coeff.size(); ++i) {
227 Uterms[i].pfirst = gates_coeff[i].first;
228 for (
size_t p=gates_coeff[i].first; p<L-1; p+=2){
229 int type1 = lattice.
get_prop<
int>(
"type", p);
230 int type2 = lattice.
get_prop<
int>(
"type", p+1);
231 if ((*parms)[
"expm_method"] ==
"heev")
232 Uterms[i].add_term(p,
op_exp_hermitian(model.phys_dim(type1)*model.phys_dim(type2), block_terms[p], gates_coeff[i].second*alpha));
234 Uterms[i].add_term(p,
op_exp(model.phys_dim(type1)*model.phys_dim(type2), block_terms[p], gates_coeff[i].second*alpha));
241 iteration_results_.
clear();
243 if (nsteps < 2 || !static_cast<bool>((*parms)[
"te_optim"])) {
245 for (
unsigned i=0; i < nsteps; ++i) evolve_time_step(Useq);
249 evolve_time_step(Useq_bmeas);
251 for (
unsigned i=1; i < nsteps-1; ++i) evolve_time_step(Useq_double);
253 evolve_time_step(Useq_ameas);
259 return iteration_results_;
263 tevol_order_tag parse_trotter_order (std::string
const & trotter_param)
265 if (trotter_param ==
"second")
267 else if (trotter_param ==
"fourth")
270 throw std::runtime_error(
"Don't know this Trotter decomposition");
275 void evolve_time_step(std::vector<std::size_t>
const & gates_i)
277 assert(gates_i.size() > 0);
279 for (
size_t i=0; i<gates_i.size(); ++i) {
280 if (mps->canonization(
true) < mps->length()/2)
281 evolve_l2r(gates_i[i]);
283 evolve_r2l(gates_i[i]);
287 void evolve_l2r(std::size_t gate_index)
289 std::size_t L = mps->length();
290 std::vector<block_matrix<Matrix, SymmGroup> >
const & ops = Uterms[gate_index].vgates;
291 std::vector<long>
const & idx = Uterms[gate_index].idx;
292 int pfirst = Uterms[gate_index].pfirst;
293 std::size_t Mmax=(*parms)[
"max_bond_dimension"];
294 double cutoff=(*parms)[
"truncation_final"];
297 assert(L == idx.size());
299 if (mps->canonization() != pfirst + 1)
300 mps->canonize(pfirst + 1);
303 for (std::size_t p = pfirst; p <= L-1; p += 2)
307 constmps[p].make_left_paired();
308 constmps[p+1].make_right_paired();
314 constmps[p].row_dim(), constmps[p+1].col_dim(),
315 constmps[p].site_dim());
320 iteration_results_[
"SmallestEV"] << trunc.
smallest_ev;
322 mps->move_normalization_l2r(p+1, p+3, DefaultSolver());
324 mps->canonization(
true);
325 assert(mps->canonization() == L-1);
329 void evolve_r2l(std::size_t gate_index)
331 std::size_t L = mps->length();
332 std::vector<block_matrix<Matrix, SymmGroup> >
const & ops = Uterms[gate_index].vgates;
333 std::vector<long>
const & idx = Uterms[gate_index].idx;
334 int pfirst = Uterms[gate_index].pfirst;
335 std::size_t Mmax=(*parms)[
"max_bond_dimension"];
336 double cutoff=(*parms)[
"truncation_final"];
339 assert(L == idx.size());
341 int startpos = std::min(L-2-(L-pfirst)%2, L-2);
342 if (mps->canonization() != startpos)
343 mps->canonize(startpos);
345 for (
int p = std::min(L-2-(L-pfirst)%2, L-2); p >= pfirst; p -= 2)
349 constmps[p].make_left_paired();
350 constmps[p+1].make_right_paired();
356 constmps[p].row_dim(), constmps[p+1].col_dim(),
357 constmps[p].site_dim());
362 iteration_results_[
"SmallestEV"] << trunc.
smallest_ev;
364 mps->move_normalization_r2l(p, std::max(static_cast<long>(p)-2,0L), DefaultSolver());
368 mps->canonization(
true);
369 assert(mps->canonization() == 0);
383 std::vector<block_matrix<Matrix, SymmGroup> > block_terms;
384 std::vector<std::pair<std::size_t,double> > gates_coeff;
385 std::vector<trotter_gate<Matrix, SymmGroup> > Uterms;
386 std::vector<std::size_t> Useq;
387 std::vector<std::size_t> Useq_double, Useq_bmeas, Useq_ameas;
void add_term(std::size_t p, block_matrix< Matrix, SymmGroup > const &block)
double truncated_fraction
std::vector< block_matrix< Matrix, SymmGroup > > vgates_t
static truncation_results replace_two_sites_l2r(MPS< Matrix, SymmGroup > &mps, std::size_t Mmax, double cutoff, block_matrix< Matrix, SymmGroup > const &t, std::size_t p)
std::vector< block_matrix< Matrix, SymmGroup > > hamil_to_blocks(Lattice const &lat, Model< Matrix, SymmGroup > const &model)
block_matrix< Matrix, SymmGroup > op_exp(Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > M, A const &alpha=1.)
utilities for the preparation of time evolution operators
void prepare_te_terms(unsigned sweep)
trotter_gate(std::size_t L)
static block_matrix< Matrix, SymmGroup > multiply_with_twosite(block_matrix< Matrix, SymmGroup > const &vec, block_matrix< Matrix, SymmGroup > const &op, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, Index< SymmGroup > const &phys_i)
T get_prop(std::string property, pos_t site) const
nearest_neighbors_evolver(DmrgParameters *parms_, MPS< Matrix, SymmGroup > *mps_, Lattice const &lattice_, Model< Matrix, SymmGroup > const &model_, int init_sweep=0)
void operator()(unsigned sweep, unsigned nsteps)
static truncation_results replace_two_sites_r2l(MPS< Matrix, SymmGroup > &mps, std::size_t Mmax, double cutoff, block_matrix< Matrix, SymmGroup > const &t, std::size_t p)
std::vector< long > idx_t
void gemm(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
results_collector const & iteration_results() const
std::ostream & operator<<(std::ostream &os, tevol_order_tag o)
block_matrix< Matrix, SymmGroup > op_exp_hermitian(Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > M, A const &alpha=1.)
std::size_t bond_dimension