This is a question about the Julia ITensors package (https://github.com/ITensor/ITensors.jl), which I am using to run DMRG on various Hamiltonians to find the ground state and low-lying excited states.
When you create a Hamiltonian on which to use DMRG, you need to create an AutoMPO object, add terms to it, and then run the command "H = MPO(ampo,sites)." However, I have observed confusing discrepancies in runtime and memory usage across different Hamiltonians.
For example, when I run the following code to create the Hamiltonian for the J1-J2 model (https://en.wikipedia.org/wiki/J1_J2_model) on N = 10^4 (resulting in 60,000 MPO terms), the code takes only 1 minute to run on my desktop.
J1 = 1
J2 = 0.5
N = 10^4
sites = siteinds("S=1/2",N)
ampo = AutoMPO()
for j=1:N-1
add!(ampo,J1,"Sx",j,"Sx",j+1)
add!(ampo,J1,"Sy",j,"Sy",j+1)
add!(ampo,J1,"Sz",j,"Sz",j+1)
end
for j=1:N-2
add!(ampo,J2,"Sx",j,"Sx",j+2)
add!(ampo,J2,"Sy",j,"Sy",j+2)
add!(ampo,J2,"Sz",j,"Sz",j+2)
end
add!(ampo,J1,"Sx",N,"Sx",1)
add!(ampo,J1,"Sy",N,"Sy",1)
add!(ampo,J1,"Sz",N,"Sz",1)
add!(ampo,J2,"Sx",N-1,"Sx",1)
add!(ampo,J2,"Sz",N-1,"Sz",1)
add!(ampo,J2,"Sx",N,"Sx",2)
add!(ampo,J2,"Sy",N,"Sy",2)
add!(ampo,J2,"Sz",N,"Sz",2)
H = MPO(ampo,sites)
However, when I run the following code to create the Hamiltonian for the lattice formulation of the Schwinger model (equation 2.6 on page 4 of https://arxiv.org/abs/1305.3765v2) on N = 60 (resulting in1948 MPO terms), the code takes 2 hours and 20 minutes to run on my desktop. Again, this is just to create the Hamiltonian, not even to run DMRG.
m_over_g = 0 # m, g are Schwinger model parameters
x = 25 # x = 1/(g^2*a^2), a = lattice spacing
μ = 2 * m_over_g * sqrt(x) # μ = 2m/(g^2*a) = 2*(m/g)*sqrt(x)
N = 60
ampo_H = AutoMPO()
trace = N*μ/2 + N^2/8
add!(ampo_H,2*2 * trace,"Sz*Sz",1) # cheat designed to add trace term to Hamiltonian
for j = 1:N
if j != N
add!(ampo_H,x,"S+",j,"S-",j+1) # S+ and S- are the same as σ+ and σ-
add!(ampo_H,x,"S-",j,"S+",j+1)
# S operators are 1/2 of Pauli matrices, so I have put factors of 2 to compensate
add!(ampo_H,2 * trunc((N-j+1)/2)/2,"Sz",j)
for i=1:j-1
add!(ampo_H,2*2 * (N-j)/2,"Sz",i,"Sz",j)
end
end
add!(ampo_H,2 * μ*(-1)^(j-1)/2,"Sz",j)
end
H = MPO(ampo_H, sites)
It is worth mentioning that this used to take a lot less time. Up until a week ago, this would take probably 5-10 minutes, but somehow, ever since downloading one of the later versions of the code last Thursday, it has been running way slower.
In addition, if I change N = 60 to N = 100 in the above code (resulting in 5248 terms), the code eventually throws an OutOfMemoryError. This also seems weird to me, since there are still far fewer MPO terms, and each individual term is not any more complicated than the terms in the J1-J2 model Hamiltonian.
The obvious difference between these two is that the Schwinger model Hamiltonian is intensely non-local, having an interaction between almost every pair of spins. However, I thought this only significantly affected the speed of DMRG, not the memory usage or speed of the creation of the Hamiltonian itself. Any insights into what factors govern the speed and memory usage of the creation of the Hamiltonian would be greatly appreciated.