Skip to content

## Bug: excitations(H, FiniteExcited(), ψ; num>1) returns energies/states in reverse order #441

Description

@kangzb

Bug: excitations(H, FiniteExcited(), ψ; num>1) returns energies/states in reverse order

excitations with FiniteExcited() and num > 1 returns ens/excis with the highest requested excitation at index 1, not the lowest.

Cause (dmrgexcitation.jl)

    envs = environments(init, super_op)
    ne, _ = find_groundstate(init, super_op, alg.gsalg, envs)
    nstates = (states..., ne)
    ens, excis = excitations(H, alg, nstates; init = init, num = num - 1)
    push!(ens, expectation_value(ne, H))
    push!(excis, ne)

ne is the ground state of the penalized operator H + λΣᵢ|ψᵢ⟩⟨ψᵢ|, i.e. the lowest excitation of H orthogonal to everything in states so far — not the ground state of H itself. On the outermost call (states=(ψ_gs,)), this is the true first excited state; the recursion then finds progressively higher excitations. Since each call recurses before pushing its own result, the last-found (highest-energy) state ends up first in the returned array.

Reproducer (TFIM)

using TensorKit, MPSKit

L = 16; J = 1.0; g = 0.7
V = ComplexSpace(2)
X = TensorMap(ComplexF64[0 1; 1 0], V, V)
Z = TensorMap(ComplexF64[1 0; 0 -1], V, V)
lattice = fill(V, L)
H = FiniteMPOHamiltonian(lattice, (i,i+1) => -J*(ZZ) for i in 1:L-1) +
    FiniteMPOHamiltonian(lattice, (i,) => -g*X for i in 1:L)

psi_gs, envs_gs, _ = find_groundstate(FiniteMPS(L, V, ComplexSpace(32)), H, DMRG())
E0 = real(expectation_value(psi_gs, H, envs_gs))

E_ex, _ = excitations(H, FiniteExcited(; weight=20.0), psi_gs; num=2)
println(real.(E_ex) .- E0)   # [0.7078, 0.00339] -- gap order reversed

Cross-checked against QuasiparticleAnsatz, which returns the same two gaps in ascending order: [0.00339, 0.7078].

Suggested fix

Replace push! with pushfirst! on the two lines above:

pushfirst!(ens, expectation_value(ne, H))
pushfirst!(excis, ne)

Since the recursive call already returns its sublist in ascending-energy order (by induction), and ne is always lower in energy than anything found by the recursion, prepending it preserves ascending order at every level.

Unrelated docstring inconsistency

The FiniteExcited type docstring states the algorithm minimizes the energy of H - λᵢ|ψᵢ⟩⟨ψᵢ|, but the actual code builds H + λᵢ|ψᵢ⟩⟨ψᵢ| (all-positive coefficients in the LinearCombination call above), consistent with the field docstring "energy penalty for enforcing orthogonality." The type docstring's minus sign looks like a typo.

Originally posted by @kangzb in https://github.com/QuantumKitHub/MPSKit.jl/discussions/440

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions