# Related to time dependent spin spin correlations.

**URL:** <https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32>\
**Category:** DMRG and Numerical Methods\
**Tags:** cpp, dmrg\
**Created:** [April 15, 2022, 7:57am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32 "2022-04-15T07:57:17Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 15, 2022, 7:57am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/1 "2022-04-15T07:57:17Z")

</div>

## Hi, I am using Itensor C++ codes. I want to calculate spin spin correlations at different time for AFM XXZ spin-half Heisenbrg chain using open boundary condition. e.g. \<gs|S2^z(0)S2^z(t)|gs\> . let length of chain N=10 . steps that I followed are:

tstep=0.05

1. using DMRG calculations |gs\>, Ground state and E0 ground state energy calculated.  
2.operator S2^z operated on |gs\> and new state |psi1\> obtained.  
3.using trotter gates time evolution of |psi1\> calculated and got |psi1(t)\>.  
4..operator S2^z operated on |psi1(t)\> and new state |psi2(t)\> obtained.
2. and finally exp(i_E0_ttotal)\*innerC(gs,psi2(t)) calculated.

output:  
E0 = -10.7364

| ttotal | abs(result) | imag(result) | real(result) |
| --- | --- | --- | --- |
| 0 | 0.25 | 0 | 0.25 |
| 0.5 | 0.420919 | -0.0996948 | 0.408942 |
| 1 | 0.340459 | -0.0501472 | 0.336746 |
| 1.5 | 0.337924 | -0.0115168 | 0.337727 |
| 2 | 0.36277 | 0.026344 | 0.361812 |
| 2.5 | 0.420865 | 0.00602888 | 0.420821 |
| 3 | 0.412091 | -0.0467875 | 0.409427 |
| 3.5 | 0.388381 | -0.0429918 | 0.385994 |
| 4 | 0.397469 | -0.04531 | 0.394878 |
| 4.5 | 0.395097 | -0.0618982 | 0.390218 |

My question is, since at each site there is spin-half, then why spin spin correlations showing result greater than 0.25? It should be less than or equal to 0.25.

---

<div class="post-metadata">

**Author:** ![JR007](https://avatars.discourse-cdn.com/v4/letter/j/439d5e/32.png) [@JR007](https://itensor.discourse.group/u/JR007)\
**Post date:** [April 15, 2022, 9:57am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/2 "2022-04-15T09:57:46Z")

</div>

When you apply the operator S2^z on |gs\> and obtain |psi1\> , you can find \<psi1|psi1\>=0.25. If you normalize the |psi1\>( I think you not), you will find the exp(i _E0_ 0)\*innerC(gs,Sz,ps1(t=0)) is not equal to 0.25 .  
While using trotter gates time evolution of |psi1\> calculated and got |psi1(t)\>. ITensors would normalize the |psi1(t)\>. These processes introduce the correlation is correct when t=0, otherwise time correlation is wrong. Please check the codes.

---

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 15, 2022, 12:28pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/3 "2022-04-15T12:28:38Z")

</div>

Hi,  
Are you saying I should normalize |psi1\> and not |psi1(t)\>?

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 15, 2022, 2:52pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/4 "2022-04-15T14:52:31Z")

</div>

Generally our time evolution codes don’t normalize the state for you unless you request that they do. However it’s a common pattern in many of our code examples that you normalize the state after each time step. Whether you do so in this case is merely a choice you can make or not, and there is not a right or wrong way to do it as long as you keep track of the overall normalization factors correctly.

Most likely if you are getting an incorrect result for this correlator of this size, then there just a bug or mistake in your code somewhere.

One potential issue that I notice in your question is that I believe you have the signs of the time evolution reversed, because it should be that S^z(t) = e^{i H t} S^z e^{-i H t} so that acting on the ground state on the right gives a factor e^{i E\_0 t} where E\_0 is the ground state energy and your time evolution should be using e^{i H t} as the evolution operator. Either that, or you could compute \langle\psi\_0|S^z(t) S^z(0)|\psi\_0\rangle if you want the signs to be the more ‘typical’ ones.

---

<div class="post-metadata">

**Author:** ![JR007](https://avatars.discourse-cdn.com/v4/letter/j/439d5e/32.png) [@JR007](https://itensor.discourse.group/u/JR007)\
**Post date:** [April 15, 2022, 3:10pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/5 "2022-04-15T15:10:29Z")

</div>

Two choices: 1） Do not normalize both of them If you can, you can get the correct results. However, during the evolution, you can find \<psi1(t)|psi1(t)\> will decrease due to cutoff. 2) I can normalize both of them, the correlation you get now exp(i _E0_ ttotal)\*innerC(gs,psi2(t) should multiply a constant (1/2) .

---

<div class="post-metadata">

**Author:** ![mtfishman](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/mtfishman/32/11_2.png) [@mtfishman](https://itensor.discourse.group/u/mtfishman)\
**Post date:** [April 15, 2022, 3:14pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/6 "2022-04-15T15:14:05Z")

</div>

Hi everyone,

Thanks you trying out our new forum, glad to see it is already getting some use. Could you please format your code and equations? We have a guide for doing that here: [Welcome to ITensor Discourse](https://itensor.discourse.group/t/welcome-to-itensor-discourse/7). It will make it easier for us and others to understand and answer your questions!

Thanks,  
Matt

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 15, 2022, 3:43pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/7 "2022-04-15T15:43:10Z")

</div>

I would suggest an even easier and safer procedure is just to numerically compute the norm of the state |\psi\_1\rangle using `inner(psi1,psi1)` and saving the result to use later on in the calculation. It might equal 1/2 but it would be even easier to just compute it numerically.

---

<div class="post-metadata">

**Author:** ![JR007](https://avatars.discourse-cdn.com/v4/letter/j/439d5e/32.png) [@JR007](https://itensor.discourse.group/u/JR007)\
**Post date:** [April 16, 2022, 12:29am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/8 "2022-04-16T00:29:39Z")

</div>

That’s right! Thanks!

---

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 16, 2022, 11:44am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/10 "2022-04-16T11:44:07Z")

</div>

Hi,  
Whether I normalize state psi1 or not, still answer is getting above 0.25 for nonzero ttotal. Here I am sharing my Itensor C++ code. I am using Itensor version 2.0.

```auto
{
int N=10;

auto sites = SpinHalf(N,{"ConserveQNs=",false});

auto ampo = AutoMPO(sites);
for(int j = 1; j < N; ++j)
    {
    ampo += 0.5,"S+",j,"S-",j+1;
    ampo += 0.5,"S-",j,"S+",j+1;
    ampo += 4.5,"Sz",j,"Sz",j+1;
    }
auto H = toMPO(ampo);

auto psi_i = randomMPS(sites);

auto sweeps = Sweeps(6);
sweeps.maxdim() = 20,50,100;
sweeps.cutoff() = 1E-10;
sweeps.niter() = 2;
sweeps.noise() = 1E-7,1E-8,1E-9;
println(sweeps);

auto [E0,psi0] = dmrg(H,psi_i,sweeps);

PrintDat(E0);

Real tstep=0.05;
Real ttotal=0.0;
Real cutoff=1E-10;

auto gates = vector<BondGate>();

auto hterm = AutoMPO(sites);
//Make the Heisenberg Hamiltonian
for(int b = 1; b < N; ++b)
    {
   auto hterm = 0.5*op(sites,"S+",b)*op(sites,"S-",b+1);
    hterm += 0.5*op(sites,"S-",b)*op(sites,"S+",b+1);
    hterm += 4.5*op(sites,"Sz",b)*op(sites,"Sz",b+1);

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

for(int b = N-1; b >= 1; --b)
    {
    auto hterm = 0.5*op(sites,"S+",b)*op(sites,"S-",b+1);
    hterm += 0.5*op(sites,"S-",b)*op(sites,"S+",b+1);
    hterm += 4.5*op(sites,"Sz",b)*op(sites,"Sz",b+1);

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

auto psi=psi0;
psi.position(2);

auto newpsi= op(sites,"Sz",2)*psi(2);
newpsi.noPrime();
psi.set(2,newpsi);

auto psi1=psi;
for(int k=1;k<=10;++k)
{

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

auto newpsi2 = op(sites,"Sz",2)*psi1(2);
newpsi2.noPrime();
psi1.set(2,newpsi2);

auto result=exp(Cplx_i*E0*ttotal)*innerC(psi0,psi1);
psi1=psi;
Print(result);

ttotal=ttotal+0.5;
}
PrintDat(E0);
return 0;
}

```

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 16, 2022, 2:33pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/11 "2022-04-16T14:33:26Z")

</div>

Hi Vrushali,  
I looked at your code (I also edited your post to format the code by putting ``` before and after). There are a number of issues in your code, so before discussing the correlator I wanted to point some of those out.

- one issue is that after you time evolve `psi1` and act S^z on it, you then reset it back to `psi` which is the state at time t=0. (The line I mean is `psi1=psi;`.) So your state is evolving forward from time t=0 over and over.
- relatedly (and here I can understand because we didn’t do a good job documenting the `gateTEvol` function, though now I’ve updated the documentation on it) the usage of `gateTEvol` is incorrect in your code. The second argument, `ttotal` is the amount of time you want it to evolve your state. Here you should not evolve it starting from t=0 by larger and larger amounts, which is highly inefficient. Instead for this kind of application you should just evolve by one `tstep` at a time. In short you should use `gateTEvol` here like this:

```auto
gateTEvol(gates,tstep,tstep,psi1,{"Cutoff=",cutoff,"Verbose=",true});

```

- now the other issue with your code, and I believe **this issue will address your question about not getting values below 0.25** is that you aren’t accounting for the norm of the state, even though it was mentioned above. Here a good debugging technique is to print things out. So when I do `Print(norm(psi));` after S^z is applied, I see that the norm of the state is |\Psi| = 0.5, or in other words `sqrt(inner(psi,psi))=`\sqrt{\langle\Psi|\Psi\rangle}=0.5. Secondly, after time evolving the state, I observe that the norm is reset to 1.0, so it means `gateTEvol` normalizes the state afterward. Therefore an extra factor of 0.5 is discarded by `gateTEvol` and must be accounted for.  
A good way to do this is to save the norm in a separate variable before you start the time evolution and then include it again in your result.  
The upshot of all this is that in your case, you need to **divide your result by 2** afterward when computing it. Then you’ll see that you always get values \<0.25 as you expect.

Please note that by printing out the norm of each wavefunction in various places in your code, you could have seen what was happening to the norm after each step.

However, I do understand that `gateTEvol` wasn’t previously documented very well & we have updated the page on that. So your question was definitely helpful to remind us to update that documentation!

Best regards,  
Miles

---

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 18, 2022, 6:39am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/12 "2022-04-18T06:39:20Z")

</div>

Hi,  
Is it like , If I want answer for ttotal=10, then I have to set ttotal=10 and time evolution will start from 0 to 10 by tstep. I don’t need to set ttotal=0.

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 18, 2022, 11:08am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/13 "2022-04-18T11:08:47Z")

</div>

Could you please say more about what you are asking? Is your question about the gateTEvol function and how to use it?

---

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 18, 2022, 11:42am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/14 "2022-04-18T11:42:40Z")

</div>

Hi,  
My question is about gateTEvol function. Suppose I want to calculate answer after ttotal=1,2,3,4,…so on. and interested how correlation is changing with time?  
Then how do I use gateTEvol ?

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 19, 2022, 1:42am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/15 "2022-04-19T01:42:26Z")

</div>

It’s a good question. The `gateTEvol` function takes these arguments:

```auto
gateTEvol(Iterable const& gatelist, Real ttotal, Real tstep, MPS & psi, Observer& obs, Args args)

```

The last two, the Observer and Args, have default values so you aren’t required to pass them.

The `ttotal` and `tstep` arguments work like this: the `gateTEvol` function assumes that the gates in `gatelist` will advance the MPS `psi` by an amount `tstep` of time. So all that the `ttotal` argument does is to say that the function should apply the gates a number `n = ttotal/tstep` times before returning.

So if you want to calculate properties of `psi` outside of `gateTEvol` at times 1,2,3,4 and say you want to use a time step of 0.1, then you would call:

```auto
for(int step = 1; step <= Nstep; step += 1) {
    gateTEvol(gates,1.0,0.1,psi);
    // do measurements of psi
}

```

Each call to `gateTEvol` above will apply the gates 10 times to psi because 1.0/0.1 = 10.

Please let me know if that’s helpful & answers your question.

I’d encourage you to check out the code for gateTEvol itself, which you can find here:

> <https://github.com/ITensor/ITensor/blob/050aa564f0307cfc94a3311c7e5c2c625c93844f/itensor/mps/tevol.h#L63>

---

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 19, 2022, 6:48am UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/16 "2022-04-19T06:48:19Z")

</div>

Hi,  
What about psi after first iteration? I mean after ttotal=1 iteration, before ttotal=2 can I reset psi to original as it was before ttotal=1 and then calculate psi from initial psi to psi at ttotal=2 . Or will it continue after ttotal=1 to ttotal=2 by tstep without resetting psi?.

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 19, 2022, 2:58pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/17 "2022-04-19T14:58:15Z")

</div>

You could reset psi to the original, but I would not recommend performing time evolution that way. A much better way to do it is to leave psi at its current value, so that it will be the wavefunction at time t=1 that is, \text{psi} = |\psi(t=1)\rangle.

Then, on the next loop when you input `psi` into `gateTEvol`, it will be evolved from time t=1 to t=2. This is a much more efficient way to do it, because you only have to do the work of evolving by a single unit of time at each step of the loop, rather than an increasingly large amount of time for every step.

(Maybe this is what you were asking in the second half of your question? Yes if you do not reset `psi` then `gateTEvol` will evolve it from time t=1 to t=2 on the next step of the loop if you set ttotal=1.0.)

Miles

---

<div class="post-metadata">

**Author:** ![vrushali.k](https://avatars.discourse-cdn.com/v4/letter/v/3e96dc/32.png) [@vrushali.k](https://itensor.discourse.group/u/vrushali.k)\
**Post date:** [April 19, 2022, 3:22pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/18 "2022-04-19T15:22:19Z")

</div>

Hi,  
Now I got it. Thanks a lot for a such a helpful discussion.

Vrushali.

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [April 19, 2022, 3:37pm UTC](https://itensor.discourse.group/t/related-to-time-dependent-spin-spin-correlations/32/19 "2022-04-19T15:37:26Z")

</div>

Glad I was able to answer your questions! 👍
