Skip to content

Commit 8b7ce46

Browse files
committed
improve MPOHamiltonian constructors
1 parent 5166fba commit 8b7ce46

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

src/operators/mpohamiltonian.jl

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ function _find_tensortype(nonzero_operators::AbstractArray)
9797
end
9898
end
9999

100+
function _find_channel(nonzero_keys; init=2)
101+
range = unique!(last.(nonzero_keys))
102+
for i in max(2, init):max(maximum(range) + 1, 2)
103+
i range && return i
104+
end
105+
return error("should not happen")
106+
end
107+
100108
function FiniteMPOHamiltonian(lattice::AbstractArray{<:VectorSpace},
101109
local_operators::Pair...)
102110
# initialize vectors for storing the data
@@ -110,14 +118,16 @@ function FiniteMPOHamiltonian(lattice::AbstractArray{<:VectorSpace},
110118
nonzero_opps[i] = []
111119
end
112120

113-
for local_operator in local_operators
114-
# instantiate the operator as Vector{MPOTensor}
115-
sites, local_mpo = instantiate_operator(lattice, local_operator)
121+
# partial sort by interaction range
122+
local_mpos = sort!(map(Base.Fix1(instantiate_operator, lattice),
123+
collect(local_operators)); by=x -> length(x[1]))
124+
125+
for (sites, local_mpo) in local_mpos
116126
local key_R # trick to define key_R before the first iteration
117127
for (i, (site, O)) in enumerate(zip(sites, local_mpo))
118128
key_L = i == 1 ? 1 : key_R
119129
key_R = i == length(local_mpo) ? 0 :
120-
maximum(last, nonzero_keys[site]; init=key_L) + 1
130+
_find_channel(nonzero_keys[site]; init=key_L)
121131
push!(nonzero_keys[site], (key_L, key_R))
122132
push!(nonzero_opps[site], O)
123133
end
@@ -189,14 +199,17 @@ function InfiniteMPOHamiltonian(lattice′::AbstractArray{<:VectorSpace},
189199
nonzero_opps[i] = []
190200
end
191201

192-
for local_operator in local_operators
193-
# instantiate the operator as Vector{MPOTensor}
194-
sites, local_mpo = instantiate_operator(lattice, local_operator)
202+
# partial sort by interaction range
203+
local_mpos = sort!(map(Base.Fix1(instantiate_operator, lattice),
204+
collect(local_operators)); by=x -> length(x[1]))
205+
206+
for (sites, local_mpo) in local_mpos
207+
@show sites
195208
local key_R # trick to define key_R before the first iteration
196209
for (i, (site, O)) in enumerate(zip(sites, local_mpo))
197210
key_L = i == 1 ? 1 : key_R
198211
key_R = i == length(local_mpo) ? 0 :
199-
maximum(last, nonzero_keys[site]; init=key_L) + 1
212+
_find_channel(nonzero_keys[site]; init=key_L)
200213
push!(nonzero_keys[site], (key_L, key_R))
201214
push!(nonzero_opps[site], O)
202215
end
@@ -220,14 +233,18 @@ function InfiniteMPOHamiltonian(lattice′::AbstractArray{<:VectorSpace},
220233
for i in 1:length(lattice)
221234
for j in findall(x -> x isa AbstractTensorMap, nonzero_opps[i])
222235
key_L, key_R′ = nonzero_keys[i][j]
223-
key_R = key_R′ == 0 ? length(virtualspaces[i + 1]) : key_R′
236+
key_R = key_R′ == 0 ? length(virtualspaces[i]) : key_R′
224237
O = nonzero_opps[i][j]
225238

226239
if ismissing(virtualspaces[i - 1][key_L])
227240
virtualspaces[i - 1][key_L] = left_virtualspace(O)
241+
else
242+
@assert virtualspaces[i - 1][key_L] == left_virtualspace(O)
228243
end
229244
if ismissing(virtualspaces[i][key_R])
230245
virtualspaces[i][key_R] = right_virtualspace(O)'
246+
else
247+
@assert virtualspaces[i][key_R] == right_virtualspace(O)'
231248
end
232249
end
233250
end
@@ -239,7 +256,7 @@ function InfiniteMPOHamiltonian(lattice′::AbstractArray{<:VectorSpace},
239256
for i in 1:length(lattice)
240257
for j in findall(x -> !(x isa AbstractTensorMap), nonzero_opps[i])
241258
key_L, key_R′ = nonzero_keys[i][j]
242-
key_R = key_R′ == 0 ? length(virtualspaces[i + 1]) : key_R′
259+
key_R = key_R′ == 0 ? length(virtualspaces[i]) : key_R′
243260

244261
if !ismissing(virtualspaces[i - 1][key_L]) &&
245262
ismissing(virtualspaces[i][key_R])
@@ -254,7 +271,13 @@ function InfiniteMPOHamiltonian(lattice′::AbstractArray{<:VectorSpace},
254271
end
255272
end
256273
end
257-
@assert all(x -> !any(ismissing, x), virtualspaces) "could not fill in all virtual spaces"
274+
275+
for i in 1:length(lattice)
276+
if any(ismissing, virtualspaces[i])
277+
@warn "missing virtual spaces at site $i: $(findall(ismissing, virtualspaces[i]))"
278+
replace!(virtualspaces[i], missing => oneunit(S))
279+
end
280+
end
258281
virtualsumspaces = map(virtualspaces) do V
259282
return SumSpace(collect(S, V))
260283
end
@@ -269,7 +292,7 @@ function InfiniteMPOHamiltonian(lattice′::AbstractArray{<:VectorSpace},
269292

270293
# Fill it
271294
for ((key_L, key_R′), o) in zip(nonzero_keys[site], nonzero_opps[site])
272-
key_R = key_R′ == 0 ? length(virtualspaces[site + 1]) : key_R′
295+
key_R = key_R′ == 0 ? length(virtualspaces[site]) : key_R′
273296
O[key_L, 1, 1, key_R] = if o isa Number
274297
iszero(o) && continue
275298
τ = BraidingTensor{E}(eachspace(O)[key_L, 1, 1, key_R])

0 commit comments

Comments
 (0)