Calculating Time Evolution Only Once

How do I use this algorithm? What does that parameter do?
Post Reply
dorf
Posts: 32
Joined: 16 Feb 2021, 16:34

Calculating Time Evolution Only Once

Post by dorf »

Hey,
so I use the `ExpMPOEvolution` to time evolve some MPS. It takes a MPS and a model as an input. I want to time evolve many different MPS with the same Hamiltonian. Is there a way to only approximate the unitary time-evolution once and use it on the different states instead of recalculating it over and over again?
Would I just use the `make_U_I` method of an MPO and apply that? How would I do that?
Thanks!
User avatar
Johannes
Site Admin
Posts: 428
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Calculating Time Evolution Only Once

Post by Johannes »

I'm not sure if I understand your question correctly - do you suggest to write U(t) as an MPO? Unfortunately, it doesn't work that way. Writing down the full time evolution operator (say as an MPO) for large t is much more expensive than just applying it to a given state: it requires exponentiating H, which effectively requires to diagonalize the full Hamiltonian, getting all excited states - since you don't know which state you will appy it to later.
You can only approximate U for small time steps - usually up to a trotter error depending on the step size, so you have to choose that time step small enough. Effectively, we approximate U(t) by N applications of U(t/N), which works since the error in our approximation of U(t/N) is O((t/N)^2), so the overall error is still O(N(t/N)^2), i.e. decays with increasing N.
The issues start when you need to truncate the MPS/MPO in addition - for the time evolution of a state after a global quench, we usually expect S(t) ~ t, so the bond dimension needs to grow exponentially as well. If you try to write down a general U that you can apply to any psi, that includes any initial state.
In contrast, when you have specific initial states, e.g. close to an eigenstate with only local perturbations or in general a low-entangled initial state, you can often get away with a much longer time evolution until finite-bond-dimension trunction errors kick in.

If your question is rather: how do I re-use the U=exp(iH dt) for small dt, the answer is as you suggest, you need to call make_U_I or make_U_II and then apply it to each state. The ExpMPOTimeEvolution already saves the U to be used again for later time steps (unless you have a time-dependent H). But don't worry about the overhead of generating the U N times for N evolutiuons of different states - the evolution itself is much more costly. You should be perfectly okay to just run the ExpMPOTimeEvoltuion for each of your states, as completely independet simulations (which let's you trivially parallelize on a cluster!).
dorf
Posts: 32
Joined: 16 Feb 2021, 16:34

Re: Calculating Time Evolution Only Once

Post by dorf »

Hey Johannes,
ok thanks! This is what I wanted to know. So you're saying the the contraction with the approximated U is much more expensive than building it, whic makes sense!
Because I apply the 'same circuit' to many different states all the time, I thought about calculating all the approximated Us once and then saving them.

Regarding the parallelization: Tenpy uses its internal vectorization of the linear algebra routines. From your experience, is it faster to leave as many nodes and RAM to these routines and serially compute time evolution for multiple states, or to multiprocess the time evolution? Does that depend on the bond dimension and memory requirements of the MPS? I played around with it, but couldn't gain much for larger system sizes.
User avatar
Johannes
Site Admin
Posts: 428
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Calculating Time Evolution Only Once

Post by Johannes »

I'd always try to exploit "trivial" parallelization first, where you can just distribute jobs (say for different Hamiltonian parameters, or in your case different initial states) to different nodes on a cluster. If you can't do that because you're working on a local machine, keep it as independent python simulations, rathern than using python multiprocessing - python has a "global interpreter lock" that will make those processes interfere otherwise.

How effective the parallelization of the linear algebra routines is, depends 1) on the LAPACK implementation you/your numpy actually uses, e.g. MKL, and 2) on the size of the matrices. The latter, again, depends essentially on the bond dimensions of both MPO and MPS, and other model details, like how many symmetry blocks you have of which size distribution - this can depend on the phase / state you're simulating.
dorf
Posts: 32
Joined: 16 Feb 2021, 16:34

Re: Calculating Time Evolution Only Once

Post by dorf »

Thank you very much for your detailed answer. Makes sense! I will try using different jobs instead of using multiprocessing.
Post Reply