# Issue with adding a product of local operators (6\<x\<N) to an MPO

**URL:** <https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446>\
**Category:** ITensor Julia Questions\
**Tags:** julia, dmrg, mpo\
**Created:** [October 4, 2022, 9:10am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446 "2022-10-04T09:10:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![asing](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@asing](https://itensor.discourse.group/u/asing)\
**Post date:** [October 4, 2022, 9:10am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/1 "2022-10-04T09:10:59Z")

</div>

Hi!  
I wish to create a Hamiltonian which consist of sum of product of 12 local operators which are eventually added to the full Hamiltonian. I was able to create MPO of 12 local spin operators using

flux = AutoMPO()  
for j in 1:((N/2)-3)  
fl =Prod{Op}()  
fl \*= Op(“Sx”, i)  
‘’’  
‘’‘’  
‘’’ #12 local operators  
M= MPO(fl, sites)  
global flux = sum(flux,M) #error  
end  
ham\_fl = ham+flux

but I get error when I add this MPO M to another MPO.

I read the answer in the following link:

> [@practical way to add the product of MANY local site operators in OpSum](https://itensor.discourse.group/t/practical-way-to-add-the-product-of-many-local-site-operators-in-opsum/443):
>
> Dear all, If a spin Hamiltonian contains a term which is the product of ALL local site operators, say \prod\_i \sigma^z\_i, how to use OpSum to add this term into the Hamiltonian MPO? Since it becomes impractical to write down this term in the usual way as other local terms… Is it possible to construct such term into an MPO manually in ITensor, and then add it into the Hamiltonian MPO which is constructed separately. Can someone elaborate on this in details. Best, Junsen

one way to solve my problem is to send set of M’s to dmrg functional. But I am not sure how to make array of M.  
The other way is to add M to the hamiltonian. For which I am getting mismatch error.  
Can you guide me how to create the Hamiltonian properly?

Thank you.

---

<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:** [October 4, 2022, 1:51pm UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/2 "2022-10-04T13:51:07Z")

</div>

Thanks for the question. I think I’d need to see more of your code to understand what is going on.

Could you show a minimal example that reproduces the error?

What is the error message you get?

---

<div class="post-metadata">

**Author:** ![asing](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@asing](https://itensor.discourse.group/u/asing)\
**Post date:** [October 4, 2022, 7:22pm UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/3 "2022-10-04T19:22:58Z")

</div>

Following is my code:

```auto
#usual spin interaction
ham = OpSum()
for j in 1:(N-1)
    if isodd(j )
        println("Sz", "\t", j, "\t", j+1)
        ham .+= K, "Sz", j, "Sz", j+1
    end
end

H = MPO(ham, sites)

#6-site interaction
F=0.0
flux = AutoMPO()
for j in 1:((N/2)-3)
    i:: Int = 1 +(j-1)*2
    fl = Prod{Op}()
    fl *= Op("Sx",i+0)
    fl *= Op("Sy",i+1)
    fl *= Op("Sz",i+2)
    fl *= Op("Sz",i+3)
    fl *= Op("Sy",i+4)
    fl *= Op("Sx",i+5)
   
    M = MPO(fl, sites)
    global flux = sum( flux, M)    
#global flux .+= F, fl #Something I tried which caused error as well.
end
#Final Hamiltonian what I need
#ham_fl = ham + flux 

```

Error:  
LoadError: MethodError: objects of type Sum{Scaled{ComplexF64, Prod{Op}}} are not callable

---

<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:** [October 5, 2022, 3:48am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/4 "2022-10-05T03:48:36Z")

</div>

Could you please write the code in a way that I could run it? For example there is a missing “end” statement and some other issues with it. I’m a little confused about some of the things you are trying with the code.

Mainly, my best guess of the issue here is that you are trying to add an AutoMPO to an MPO. But this is not defined. You will need to convert the AutoMPO to an MPO first. I see you have done this actually (H) but then you did not use H in the code at the end.

---

<div class="post-metadata">

**Author:** ![asing](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@asing](https://itensor.discourse.group/u/asing)\
**Post date:** [October 5, 2022, 7:30am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/5 "2022-10-05T07:30:32Z")

</div>

```auto
using ITensors
using DelimitedFiles
using Printf
using Random

include(get(ARGS, 1, "input.jl"))

sweeps = Sweeps(nsweep, sweeps_args)

sites = siteinds("S=1/2", N, conserve_qns=false)
ham = OpSum()

K = 1
# Kitaev exchange
for j in 1:(N-2)
    if iseven(j)
        ham .+= K, "Sx", j, "Sx", j+1
    end

    if isodd(j)
        ham .+= K, "Sy", j, "Sy", j+3
    end
end

for j in 1:(N-1)   
    if isodd(j )
        ham .+= K, "Sz", j, "Sz", j+1
    end
end

H = MPO(ham, sites)

#flux-interaction
F=0.0
flux = AutoMPO()
for j in 1:((N/2)-3)
    i:: Int = 1 +(j-1)*2
    fl = Prod{Op}()
    fl *= Op("Sx",i+0)
    fl *= Op("Sy",i+1)
    fl *= Op("Sz",i+2)
    fl *= Op("Sz",i+3)
    fl *= Op("Sy",i+4)
    fl *= Op("Sx",i+5)
    M = MPO(fl, sites) #This is where I am creating a 6 site operator 
    global flux = sum( flux, M) # Adding one 6 site operator to flux 
end

ham_fl = H + flux #adding flux operator for the whole lattice to hamiltonian

psi0 = randomMPS(sites, 10)

energy, psi = dmrg(ham_fl, psi0, sweeps)
@printf("Final energy = %.12f\n", energy)

```

ERROR: LoadError: MethodError: objects of type Sum{Scaled{ComplexF64, Prod{Op}}} are not callable

---

<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:** [October 6, 2022, 2:33am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/6 "2022-10-06T02:33:03Z")

</div>

Thanks for posting the more complete code. I agree the error message could be clearer here, but if you look at the stack trace coming from the error message, it will point you to a particular line. That line is the following:

```auto
global flux = sum( flux, M)

```

There you are trying to add an MPO (`M`) to the object `flux` which is of type AutoMPO (note that these days we are calling AutoMPO `OpSum` but both names are allowed). I think the issue here is that one cannot add these two types in ITensor. An AutoMPO is just an object for storing a sum of operator names that will later be converted to an MPO. So if you want to sum the result of an AutoMPO with an MPO, you will need to convert the AutoMPO to an MPO first.

The good news is that for what you’re trying to do, you can just use AutoMPO entirely, like this:

```auto
os = OpSum() # equivalent to AutoMPO
for j in 1:((N/2)-3)
  i = 1 +(j-1)*2
  os += "Sx",i,"Sy",i+1,"Sz",i+2,"Sz",i+3,"Sy",i+4,"Sx",i+5
end
flux = MPO(os, sites)

```

Please let me know if that looks like it is doing what you want.

---

<div class="post-metadata">

**Author:** ![asing](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@asing](https://itensor.discourse.group/u/asing)\
**Post date:** [October 7, 2022, 11:37am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/7 "2022-10-07T11:37:02Z")

</div>

Thank you for the solution.  
I am curious as to how to convert and AutoMPO to an MPO?

For example I want to create an operator consisting of these 6 site operators to calculate the expectation value using the function “inner”.

```auto
 "Sx",i,"Sy",i+1,"Sz",i+2,"Sz",i+3,"Sy",i+4,"Sx",i+5

```

---

<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:** [October 8, 2022, 1:54am UTC](https://itensor.discourse.group/t/issue-with-adding-a-product-of-local-operators-6-x-n-to-an-mpo/446/8 "2022-10-08T01:54:43Z")

</div>

Regarding how to convert an OpSum to an MPO (remember that AutoMPO is now named “OpSum”), you can see some examples here:  
[https://itensor.github.io/ITensors.jl/dev/examples/DMRG.html](https://itensor.github.io/ITensors.jl/dev/examples/DMRG.html)

Here is one of them:

```auto
os = OpSum()
for j=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,sites)

```

where the OpSum in the above example is making the Hamiltonian of the 1D Heisenberg model:

H = \sum\_{j=1}^{N-1} S^z\_j S^z\_{j+1} + \frac{1}{2} S^+\_j S^-\_{j+1} + \frac{1}{2} S^-\_j S^+\_{j+1}

So the answer to your question is basically the line:

```auto
H = MPO(os,sites)

```

and in your case you could make the OpSum like this:

```auto
os = OpSum()
os += "Sx",i,"Sy",i+1,"Sz",i+2,"Sz",i+3,"Sy",i+4,"Sx",i+5

```

and of course add any other terms to it that you want to add (maybe looping over all the values that `i` takes.
