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:
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.
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
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.
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.