# Doubts regarding single-site TDVP implementation.

**URL:** <https://itensor.discourse.group/t/doubts-regarding-single-site-tdvp-implementation/218>\
**Category:** ITensor Julia Questions\
**Tags:** julia, mpo\
**Created:** [June 19, 2022, 11:26am UTC](https://itensor.discourse.group/t/doubts-regarding-single-site-tdvp-implementation/218 "2022-06-19T11:26:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sandipanmanna](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@sandipanmanna](https://itensor.discourse.group/u/sandipanmanna)\
**Post date:** [June 19, 2022, 11:26am UTC](https://itensor.discourse.group/t/doubts-regarding-single-site-tdvp-implementation/218/1 "2022-06-19T11:26:44Z")

</div>

Hi!

I am trying to implement single-site TDVP following this paper ([Haegeman et al. (2016)](https://arxiv.org/pdf/1408.5056.pdf)). The algorithm is clearly described on page 8,Appendix B. First,I decided to go for only a single time step. My test system is  
15-site Heisenberg model.

```auto
N = 15
cutoff = 1e-10

s = siteinds("S=1/2", N)

os = OpSum()
for j in 1:(N - 1)
    os += 0.5, "S+", j, "S-", j + 1
    os += 0.5, "S-", j, "S+", j + 1
    os += "Sz", j, "Sz", j + 1
end

H = MPO(os, s)
ψ = productMPS(s, n -> isodd(n) ? "Up" : "Dn")

tf=4
dt=0.1 # delta t
num_time_steps = Int(tf/dt)
nsite=1
τ = 1im*dt
println(ψ)

```

Now, I have tried to implement first only for left-to-right swap. The code is below.

```auto
function measure_Sz(psi,n)
    psi = ITensors.orthogonalize(psi,n)
    sn = siteind(psi,n)
    Sz = scalar(dag(prime(psi[n],"Site"))*op("Sz",sn)*psi[n])
    return real(Sz)
end

```

```auto
#ψ = productMPS(s, n -> isodd(n) ? "Up" : "Dn")
println(ψ)

ITensors.orthogonalize!(ψ,1)
PH=ProjMPO(H)
position!(PH,ψ,1)
N=length(ψ)

ha=1 # For left-to-right swap
for n=1:N-1
    
    # left-to-right sweep
    ITensors.orthogonalize!(ψ,n) 
    #This brings the orthogonality center to site n?
    println("Site : ",n," Current centre : ",ITensors.orthocenter(ψ))
    set_nsite!(PH,1)
    position!(PH,ψ,n)
    phi1=ψ[n]
    
    println("Before expo ",n)
    phi1, info = exponentiate(PH, -τ/2, phi1; ishermitian=hermitian , tol=exp_tol, krylovdim=krylovdim)
    info.converged==0 && throw("exponentiate did not converge")

    
    ψ[n] = phi1
    
    
    uinds = uniqueinds(phi1, ψ[n + 1])
    U, S, V = svd(phi1, uinds)
    ψ[n] = U
    phi0 = S * V
    if ha == 1
      ITensors.setleftlim!(ψ, n)
    elseif ha == 2
      ITensors.setrightlim!(ψ, n)
    end
    
    
    set_nsite!(PH, 0)
    ITensors.position!(PH, ψ, n+1)
    phi0, info = exponentiate(PH, τ/2, phi0; ishermitian=hermitian , tol=exp_tol, krylovdim=krylovdim)
    phi0 ./= norm(phi0)
    
    ψ[n+1] = ψ[n+1] * phi0
    if ha == 1
      ITensors.setrightlim!(ψ, n + 2)
    elseif ha == 2
      ITensors.setleftlim!(ψ, n )
    end
   
    
    
                    
end

#Evolve A_C (N,t)
ITensors.orthogonalize!(ψ,N) 
#This brings the orthogonality center to site n?
println("Site : ",N," Current centre : ",ITensors.orthocenter(ψ))
set_nsite!(PH,1)
position!(PH,ψ,N)
phi1=ψ[N]

println("Before expo ",N)
phi1, info = exponentiate(PH, -τ, phi1; ishermitian=hermitian , tol=exp_tol, krylovdim=krylovdim)
info.converged==0 && throw("exponentiate did not converge")

#Check if phi1 is normalised
(phi1 /= norm(phi1))

ψ[N] = phi1
println("Test")
ha=2 # right-to-left

```

As it turns out, this doesn’t ever increase the bond dimension off the MPS & the expectation values of Sz remains same as the initial one.  
I know it is not the complete algo & we should also do the reverse swap. But shouldn’t just doing this step have some effect on bond dim/Sz (we are applying exponentiate here)?I guess I’m doing something wrong here but can’t figure out what I am missing.

I would really appreciate any suggestion.Thank you in advance.

---

<div class="post-metadata">

**Author:** ![sandipanmanna](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@sandipanmanna](https://itensor.discourse.group/u/sandipanmanna)\
**Post date:** [June 21, 2022, 2:30pm UTC](https://itensor.discourse.group/t/doubts-regarding-single-site-tdvp-implementation/218/2 "2022-06-21T14:30:10Z")

</div>

Hi! I have got it in somewhat working condition. But I have 2 doubts.

i) If I start with a Neel state(Bond dim 1) for the same hamiltonian ,the 2-site algorithm gives magnetisation data but the 1-site TDVP gives only 0.5,-0.5 alternatively (i.e. same as the initial state).

On the other hand,starting with a random state gives values for both 1-site & 2-site. Is it not a good idea to use 1-site TDVP for initial product state?

ii) I am getting magnetisation values that are close but have notable difference with TEBD for time step 0.05.

[Code here](https://github.com/sandipanman/TDVP-custom/blob/main/TDVP_jl.ipynb)

Is there any issue with the cutoff dim?

I would really appreciate any help. Thank you in advance.

---

<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:** [June 21, 2022, 3:18pm UTC](https://itensor.discourse.group/t/doubts-regarding-single-site-tdvp-implementation/218/3 "2022-06-21T15:18:57Z")

</div>

That’s great that you are working on implementing TDVP using ITensor. But it may help you to know that we have been working on an official TDVP implementation (including single-site) that will soon be released, and is already available (in ‘experimental’ mode) here:  
[https://github.com/ITensor/ITensorTDVP.jl](https://github.com/ITensor/ITensorTDVP.jl)

Would using that code solve your problem?

About the growth of the bond dimension, in the plain single-site TDVP algorithm the bond dimension never grows. It’s just an aspect of how the algorithm works, and is viewed as something of a limitation of that algorithm. To deal with that fact, there have been a number of proposals of “subspace expansion” methods.

The other part, about the expectation values of Sz never changing, and your other post about starting from a bond-dimension-one state (product state) is likely explained by what I just discussed above, that in the single-site TDVP the bond dimension doesn’t change. So if you initialize single-site TDVP from a product state, that algorithm will generally do a very poor job and give an answer that’s far from the correct one, since the basis will always stay very small (just as bond dimension = 1). To start from a product state with single-site TDVP you need to use a subspace expansion method or some other initialization procedure. A simpler choice is just to use two-site. Some people do things like start with two-site then switch to one-site later in the time evolution.

---

<div class="post-metadata">

**Author:** ![sandipanmanna](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@sandipanmanna](https://itensor.discourse.group/u/sandipanmanna)\
**Post date:** [June 21, 2022, 4:38pm UTC](https://itensor.discourse.group/t/doubts-regarding-single-site-tdvp-implementation/218/4 "2022-06-21T16:38:59Z")

</div>

Thanks miles for the quick response. This clears up the things.

Have a nice day.
