How to obtain first 10 eigenvalues of a ITensorMPO.MPS Hamiltonian

I have a code for an Ising model defined by a Hamiltonian. I want to obtain the first 10 eigenvalues of that hamiltonian. I tried 2 different approaches: a) First convert it into a sparse matrix and then use arpack’s eigensolver. b) Run DMRG sweep.

I have a running code for (a) but the result I am getting from there doesn’t seem to be right.


using ITensors
using LinearAlgebra
using SparseArrays
using Arpack

N = 4
NA = 2
chi = 5
chisigma = 2
n = 5  # number of batches, number of moments this generates is n-1
crit = 2

ITensors.set_warn_order(20)

# Ensure these operations are within the same scope
global ops1 = OpSum()
global ops2 = OpSum()
println("ops1 initialized: ", ops1)
println("ops2 initialized: ", ops2)

# Test loop to check for initialization issues
for j in 1:(N - 1)
    global ops1
    ops1 += -1, "Z", j, "Z", j + 1
end
println("ops1 after loop: ", ops1)

for j in 1:N
    global ops2
    ops2 += "X", j
end
println("ops2 after loop: ", ops2)

# Add crit*ops2 to ops1
global ops1 += crit * ops2
println("ops1 after adding crit*ops2: ", ops1)

sites = siteinds("S=1/2", N)
println("sites: ", sites)

H = MPO(ops1, sites)
println("Hamiltonian H created")

The above is the snippet of the code where I define my Hamiltonian. The reason I want to obtain the first 10 eigenvalues is because I want to know if the way I am adding ops1 + 2* ops 2 is working the way I intend it to or not. Method (a) tells me that it doesn’t (cause I get that the first 10 eigenvalues are all 0, which shouldn’t be for crit != 1). But I can’t get a working code for doing a DMRG sweep and obtaining the first 10 eigenvalues.

Here’s the code that I wrote to find the ground state wave function and energy, but I don’t really know how to obtain the next 9 eigenenergies:


        H = MPO(ops1, sites)
        psi0 = randomMPS(sites; linkdims=chi)
        # define parameters for DMRG sweeps
        nsweeps = 10
        maxdim = [10, 20, chi]
        cutoff = [1E-10]
        
       # We obtain the ground state via DMRG
        energy, psi = dmrg(H, psi0; nsweeps, maxdim, cutoff, outputlevel = 0)

So, basically I have 2 questions:

  1. Is the code that I wrote to add ops1 with 2*ops2 doing what I want it to do (is the syntax right basically?)
  2. How to check that by obtaining the first 10 eigenenergies via DMRG sweep?
  1. Looks right to me. You can also run ED on the MPO if you have a system small enough to double check it is what you expect.
  2. To find an excited state check out the docs here: DMRG Examples · ITensors.jl. You’ll have to go one by one and compute each of the 10 states before moving on.

There are also lots of more advanced techniques on finding excited states, such as those in ITensorAGP.jl (see their paper + citations [7–16])

1 Like