# Best way to generate the MPO of an entangled state

**URL:** <https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942>\
**Category:** ITensor Julia Questions\
**Created:** [August 24, 2024, 8:08pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942 "2024-08-24T20:08:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bananafish](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@Bananafish](https://itensor.discourse.group/u/Bananafish)\
**Post date:** [August 24, 2024, 8:08pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942/1 "2024-08-24T20:08:16Z")

</div>

Hey there,  
I’m trying to generate an initial state composed of the tensor product of L Bell states |\psi\rangle = (\frac{|00\>+|11\>}{\sqrt{2}})^{\otimes L}, and then obtain the MPO of its density matrix \rho = |\psi\rangle\langle\psi|. Initially, I tried the following code:

```Julia
using ITensors
Bell = [1; 0; 0; 1]/√(2)
state = 1
for i = 1:L
    global state = kron(state, Bell)
end
Idx_list = siteinds("Qubit", 2*L)
psi = MPS(state, Idx_list; cutoff = 1E-8, maxdim = 1000)
rho = outer(psi,psi')

```

It works fine when L\<7, but displays a warning when I set L=8:

> Contraction resulted in ITensor with 16 indices, which is greater than or equal to the ITensor order warning threshold 14. You can modify the threshold with macros like `@set_warn_order N`, `@reset_warn_order`, and `@disable_warn_order` or functions like `ITensors.set_warn_order(N::Int)`, `ITensors.reset_warn_order()`, and `ITensors.disable_warn_order()`.

I tried `ITensors.disable_warn_order()` but the system automatically kills the run due to large memory.

I’m not sure if I can create an empty MPO first and assign each element to the corresponding ITensor of the Bell states (in the density matrix form), as each contains 4 indices and is entangled. I could also start with a product state, and then apply two-site gates to evolve it to the state that I want, but that’ll be too much trouble. So I’m wondering what the best way is.

Thank you so much for your time!

---

<div class="post-metadata">

**Author:** ![Bananafish](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@Bananafish](https://itensor.discourse.group/u/Bananafish)\
**Post date:** [August 26, 2024, 9:30pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942/2 "2024-08-26T21:30:37Z")

</div>

I tried the last method that I mentioned and succeeded, below is my code:

```Julia
using ITensors
L=2
Idx_list = siteinds("Qubit", 2*L)
P_u = [1 0; 0 0]
rho_0 = MPO(2L)
# Initialize a product state |000...>
for j=1:2L
    T = op(P_u, Idx_list[j])
    rho_0[j] = T
end
# Map from |00> to Bell state (|00>+|11>)/√2
U = [1 0 0 0; 0 0 0 0; 0 0 0 0; 1 0 0 0]./√2
for i=1:L
    x_1 = 2i-1
    x_2 = 2i
    U_B = op(U,Idx_list[x_1],Idx_list[x_2])
    rho_0 = apply(U_B,rho_0,apply_dag=true; cutoff=Cutoff, maxdim=Maxdim)
end

```

Still curious to know if there’s a simpler way though.

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [August 27, 2024, 1:51pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942/3 "2024-08-27T13:51:34Z")

</div>

What you did is fine, although you can initialize the MPO to be |0\rangle\langle0| directly with `MPO(Idx_list,"Proj0")`.

If you combine your two codes, you’ll get you’re after I think

```julia
using ITensors, ITensorMPS

L=10 # number of pairs
cutoff = 1e-10
maxdim = 10
sites = siteinds("Qubit", L*2)
# Initialize a product state |000...>
psi = MPS(sites,"0")
# Map from |00> to Bell state (|00>+|11>)/√2
U = [1 0 0 0; 0 0 0 0; 0 0 0 0; 1 0 0 0]./√2
# for each pair of sites, apply U to them
for i=1:2:L*2
    x_1 = i
    x_2 = i+1
    U_B = op(U,sites[x_1],sites[x_2])
    global psi = apply(U_B,psi; cutoff, maxdim)
end
@show maxlinkdim(psi) # should be 2
ρ_0 = outer(psi',psi)
@show maxlinkdim(ρ_0) # should be 4

```

In general if there is a low bond dimension |\psi\rangle that you want to form \rho = |\psi\rangle\langle\psi| then doing `outer(psi',psi)` should work, or apply the unitary gates.

---

<div class="post-metadata">

**Author:** ![Bananafish](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@Bananafish](https://itensor.discourse.group/u/Bananafish)\
**Post date:** [August 27, 2024, 11:08pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942/4 "2024-08-27T23:08:09Z")

</div>

Thank you Ryan! The “Proj0” matrix is very useful. It’s interesting that the warning of contracting a large number of indices in the outer() function doesn’t appear this time.

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [August 28, 2024, 1:41pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942/5 "2024-08-28T13:41:12Z")

</div>

> [@Bananafish](#):
>
> It’s interesting that the warning of contracting a large number of indices in the outer() function doesn’t appear this time.

Note that, at least for when I run your code, the warning was coming from `psi = MPS(state, Idx_list; cutoff = 1E-8, maxdim = 1000)` not `outer()`

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/free1/uploads/itensor/original/1X/d3072b13e047cd06df7f3981547c0917d940dfa4.png) [@system](https://itensor.discourse.group/u/system)\
**Post date:** [September 7, 2024, 1:41pm UTC](https://itensor.discourse.group/t/best-way-to-generate-the-mpo-of-an-entangled-state/1942/6 "2024-09-07T13:41:37Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
