Skip to content

Commit e9a1011

Browse files
committed
handle repeated indices
1 parent 3cf7a86 commit e9a1011

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

src/operators/mpo.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,3 +414,11 @@ function swap!(
414414
@plansor mpo[i + 1][-1 -2; -3 -4] := sqrtS[-1; 1] * Vᴴ[1; -3 -4 -2]
415415
return mpo
416416
end
417+
418+
function multiply_neighbours!(mpo::FiniteMPO{<:MPOTensor}, i::Integer)
419+
1 <= i < length(mpo) || throw(BoundsError(mpo, i))
420+
O₁ = mpo[i]
421+
O₂ = popat!(parent(mpo), i + 1)
422+
@plansor mpo[i][-1 -2; -3 -4] := O₁[-1 -2; 1 2] * τ[1 2; 3 4] * O₂[3 4; -3 -4]
423+
return mpo
424+
end

src/operators/mpohamiltonian.jl

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -305,16 +305,17 @@ Instantiate a local operator `O` on a lattice `lattice` as a vector of MPO tenso
305305
vector of linear site indices.
306306
"""
307307
function instantiate_operator(lattice::AbstractArray{<:VectorSpace}, (inds′, O)::Pair)
308-
inds = inds′ isa Int ? tuple(inds′) : inds′
309-
mpo = O isa FiniteMPO ? O : FiniteMPO(O)
308+
inds = inds′ isa Int ? [inds′] : inds′
309+
mpo = O isa FiniteMPO ? copy(O) : FiniteMPO(O)
310310

311311
# convert to linear index type
312-
indices = map(inds) do I
313-
return Base._to_linear_index(lattice, Tuple(I)...) # this should mean all inds are valid...
312+
indices = Vector{Int}(undef, length(inds))
313+
for i in eachindex(indices)
314+
indices[i] = Base._to_linear_index(lattice, Tuple(inds[i])...) # this should mean all inds are valid...
314315
end
315316

316317
# sort indices and deduplicate
317-
indices, mpo = canonicalize_indices(indices, mpo)
318+
indices, mpo = canonicalize_indices!(indices, mpo)
318319
operators = parent(mpo)
319320

320321
@assert allunique(indices) && issorted(indices) "From here on we require unique and ascending indices\n$indices"
@@ -338,14 +339,23 @@ function instantiate_operator(lattice::AbstractArray{<:VectorSpace}, (inds′, O
338339
return sites => local_mpo
339340
end
340341

341-
function canonicalize_indices(indices, mpo)
342-
issorted(indices) && return indices, mpo
343-
mpo = copy(mpo)
344-
I = TensorKit.TupleTools.sortperm(indices)
345-
for s in TensorKit.permutation2swaps(I)
346-
swap!(mpo, s)
342+
function canonicalize_indices!(indices, mpo)
343+
# swap non-sorted entries
344+
for i in 2:length(indices)
345+
for j in reverse(i:length(indices))
346+
if indices[j] < indices[j-1]
347+
swap!(mpo, j - 1)
348+
indices[j - 1], indices[j] = indices[j], indices[j - 1]
349+
end
350+
end
347351
end
348-
return TensorKit.TupleTools.getindices(indices, I), mpo
352+
for i in length(indices):-1:2
353+
if indices[i] == indices[i-1]
354+
multiply_neighbours!(mpo, i-1)
355+
popat!(indices, i)
356+
end
357+
end
358+
return indices, mpo
349359
end
350360

351361
# yields the promoted tensortype of all tensors

0 commit comments

Comments
 (0)