# string correlation function of several sites

**URL:** <https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066>\
**Category:** ITensor Julia Questions\
**Tags:** julia, mpo\
**Created:** [July 30, 2023, 4:00pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066 "2023-07-30T16:00:07Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![luckyzy](https://avatars.discourse-cdn.com/v4/letter/l/a5b964/32.png) [@luckyzy](https://itensor.discourse.group/u/luckyzy)\
**Post date:** [July 30, 2023, 4:00pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/1 "2023-07-30T16:00:07Z")

</div>

Hi,  
I am new to ITensor, so please forgive me if my question is naive. I want to get the results of string correlation function like \<psi | N\_i N\_i+1 N\_i+2 … N\_L|psi\>. From searching the categories, I finded it that I can achieve my goal as far as using the OpSum interface:

```auto
os = OpSum()
os *= "N",i,"N",2,"N",3,...,"N",L

```

But, at the end, I encountered some errors. I could not find the problems from the tensors. Here are my codes:

```auto
using ITensors
L=10;cutoff=1E-8;δτ=0.1;beta_max=2.0;

```

```auto
function ITensors.op(::OpName"expτnn", ::SiteType"Boson", adag::Index,amis::Index; τ)
    h =
      1 / 2 * op("a†", adag) * op("A", amis) +
      1 / 2 * op("A", amis) * op("a†", adag) +
      op("N", adag) * op("N",amis)
    return exp(τ * h)
end

```

```auto
s = siteinds("Boson", L; conserve_number=false);
gates = ops([("expτnn", (e, e + 1), (τ=-δτ / 2,)) for e in 1:(L - 1)], s);
append!(gates, reverse(gates));
rho = MPO(s, "Id") ./ √2;

```

```auto
terms = OpSum();
U=4;V=4;
for j in 1:(L - 1)
    terms += "a†", j, "A", j + 1
    terms += "A", j, "a†", j + 1
    terms += U / 2, "N", j, "N", j
    terms += V, "N", j, "N", j + 1
end
H = MPO(terms, s)

```

```auto
for w in 0:δτ:beta_max
    energy = inner(rho, H)
    @printf("β = %.2f energy = %.8f\n", w, energy)
    rho = apply(gates, rho; cutoff)
    rho = rho / tr(rho)
end
τ_range = δτ:δτ:(beta_max / 2)
psi = randomMPS(s);
for τ in τ_range
    psi = apply(gates, psi; cutoff)
    normalize!(psi)
end

```

```auto
n_2=op("N",s[2]);

n_3=op("N",s[3]);

n_4=op("N",s[4]);

n_5=op("N",s[5]);

orthogonalize!(psi,2)

c=psi[2];

c *= n_2;

ir2=commonindex(psi[2],psi[3],"Link");

c *=dag(prime(prime(psi[2],"Site"),ir2));

c *=psi[3];

c *=n_3;

c *=dag(prime(prime(psi[3],"Site"),"Link"));

c *=psi[4];

c *=n_4;

c *=dag(prime(prime(psi[4],"Site"),"Link"));

c *=psi[5];

c *=n_5;

il5=commonindex(psi[5],psi[4],"Link");

c *=dag(prime(prime(psi[5],"Site"),il5));

scalar(c)

```

The error tolds me that “In scalar(T) or T, ITensor T is not a scalar.” Please tell me the reasons and give me a hand.  
Thanks a lot!

---

<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:** [July 31, 2023, 1:35pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/2 "2023-07-31T13:35:41Z")

</div>

Hi, thanks for the question. Your code looks really good, so I think you are close to getting it working.

If you could print out `inds(c)` at the end, right before you call `scalar` on it, what indices does `c` have? Based on the error, it has one or more indices and is not actually a scalar. But your code seems correct i.e. I would also have thought it would give a scalar. So printing out `inds(c)` would help to see which indices were not contracted.

---

<div class="post-metadata">

**Author:** ![luckyzy](https://avatars.discourse-cdn.com/v4/letter/l/a5b964/32.png) [@luckyzy](https://itensor.discourse.group/u/luckyzy)\
**Post date:** [August 2, 2023, 5:25am UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/3 "2023-08-02T05:25:40Z")

</div>

HI，miles.  
Thanks a lot for your quick reply. I worked hard to do the contraction, but I still could not. I think there might be some minor errors. Here are my codes:

```auto
orthogonalize!(psi,2)

n_2=op("N",s[2]) /ITensor ord=2 (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=862|"Boson,Site,n=2")
n_3=op("N",s[3])
n_4=op("N",s[4])
n_5=op("N",s[5])

c=psi[2] /ITensor ord=3 (dim=2|id=574|"Link,n=1") (dim=4|id=952|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")'
c *= n_2 /ITensor ord=3 (dim=2|id=574|"Link,n=1") (dim=4|id=952|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")'
ir=commonind(psi[2],psi[3],"Link")
c *=dag(prime(prime(psi[2],"Site"),ir)) /ITensor ord=6 (dim=2|id=574|"Link,n=1") (dim=4|id=952|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=4|id=952|"Link,n=1")'

c *=psi[3] /ITensor ord=6 (dim=2|id=574|"Link,n=1") (dim=4|id=952|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=4|id=952|"Link,n=1")'
c *=n_3 /ITensor ord=7 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=4|id=952|"Link,n=1")' (dim=5|id=720|"Link,n=1") (dim=2|id=253|"Boson,Site,n=3")'
c *=dag(prime(prime(psi[3],"Site"))) /ITensor ord=8 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=5|id=720|"Link,n=1") (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=5|id=720|"Link,n=1")'

c *=psi[4] /ITensor ord=9 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=5|id=720|"Link,n=1")' (dim=2|id=546|"Boson,Site,n=4") (dim=4|id=508|"Link,n=1")
c *=n_4 /ITensor ord=9 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=5|id=720|"Link,n=1")' (dim=4|id=508|"Link,n=1") (dim=2|id=546|"Boson,Site,n=4")'
c *=dag(prime(prime(psi[4],"Site"))) /ITensor ord=10 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=4|id=508|"Link,n=1") (dim=2|id=546|"Boson,Site,n=4")' (dim=2|id=546|"Boson,Site,n=4")'' (dim=4|id=508|"Link,n=1")'

c *=psi[5] /ITensor ord=11 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=2|id=546|"Boson,Site,n=4")' (dim=2|id=546|"Boson,Site,n=4")'' (dim=4|id=508|"Link,n=1")' (dim=2|id=223|"Boson,Site,n=5") (dim=5|id=977|"Link,n=1")
c *=n_5 /ITensor ord=11 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=2|id=546|"Boson,Site,n=4")' (dim=2|id=546|"Boson,Site,n=4")'' (dim=4|id=508|"Link,n=1")' (dim=5|id=977|"Link,n=1") (dim=2|id=223|"Boson,Site,n=5")'
il5=commonindex(psi[5],psi[4],"Link")
c *=dag(prime(prime(psi[5],"Site"),il5)) /ITensor ord=12 (dim=2|id=574|"Link,n=1") (dim=2|id=862|"Boson,Site,n=2")' (dim=2|id=574|"Link,n=1")' (dim=2|id=862|"Boson,Site,n=2")'' (dim=2|id=253|"Boson,Site,n=3")' (dim=2|id=253|"Boson,Site,n=3")'' (dim=2|id=546|"Boson,Site,n=4")' (dim=2|id=546|"Boson,Site,n=4")'' (dim=5|id=977|"Link,n=1") (dim=2|id=223|"Boson,Site,n=5")' (dim=2|id=223|"Boson,Site,n=5")'' (dim=5|id=977|"Link,n=1")'

```

With Regards,  
Yuanyu

---

<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:** [August 2, 2023, 1:45pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/4 "2023-08-02T13:45:55Z")

</div>

Thanks for providing that output – it’s helpful. I found the problem, which is a bit subtle.

If you print out the variable `ir` returned from `commonindex` you will see that it is equal to `nothing` rather than an Index. This is because you should actually call `commonind` this way:

```julia
ir = commonind(psi[2],psi[3];tags="Link")

```

where I have put a semicolon then passed `"Link"` as the value of the keyword argument named `tags`. This way `commonind` knows that `"Link"` is referring to a specific tag value.

Please try that and let me know if it works! We will improve the documentation for `commonind` to make it clearer what keyword arguments you can pass to it. It’s a bit confusing right now that it lets you pass the string `"Link"` without giving an error.

---

<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:** [August 2, 2023, 2:05pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/5 "2023-08-02T14:05:27Z")

</div>

Is it necessary to use the tag filtering at all, or is `ir = commonind(psi[2], psi[3])` sufficient? I usually prefer to avoid using tags to filter when possible, usually it is avoidable by using set/network functions like `siteinds`, `linkinds,` commoninds`, `uniqueinds`, etc.

---

<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:** [August 2, 2023, 2:19pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/6 "2023-08-02T14:19:04Z")

</div>

Agreed, it would be totally sufficient here to use

```auto
ir = commonind(psi[2],psi[3])

```

also, since for an MPS by definition there is only one common index between neighboring tensors.

---

<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:** [August 2, 2023, 3:10pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/7 "2023-08-02T15:10:06Z")

</div>

I guess that isn’t really constrained anywhere and in principle someone could make an MPS with more than one index shared between neighboring tensors, but usually there is only one.

The safest thing would be to use:

```auto
ir = only(commoninds(psi[2], psi[3]))

```

which errors if there are either zero or more than one shared Index.

---

<div class="post-metadata">

**Author:** ![luckyzy](https://avatars.discourse-cdn.com/v4/letter/l/a5b964/32.png) [@luckyzy](https://itensor.discourse.group/u/luckyzy)\
**Post date:** [August 2, 2023, 3:42pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/8 "2023-08-02T15:42:10Z")

</div>

Hi  
The results are a bit amusing,

```auto
commonind(psi[2],psi[3],tags="Link") /(dim=4|id=507|"Link,n=1")
commonind(psi[2],psi[3]) /(dim=4|id=507|"Link,n=1")
commonind(psi[2],psi[3],"Link") /nothing

```

The tags are avoidable or need to be correct.

In the end, I got:

```auto
ir=commonind(psi[2],psi[3],tags="Link") /(dim=4|id=507|"Link,n=1")
...
il5=commonindex(psi[5],psi[4],tags="Link") / il5=commonindex(psi[5],psi[4],tags="Link")
...
c *=dag(prime(prime(psi[5],tags="Site"),il5)) /ITensor ord=4 (dim=4|id=507|"Link,n=1")' (dim=4|id=507|"Link,n=1") (dim=4|id=263|"Link,n=1") (dim=4|id=263|"Link,n=1")'

```

Is it possible to change the id number?

---

<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:** [August 2, 2023, 4:47pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/9 "2023-08-02T16:47:29Z")

</div>

At this point I think you should have all the pieces you need to have a working code. In terms of how to combine these pieces correctly, I would strongly recommend drawing all of the tensors as diagrams on paper or on a board, then marking which indices are primed and by how much, in order to reason about how the next contraction will go and what priming to do next. Then I think you will find a pattern that works such that `c` always has the correct number of indices that you want.

---

<div class="post-metadata">

**Author:** ![luckyzy](https://avatars.discourse-cdn.com/v4/letter/l/a5b964/32.png) [@luckyzy](https://itensor.discourse.group/u/luckyzy)\
**Post date:** [August 2, 2023, 11:45pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/10 "2023-08-02T23:45:15Z")

</div>

Hi miles,

Thanks for your patiently reply, you have helped me save a lot time. I think I will try to code in C.

With regards  
Yuanyu

---

<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:** [August 4, 2023, 4:05pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/11 "2023-08-04T16:05:15Z")

</div>

Note that you can try out this (slightly) experimental package to compute general correlators: [GitHub - ITensor/ITensorCorrelators.jl](https://github.com/ITensor/ITensorCorrelators.jl).

**EDIT:** There is a slightly more extensive example here: [https://github.com/ITensor/ITensorCorrelators.jl/blob/main/examples/4\_point\_correlator.jl](https://github.com/ITensor/ITensorCorrelators.jl/blob/main/examples/4_point_correlator.jl) which compares against using a more naive approach with `OpSum`/`MPO`, which you can run by including the example file and running `main(; N=20)` where `N` is the system size.

---

<div class="post-metadata">

**Author:** ![luckyzy](https://avatars.discourse-cdn.com/v4/letter/l/a5b964/32.png) [@luckyzy](https://itensor.discourse.group/u/luckyzy)\
**Post date:** [August 4, 2023, 11:41pm UTC](https://itensor.discourse.group/t/string-correlation-function-of-several-sites/1066/12 "2023-08-04T23:41:32Z")

</div>

Hi,  
Thanks for your reply. A few days ago, I have tried to do this update but got no response from system. Luckily, I success this time.  
With regards,  
Yuanyu
