From fa918049ab959b5e74096312c2c103d518b712d5 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Wed, 12 Nov 2025 17:36:09 -0500 Subject: [PATCH 01/24] add styles --- src/utility/styles.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/utility/styles.jl diff --git a/src/utility/styles.jl b/src/utility/styles.jl new file mode 100644 index 000000000..a358facee --- /dev/null +++ b/src/utility/styles.jl @@ -0,0 +1,10 @@ +abstract type OperatorStyle end + +struct MPOStyle <: OperatorStyle end +struct HamiltonianStyle <: OperatorStyle end + + +abstract type IsfiniteStyle end + +struct FiniteStyle <: IsfiniteStyle end +struct InfiniteStyle <: IsfiniteStyle end From 1334fcba8f0d4be5a43f4807cf5cd3136ec629a1 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Wed, 12 Nov 2025 18:17:07 -0500 Subject: [PATCH 02/24] start rewrite --- src/operators/mpo.jl | 3 +++ src/operators/mpohamiltonian.jl | 3 +++ src/states/abstractmps.jl | 4 ++-- src/states/finitemps.jl | 1 + src/states/infinitemps.jl | 1 + 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/operators/mpo.jl b/src/operators/mpo.jl index ae16181fd..a8963c858 100644 --- a/src/operators/mpo.jl +++ b/src/operators/mpo.jl @@ -17,6 +17,8 @@ Matrix Product Operator (MPO) acting on a finite tensor product space with a lin """ const FiniteMPO{O} = MPO{O, Vector{O}} Base.isfinite(::Type{<:FiniteMPO}) = true +IsfiniteStyle(::FiniteMPO) = FiniteStyle() +OperatorStyle(::MPO) = MPOStyle() function FiniteMPO(Os::AbstractVector{O}) where {O} for i in eachindex(Os)[1:(end - 1)] @@ -37,6 +39,7 @@ Matrix Product Operator (MPO) acting on an infinite tensor product space with a """ const InfiniteMPO{O} = MPO{O, PeriodicVector{O}} Base.isfinite(::Type{<:InfiniteMPO}) = false +IsfiniteStyle(::InfiniteMPO) = InfiniteStyle() function InfiniteMPO(Os::AbstractVector{O}) where {O} for i in eachindex(Os) diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 97f938609..9f2218968 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -31,9 +31,11 @@ operators in a form that is compatible with this constructor. struct MPOHamiltonian{TO <: JordanMPOTensor, V <: AbstractVector{TO}} <: AbstractMPO{TO} W::V end +OperatorStyle(::MPOHamiltonian) = HamiltonianStyle() const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}} Base.isfinite(::Type{<:FiniteMPOHamiltonian}) = true +IsfiniteStyle(::FiniteMPOHamiltonian) = FiniteStyle() function FiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor} for i in eachindex(Ws)[1:(end - 1)] @@ -45,6 +47,7 @@ end const InfiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, PeriodicVector{O}} Base.isfinite(::Type{<:InfiniteMPOHamiltonian}) = false +IsfiniteStyle(::InfiniteMPOHamiltonian) = InfiniteStyle() function InfiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor} for i in eachindex(Ws) diff --git a/src/states/abstractmps.jl b/src/states/abstractmps.jl index 6dd8a1341..0503a33be 100644 --- a/src/states/abstractmps.jl +++ b/src/states/abstractmps.jl @@ -15,7 +15,7 @@ const MPSTensor{S} = GenericMPSTensor{S, 2} # the usual mps tensors on which we """ MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int]) - MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, + MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace} Construct an `MPSTensor` with given physical and virtual spaces. @@ -201,7 +201,7 @@ TensorKit.sectortype(ψtype::Type{<:AbstractMPS}) = sectortype(site_type(ψtype) """ left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)]) - + Return the virtual space of the bond to the left of sites `pos`. !!! warning diff --git a/src/states/finitemps.jl b/src/states/finitemps.jl index 44ac3fa64..969201eaf 100644 --- a/src/states/finitemps.jl +++ b/src/states/finitemps.jl @@ -312,6 +312,7 @@ function Base.similar(ψ::FiniteMPS{A, B}) where {A, B} end Base.isfinite(ψ::FiniteMPS) = true +IsfiniteStyle(::FiniteMPS) = FiniteStyle() Base.eachindex(ψ::FiniteMPS) = eachindex(ψ.AL) Base.eachindex(l::IndexStyle, ψ::FiniteMPS) = eachindex(l, ψ.AL) diff --git a/src/states/infinitemps.jl b/src/states/infinitemps.jl index 62c278afb..fbb1ffa4d 100644 --- a/src/states/infinitemps.jl +++ b/src/states/infinitemps.jl @@ -242,6 +242,7 @@ Base.length(ψ::InfiniteMPS) = length(ψ.AL) Base.eltype(ψ::InfiniteMPS) = eltype(typeof(ψ)) Base.eltype(::Type{<:InfiniteMPS{A}}) where {A} = A Base.isfinite(ψ::InfiniteMPS) = false +IsfiniteStyle(::InfiniteMPS) = InfiniteStyle() Base.copy(ψ::InfiniteMPS) = InfiniteMPS(copy(ψ.AL), copy(ψ.AR), copy(ψ.C), copy(ψ.AC)) function Base.copy!(ψ::InfiniteMPS, ϕ::InfiniteMPS) From 140005f13eba221d7dae4aa4f1c0a4e416123aa6 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Wed, 12 Nov 2025 21:05:01 -0500 Subject: [PATCH 03/24] start defining the styles --- src/operators/multilinempo.jl | 1 + src/states/multilinemps.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/src/operators/multilinempo.jl b/src/operators/multilinempo.jl index 92e3e791b..bb71af292 100644 --- a/src/operators/multilinempo.jl +++ b/src/operators/multilinempo.jl @@ -12,6 +12,7 @@ Type that represents multiple lines of `MPO` objects. See also: [`Multiline`](@ref), [`AbstractMPO`](@ref) """ const MultilineMPO = Multiline{<:AbstractMPO} +OperatorStyle(mpos::MultilineMPO) = OperatorStyle(O) function MultilineMPO(Os::AbstractMatrix) return MultilineMPO(map(FiniteMPO, eachrow(Os))) diff --git a/src/states/multilinemps.jl b/src/states/multilinemps.jl index 73f68fac6..38f712fc8 100644 --- a/src/states/multilinemps.jl +++ b/src/states/multilinemps.jl @@ -102,6 +102,7 @@ Base.eltype(t::MultilineMPS) = eltype(t[1]) Base.copy!(ψ::MultilineMPS, ϕ::MultilineMPS) = (copy!.(parent(ψ), parent(ϕ)); ψ) Base.isfinite(ψ::MultilineMPS) = false +IsfiniteStyle(::MultilineMPS) = InfiniteStyle() for f_space in (:physicalspace, :left_virtualspace, :right_virtualspace) @eval $f_space(t::MultilineMPS, i::Int, j::Int) = $f_space(t[i], j) From bd6ccdf66ca779e4dc3afa0c874404eff9656798 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 09:29:57 -0500 Subject: [PATCH 04/24] implement styles for states and operators and add tests --- src/operators/multilinempo.jl | 1 - src/states/quasiparticle_state.jl | 3 +++ src/utility/styles.jl | 27 +++++++++++++++++++++++++++ test/operators.jl | 24 ++++++++++++++++++++++++ test/states.jl | 8 ++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/operators/multilinempo.jl b/src/operators/multilinempo.jl index bb71af292..92e3e791b 100644 --- a/src/operators/multilinempo.jl +++ b/src/operators/multilinempo.jl @@ -12,7 +12,6 @@ Type that represents multiple lines of `MPO` objects. See also: [`Multiline`](@ref), [`AbstractMPO`](@ref) """ const MultilineMPO = Multiline{<:AbstractMPO} -OperatorStyle(mpos::MultilineMPO) = OperatorStyle(O) function MultilineMPO(Os::AbstractMatrix) return MultilineMPO(map(FiniteMPO, eachrow(Os))) diff --git a/src/states/quasiparticle_state.jl b/src/states/quasiparticle_state.jl index 87dbfc6e7..fd34c7fa0 100644 --- a/src/states/quasiparticle_state.jl +++ b/src/states/quasiparticle_state.jl @@ -208,6 +208,7 @@ end # gauge independent code const QP{S, T1, T2} = Union{LeftGaugedQP{S, T1, T2}, RightGaugedQP{S, T1, T2}} +# TODO: Remove FiniteQP and InfiniteQP in favor of styles. const FiniteQP{S <: FiniteMPS, T1, T2} = QP{S, T1, T2} const InfiniteQP{S <: InfiniteMPS, T1, T2} = QP{S, T1, T2} const MultilineQP{Q <: QP} = Multiline{Q} @@ -228,6 +229,8 @@ eachsite(state::QP) = eachsite(state.left_gs) istopological(qp::QP) = qp.left_gs !== qp.right_gs istrivial(qp::QP) = !istopological(qp) && isone(auxiliarysector(qp)) +IsfiniteStyle(qp::QP) = IsfiniteStyle(qp.left_gs) + Base.copy(a::QP) = copy!(similar(a), a) Base.copyto!(a::QP, b::QP) = copy!(a, b) function Base.copy!(a::T, b::T) where {T <: QP} diff --git a/src/utility/styles.jl b/src/utility/styles.jl index a358facee..f2ab8ad9f 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -1,9 +1,36 @@ +""" +`OperatorStyle` + +Holy trait used as a dispatch tag for operator representations. +Concrete subtypes (`MPOStyle` and `HamiltonianStyle`) indicate +whether an operator is stored as an MPO or as a Hamiltonian. +Use `OperatorStyle` in method signatures to select implementation- +specific code paths for different operator types. + +To opt a custom operator type into this dispatch scheme implement: +```julia +OperatorStyle(::T) where {T<:YourOperatorType} +``` +""" abstract type OperatorStyle end struct MPOStyle <: OperatorStyle end struct HamiltonianStyle <: OperatorStyle end +""" +`IsfiniteStyle` +Holy trait used as a dispatch tag to distinguish between finite +and infinite types. Concrete subtypes (`FiniteStyle` and +`InfiniteStyle`) indicate whether a system is finite or infinite. +Use `IsfiniteStyle` in method signatures to select implementation- +specific code paths for different types. + +To opt a custom type into this dispatch scheme implement: +```julia +IsfiniteStyle(::T) where {T<:YourType} +``` +""" abstract type IsfiniteStyle end struct FiniteStyle <: IsfiniteStyle end diff --git a/test/operators.jl b/test/operators.jl index 03fadeea4..8b09bbe06 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -10,6 +10,8 @@ module TestOperators using MPSKit using MPSKit: _transpose_front, _transpose_tail, C_hamiltonian, AC_hamiltonian, AC2_hamiltonian + using MPSKit: IsfiniteStyle, FiniteStyle, InfiniteStyle, OperatorStyle, MPOStyle, + HamiltonianStyle using TensorKit using TensorKit: ℙ using VectorInterface: One @@ -32,6 +34,10 @@ module TestOperators mpo₂ = FiniteMPO(O₂) mpo₃ = FiniteMPO(O₃) + @test IsfiniteStyle(mpo₁) == FiniteStyle() + @test OperatorStyle(mpo₁) == MPOStyle() + + @test @constinferred physicalspace(mpo₁) == fill(V, L) Vleft = @constinferred left_virtualspace(mpo₁) Vright = @constinferred right_virtualspace(mpo₂) @@ -81,6 +87,18 @@ module TestOperators end end + @testset "InfiniteMPO" begin + P = ℂ^2 + T = Float64 + + H1 = randn(T, P ← P) + H1 += H1' + H = InfiniteMPO(H1) + + @test IsfiniteStyle(H) == InfiniteStyle() + @test OperatorStyle(H) == MPOStyle() + end + @testset "MPOHamiltonian constructors" begin P = ℂ^2 T = Float64 @@ -109,6 +127,9 @@ module TestOperators H′ = FiniteMPOHamiltonian(map(Base.Fix1(collect, Any), Ws)) # without type info @test H ≈ H′ + @test IsfiniteStyle(H) == FiniteStyle() + @test OperatorStyle(H) == HamiltonianStyle() + # Infinite Ws = [Wmid] H = InfiniteMPOHamiltonian( @@ -119,6 +140,9 @@ module TestOperators H′ = InfiniteMPOHamiltonian(map(Base.Fix1(collect, Any), Ws)) # without type info @test all(parent(H) .≈ parent(H′)) + + @test IsfiniteStyle(H) == InfiniteStyle() + @test OperatorStyle(H) == HamiltonianStyle() end @testset "Finite MPOHamiltonian" begin diff --git a/test/states.jl b/test/states.jl index 7762b844c..b87f07500 100644 --- a/test/states.jl +++ b/test/states.jl @@ -9,6 +9,7 @@ module TestStates using Test, TestExtras using MPSKit using MPSKit: _transpose_front, _transpose_tail + using MPSKit: IsfiniteStyle, FiniteStyle, InfiniteStyle using MPSKit: TransferMatrix using TensorKit using TensorKit: ℙ @@ -25,6 +26,7 @@ module TestStates ψ = FiniteMPS(rand, elt, L, d, D) @test isfinite(ψ) + @test IsfiniteStyle(ψ) == FiniteStyle() @test @constinferred physicalspace(ψ) == fill(d, L) @test all(x -> x ≾ D, @constinferred left_virtualspace(ψ)) @test all(x -> x ≾ D, @constinferred right_virtualspace(ψ)) @@ -101,6 +103,8 @@ module TestStates ψ = InfiniteMPS([rand(elt, D * d, D), rand(elt, D * d, D)]; tol) @test !isfinite(ψ) + @test IsfiniteStyle(ψ) == InfiniteStyle() + @test physicalspace(ψ) == fill(d, 2) @test all(x -> x ≾ D, left_virtualspace(ψ)) @test all(x -> x ≾ D, right_virtualspace(ψ)) @@ -231,6 +235,8 @@ module TestStates ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) + @test IsfiniteStyle(ϕ₁) == FiniteStyle() + @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) @test @constinferred right_virtualspace(ϕ₁) == right_virtualspace(ψ) @@ -266,6 +272,8 @@ module TestStates ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) + @test IsfiniteStyle(ϕ₁) == InfiniteStyle() + @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) @test @constinferred right_virtualspace(ϕ₁) == right_virtualspace(ψ) From 0896113aef7fbc3ba2804d0e6280549b6f56b7e4 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 09:32:54 -0500 Subject: [PATCH 05/24] add include styles --- src/MPSKit.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MPSKit.jl b/src/MPSKit.jl index 8e96d607d..f3c09a887 100644 --- a/src/MPSKit.jl +++ b/src/MPSKit.jl @@ -103,6 +103,7 @@ include("utility/multiline.jl") include("utility/utility.jl") # random utility functions include("utility/plotting.jl") include("utility/linearcombination.jl") +include("utility/styles.jl") # maybe we should introduce an abstract state type include("states/abstractmps.jl") From 6350c96dd0c76ec6fcbdda9e0e907a82c11b8aea Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 09:47:21 -0500 Subject: [PATCH 06/24] fix InfiniteMPO test --- test/operators.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/operators.jl b/test/operators.jl index 8b09bbe06..0996b8f2c 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -93,7 +93,7 @@ module TestOperators H1 = randn(T, P ← P) H1 += H1' - H = InfiniteMPO(H1) + H = InfiniteMPO([H1]) @test IsfiniteStyle(H) == InfiniteStyle() @test OperatorStyle(H) == MPOStyle() From 50793bf4aa116deeec04ea11e774d2cf563028d0 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 10:11:28 -0500 Subject: [PATCH 07/24] dispatch styles on type and rename IsfiniteStyle to GeometryStyle --- src/operators/abstractmpo.jl | 1 - src/operators/mpo.jl | 6 +++--- src/operators/mpohamiltonian.jl | 4 ++-- src/states/finitemps.jl | 4 ++-- src/states/infinitemps.jl | 4 ++-- src/states/multilinemps.jl | 3 +-- src/states/quasiparticle_state.jl | 4 ++-- src/utility/multiline.jl | 6 ++++++ src/utility/styles.jl | 25 +++++++++++++++---------- test/operators.jl | 10 +++++----- test/states.jl | 12 ++++++------ 11 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/operators/abstractmpo.jl b/src/operators/abstractmpo.jl index 29f40ac1f..4b49d048b 100644 --- a/src/operators/abstractmpo.jl +++ b/src/operators/abstractmpo.jl @@ -9,7 +9,6 @@ abstract type AbstractMPO{O} <: AbstractVector{O} end # useful union types const SparseMPO{O <: SparseBlockTensorMap} = AbstractMPO{O} -Base.isfinite(O::AbstractMPO) = isfinite(typeof(O)) # By default, define things in terms of parent Base.size(mpo::AbstractMPO, args...) = size(parent(mpo), args...) diff --git a/src/operators/mpo.jl b/src/operators/mpo.jl index a8963c858..1c4837a4d 100644 --- a/src/operators/mpo.jl +++ b/src/operators/mpo.jl @@ -17,8 +17,8 @@ Matrix Product Operator (MPO) acting on a finite tensor product space with a lin """ const FiniteMPO{O} = MPO{O, Vector{O}} Base.isfinite(::Type{<:FiniteMPO}) = true -IsfiniteStyle(::FiniteMPO) = FiniteStyle() -OperatorStyle(::MPO) = MPOStyle() +GeometryStyle(::Type{<:FiniteMPO}) = FiniteStyle() +OperatorStyle(::Type{<:MPO}) = MPOStyle() function FiniteMPO(Os::AbstractVector{O}) where {O} for i in eachindex(Os)[1:(end - 1)] @@ -39,7 +39,7 @@ Matrix Product Operator (MPO) acting on an infinite tensor product space with a """ const InfiniteMPO{O} = MPO{O, PeriodicVector{O}} Base.isfinite(::Type{<:InfiniteMPO}) = false -IsfiniteStyle(::InfiniteMPO) = InfiniteStyle() +GeometryStyle(::Type{<:InfiniteMPO}) = InfiniteStyle() function InfiniteMPO(Os::AbstractVector{O}) where {O} for i in eachindex(Os) diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 9f2218968..f2788d0e0 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -35,7 +35,7 @@ OperatorStyle(::MPOHamiltonian) = HamiltonianStyle() const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}} Base.isfinite(::Type{<:FiniteMPOHamiltonian}) = true -IsfiniteStyle(::FiniteMPOHamiltonian) = FiniteStyle() +GeometryStyle(::Type{<:FiniteMPOHamiltonian}) = FiniteStyle() function FiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor} for i in eachindex(Ws)[1:(end - 1)] @@ -47,7 +47,7 @@ end const InfiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, PeriodicVector{O}} Base.isfinite(::Type{<:InfiniteMPOHamiltonian}) = false -IsfiniteStyle(::InfiniteMPOHamiltonian) = InfiniteStyle() +GeometryStyle(::Type{<:InfiniteMPOHamiltonian}) = InfiniteStyle() function InfiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor} for i in eachindex(Ws) diff --git a/src/states/finitemps.jl b/src/states/finitemps.jl index 969201eaf..1a6a92bef 100644 --- a/src/states/finitemps.jl +++ b/src/states/finitemps.jl @@ -311,8 +311,8 @@ function Base.similar(ψ::FiniteMPS{A, B}) where {A, B} return FiniteMPS{A, B}(similar(ψ.ALs), similar(ψ.ARs), similar(ψ.ACs), similar(ψ.Cs)) end -Base.isfinite(ψ::FiniteMPS) = true -IsfiniteStyle(::FiniteMPS) = FiniteStyle() +Base.isfinite(::Type{<:FiniteMPS}) = true +GeometryStyle(::Type{<:FiniteMPS}) = FiniteStyle() Base.eachindex(ψ::FiniteMPS) = eachindex(ψ.AL) Base.eachindex(l::IndexStyle, ψ::FiniteMPS) = eachindex(l, ψ.AL) diff --git a/src/states/infinitemps.jl b/src/states/infinitemps.jl index fbb1ffa4d..466e4ec9d 100644 --- a/src/states/infinitemps.jl +++ b/src/states/infinitemps.jl @@ -241,8 +241,8 @@ Base.size(ψ::InfiniteMPS, args...) = size(ψ.AL, args...) Base.length(ψ::InfiniteMPS) = length(ψ.AL) Base.eltype(ψ::InfiniteMPS) = eltype(typeof(ψ)) Base.eltype(::Type{<:InfiniteMPS{A}}) where {A} = A -Base.isfinite(ψ::InfiniteMPS) = false -IsfiniteStyle(::InfiniteMPS) = InfiniteStyle() +Base.isfinite(::Type{<:InfiniteMPS}) = false +GeometryStyle(::Type{<:InfiniteMPS}) = InfiniteStyle() Base.copy(ψ::InfiniteMPS) = InfiniteMPS(copy(ψ.AL), copy(ψ.AR), copy(ψ.C), copy(ψ.AC)) function Base.copy!(ψ::InfiniteMPS, ϕ::InfiniteMPS) diff --git a/src/states/multilinemps.jl b/src/states/multilinemps.jl index 38f712fc8..6a66437b4 100644 --- a/src/states/multilinemps.jl +++ b/src/states/multilinemps.jl @@ -101,8 +101,7 @@ Base.convert(::Type{InfiniteMPS}, st::MultilineMPS) = only(st) Base.eltype(t::MultilineMPS) = eltype(t[1]) Base.copy!(ψ::MultilineMPS, ϕ::MultilineMPS) = (copy!.(parent(ψ), parent(ϕ)); ψ) -Base.isfinite(ψ::MultilineMPS) = false -IsfiniteStyle(::MultilineMPS) = InfiniteStyle() +Base.isfinite(::Type{<:MultilineMPS}) = false for f_space in (:physicalspace, :left_virtualspace, :right_virtualspace) @eval $f_space(t::MultilineMPS, i::Int, j::Int) = $f_space(t[i], j) diff --git a/src/states/quasiparticle_state.jl b/src/states/quasiparticle_state.jl index fd34c7fa0..83272df5c 100644 --- a/src/states/quasiparticle_state.jl +++ b/src/states/quasiparticle_state.jl @@ -213,6 +213,8 @@ const FiniteQP{S <: FiniteMPS, T1, T2} = QP{S, T1, T2} const InfiniteQP{S <: InfiniteMPS, T1, T2} = QP{S, T1, T2} const MultilineQP{Q <: QP} = Multiline{Q} +GeometryStyle(::Type{<:QP{S, T1, T2}}) where {S, T1, T2} = GeometryStyle(S) + TensorKit.spacetype(::Union{QP{S}, Type{<:QP{S}}}) where {S} = spacetype(S) TensorKit.sectortype(::Union{QP{S}, Type{<:QP{S}}}) where {S} = sectortype(S) @@ -229,8 +231,6 @@ eachsite(state::QP) = eachsite(state.left_gs) istopological(qp::QP) = qp.left_gs !== qp.right_gs istrivial(qp::QP) = !istopological(qp) && isone(auxiliarysector(qp)) -IsfiniteStyle(qp::QP) = IsfiniteStyle(qp.left_gs) - Base.copy(a::QP) = copy!(similar(a), a) Base.copyto!(a::QP, b::QP) = copy!(a, b) function Base.copy!(a::T, b::T) where {T <: QP} diff --git a/src/utility/multiline.jl b/src/utility/multiline.jl index 549766ee9..3bab8c35f 100644 --- a/src/utility/multiline.jl +++ b/src/utility/multiline.jl @@ -54,6 +54,12 @@ function Base.repeat(A::Multiline, rows::Int, cols::Int) return Multiline(outer) end +# Style +# ---------------- + +OperatorStyle(::Type{Multiline{T}}) where {T} = OperatorStyle(T) +GeometryStyle(::Type{Multiline{T}}) where {T} = GeometryStyle(T) + # VectorInterface # --------------- VectorInterface.scalartype(::Type{Multiline{T}}) where {T} = scalartype(T) diff --git a/src/utility/styles.jl b/src/utility/styles.jl index f2ab8ad9f..2a0a70725 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -13,25 +13,30 @@ OperatorStyle(::T) where {T<:YourOperatorType} ``` """ abstract type OperatorStyle end +OperatorStyle(x) = OperatorStyle(typeof(x)) +OperatorStyle(T::Type) = throw(MethodError(OperatorStyle, T)) # avoid stackoverflow if not defined struct MPOStyle <: OperatorStyle end struct HamiltonianStyle <: OperatorStyle end """ -`IsfiniteStyle` -Holy trait used as a dispatch tag to distinguish between finite -and infinite types. Concrete subtypes (`FiniteStyle` and -`InfiniteStyle`) indicate whether a system is finite or infinite. -Use `IsfiniteStyle` in method signatures to select implementation- -specific code paths for different types. +`GeometryStyle` + +Holy trait used as a dispatch tag to distinguish between different +geometry (currently finite and infinite). Concrete subtypes +(`FiniteStyle` and `InfiniteStyle`) indicate whether a system is +finite or infinite. Use `GeometryStyle` in method signatures to +select implementation-specific code paths for different types. To opt a custom type into this dispatch scheme implement: ```julia -IsfiniteStyle(::T) where {T<:YourType} +GeometryStyle(::T) where {T<:YourType} ``` """ -abstract type IsfiniteStyle end +abstract type GeometryStyle end +GeometryStyle(x) = GeometryStyle(typeof(x)) +GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverflow if not defined -struct FiniteStyle <: IsfiniteStyle end -struct InfiniteStyle <: IsfiniteStyle end +struct FiniteStyle <: GeometryStyle end +struct InfiniteStyle <: GeometryStyle end diff --git a/test/operators.jl b/test/operators.jl index 0996b8f2c..420add464 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -10,7 +10,7 @@ module TestOperators using MPSKit using MPSKit: _transpose_front, _transpose_tail, C_hamiltonian, AC_hamiltonian, AC2_hamiltonian - using MPSKit: IsfiniteStyle, FiniteStyle, InfiniteStyle, OperatorStyle, MPOStyle, + using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, OperatorStyle, MPOStyle, HamiltonianStyle using TensorKit using TensorKit: ℙ @@ -34,7 +34,7 @@ module TestOperators mpo₂ = FiniteMPO(O₂) mpo₃ = FiniteMPO(O₃) - @test IsfiniteStyle(mpo₁) == FiniteStyle() + @test GeometryStyle(mpo₁) == FiniteStyle() @test OperatorStyle(mpo₁) == MPOStyle() @@ -95,7 +95,7 @@ module TestOperators H1 += H1' H = InfiniteMPO([H1]) - @test IsfiniteStyle(H) == InfiniteStyle() + @test GeometryStyle(H) == InfiniteStyle() @test OperatorStyle(H) == MPOStyle() end @@ -127,7 +127,7 @@ module TestOperators H′ = FiniteMPOHamiltonian(map(Base.Fix1(collect, Any), Ws)) # without type info @test H ≈ H′ - @test IsfiniteStyle(H) == FiniteStyle() + @test GeometryStyle(H) == FiniteStyle() @test OperatorStyle(H) == HamiltonianStyle() # Infinite @@ -141,7 +141,7 @@ module TestOperators H′ = InfiniteMPOHamiltonian(map(Base.Fix1(collect, Any), Ws)) # without type info @test all(parent(H) .≈ parent(H′)) - @test IsfiniteStyle(H) == InfiniteStyle() + @test GeometryStyle(H) == InfiniteStyle() @test OperatorStyle(H) == HamiltonianStyle() end diff --git a/test/states.jl b/test/states.jl index b87f07500..9ccd1bc67 100644 --- a/test/states.jl +++ b/test/states.jl @@ -9,7 +9,7 @@ module TestStates using Test, TestExtras using MPSKit using MPSKit: _transpose_front, _transpose_tail - using MPSKit: IsfiniteStyle, FiniteStyle, InfiniteStyle + using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle using MPSKit: TransferMatrix using TensorKit using TensorKit: ℙ @@ -25,8 +25,8 @@ module TestStates L = rand(3:20) ψ = FiniteMPS(rand, elt, L, d, D) - @test isfinite(ψ) - @test IsfiniteStyle(ψ) == FiniteStyle() + @test isfinite(typeof(ψ)) + @test GeometryStyle(ψ) == FiniteStyle() @test @constinferred physicalspace(ψ) == fill(d, L) @test all(x -> x ≾ D, @constinferred left_virtualspace(ψ)) @test all(x -> x ≾ D, @constinferred right_virtualspace(ψ)) @@ -103,7 +103,7 @@ module TestStates ψ = InfiniteMPS([rand(elt, D * d, D), rand(elt, D * d, D)]; tol) @test !isfinite(ψ) - @test IsfiniteStyle(ψ) == InfiniteStyle() + @test GeometryStyle(ψ) == InfiniteStyle() @test physicalspace(ψ) == fill(d, 2) @test all(x -> x ≾ D, left_virtualspace(ψ)) @@ -235,7 +235,7 @@ module TestStates ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) - @test IsfiniteStyle(ϕ₁) == FiniteStyle() + @test GeometryStyle(ϕ₁) == FiniteStyle() @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) @@ -272,7 +272,7 @@ module TestStates ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) - @test IsfiniteStyle(ϕ₁) == InfiniteStyle() + @test GeometryStyle(ϕ₁) == InfiniteStyle() @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) From 7226788c11503636f1e0a6adcd3effafa43f66d9 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 10:34:15 -0500 Subject: [PATCH 08/24] readd Base.isfinite for AbstractMPS, MPO and MPOHamiltonian --- src/operators/mpo.jl | 1 + src/operators/mpohamiltonian.jl | 1 + src/states/abstractmps.jl | 1 + 3 files changed, 3 insertions(+) diff --git a/src/operators/mpo.jl b/src/operators/mpo.jl index 1c4837a4d..3e8837283 100644 --- a/src/operators/mpo.jl +++ b/src/operators/mpo.jl @@ -16,6 +16,7 @@ end Matrix Product Operator (MPO) acting on a finite tensor product space with a linear order. """ const FiniteMPO{O} = MPO{O, Vector{O}} +Base.isfinite(O::MPO) = isfinite(typeof(O)) Base.isfinite(::Type{<:FiniteMPO}) = true GeometryStyle(::Type{<:FiniteMPO}) = FiniteStyle() OperatorStyle(::Type{<:MPO}) = MPOStyle() diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index f2788d0e0..8eb085253 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -31,6 +31,7 @@ operators in a form that is compatible with this constructor. struct MPOHamiltonian{TO <: JordanMPOTensor, V <: AbstractVector{TO}} <: AbstractMPO{TO} W::V end +Base.isfinite(mpo::MPOHamiltonian) = isfinite(typeof(mpo)) OperatorStyle(::MPOHamiltonian) = HamiltonianStyle() const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}} diff --git a/src/states/abstractmps.jl b/src/states/abstractmps.jl index 0503a33be..09ae8ef08 100644 --- a/src/states/abstractmps.jl +++ b/src/states/abstractmps.jl @@ -173,6 +173,7 @@ abstract type AbstractFiniteMPS <: AbstractMPS end Base.eltype(ψ::AbstractMPS) = eltype(typeof(ψ)) VectorInterface.scalartype(T::Type{<:AbstractMPS}) = scalartype(site_type(T)) +Base.isfinite(ψ::AbstractMPS) = isfinite(typeof(ψ)) function Base.checkbounds(ψ::AbstractMPS, i) return Base.checkbounds(Bool, ψ, i) || throw(BoundsError(ψ, i)) From c206de85a5335adea8708d89f94bfdec2de564d9 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 11:03:06 -0500 Subject: [PATCH 09/24] add tests for styles of types --- test/operators.jl | 16 ++++++++++++++++ test/states.jl | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/test/operators.jl b/test/operators.jl index 420add464..afad18c8e 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -34,7 +34,11 @@ module TestOperators mpo₂ = FiniteMPO(O₂) mpo₃ = FiniteMPO(O₃) + @test isfinite(mpo₁) + @test isfinite(typeof(mpo₁)) + @test GeometryStyle(typeof(mpo₁)) == FiniteStyle() @test GeometryStyle(mpo₁) == FiniteStyle() + @test OperatorStyle(typeof(mpo₁)) == MPOStyle() @test OperatorStyle(mpo₁) == MPOStyle() @@ -95,7 +99,11 @@ module TestOperators H1 += H1' H = InfiniteMPO([H1]) + @test !isfinite(H) + @test !isfinite(typeof(H)) + @test GeometryStyle(typeof(H)) == InfiniteStyle() @test GeometryStyle(H) == InfiniteStyle() + @test OperatorStyle(typeof(H)) == MPOStyle() @test OperatorStyle(H) == MPOStyle() end @@ -127,7 +135,11 @@ module TestOperators H′ = FiniteMPOHamiltonian(map(Base.Fix1(collect, Any), Ws)) # without type info @test H ≈ H′ + @test isfinite(H) + @test isfinite(typeof(H)) + @test GeometryStyle(typeof(H)) == FiniteStyle() @test GeometryStyle(H) == FiniteStyle() + @test OperatorStyle(typeof(H)) == HamiltonianStyle() @test OperatorStyle(H) == HamiltonianStyle() # Infinite @@ -141,7 +153,11 @@ module TestOperators H′ = InfiniteMPOHamiltonian(map(Base.Fix1(collect, Any), Ws)) # without type info @test all(parent(H) .≈ parent(H′)) + @test !isfinite(H) + @test !isfinite(typeof(H)) + @test GeometryStyle(typeof(H)) == InfiniteStyle() @test GeometryStyle(H) == InfiniteStyle() + @test OperatorStyle(typeof(H)) == HamiltonianStyle() @test OperatorStyle(H) == HamiltonianStyle() end diff --git a/test/states.jl b/test/states.jl index 9ccd1bc67..a18b35d8a 100644 --- a/test/states.jl +++ b/test/states.jl @@ -25,7 +25,9 @@ module TestStates L = rand(3:20) ψ = FiniteMPS(rand, elt, L, d, D) + @test isfinite(ψ) @test isfinite(typeof(ψ)) + @test GeometryStyle(typeof(ψ)) == FiniteStyle() @test GeometryStyle(ψ) == FiniteStyle() @test @constinferred physicalspace(ψ) == fill(d, L) @test all(x -> x ≾ D, @constinferred left_virtualspace(ψ)) @@ -102,7 +104,9 @@ module TestStates ψ = InfiniteMPS([rand(elt, D * d, D), rand(elt, D * d, D)]; tol) + @test !isfinite(typeof(ψ)) @test !isfinite(ψ) + @test GeometryStyle(typeof(ψ)) == InfiniteStyle() @test GeometryStyle(ψ) == InfiniteStyle() @test physicalspace(ψ) == fill(d, 2) @@ -236,6 +240,7 @@ module TestStates ϕ₂ = LeftGaugedQP(rand, ψ) @test GeometryStyle(ϕ₁) == FiniteStyle() + @test GeometryStyle(typeof(ϕ₂)) == FiniteStyle() @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) @@ -273,6 +278,7 @@ module TestStates ϕ₂ = LeftGaugedQP(rand, ψ) @test GeometryStyle(ϕ₁) == InfiniteStyle() + @test GeometryStyle(typeof(ϕ₂)) == InfiniteStyle() @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) From 07f579c4cf3449bca8a42b2e60d54b7f7a531d3c Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 12:52:13 -0500 Subject: [PATCH 10/24] fix include order --- src/MPSKit.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MPSKit.jl b/src/MPSKit.jl index f3c09a887..59b7cd968 100644 --- a/src/MPSKit.jl +++ b/src/MPSKit.jl @@ -99,11 +99,11 @@ include("utility/iterativesolvers.jl") include("utility/periodicarray.jl") include("utility/windowarray.jl") -include("utility/multiline.jl") include("utility/utility.jl") # random utility functions include("utility/plotting.jl") include("utility/linearcombination.jl") include("utility/styles.jl") +include("utility/multiline.jl") # maybe we should introduce an abstract state type include("states/abstractmps.jl") From d278a3abbd9e9cf12d62f95748ed23bcd0d3f557 Mon Sep 17 00:00:00 2001 From: afeuerpfeil Date: Fri, 14 Nov 2025 13:13:42 -0500 Subject: [PATCH 11/24] fix OperatorStyle for MPOHamiltonian --- src/operators/mpohamiltonian.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 8eb085253..c4c7dbf9b 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -32,7 +32,7 @@ struct MPOHamiltonian{TO <: JordanMPOTensor, V <: AbstractVector{TO}} <: Abstrac W::V end Base.isfinite(mpo::MPOHamiltonian) = isfinite(typeof(mpo)) -OperatorStyle(::MPOHamiltonian) = HamiltonianStyle() +OperatorStyle(::Type{<:MPOHamiltonian}) = HamiltonianStyle() const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}} Base.isfinite(::Type{<:FiniteMPOHamiltonian}) = true From ea5366c3f750e416ce4ff0450ef9e8a4c896dc1d Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Fri, 14 Nov 2025 15:18:03 -0500 Subject: [PATCH 12/24] Add WindowStyle and increase code coverage --- src/states/windowmps.jl | 4 +++- src/utility/styles.jl | 1 + test/other.jl | 13 +++++++++++-- test/states.jl | 21 ++++++++++++++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/states/windowmps.jl b/src/states/windowmps.jl index 5c0bab9d0..e67ac9a23 100644 --- a/src/states/windowmps.jl +++ b/src/states/windowmps.jl @@ -20,7 +20,7 @@ Type that represents a finite Matrix Product State embedded in an infinte Matrix [right_gs::InfiniteMPS]) WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}}, maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS]) - + Construct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of [`FiniteMPS`](@ref), followed by a @@ -50,6 +50,8 @@ struct WindowMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractFiniteMPS end end +GeometryStyle(::Type{<:WindowMPS}) = WindowStyle() + #=========================================================================================== Constructors ===========================================================================================# diff --git a/src/utility/styles.jl b/src/utility/styles.jl index 2a0a70725..c7210f5a9 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -40,3 +40,4 @@ GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverf struct FiniteStyle <: GeometryStyle end struct InfiniteStyle <: GeometryStyle end +struct WindowStyle <: GeometryStyle end diff --git a/test/other.jl b/test/other.jl index af1ca0563..62a05e1f4 100644 --- a/test/other.jl +++ b/test/other.jl @@ -8,6 +8,8 @@ module TestMiscellaneous using ..TestSetup using Test, TestExtras using MPSKit + using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, OperatorStyle, MPOStyle, + HamiltonianStyle using TensorKit using TensorKit: ℙ using Plots @@ -74,7 +76,7 @@ module TestMiscellaneous output = String(take!(buffer)) check = """ ... 🭻⎡⠉⢈⎤🭻 ... - ⎣⠀⢀⎦ + ⎣⠀⢀⎦ """ @test output == check @@ -83,7 +85,7 @@ module TestMiscellaneous output = String(take!(buffer)) check = """ ... 🭻⎡⡏⠉⠛⠟⎤🭻 ... - ⎣⡇⠀⠀⡂⎦ + ⎣⡇⠀⠀⡂⎦ """ @test output == check @@ -101,4 +103,11 @@ module TestMiscellaneous check = " ⎡⠉⠉⠉⠉⎤🭻🭻⎡⡏⠉⠛⠟⎤🭻🭻⎡⡏⠉⠛⠟⎤🭻🭻⎡⡇⠀⎤ \n ⎣⠀⠀⠀⠀⎦ ⎣⡇⠀⠀⡂⎦ ⎣⡇⠀⠀⡂⎦ ⎣⡇⠀⎦ \n" @test output == check end + + @testset "Styles" begin + @test_throws MethodError OperatorStyle(42) + @test_throws MethodError OperatorStyle(Float64) + @test_throws MethodError GeometryStyle("abc") + @test_throws MethodError GeometryStyle(UInt8) + end end diff --git a/test/states.jl b/test/states.jl index a18b35d8a..6f4036ea9 100644 --- a/test/states.jl +++ b/test/states.jl @@ -9,7 +9,7 @@ module TestStates using Test, TestExtras using MPSKit using MPSKit: _transpose_front, _transpose_tail - using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle + using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, WindowStyle using MPSKit: TransferMatrix using TensorKit using TensorKit: ℙ @@ -25,14 +25,18 @@ module TestStates L = rand(3:20) ψ = FiniteMPS(rand, elt, L, d, D) + @test eachindex(IndexLinear(), ψ) == eachindex(ψ) @test isfinite(ψ) @test isfinite(typeof(ψ)) + @test isfinite(ψ) == isfinite(typeof(ψ)) @test GeometryStyle(typeof(ψ)) == FiniteStyle() @test GeometryStyle(ψ) == FiniteStyle() @test @constinferred physicalspace(ψ) == fill(d, L) @test all(x -> x ≾ D, @constinferred left_virtualspace(ψ)) @test all(x -> x ≾ D, @constinferred right_virtualspace(ψ)) + @test eltype(ψ) == eltype(typeof(ψ)) + ovl = dot(ψ, ψ) @test ovl ≈ norm(ψ.AC[1])^2 @@ -106,9 +110,12 @@ module TestStates @test !isfinite(typeof(ψ)) @test !isfinite(ψ) + @test isfinite(ψ) == isfinite(typeof(ψ)) @test GeometryStyle(typeof(ψ)) == InfiniteStyle() @test GeometryStyle(ψ) == InfiniteStyle() + @test eltype(ψ) == eltype(typeof(ψ)) + @test physicalspace(ψ) == fill(d, 2) @test all(x -> x ≾ D, left_virtualspace(ψ)) @test all(x -> x ≾ D, right_virtualspace(ψ)) @@ -140,6 +147,9 @@ module TestStates ]; tol ) + @test GeometryStyle(typeof(ψ)) == InfiniteStyle() + @test GeometryStyle(ψ) == InfiniteStyle() + @test physicalspace(ψ) == fill(d, 2, 2) @test all(x -> x ≾ D, left_virtualspace(ψ)) @test all(x -> x ≾ D, right_virtualspace(ψ)) @@ -178,6 +188,12 @@ module TestStates # constructor 2 - used to take a "slice" from an infinite mps window_2 = WindowMPS(gs, 10) + @test GeometryStyle(typeof(window_1)) == WindowStyle() + @test GeometryStyle(window_1) == WindowStyle() + @test GeometryStyle(window_1) == GeometryStyle(window_2) + + @test eltype(window_1) == eltype(typeof(window_1)) + P = @constinferred physicalspace(window_2) Vleft = @constinferred left_virtualspace(window_2) Vright = @constinferred right_virtualspace(window_2) @@ -245,6 +261,7 @@ module TestStates @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) @test @constinferred right_virtualspace(ϕ₁) == right_virtualspace(ψ) + @test TensorKit.sectortype(ϕ₁) == TensorKit.sectortype(ψ) @test norm(axpy!(1, ϕ₁, copy(ϕ₂))) ≤ norm(ϕ₁) + norm(ϕ₂) @test norm(ϕ₁) * 3 ≈ norm(ϕ₁ * 3) @@ -273,6 +290,8 @@ module TestStates period = rand(1:4) ψ = InfiniteMPS(fill(d, period), fill(D, period)) + @test eltype(ψ) == eltype(typeof(ψ)) + #rand_quasiparticle is a private non-exported function ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) From 18b5ef297e066899fb6656487f30e414770322c0 Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Fri, 14 Nov 2025 15:46:09 -0500 Subject: [PATCH 13/24] fix test and hopefully also runic --- test/other.jl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/other.jl b/test/other.jl index 62a05e1f4..871ce4a7e 100644 --- a/test/other.jl +++ b/test/other.jl @@ -74,19 +74,15 @@ module TestMiscellaneous buffer = IOBuffer() braille(buffer, H) output = String(take!(buffer)) - check = """ - ... 🭻⎡⠉⢈⎤🭻 ... - ⎣⠀⢀⎦ - """ + check = "... 🭻⎡⠉⢈⎤🭻 ...\n ⎣⠀⢀⎦ \n" + @test output == check O = make_time_mpo(H, 1.0, TaylorCluster(3, false, false)) braille(buffer, O) output = String(take!(buffer)) - check = """ - ... 🭻⎡⡏⠉⠛⠟⎤🭻 ... - ⎣⡇⠀⠀⡂⎦ - """ + check = "... 🭻⎡⡏⠉⠛⠟⎤🭻 ...\n ⎣⡇⠀⠀⡂⎦ \n" + @test output == check # Finite Hamiltonians and MPOs From 5af306061398e0a599c882b091152984c3a1c47f Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Fri, 14 Nov 2025 16:07:58 -0500 Subject: [PATCH 14/24] more tests --- test/operators.jl | 3 +-- test/other.jl | 15 +++++++++++++++ test/states.jl | 2 ++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/test/operators.jl b/test/operators.jl index afad18c8e..7d1ad7575 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -10,7 +10,7 @@ module TestOperators using MPSKit using MPSKit: _transpose_front, _transpose_tail, C_hamiltonian, AC_hamiltonian, AC2_hamiltonian - using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, OperatorStyle, MPOStyle, + using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, WindowStyle, OperatorStyle, MPOStyle, HamiltonianStyle using TensorKit using TensorKit: ℙ @@ -39,7 +39,6 @@ module TestOperators @test GeometryStyle(typeof(mpo₁)) == FiniteStyle() @test GeometryStyle(mpo₁) == FiniteStyle() @test OperatorStyle(typeof(mpo₁)) == MPOStyle() - @test OperatorStyle(mpo₁) == MPOStyle() @test @constinferred physicalspace(mpo₁) == fill(V, L) diff --git a/test/other.jl b/test/other.jl index 871ce4a7e..a62b378b7 100644 --- a/test/other.jl +++ b/test/other.jl @@ -105,5 +105,20 @@ module TestMiscellaneous @test_throws MethodError OperatorStyle(Float64) @test_throws MethodError GeometryStyle("abc") @test_throws MethodError GeometryStyle(UInt8) + + @test OperatorStyle(MPO) == MPOStyle() + @test OperatorStyle(FiniteMPOHamiltonian) == HamiltonianStyle() + @test OperatorStyle(InfiniteMPO) == MPOStyle() + @test OperatorStyle(InfiniteMPOHamiltonian) == HamiltonianStyle() + @test OperatorStyle(MultilineMPO) == MPOStyle() + + @test GeometryStyle(FiniteMPOHamiltonian) == FiniteStyle() + @test GeometryStyle(InfiniteMPS) == InfiniteStyle() + @test GeometryStyle(WindowArray) == WindowStyle() + @test GeometryStyle(FiniteMPS) == FiniteStyle() + @test GeometryStyle(FiniteMPO) == FiniteStyle() + @test GeometryStyle(FiniteMPOHamiltonian) == FiniteStyle() + @test GeometryStyle(InfiniteMPO) == InfiniteStyle() + @test GeometryStyle(InfiniteMPOHamiltonian) == InfiniteStyle() end end diff --git a/test/states.jl b/test/states.jl index 6f4036ea9..450aa2eff 100644 --- a/test/states.jl +++ b/test/states.jl @@ -150,6 +150,8 @@ module TestStates @test GeometryStyle(typeof(ψ)) == InfiniteStyle() @test GeometryStyle(ψ) == InfiniteStyle() + @test !isfinite(typeof(ψ)) + @test physicalspace(ψ) == fill(d, 2, 2) @test all(x -> x ≾ D, left_virtualspace(ψ)) @test all(x -> x ≾ D, right_virtualspace(ψ)) From 8f72c212f94ab272e08b0a3c913df209eb9b7221 Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Fri, 14 Nov 2025 16:38:26 -0500 Subject: [PATCH 15/24] fix other tests --- test/other.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/other.jl b/test/other.jl index a62b378b7..84ee7e055 100644 --- a/test/other.jl +++ b/test/other.jl @@ -107,14 +107,10 @@ module TestMiscellaneous @test_throws MethodError GeometryStyle(UInt8) @test OperatorStyle(MPO) == MPOStyle() - @test OperatorStyle(FiniteMPOHamiltonian) == HamiltonianStyle() @test OperatorStyle(InfiniteMPO) == MPOStyle() - @test OperatorStyle(InfiniteMPOHamiltonian) == HamiltonianStyle() - @test OperatorStyle(MultilineMPO) == MPOStyle() @test GeometryStyle(FiniteMPOHamiltonian) == FiniteStyle() @test GeometryStyle(InfiniteMPS) == InfiniteStyle() - @test GeometryStyle(WindowArray) == WindowStyle() @test GeometryStyle(FiniteMPS) == FiniteStyle() @test GeometryStyle(FiniteMPO) == FiniteStyle() @test GeometryStyle(FiniteMPOHamiltonian) == FiniteStyle() From 9b7905c4219d88bcb9c1af1c04f0c8432c157ce5 Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Fri, 14 Nov 2025 20:44:20 -0500 Subject: [PATCH 16/24] make GeometryStyle names more descriptive --- src/operators/mpo.jl | 4 ++-- src/operators/mpohamiltonian.jl | 4 ++-- src/states/finitemps.jl | 2 +- src/states/infinitemps.jl | 2 +- src/states/windowmps.jl | 2 +- src/utility/styles.jl | 12 ++++++------ test/operators.jl | 18 +++++++++--------- test/other.jl | 16 ++++++++-------- test/states.jl | 26 +++++++++++++------------- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/operators/mpo.jl b/src/operators/mpo.jl index 3e8837283..f08731f43 100644 --- a/src/operators/mpo.jl +++ b/src/operators/mpo.jl @@ -18,7 +18,7 @@ Matrix Product Operator (MPO) acting on a finite tensor product space with a lin const FiniteMPO{O} = MPO{O, Vector{O}} Base.isfinite(O::MPO) = isfinite(typeof(O)) Base.isfinite(::Type{<:FiniteMPO}) = true -GeometryStyle(::Type{<:FiniteMPO}) = FiniteStyle() +GeometryStyle(::Type{<:FiniteMPO}) = FiniteChainStyle() OperatorStyle(::Type{<:MPO}) = MPOStyle() function FiniteMPO(Os::AbstractVector{O}) where {O} @@ -40,7 +40,7 @@ Matrix Product Operator (MPO) acting on an infinite tensor product space with a """ const InfiniteMPO{O} = MPO{O, PeriodicVector{O}} Base.isfinite(::Type{<:InfiniteMPO}) = false -GeometryStyle(::Type{<:InfiniteMPO}) = InfiniteStyle() +GeometryStyle(::Type{<:InfiniteMPO}) = InfiniteChainStyle() function InfiniteMPO(Os::AbstractVector{O}) where {O} for i in eachindex(Os) diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index c4c7dbf9b..40350bcbe 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -36,7 +36,7 @@ OperatorStyle(::Type{<:MPOHamiltonian}) = HamiltonianStyle() const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}} Base.isfinite(::Type{<:FiniteMPOHamiltonian}) = true -GeometryStyle(::Type{<:FiniteMPOHamiltonian}) = FiniteStyle() +GeometryStyle(::Type{<:FiniteMPOHamiltonian}) = FiniteChainStyle() function FiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor} for i in eachindex(Ws)[1:(end - 1)] @@ -48,7 +48,7 @@ end const InfiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, PeriodicVector{O}} Base.isfinite(::Type{<:InfiniteMPOHamiltonian}) = false -GeometryStyle(::Type{<:InfiniteMPOHamiltonian}) = InfiniteStyle() +GeometryStyle(::Type{<:InfiniteMPOHamiltonian}) = InfiniteChainStyle() function InfiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor} for i in eachindex(Ws) diff --git a/src/states/finitemps.jl b/src/states/finitemps.jl index 1a6a92bef..b9e1e8734 100644 --- a/src/states/finitemps.jl +++ b/src/states/finitemps.jl @@ -312,7 +312,7 @@ function Base.similar(ψ::FiniteMPS{A, B}) where {A, B} end Base.isfinite(::Type{<:FiniteMPS}) = true -GeometryStyle(::Type{<:FiniteMPS}) = FiniteStyle() +GeometryStyle(::Type{<:FiniteMPS}) = FiniteChainStyle() Base.eachindex(ψ::FiniteMPS) = eachindex(ψ.AL) Base.eachindex(l::IndexStyle, ψ::FiniteMPS) = eachindex(l, ψ.AL) diff --git a/src/states/infinitemps.jl b/src/states/infinitemps.jl index 466e4ec9d..8e3780ad3 100644 --- a/src/states/infinitemps.jl +++ b/src/states/infinitemps.jl @@ -242,7 +242,7 @@ Base.length(ψ::InfiniteMPS) = length(ψ.AL) Base.eltype(ψ::InfiniteMPS) = eltype(typeof(ψ)) Base.eltype(::Type{<:InfiniteMPS{A}}) where {A} = A Base.isfinite(::Type{<:InfiniteMPS}) = false -GeometryStyle(::Type{<:InfiniteMPS}) = InfiniteStyle() +GeometryStyle(::Type{<:InfiniteMPS}) = InfiniteChainStyle() Base.copy(ψ::InfiniteMPS) = InfiniteMPS(copy(ψ.AL), copy(ψ.AR), copy(ψ.C), copy(ψ.AC)) function Base.copy!(ψ::InfiniteMPS, ϕ::InfiniteMPS) diff --git a/src/states/windowmps.jl b/src/states/windowmps.jl index e67ac9a23..2ee5297f6 100644 --- a/src/states/windowmps.jl +++ b/src/states/windowmps.jl @@ -50,7 +50,7 @@ struct WindowMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractFiniteMPS end end -GeometryStyle(::Type{<:WindowMPS}) = WindowStyle() +GeometryStyle(::Type{<:WindowMPS}) = WindowChainStyle() #=========================================================================================== Constructors diff --git a/src/utility/styles.jl b/src/utility/styles.jl index c7210f5a9..f91760d5a 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -24,9 +24,9 @@ struct HamiltonianStyle <: OperatorStyle end `GeometryStyle` Holy trait used as a dispatch tag to distinguish between different -geometry (currently finite and infinite). Concrete subtypes -(`FiniteStyle` and `InfiniteStyle`) indicate whether a system is -finite or infinite. Use `GeometryStyle` in method signatures to +geometries Concrete subtypes +(`FiniteChainStyle`, `InfiniteChainStyle` and `WindowChainStyle`) indicate whether a system is +finite, infinite or a finite window in an infinite chain. Use `GeometryStyle` in method signatures to select implementation-specific code paths for different types. To opt a custom type into this dispatch scheme implement: @@ -38,6 +38,6 @@ abstract type GeometryStyle end GeometryStyle(x) = GeometryStyle(typeof(x)) GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverflow if not defined -struct FiniteStyle <: GeometryStyle end -struct InfiniteStyle <: GeometryStyle end -struct WindowStyle <: GeometryStyle end +struct FiniteChainStyle <: GeometryStyle end +struct InfiniteChainStyle <: GeometryStyle end +struct WindowChainStyle <: GeometryStyle end diff --git a/test/operators.jl b/test/operators.jl index 7d1ad7575..490200860 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -10,7 +10,7 @@ module TestOperators using MPSKit using MPSKit: _transpose_front, _transpose_tail, C_hamiltonian, AC_hamiltonian, AC2_hamiltonian - using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, WindowStyle, OperatorStyle, MPOStyle, + using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, WindowChainStyle, OperatorStyle, MPOStyle, HamiltonianStyle using TensorKit using TensorKit: ℙ @@ -36,8 +36,8 @@ module TestOperators @test isfinite(mpo₁) @test isfinite(typeof(mpo₁)) - @test GeometryStyle(typeof(mpo₁)) == FiniteStyle() - @test GeometryStyle(mpo₁) == FiniteStyle() + @test GeometryStyle(typeof(mpo₁)) == FiniteChainStyle() + @test GeometryStyle(mpo₁) == FiniteChainStyle() @test OperatorStyle(typeof(mpo₁)) == MPOStyle() @@ -100,8 +100,8 @@ module TestOperators @test !isfinite(H) @test !isfinite(typeof(H)) - @test GeometryStyle(typeof(H)) == InfiniteStyle() - @test GeometryStyle(H) == InfiniteStyle() + @test GeometryStyle(typeof(H)) == InfiniteChainStyle() + @test GeometryStyle(H) == InfiniteChainStyle() @test OperatorStyle(typeof(H)) == MPOStyle() @test OperatorStyle(H) == MPOStyle() end @@ -136,8 +136,8 @@ module TestOperators @test isfinite(H) @test isfinite(typeof(H)) - @test GeometryStyle(typeof(H)) == FiniteStyle() - @test GeometryStyle(H) == FiniteStyle() + @test GeometryStyle(typeof(H)) == FiniteChainStyle() + @test GeometryStyle(H) == FiniteChainStyle() @test OperatorStyle(typeof(H)) == HamiltonianStyle() @test OperatorStyle(H) == HamiltonianStyle() @@ -154,8 +154,8 @@ module TestOperators @test !isfinite(H) @test !isfinite(typeof(H)) - @test GeometryStyle(typeof(H)) == InfiniteStyle() - @test GeometryStyle(H) == InfiniteStyle() + @test GeometryStyle(typeof(H)) == InfiniteChainStyle() + @test GeometryStyle(H) == InfiniteChainStyle() @test OperatorStyle(typeof(H)) == HamiltonianStyle() @test OperatorStyle(H) == HamiltonianStyle() end diff --git a/test/other.jl b/test/other.jl index 84ee7e055..b8644c89e 100644 --- a/test/other.jl +++ b/test/other.jl @@ -8,7 +8,7 @@ module TestMiscellaneous using ..TestSetup using Test, TestExtras using MPSKit - using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, OperatorStyle, MPOStyle, + using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, OperatorStyle, MPOStyle, HamiltonianStyle using TensorKit using TensorKit: ℙ @@ -109,12 +109,12 @@ module TestMiscellaneous @test OperatorStyle(MPO) == MPOStyle() @test OperatorStyle(InfiniteMPO) == MPOStyle() - @test GeometryStyle(FiniteMPOHamiltonian) == FiniteStyle() - @test GeometryStyle(InfiniteMPS) == InfiniteStyle() - @test GeometryStyle(FiniteMPS) == FiniteStyle() - @test GeometryStyle(FiniteMPO) == FiniteStyle() - @test GeometryStyle(FiniteMPOHamiltonian) == FiniteStyle() - @test GeometryStyle(InfiniteMPO) == InfiniteStyle() - @test GeometryStyle(InfiniteMPOHamiltonian) == InfiniteStyle() + @test GeometryStyle(FiniteMPOHamiltonian) == FiniteChainStyle() + @test GeometryStyle(InfiniteMPS) == InfiniteChainStyle() + @test GeometryStyle(FiniteMPS) == FiniteChainStyle() + @test GeometryStyle(FiniteMPO) == FiniteChainStyle() + @test GeometryStyle(FiniteMPOHamiltonian) == FiniteChainStyle() + @test GeometryStyle(InfiniteMPO) == InfiniteChainStyle() + @test GeometryStyle(InfiniteMPOHamiltonian) == InfiniteChainStyle() end end diff --git a/test/states.jl b/test/states.jl index 450aa2eff..3bac09af6 100644 --- a/test/states.jl +++ b/test/states.jl @@ -9,7 +9,7 @@ module TestStates using Test, TestExtras using MPSKit using MPSKit: _transpose_front, _transpose_tail - using MPSKit: GeometryStyle, FiniteStyle, InfiniteStyle, WindowStyle + using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, WindowChainStyle using MPSKit: TransferMatrix using TensorKit using TensorKit: ℙ @@ -29,8 +29,8 @@ module TestStates @test isfinite(ψ) @test isfinite(typeof(ψ)) @test isfinite(ψ) == isfinite(typeof(ψ)) - @test GeometryStyle(typeof(ψ)) == FiniteStyle() - @test GeometryStyle(ψ) == FiniteStyle() + @test GeometryStyle(typeof(ψ)) == FiniteChainStyle() + @test GeometryStyle(ψ) == FiniteChainStyle() @test @constinferred physicalspace(ψ) == fill(d, L) @test all(x -> x ≾ D, @constinferred left_virtualspace(ψ)) @test all(x -> x ≾ D, @constinferred right_virtualspace(ψ)) @@ -111,8 +111,8 @@ module TestStates @test !isfinite(typeof(ψ)) @test !isfinite(ψ) @test isfinite(ψ) == isfinite(typeof(ψ)) - @test GeometryStyle(typeof(ψ)) == InfiniteStyle() - @test GeometryStyle(ψ) == InfiniteStyle() + @test GeometryStyle(typeof(ψ)) == InfiniteChainStyle() + @test GeometryStyle(ψ) == InfiniteChainStyle() @test eltype(ψ) == eltype(typeof(ψ)) @@ -147,8 +147,8 @@ module TestStates ]; tol ) - @test GeometryStyle(typeof(ψ)) == InfiniteStyle() - @test GeometryStyle(ψ) == InfiniteStyle() + @test GeometryStyle(typeof(ψ)) == InfiniteChainStyle() + @test GeometryStyle(ψ) == InfiniteChainStyle() @test !isfinite(typeof(ψ)) @@ -190,8 +190,8 @@ module TestStates # constructor 2 - used to take a "slice" from an infinite mps window_2 = WindowMPS(gs, 10) - @test GeometryStyle(typeof(window_1)) == WindowStyle() - @test GeometryStyle(window_1) == WindowStyle() + @test GeometryStyle(typeof(window_1)) == WindowChainStyle() + @test GeometryStyle(window_1) == WindowChainStyle() @test GeometryStyle(window_1) == GeometryStyle(window_2) @test eltype(window_1) == eltype(typeof(window_1)) @@ -257,8 +257,8 @@ module TestStates ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) - @test GeometryStyle(ϕ₁) == FiniteStyle() - @test GeometryStyle(typeof(ϕ₂)) == FiniteStyle() + @test GeometryStyle(ϕ₁) == FiniteChainStyle() + @test GeometryStyle(typeof(ϕ₂)) == FiniteChainStyle() @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) @@ -298,8 +298,8 @@ module TestStates ϕ₁ = LeftGaugedQP(rand, ψ) ϕ₂ = LeftGaugedQP(rand, ψ) - @test GeometryStyle(ϕ₁) == InfiniteStyle() - @test GeometryStyle(typeof(ϕ₂)) == InfiniteStyle() + @test GeometryStyle(ϕ₁) == InfiniteChainStyle() + @test GeometryStyle(typeof(ϕ₂)) == InfiniteChainStyle() @test @constinferred physicalspace(ϕ₁) == physicalspace(ψ) @test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ) From bb74ee854dcf5ab2af9b8ba19bbbf36a6045a0a7 Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Sat, 15 Nov 2025 07:39:56 -0500 Subject: [PATCH 17/24] implement changes --- src/operators/abstractmpo.jl | 1 + src/states/windowmps.jl | 2 -- src/utility/multiline.jl | 1 + src/utility/styles.jl | 19 ++++++++----------- test/operators.jl | 2 +- test/states.jl | 6 +----- 6 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/operators/abstractmpo.jl b/src/operators/abstractmpo.jl index 4b49d048b..a7305efa9 100644 --- a/src/operators/abstractmpo.jl +++ b/src/operators/abstractmpo.jl @@ -11,6 +11,7 @@ abstract type AbstractMPO{O} <: AbstractVector{O} end const SparseMPO{O <: SparseBlockTensorMap} = AbstractMPO{O} # By default, define things in terms of parent +Base.isfinite(mpo::AbstractMPO) = isfinite(typeof(mpo)) Base.size(mpo::AbstractMPO, args...) = size(parent(mpo), args...) Base.length(mpo::AbstractMPO) = length(parent(mpo)) eachsite(mpo::AbstractMPO) = eachindex(mpo) diff --git a/src/states/windowmps.jl b/src/states/windowmps.jl index 2ee5297f6..39d5e4a42 100644 --- a/src/states/windowmps.jl +++ b/src/states/windowmps.jl @@ -50,8 +50,6 @@ struct WindowMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractFiniteMPS end end -GeometryStyle(::Type{<:WindowMPS}) = WindowChainStyle() - #=========================================================================================== Constructors ===========================================================================================# diff --git a/src/utility/multiline.jl b/src/utility/multiline.jl index 3bab8c35f..a1c861ff1 100644 --- a/src/utility/multiline.jl +++ b/src/utility/multiline.jl @@ -29,6 +29,7 @@ function Base.axes(m::Multiline, i::Int) i == 2 ? axes(parent(m)[1], 1) : throw(ArgumentError("Invalid index $i")) end Base.eachindex(m::Multiline) = CartesianIndices(size(m)) +Base.isfinite(m::Multiline) = isfinite(typeof(m)) eachsite(m::Multiline) = eachsite(first(parent(m))) diff --git a/src/utility/styles.jl b/src/utility/styles.jl index f91760d5a..84dd547bf 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -1,15 +1,14 @@ """ -`OperatorStyle` + abstract type OperatorStyle end Holy trait used as a dispatch tag for operator representations. Concrete subtypes (`MPOStyle` and `HamiltonianStyle`) indicate -whether an operator is stored as an MPO or as a Hamiltonian. -Use `OperatorStyle` in method signatures to select implementation- -specific code paths for different operator types. +whether an operator represents a Hamiltonian operator (sum of terms) +or a transfer matrix (product of factors). To opt a custom operator type into this dispatch scheme implement: ```julia -OperatorStyle(::T) where {T<:YourOperatorType} +OperatorStyle(::T) where {T <: YourOperatorType} ``` """ abstract type OperatorStyle end @@ -21,17 +20,16 @@ struct HamiltonianStyle <: OperatorStyle end """ -`GeometryStyle` + abstract type GeometryStyle end Holy trait used as a dispatch tag to distinguish between different geometries Concrete subtypes -(`FiniteChainStyle`, `InfiniteChainStyle` and `WindowChainStyle`) indicate whether a system is -finite, infinite or a finite window in an infinite chain. Use `GeometryStyle` in method signatures to -select implementation-specific code paths for different types. +(`FiniteChainStyle`, `InfiniteChainStyle`) indicate whether a system is +a finite or infinite chain. To opt a custom type into this dispatch scheme implement: ```julia -GeometryStyle(::T) where {T<:YourType} +GeometryStyle(::T) where {T <: YourType} ``` """ abstract type GeometryStyle end @@ -40,4 +38,3 @@ GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverf struct FiniteChainStyle <: GeometryStyle end struct InfiniteChainStyle <: GeometryStyle end -struct WindowChainStyle <: GeometryStyle end diff --git a/test/operators.jl b/test/operators.jl index 490200860..b2390437d 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -10,7 +10,7 @@ module TestOperators using MPSKit using MPSKit: _transpose_front, _transpose_tail, C_hamiltonian, AC_hamiltonian, AC2_hamiltonian - using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, WindowChainStyle, OperatorStyle, MPOStyle, + using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, OperatorStyle, MPOStyle, HamiltonianStyle using TensorKit using TensorKit: ℙ diff --git a/test/states.jl b/test/states.jl index 3bac09af6..3bed6207f 100644 --- a/test/states.jl +++ b/test/states.jl @@ -9,7 +9,7 @@ module TestStates using Test, TestExtras using MPSKit using MPSKit: _transpose_front, _transpose_tail - using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, WindowChainStyle + using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle using MPSKit: TransferMatrix using TensorKit using TensorKit: ℙ @@ -190,10 +190,6 @@ module TestStates # constructor 2 - used to take a "slice" from an infinite mps window_2 = WindowMPS(gs, 10) - @test GeometryStyle(typeof(window_1)) == WindowChainStyle() - @test GeometryStyle(window_1) == WindowChainStyle() - @test GeometryStyle(window_1) == GeometryStyle(window_2) - @test eltype(window_1) == eltype(typeof(window_1)) P = @constinferred physicalspace(window_2) From 692f895260c66b13a9d7fca76dd377f93689ebfc Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Sat, 15 Nov 2025 07:41:44 -0500 Subject: [PATCH 18/24] remove unnecessary Base.isfinite definitions, because it is already defined for AbstractMPO --- src/operators/mpo.jl | 1 - src/operators/mpohamiltonian.jl | 1 - 2 files changed, 2 deletions(-) diff --git a/src/operators/mpo.jl b/src/operators/mpo.jl index f08731f43..58b7e2ecf 100644 --- a/src/operators/mpo.jl +++ b/src/operators/mpo.jl @@ -16,7 +16,6 @@ end Matrix Product Operator (MPO) acting on a finite tensor product space with a linear order. """ const FiniteMPO{O} = MPO{O, Vector{O}} -Base.isfinite(O::MPO) = isfinite(typeof(O)) Base.isfinite(::Type{<:FiniteMPO}) = true GeometryStyle(::Type{<:FiniteMPO}) = FiniteChainStyle() OperatorStyle(::Type{<:MPO}) = MPOStyle() diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 40350bcbe..aa7c4004e 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -31,7 +31,6 @@ operators in a form that is compatible with this constructor. struct MPOHamiltonian{TO <: JordanMPOTensor, V <: AbstractVector{TO}} <: AbstractMPO{TO} W::V end -Base.isfinite(mpo::MPOHamiltonian) = isfinite(typeof(mpo)) OperatorStyle(::Type{<:MPOHamiltonian}) = HamiltonianStyle() const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}} From 38db5da7ea3d64477930153cc857b14fad8ade04 Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Sat, 15 Nov 2025 07:46:06 -0500 Subject: [PATCH 19/24] fix braille tests --- test/other.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/other.jl b/test/other.jl index b8644c89e..baae292e5 100644 --- a/test/other.jl +++ b/test/other.jl @@ -74,14 +74,20 @@ module TestMiscellaneous buffer = IOBuffer() braille(buffer, H) output = String(take!(buffer)) - check = "... 🭻⎡⠉⢈⎤🭻 ...\n ⎣⠀⢀⎦ \n" + check = """ + ... 🭻⎡⠉⢈⎤🭻 ... + ⎣⠀⢀⎦ + """ @test output == check O = make_time_mpo(H, 1.0, TaylorCluster(3, false, false)) braille(buffer, O) output = String(take!(buffer)) - check = "... 🭻⎡⡏⠉⠛⠟⎤🭻 ...\n ⎣⡇⠀⠀⡂⎦ \n" + check = """ + ... 🭻⎡⡏⠉⠛⠟⎤🭻 ... + ⎣⡇⠀⠀⡂⎦ + """ @test output == check From 5d1f975b8b5a79f05e00a1b3ad993acfce6e598d Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Mon, 17 Nov 2025 10:28:22 -0500 Subject: [PATCH 20/24] addd --- src/MPSKit.jl | 6 ++++-- src/operators/abstractmpo.jl | 2 +- src/states/abstractmps.jl | 4 ++-- src/states/quasiparticle_state.jl | 1 - src/states/windowmps.jl | 2 +- test/other.jl | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/MPSKit.jl b/src/MPSKit.jl index 59b7cd968..063b2d522 100644 --- a/src/MPSKit.jl +++ b/src/MPSKit.jl @@ -97,13 +97,15 @@ include("utility/logging.jl") using .IterativeLoggers include("utility/iterativesolvers.jl") +include("utility/styles.jl") include("utility/periodicarray.jl") include("utility/windowarray.jl") +include("utility/multiline.jl") include("utility/utility.jl") # random utility functions include("utility/plotting.jl") include("utility/linearcombination.jl") -include("utility/styles.jl") -include("utility/multiline.jl") + + # maybe we should introduce an abstract state type include("states/abstractmps.jl") diff --git a/src/operators/abstractmpo.jl b/src/operators/abstractmpo.jl index a7305efa9..2633aa1c0 100644 --- a/src/operators/abstractmpo.jl +++ b/src/operators/abstractmpo.jl @@ -9,9 +9,9 @@ abstract type AbstractMPO{O} <: AbstractVector{O} end # useful union types const SparseMPO{O <: SparseBlockTensorMap} = AbstractMPO{O} +Base.isfinite(mpo::AbstractMPO) = isfinite(typeof(mpo)) # By default, define things in terms of parent -Base.isfinite(mpo::AbstractMPO) = isfinite(typeof(mpo)) Base.size(mpo::AbstractMPO, args...) = size(parent(mpo), args...) Base.length(mpo::AbstractMPO) = length(parent(mpo)) eachsite(mpo::AbstractMPO) = eachindex(mpo) diff --git a/src/states/abstractmps.jl b/src/states/abstractmps.jl index 09ae8ef08..5c1e82c1d 100644 --- a/src/states/abstractmps.jl +++ b/src/states/abstractmps.jl @@ -15,7 +15,7 @@ const MPSTensor{S} = GenericMPSTensor{S, 2} # the usual mps tensors on which we """ MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int]) - MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, + MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace} Construct an `MPSTensor` with given physical and virtual spaces. @@ -202,7 +202,7 @@ TensorKit.sectortype(ψtype::Type{<:AbstractMPS}) = sectortype(site_type(ψtype) """ left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)]) - + Return the virtual space of the bond to the left of sites `pos`. !!! warning diff --git a/src/states/quasiparticle_state.jl b/src/states/quasiparticle_state.jl index 83272df5c..6fd61f30e 100644 --- a/src/states/quasiparticle_state.jl +++ b/src/states/quasiparticle_state.jl @@ -208,7 +208,6 @@ end # gauge independent code const QP{S, T1, T2} = Union{LeftGaugedQP{S, T1, T2}, RightGaugedQP{S, T1, T2}} -# TODO: Remove FiniteQP and InfiniteQP in favor of styles. const FiniteQP{S <: FiniteMPS, T1, T2} = QP{S, T1, T2} const InfiniteQP{S <: InfiniteMPS, T1, T2} = QP{S, T1, T2} const MultilineQP{Q <: QP} = Multiline{Q} diff --git a/src/states/windowmps.jl b/src/states/windowmps.jl index 39d5e4a42..5c0bab9d0 100644 --- a/src/states/windowmps.jl +++ b/src/states/windowmps.jl @@ -20,7 +20,7 @@ Type that represents a finite Matrix Product State embedded in an infinte Matrix [right_gs::InfiniteMPS]) WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}}, maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS]) - + Construct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of [`FiniteMPS`](@ref), followed by a diff --git a/test/other.jl b/test/other.jl index baae292e5..b33891038 100644 --- a/test/other.jl +++ b/test/other.jl @@ -76,7 +76,7 @@ module TestMiscellaneous output = String(take!(buffer)) check = """ ... 🭻⎡⠉⢈⎤🭻 ... - ⎣⠀⢀⎦ + ⎣⠀⢀⎦ """ @test output == check @@ -86,7 +86,7 @@ module TestMiscellaneous output = String(take!(buffer)) check = """ ... 🭻⎡⡏⠉⠛⠟⎤🭻 ... - ⎣⡇⠀⠀⡂⎦ + ⎣⡇⠀⠀⡂⎦ """ @test output == check From abcf6a699e4b651d7d7aace582841e8ac92d34f5 Mon Sep 17 00:00:00 2001 From: AFeuerpfeil Date: Mon, 17 Nov 2025 10:29:37 -0500 Subject: [PATCH 21/24] revert unnecessary changes --- src/operators/abstractmpo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operators/abstractmpo.jl b/src/operators/abstractmpo.jl index 2633aa1c0..29f40ac1f 100644 --- a/src/operators/abstractmpo.jl +++ b/src/operators/abstractmpo.jl @@ -9,7 +9,7 @@ abstract type AbstractMPO{O} <: AbstractVector{O} end # useful union types const SparseMPO{O <: SparseBlockTensorMap} = AbstractMPO{O} -Base.isfinite(mpo::AbstractMPO) = isfinite(typeof(mpo)) +Base.isfinite(O::AbstractMPO) = isfinite(typeof(O)) # By default, define things in terms of parent Base.size(mpo::AbstractMPO, args...) = size(parent(mpo), args...) From 0718f63432b4c0d21bc032c180708c9311d4abde Mon Sep 17 00:00:00 2001 From: Lukas Devos Date: Mon, 17 Nov 2025 13:01:59 -0500 Subject: [PATCH 22/24] update style docs --- src/utility/styles.jl | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/utility/styles.jl b/src/utility/styles.jl index 84dd547bf..97c14e68e 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -1,15 +1,11 @@ """ - abstract type OperatorStyle end + abstract type OperatorStyle + OperatorStyle(x) + OperatorStyle(::Type{T}) -Holy trait used as a dispatch tag for operator representations. -Concrete subtypes (`MPOStyle` and `HamiltonianStyle`) indicate -whether an operator represents a Hamiltonian operator (sum of terms) -or a transfer matrix (product of factors). - -To opt a custom operator type into this dispatch scheme implement: -```julia -OperatorStyle(::T) where {T <: YourOperatorType} -``` +Trait to describe the operator behavior of the input `x` or type `T`, which can be either +* `MPOStyle()`: product of local factors; +* `HamiltonianStyle()`: sum of local terms. """ abstract type OperatorStyle end OperatorStyle(x) = OperatorStyle(typeof(x)) @@ -18,19 +14,18 @@ OperatorStyle(T::Type) = throw(MethodError(OperatorStyle, T)) # avoid stackoverf struct MPOStyle <: OperatorStyle end struct HamiltonianStyle <: OperatorStyle end +@doc (@doc OperatorStyle) MPOStyle +@doc (@doc OperatorStyle) HamiltonianStyle """ - abstract type GeometryStyle end + abstract type GeometryStyle + GeometryStyle(x) + GeometryStyle(::Type{T}) -Holy trait used as a dispatch tag to distinguish between different -geometries Concrete subtypes -(`FiniteChainStyle`, `InfiniteChainStyle`) indicate whether a system is -a finite or infinite chain. +Trait to describe the geometry of the input `x` or type `T`, which can be either -To opt a custom type into this dispatch scheme implement: -```julia -GeometryStyle(::T) where {T <: YourType} -``` +* `FiniteChainStyle()`: object is defined on a finite chain; +* `InfiniteChainStyle()`: object is defined on an infinite chain. """ abstract type GeometryStyle end GeometryStyle(x) = GeometryStyle(typeof(x)) @@ -38,3 +33,6 @@ GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverf struct FiniteChainStyle <: GeometryStyle end struct InfiniteChainStyle <: GeometryStyle end + +@doc (@doc GeometryStyle) FiniteChainStyle +@doc (@doc GeometryStyle) InfiniteChainStyle From ffc50d5d58fa9b98158cff0d6cd2c5d74a3b6e3a Mon Sep 17 00:00:00 2001 From: Lukas Devos Date: Mon, 17 Nov 2025 13:02:42 -0500 Subject: [PATCH 23/24] fix formatting --- src/utility/styles.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utility/styles.jl b/src/utility/styles.jl index 97c14e68e..104b4e562 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -23,7 +23,6 @@ struct HamiltonianStyle <: OperatorStyle end GeometryStyle(::Type{T}) Trait to describe the geometry of the input `x` or type `T`, which can be either - * `FiniteChainStyle()`: object is defined on a finite chain; * `InfiniteChainStyle()`: object is defined on an infinite chain. """ From 776748bfd2f01a38c54de9d1a95d190cf42f05de Mon Sep 17 00:00:00 2001 From: Lukas Devos Date: Mon, 17 Nov 2025 13:03:54 -0500 Subject: [PATCH 24/24] more formatting --- src/MPSKit.jl | 2 -- test/other.jl | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/MPSKit.jl b/src/MPSKit.jl index 063b2d522..cd465643d 100644 --- a/src/MPSKit.jl +++ b/src/MPSKit.jl @@ -105,8 +105,6 @@ include("utility/utility.jl") # random utility functions include("utility/plotting.jl") include("utility/linearcombination.jl") - - # maybe we should introduce an abstract state type include("states/abstractmps.jl") include("states/infinitemps.jl") diff --git a/test/other.jl b/test/other.jl index b33891038..17b3138fe 100644 --- a/test/other.jl +++ b/test/other.jl @@ -78,7 +78,6 @@ module TestMiscellaneous ... 🭻⎡⠉⢈⎤🭻 ... ⎣⠀⢀⎦ """ - @test output == check O = make_time_mpo(H, 1.0, TaylorCluster(3, false, false)) @@ -88,7 +87,6 @@ module TestMiscellaneous ... 🭻⎡⡏⠉⠛⠟⎤🭻 ... ⎣⡇⠀⠀⡂⎦ """ - @test output == check # Finite Hamiltonians and MPOs