Skip to content

Commit d6f1310

Browse files
committed
handle repeated indices
1 parent e9b2b1d commit d6f1310

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
@@ -422,3 +422,11 @@ function swap!(
422422
@plansor mpo[i + 1][-1 -2; -3 -4] := sqrtS[-1; 1] * Vᴴ[1; -3 -4 -2]
423423
return mpo
424424
end
425+
426+
function multiply_neighbours!(mpo::FiniteMPO{<:MPOTensor}, i::Integer)
427+
1 <= i < length(mpo) || throw(BoundsError(mpo, i))
428+
O₁ = mpo[i]
429+
O₂ = popat!(parent(mpo), i + 1)
430+
@plansor mpo[i][-1 -2; -3 -4] := O₁[-1 -2; 1 2] * τ[1 2; 3 4] * O₂[3 4; -3 -4]
431+
return mpo
432+
end

src/operators/mpohamiltonian.jl

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -309,16 +309,17 @@ function instantiate_operator(state::AbstractMPS, O::Pair)
309309
return instantiate_operator(physicalspace(state), O)
310310
end
311311
function instantiate_operator(lattice::AbstractArray{<:VectorSpace}, (inds′, O)::Pair)
312-
inds = inds′ isa Int ? tuple(inds′) : inds′
313-
mpo = O isa FiniteMPO ? O : FiniteMPO(O)
312+
inds = inds′ isa Int ? [inds′] : inds′
313+
mpo = O isa FiniteMPO ? copy(O) : FiniteMPO(O)
314314

315315
# convert to linear index type
316-
indices = map(inds) do I
317-
return Base._to_linear_index(lattice, Tuple(I)...) # this should mean all inds are valid...
316+
indices = Vector{Int}(undef, length(inds))
317+
for i in eachindex(indices)
318+
indices[i] = Base._to_linear_index(lattice, Tuple(inds[i])...) # this should mean all inds are valid...
318319
end
319320

320321
# sort indices and deduplicate
321-
indices, mpo = canonicalize_indices(indices, mpo)
322+
indices, mpo = canonicalize_indices!(indices, mpo)
322323
operators = parent(mpo)
323324

324325
@assert allunique(indices) && issorted(indices) "From here on we require unique and ascending indices\n$indices"
@@ -345,14 +346,23 @@ function instantiate_operator(lattice::AbstractArray{<:VectorSpace}, (inds′, O
345346
return sites => local_mpo
346347
end
347348

348-
function canonicalize_indices(indices, mpo)
349-
issorted(indices) && return indices, mpo
350-
mpo = copy(mpo)
351-
I = TensorKit.TupleTools.sortperm(indices)
352-
for s in TensorKit.permutation2swaps(I)
353-
swap!(mpo, s)
349+
function canonicalize_indices!(indices, mpo)
350+
# swap non-sorted entries
351+
for i in 2:length(indices)
352+
for j in reverse(i:length(indices))
353+
if indices[j] < indices[j - 1]
354+
swap!(mpo, j - 1)
355+
indices[j - 1], indices[j] = indices[j], indices[j - 1]
356+
end
357+
end
358+
end
359+
for i in length(indices):-1:2
360+
if indices[i] == indices[i - 1]
361+
multiply_neighbours!(mpo, i - 1)
362+
popat!(indices, i)
363+
end
354364
end
355-
return TensorKit.TupleTools.getindices(indices, I), mpo
365+
return indices, mpo
356366
end
357367

358368
# yields the promoted tensortype of all tensors

0 commit comments

Comments
 (0)