# time-dependent Hamiltonian

edited

Is it possible to evolve the given state with time-dependent Hamiltonian H(t)?
The hamiltonian is periodic, namely H(t)=H(t+T)
More details:

1) I need to find the ground state psi0 of H(0)
2) find psi
t of the Schroedinger eq. with psi0 and H(t)
3) compute the average <psi
t| O | psi_t> of some operator O
4) integrate the result over t

Hi, yes, so one way to do this is to
1. use DMRG to find the ground state of H(0)
2. use the Trotter gate method to do time evolution as described here:
http://itensor.org/docs.cgi?vers=cppv2&page=formulas/tevol_trotter
but at each time step, use the Hamiltonian H(t) appropriate for that time step to define the gates

Steps 3. and 4. involve computing expectation values the normal way (http://itensor.org/docs.cgi?vers=cppv2&page=formulas/measure_mps) and then the integration for step 4 is up to you to perform as appropriate.

Hope that helps!

Miles

commented by (640 points)
thx. I posted possible answer below.
edited

Thank you very much, Miles. I would like to specify the 2nd point of your answer. I understand what you mean, but I can't imagine how it can be done. Could you please write an example.

For instance, how one can replace 'delt' by the function 'delt(t)'

  float delt(float t)
{
return 0.5* sin(t);
}


snippet for Trotter gates

for(int b = 1; b <= N-1; ++b)
{
auto hterm = delt*sites.op("Sz",b)*sites.op("Sz",b+1);
hterm += delt*sites.op("S+",b)*sites.op("S-",b+1);
hterm +=  delt* sites.op("S-",b)*sites.op("S+",b+1);

auto g = Gate(sites,b,b+1,Gate::tReal,tstep/2.,hterm);
gates.push_back(g);
}


(and the same for the reverse oder)
time evolve

   gateTEvol(gates,ttotal,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});


Is there any detailed documentation of 'gateTEvol' function?

Although, I know one of the solutions, which is to divide the total time by N small steps and perform Trotter evolution N times. But i think it is the worst solution.

commented by (70.1k points)
Hi, so actually the solution you are saying about splitting the time into N small steps and performing Trotter evolution N times is in fact the *only* way you can use Trotter evolution at all, even for a time-independent Hamiltonian. If you use Trotter gates for large time steps, each step will make a large error and your results will not be accurate whatsoever. This is an important aspect of Trotter evolution that is important to understand, so please review the background derivation of how Trotter evolution is defined and justified.

Within this context of many small time steps, the idea is that within the loop you do over time steps, you re-make the Trotter gates each time, once per loop over time steps, and make the parameters defining the Hamiltonian terms depend on the time step number.

Best regards,
Miles
commented by (640 points)
I meant to use gateTEvol N times with ttotal=tstep for each step, i.e.

gateTEvol(gates,ttotal=tstep,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});

for example.

Real t=0;
for(i=1; i<=10;i++)
{
for(int b = 1; b <= N-1; ++b)
{
auto hterm = delt (t)*sites.op("Sz",b)*sites.op("Sz",b+1);
hterm += delt (t)*sites.op("S+",b)*sites.op("S-",b+1);
hterm +=  delt(t)* sites.op("S-",b)*sites.op("S+",b+1);

auto g = Gate(sites,b,b+1,Gate::tReal,tstep/2.,hterm);
gates.push_back(g);
}
gateTEvol(gates,ttotal=tstep,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});
t=t+tstep*i
}
Is it possible to use gateTEvol only once?
commented by (70.1k points)
Hi, so you're right we need to document gateTEvol. Thanks for the reminder to do that.

In the meantime, here is how it works: given a list/container of gates, which when applied perform one step of time evolution (assumed to be by an amount tstep), will apply these gates a ttotal/tstep number of times until the total time evolved is ttotal. So if you set ttotal and tstep to be equal, it will just apply the gates once to your MPS.  If you want to evolve by more than one time step, just set ttotal to be the time you want to evolve to (it needs to be an integer multiple of tstep).

Internally, gateTEvol is smart about how it adjusts the gauge of the MPS and other technical things to make sure the gates are applied in the most efficient manner possible, given the ordering of the gates (which it accepts and doesn't try to change).

Since your gates are changing with every time step, the way you are using gateTEvol with ttotal equal to tstep seems right to me, unless for some reason you want to change your Hamiltonian only every other time step or something like that.

Finally, it's not standard C++ notation to put assignments (such as ttotal=tstep) into function calls. Technically it's not possible but I would not recommend it. Better to just pass the values you want in the standard way (no equals signs or assignments; if you need to assign to a variable do that before calling the function).

Best regards,
Miles
commented by (640 points)