How to compute inner product of MPS with another MPS translated by 1 right sites

Hello everyone,

I would like to ask if there is a way to compute the inner product ⟨ψ | T₁ | ψ⟩, where T₁ is a cyclic translation operator that shifts site n-to-n+1, by successively applying ITensor’s movesite functions, without the need to explicitly build an MPO for T₁.

Could this be considered a correct interpretation?

I would appreciate any help or insights you can provide.

Best regards,

Juan.

Hi @JuanD_H,
yes movesite is a way to implement it and you should actually do a single call (movesite(mps, i => j) does not swap site i with site j but it performs internal swaps so that, taking j>i, in i you have i+1, in i+1 you have i+2 and so on, which is directly what I think you wanted to do), see this example:

julia> using ITensorMPS

julia> sites = siteinds("S=1/2", 4);

julia> mps = MPS(sites, _ -> rand(["Up", "Dn"]))
MPS
[1] ((dim=2|id=514|"S=1/2,Site,n=1"), (dim=1|id=994|"Link,l=1"))
[2] ((dim=1|id=994|"Link,l=1"), (dim=2|id=934|"S=1/2,Site,n=2"), (dim=1|id=247|"Link,l=2"))
[3] ((dim=1|id=247|"Link,l=2"), (dim=2|id=916|"S=1/2,Site,n=3"), (dim=1|id=359|"Link,l=3"))
[4] ((dim=1|id=359|"Link,l=3"), (dim=2|id=24|"S=1/2,Site,n=4"))


julia> expect(mps, "Sz")
4-element Vector{Float64}:
  0.5
 -0.5
  0.5
  0.5

julia> mps = movesite(mps, 1 => 4)
MPS
[1] ((dim=2|id=934|"S=1/2,Site,n=2"), (dim=2|id=481|"Link,l=1"))
[2] ((dim=2|id=481|"Link,l=1"), (dim=2|id=916|"S=1/2,Site,n=3"), (dim=2|id=343|"Link,l=2"))
[3] ((dim=2|id=343|"Link,l=2"), (dim=2|id=24|"S=1/2,Site,n=4"), (dim=2|id=110|"Link,l=3"))
[4] ((dim=2|id=110|"Link,l=3"), (dim=2|id=514|"S=1/2,Site,n=1"))


julia> expect(mps, "Sz")
4-element Vector{Float64}:
 -0.5
  0.5
  0.5
  0.5

Just to clarify, internally the way it is implemented it is equivalent to doing a series of pairwise swaps.

Thank you, I have edited the answer to make this clearer

Thank you very much for your help!.. I’m left with one question though: could this work well if I have an MPS with high entanglement?

All MPS algorithms work the same regardless of the amount of entanglement. What this means is that a given algorithm with have some scaling with the bond dimension m, usually m^3 scaling. Then having high entanglement will mean that m is large, and there’s no way around this besides changing the problem you are solving or using a different type of tensor network.

The only other conceptual possibility would be to seek an algorithm having better scaling with m but a larger prefactor. Some sampling algorithms are like this but they are difficult to use for most purposes and give low-precision results.

Hi,

This example is for spin-1/2 particles. When the pairwise swaps are performed for a fermionic system, are Jordan-Wigner strings handled automatically?

Yes, I believe movesite appropriately handles the fermion exchange. Here’s an example, note that this is only done when conserve_qns=true.

using ITensors, ITensorMPS

function make_sites_match!(psi::MPS, reference::MPS)::Nothing
  reference_sites = siteinds(reference)
  sites = siteinds(psi)
  for i in eachindex(psi)
    replaceind!(psi[i], sites[i], reference_sites[i])
  end

  return nothing
end

let
  for conserve_qns in (false, true)
    @show conserve_qns
    sites = siteinds("Fermion", 2; conserve_qns)
    @show isfermionic(sites[1])

    psi = MPS(sites, ["Occ", "Occ"])
    psi_swapped = movesite(psi, 1 => 2)
    make_sites_match!(psi_swapped, psi)
    @show inner(psi, psi_swapped)

    println()
  end
end

Output:

conserve_qns = false
isfermionic(sites[1]) = false
inner(psi, psi_swapped) = 1.0

conserve_qns = true
isfermionic(sites[1]) = true
inner(psi, psi_swapped) = -1.0