From d190fd1615731047a12daa3bee03b2bd2a4ce980 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 5 Aug 2026 14:29:01 +0200 Subject: [PATCH 1/5] allow calculating entanglement of left boundary --- src/algorithms/toolbox.jl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/algorithms/toolbox.jl b/src/algorithms/toolbox.jl index b995329f1..339199cd8 100644 --- a/src/algorithms/toolbox.jl +++ b/src/algorithms/toolbox.jl @@ -7,7 +7,8 @@ MPS state or directly from an entanglement spectrum as obtained from [`entanglement_spectrum`](@ref). When called on an MPS with an integer `site`, the entropy is computed across the -entanglement cut to the right of site `site`. For `InfiniteMPS`, omitting `site` returns a +entanglement cut to the right of site `site` (or equivalently, to the left of bond `site`). +For `InfiniteMPS`, omitting `site` returns a vector of entropies, one for each site. For `FiniteMPS` and `WindowMPS`, `site` is required. """ @@ -87,14 +88,16 @@ values. The contributions from specific sectors can be viewed by indexing accord For `InfiniteMPS` and `WindowMPS` the default value for `site` is 0. -For `FiniteMPS` no default value for `site` is given; it is up to the user to specify. +For `FiniteMPS` no default value for `site` is given; +it is up to the user to specify, and must lie in `0:length(ψ)`. +`0` and `length(ψ)` correspond to the left and right boundary virtual spaces, respectively. """ function entanglement_spectrum(st::Union{InfiniteMPS, WindowMPS}, site::Int = 0) checkbounds(st, site) return LinearAlgebra.svdvals(st.C[site]) end function entanglement_spectrum(st::FiniteMPS, site::Int) - checkbounds(st, site) + checkbounds(st.C, site) return LinearAlgebra.svdvals(st.C[site]) end From 70942705ad75c187762a5c835efe8e04d893791b Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 5 Aug 2026 14:29:19 +0200 Subject: [PATCH 2/5] remove redundant check in entanglementplot --- src/utility/plotting.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/utility/plotting.jl b/src/utility/plotting.jl index ec491693e..388a99faf 100644 --- a/src/utility/plotting.jl +++ b/src/utility/plotting.jl @@ -32,8 +32,6 @@ function entanglementplot end sector_margin = 1 // 10, sector_formatter = string ) mps = h.args[1] - (site <= length(mps) && !(isa(mps, FiniteMPS) && site == 0)) || - throw(ArgumentError("Invalid site $site for the given mps.")) spectra = entanglement_spectrum(mps, site) sectors = [] From 55c0ad2c72e088f8c79bb7fb0bfc14ca36b7d749 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 5 Aug 2026 14:29:46 +0200 Subject: [PATCH 3/5] add tests to finitemps entropy --- test/states/finitemps.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/states/finitemps.jl b/test/states/finitemps.jl index 357e6793e..7e3796e02 100644 --- a/test/states/finitemps.jl +++ b/test/states/finitemps.jl @@ -146,6 +146,10 @@ end @test real(entropy(ψ, site)) >= 0 end + @test entropy(ψ, 0) ≈ 0 atol = 1.0e-10 # trivial left bond + @test_throws BoundsError entanglement_spectrum(ψ, -1) + @test_throws BoundsError entanglement_spectrum(ψ, L + 1) + # entropy is consistent with entanglement_spectrum for site in 1:L @test entropy(ψ, site) ≈ entropy(entanglement_spectrum(ψ, site)) @@ -155,7 +159,7 @@ end @test entropy(ψ, L) ≈ 0 atol = 1.0e-10 # product state has zero entropy everywhere - ψ_product = FiniteMPS(rand, elt, L, d, oneunit(D)) + ψ_product = FiniteMPS(rand, elt, L, d, unitspace(D)) for site in 1:L @test entropy(ψ_product, site) ≈ 0 atol = 1.0e-10 end From 412981693f3723d0957434fd3a9fa5133fafc39e Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 5 Aug 2026 14:41:40 +0200 Subject: [PATCH 4/5] plot correct bond without bounds check --- src/utility/plotting.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utility/plotting.jl b/src/utility/plotting.jl index 388a99faf..b58b912cc 100644 --- a/src/utility/plotting.jl +++ b/src/utility/plotting.jl @@ -74,7 +74,7 @@ function entanglementplot end grid --> :xy widen --> true - xguide --> "χ = $(dim(left_virtualspace(mps, site)))" + xguide --> "χ = $(dim(_firstspace(mps.C[site])))" xticks --> (1:length(sectors), sector_formatter.(sectors)) xtickfonthalign --> :center xtick_direction --> :out From 44947516d6e257b54d545e175be06de148ff52e5 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 5 Aug 2026 16:43:30 +0200 Subject: [PATCH 5/5] clarifying docstrings [skip ci] --- src/algorithms/toolbox.jl | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/algorithms/toolbox.jl b/src/algorithms/toolbox.jl index 339199cd8..331d4ab36 100644 --- a/src/algorithms/toolbox.jl +++ b/src/algorithms/toolbox.jl @@ -6,11 +6,11 @@ Calculate the von Neumann entanglement entropy. The entropy can be computed from MPS state or directly from an entanglement spectrum as obtained from [`entanglement_spectrum`](@ref). -When called on an MPS with an integer `site`, the entropy is computed across the -entanglement cut to the right of site `site` (or equivalently, to the left of bond `site`). -For `InfiniteMPS`, omitting `site` returns a -vector of entropies, one for each site. For `FiniteMPS` and `WindowMPS`, `site` is -required. +When called on an MPS with an integer `site`, the entropy is computed for the bipartition that +splits the chain between sites `site` and `site + 1`. +`site = 0` therefore denotes the cut to the left of the first site. +For `InfiniteMPS`, omitting `site` returns a vector of entropies, one for each site. +For `FiniteMPS` and `WindowMPS`, `site` is required. """ entropy(state::InfiniteMPS) = map(Base.Fix1(entropy, state), 1:length(state)) function entropy(state::Union{FiniteMPS, WindowMPS, InfiniteMPS}, loc::Int) @@ -81,16 +81,15 @@ end """ entanglement_spectrum(ψ, site::Int) -> SectorVector{T, sectortype(ψ), AbstractVector{T}} -Compute the entanglement spectrum at a given site, i.e. the singular values of the gauge -matrix to the right of a given site. This is a vector containing the singular -values. The contributions from specific sectors can be viewed by indexing accordingly, i.e. +Compute the entanglement spectrum across the cut that splits the chain between sites `site` and +`site + 1`, i.e. the singular values of the gauge tensor `ψ.C[site]`. +The contributions from specific sectors can be viewed by indexing accordingly, i.e. `entanglement_spectrum(ψ, site)[sector]`. -For `InfiniteMPS` and `WindowMPS` the default value for `site` is 0. - -For `FiniteMPS` no default value for `site` is given; -it is up to the user to specify, and must lie in `0:length(ψ)`. -`0` and `length(ψ)` correspond to the left and right boundary virtual spaces, respectively. +`site` runs over `0:length(ψ)`. +For `FiniteMPS`, `0` and `length(ψ)` are the cuts at the left and right edge of the chain. +No default is given for `FiniteMPS`; it is up to the user to specify. +For `WindowMPS` and `InfiniteMPS`, `site` defaults to `0`. """ function entanglement_spectrum(st::Union{InfiniteMPS, WindowMPS}, site::Int = 0) checkbounds(st, site)