So I have a very simple spin 1 complex Hamiltonian, with hopping terms but with an added complex phase for every hop to make it complex. I will write all my code out, so it’s long but you can copy everything and see it (doesn’t) work. First I initialize two complex hopping operators bp
and bm
using ITensors,ITensorMPS, LinearAlgebra,Random
#Initialize complex local operators
dim = 3 #spin 1 model
theta = 0.5*pi #e^i*pi*theta to make it complex
dia = sqrt.(collect(1:dim-1)) / sqrt(2)
nopp = diagm(exp.(im .* (0:dim-1) .* theta))
nopm = diagm(exp.(im .* (0:dim-1) .* -theta))
bp_mat = diagm( 1=>dia )
bm_mat = diagm( -1=>dia)
bp_mat = bp_mat*nopp
bm_mat = nopm*bm_mat
display(bp_mat) #how "bp" look like in matrix
display(bm_mat) #how "bm" look like in matrix
ITensors.op(::OpName"bp",::SiteType"S=1") = bp_mat #bp
ITensors.op(::OpName"bm",::SiteType"S=1") = bm_mat #bm
Overall you can print bp_mat
and bm_mat
out to see it’s complex. Then I create a hopping Hamiltonian similar to Fermi-Hubbard
N=10 #number of sites
sites = siteinds("S=1",N;conserve_qns=true)
os = OpSum() #hopping operator like Hubbard, but with complex phase
for j=1:N-1
os += "bp",j,"bm",j+1
os += "bm",j,"bp",j+1
end
H = MPO(os,sites)
Then I try to solve with conserved quantum number
# Create the initial guess with "Up" and "Dn"
density = 0.9 # density of "Up" to pick conserved sector
num_up = ceil(Int, density * N)
num_dn = N - num_up
psi_init = vcat(fill("Up", num_up), fill("Dn", num_dn))
psi_init = psi_init[Random.randperm(N)] #shuffle the list
psi0 = MPS(sites,psi_init)
Then I run DMRG
#Parameters of DMRG
nsweeps = 20
maxdim = [400]
cutoff = [1E-15]
weight = 1
no_state = 5
energies = [] #array of energy
states = [] #array of excited states
for energy_lvl in 1:no_state
if energy_lvl == 1
energy, psi = dmrg(H, psi0; nsweeps, maxdim, cutoff,outputlevel=0,ishermitian=false)
states = [psi] #insert ground state
energies = [energy] #insert ground energy
else
energy, psi = dmrg(H, states, psi0; nsweeps, maxdim, cutoff,outputlevel=0,ishermitian=false,weight)
push!(states, copy(psi)) #insert excited state
push!(energies, copy(energy)) #insert excited energy
end
end
display(energies)
However Julia DMRG is failing. As you can see if you run all this code, the energy as well as ground/excited states are all just the one for the real Hamiltonian case (when theta = 0
), with some “noise” imaginary compenent that’s at order e-31
, but at least it shows DMRG do recognize the complex Hamiltonian. Yet, we can vary theta
and see that nothing changes, even though bp
and bm
obviously do change.
I have turned on ishermitian=false
. I tried this first on SciPy eigsh
(at N=10 it’s a small matrix so exact diagonalization also work) and it does show both the energy and the states change. What else can I do to improve this? Is there anything I did wrong? I’m new to DMRG, so I’ll be glad if you can help me with this. Thank you!