I had some code that I decided to migrate from TenPy, but unfortunately performance is far worse for some reason. The relevant part of the Julia code is this:
disordered_distance(i, j, dx) = abs(j - i + dx[j] - dx[i])
function build_rydberg_hamiltonian(L, Δ, Ω, σ, t, V, seed)
# Random displacements per site, uniform in [-sigma/2, sigma/2]
rng = MersenneTwister(seed)
dx = (rand(rng, L) .- 0.5) .* σ
Vphys = ℂ^2
physical_spaces = fill(Vphys, L)
σx = TensorMap([0 1; 1 0], Vphys ← Vphys)
σz = TensorMap([1 0; 0 -1], Vphys ← Vphys)
Id = id(Vphys)
Nop = (Id + σz) / 2
Sp = TensorMap([0 1; 0 0], Vphys ← Vphys)
Sm = TensorMap([0 0; 1 0], Vphys ← Vphys)
lattice = fill(Vphys, L)
on_site_terms = [(i,) => -Δ * Nop + Ω * σx for i in 1:L]
interaction_terms = []
for i in 1:L, j in 1:L
if i < j
r = disordered_distance(i,j,dx)
Vij = V/r^6
tij = t/r^3
push!(interaction_terms, (i,j) => Vij*Nop⊗Nop + tij * ( Sp ⊗ Sm + Sm⊗Sp))
end
end
H = FiniteMPOHamiltonian(lattice, on_site_terms..., interaction_terms...)
return H, physical_spaces
end
# Sample values
Δ = 1.0; Ω = 1.0; V = 1.0; t=1.0;
L = 25
chi_max = 50
psi = FiniteMPS(L, ComplexSpace(2), ComplexSpace(chi_max))
H, physical_spaces = build_rydberg_hamiltonian(L, Δ, Ω, sigma, t, V, seed)
psi, envs, dmrg_info = find_groundstate!(psi, H, DMRG(; maxiter=10))
As you can see this implements a Hamiltonian with long range interactions. For comparison, the TenPy code model definition is:
class RydbergModel(CouplingMPOModel):
def init_sites(self, model_params):
# symmetry settings
conserve = model_params.get('conserve', None, str)
sort_charge = model_params.get('sort_charge', True, bool)
# define spin-1/2 local Hilbert space
site = SpinHalfSite(conserve=conserve, sort_charge=sort_charge)
n = np.diag([1,0])
# site.add_op('N', 0.5 * site.Sigmaz + 0.5 * site.Id)
site.add_op('N',n)
return site
def init_terms(self, model_params):
counter = 0
# read parameters
Delta = model_params.get('Delta', 0.0)
Omega = model_params.get('Omega', 0.0)
sigma = model_params.get('sigma', 0.0)
t = model_params.get('t', 0.0)
V = model_params.get('V', 1.0)
seed = model_params.get('seed', 0.0)
N = self.lat.N_sites
L = self.lat.Ls[0]
#for dx in range(1, L):
# randomness on possition dxi:
# so true position of each atom is no longer i, but i + dxi
rng = np.random.default_rng(seed)
dx_randomness = rng.uniform(-0.5, 0.5, size=L) * sigma
# This is for non-periodic boundary conditions
for i in range(L):
for j in range(i+1,L): # This ensures i < j
dx = abs((j+dx_randomness[j]) - (i + dx_randomness[i]))
Vij = V / dx**6
tij = t / ( dx**3) # run again with this value
self.add_coupling_term(tij, i,j, 'Sp', 'Sm', plus_hc=True)
self.add_coupling_term(Vij, i, j,'N','N')
self.add_onsite(-Delta, 0, 'N')
self.add_onsite(Omega, 0, 'Sigmax')
and then for the actual ground state computation I run something like
model = MyTFIChain(model_params)
psi = MPS.from_lat_product_state(model.lat, [['up']])
dmrg_params = {
'mixer': True, # setting this to True helps to escape local minima
'max_E_err': 1.e-6,
'trunc_params': {
'chi_max': chi_max,
'svd_min': 1.e-10,
},
'verbose': True,
'combine': True
}
# get the data:
eng = dmrg.TwoSiteDMRGEngine(psi, model, dmrg_params)
E, psi = eng.run()
The TenPy version runs a lot faster. In my actual code, I perform sweeps over regions of Δ and Ω. The TenPy version took about 4.5 minutes to run a sweep over a 5x5 region, while MPSKit takes almost as much time for even the first DMRG calculation (I don't count the time for compilation).
Am I using the wrong algorithm for something, is it a problem with my code, or is TenPy just faster currently?
I had some code that I decided to migrate from TenPy, but unfortunately performance is far worse for some reason. The relevant part of the Julia code is this:
As you can see this implements a Hamiltonian with long range interactions. For comparison, the TenPy code model definition is:
and then for the actual ground state computation I run something like
The TenPy version runs a lot faster. In my actual code, I perform sweeps over regions of Δ and Ω. The TenPy version took about 4.5 minutes to run a sweep over a 5x5 region, while MPSKit takes almost as much time for even the first DMRG calculation (I don't count the time for compilation).
Am I using the wrong algorithm for something, is it a problem with my code, or is TenPy just faster currently?