0 votes
asked by (290 points)

Hi Miles
I started with the code given in iTensor website for trotter gates using Heisenberg chain and took my initial state to be ground state(GS) of Hamiltonian.Then I evolved my state using trotter gates formulation and after each T ,I calculated the overlap with the GS and got 1 as expected for small T(order 1E-2) as well as large T(order 1E0).
But when I modified my hamiltonian just by including a onsite term like -@@\sum_i\sigma_i^x @@ and did the same calcuation i.e taking GS as my initial state and calculate overlap of evolved wavefunction with my GS.Here also i should get 1 after every trotter gate evolution but instead I am getting overlap less then 1 which also depends how much is my T(total time).For smaller T (order1E-2 and time step @@\tau@@ 1E-4) overlap decreases sucessively but the starting value is around 0.99 after applying U(T).And for larger value of T(order 1E0 time step 1E-2) overlap is coming out to be very small.

1 Answer

0 votes
answered by (70.1k points)

Hi, thanks for the question. The answer is that why this is happening could be due to many reasons, so it's hard to tell just from the description of the results you are seeing.

The most likely reason, if I had to guess, is that Trotter gates very generally incur a finite-time-step error, as you know. So the evolution is not exact. Therefore even if theoretically the overlap should stay very close to 1, in practice it will not. How close it stays should then depend on how small of a time step you use, how many steps you do, and how accurately you decompose/truncate the MPS after each step.

Another possibility is that there is a slight error or bug in your code.

If you try adjusting the time step and other accuracy parameters, and do other checks you can think of, but then think the results you are seeing cannot be right, please post a follow up comment or new question, perhaps with some code, and we can discuss more.

Best regards,
Miles

commented by (290 points)
edited by
Thank you so much Miles for your quick response.Below I am attaching the code that I wrote-

for(int i=1;i<N;i++)
{
nav+=1,"Sz",i,"Sz",i+1;
nav+=0.5,"S-",i,"S+",i+1;
nav+=0.5,"S+",i,"S-",i+1;
nav+=1,"S+",i;
nav+=1,"S-",i;
}
nav+=1,"S+",N;
nav+=1,"S-",N;

auto H=MPO(nav);
auto sweeps=Sweeps(50);
sweeps.maxm()=10,20,50,100,200,300,600;
sweeps.cutoff()=1E-10;
sweeps.niter() = 2;
sweeps.noise() = 1E-7,1E-8,1E-5,0.0,0.0,0.0;

auto psi=MPS(sites);
auto energy=dmrg(psi,H,sweeps,{"Quiet=",true});
auto psi0 = psi;
Real tstep = 0.02;  
Real ttotal = 2.0;
Real cutoff = 1E-10;

using Gate = BondGate<ITensor>;
auto gates = vector<Gate>();


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

            auto g = Gate(sites,b,b+1,Gate::tReal,tstep/2.,hterm);
            gates.push_back(g);  
        }
        else
        {
            auto hterm=sites.op("Id",b-1)*sites.op("S-",b);
            hterm+=sites.op("Id",b-1)*sites.op("S+",b);

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

for(int b = N; b >= 1; --b)
    {
        if(b==N)
        {
            auto hterm=sites.op("Id",b-1)*sites.op("S-",b);
            hterm+=sites.op("Id",b-1)*sites.op("S+",b);
            auto g = Gate(sites,b-1,b,Gate::tReal,tstep/2.,hterm);
            gates.push_back(g);

        }

    else
    {
        auto hterm = sites.op("Sz",b)*sites.op("Sz",b+1);
        hterm += 0.5*sites.op("S+",b)*sites.op("S-",b+1);
        hterm += 0.5*sites.op("S-",b)*sites.op("S+",b+1);

        hterm+=sites.op("S+",b)*sites.op("Id",b+1);
        hterm+=sites.op("S-",b)*sites.op("Id",b+1);

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

for(int i=1;i<=2;i++)
{
gateTEvol(gates,ttotal,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});

cout<<std::abs(overlapC(psi,psi0))<<"\n";
}

I expect that overlap should be close to 1 but as I mentioned it's coming to be very small when there is onsite terms and it becomes more smaller as I increase the ttotal .
commented by (300 points)
Hi,

For onsite terms, I find that sometimes it is better to divide the terms between two neighbors, like the following. (loop is running from b=1:N-1)

       hterm += 0.5 * sites.op("Sx",b) * sites.op("Id",b+1);
       hterm += 0.5 * sites.op("Sx", b+1) * sites.op("Id",b);

       if (b == 1) // for boundary, as for boudary, gates will be applied only once per site
          hterm += 0.5 * sites.op("Id",b+1) * sites.op("Sx",b);

       if (b == N-1)
          hterm += 0.5 * sites.op("Id",b) * sites.op("Sx",b+1);

Or, something similar depending on your problem. Can you please verify if this works?
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.

Categories

...