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

**URL:** <https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378>\
**Category:** DMRG and Numerical Methods\
**Tags:** mps\
**Created:** [May 6, 2025, 8:51pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378 "2025-05-06T20:51:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![JuanD\_H](https://avatars.discourse-cdn.com/v4/letter/j/a4c791/32.png) [@JuanD\_H](https://itensor.discourse.group/u/JuanD_H)\
**Post date:** [May 6, 2025, 8:51pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/1 "2025-05-06T20:51:11Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![VinceNeede](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/vinceneede/32/731_2.png) [@VinceNeede](https://itensor.discourse.group/u/VinceNeede)\
**Post date:** [May 8, 2025, 12:54pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/2 "2025-05-08T12:54:58Z")

</div>

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-repl
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

```

---

<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:** [May 8, 2025, 1:10pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/3 "2025-05-08T13:10:46Z")

</div>

> [@VinceNeede](#):
>
> it does not swap the sites, but moves them

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

---

<div class="post-metadata">

**Author:** ![VinceNeede](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/vinceneede/32/731_2.png) [@VinceNeede](https://itensor.discourse.group/u/VinceNeede)\
**Post date:** [May 8, 2025, 2:17pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/4 "2025-05-08T14:17:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![JuanD\_H](https://avatars.discourse-cdn.com/v4/letter/j/a4c791/32.png) [@JuanD\_H](https://itensor.discourse.group/u/JuanD_H)\
**Post date:** [May 11, 2025, 2:25pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/5 "2025-05-11T14:25:54Z")

</div>

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?

---

<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:** [May 11, 2025, 2:45pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/6 "2025-05-11T14:45:01Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![hmargasak](https://avatars.discourse-cdn.com/v4/letter/h/b2d939/32.png) [@hmargasak](https://itensor.discourse.group/u/hmargasak)\
**Post date:** [April 3, 2026, 1:07am UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/7 "2026-04-03T01:07:47Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![corbett5](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/corbett5/32/886_2.png) [@corbett5](https://itensor.discourse.group/u/corbett5)\
**Post date:** [April 3, 2026, 3:43pm UTC](https://itensor.discourse.group/t/how-to-compute-inner-product-of-mps-with-another-mps-translated-by-1-right-sites/2378/8 "2026-04-03T15:43:42Z")

</div>

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

```julia
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:

```plaintext
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

```
