Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fa91804
add styles
AFeuerpfeil Nov 12, 2025
1334fcb
start rewrite
AFeuerpfeil Nov 12, 2025
140005f
start defining the styles
AFeuerpfeil Nov 13, 2025
bd6ccdf
implement styles for states and operators and add tests
AFeuerpfeil Nov 14, 2025
5be03c3
Merge pull request #1 from AFeuerpfeil/pr-mpo-styles
AFeuerpfeil Nov 14, 2025
0896113
add include styles
AFeuerpfeil Nov 14, 2025
6350c96
fix InfiniteMPO test
AFeuerpfeil Nov 14, 2025
50793bf
dispatch styles on type and rename IsfiniteStyle to GeometryStyle
AFeuerpfeil Nov 14, 2025
7226788
readd Base.isfinite for AbstractMPS, MPO and MPOHamiltonian
AFeuerpfeil Nov 14, 2025
c206de8
add tests for styles of types
AFeuerpfeil Nov 14, 2025
07f579c
fix include order
AFeuerpfeil Nov 14, 2025
d278a3a
fix OperatorStyle for MPOHamiltonian
AFeuerpfeil Nov 14, 2025
ea5366c
Add WindowStyle and increase code coverage
AFeuerpfeil Nov 14, 2025
18b5ef2
fix test and hopefully also runic
AFeuerpfeil Nov 14, 2025
5af3060
more tests
AFeuerpfeil Nov 14, 2025
8f72c21
fix other tests
AFeuerpfeil Nov 14, 2025
9b7905c
make GeometryStyle names more descriptive
AFeuerpfeil Nov 15, 2025
bb74ee8
implement changes
AFeuerpfeil Nov 15, 2025
692f895
remove unnecessary Base.isfinite definitions, because it is already d…
AFeuerpfeil Nov 15, 2025
38db5da
fix braille tests
AFeuerpfeil Nov 15, 2025
5d1f975
addd
AFeuerpfeil Nov 17, 2025
abcf6a6
revert unnecessary changes
AFeuerpfeil Nov 17, 2025
0718f63
update style docs
lkdvos Nov 17, 2025
ffc50d5
fix formatting
lkdvos Nov 17, 2025
776748b
more formatting
lkdvos Nov 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/MPSKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ 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")
Expand Down
3 changes: 3 additions & 0 deletions src/operators/mpo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
GeometryStyle(::Type{<:FiniteMPO}) = FiniteChainStyle()
OperatorStyle(::Type{<:MPO}) = MPOStyle()

function FiniteMPO(Os::AbstractVector{O}) where {O}
for i in eachindex(Os)[1:(end - 1)]
Expand All @@ -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
GeometryStyle(::Type{<:InfiniteMPO}) = InfiniteChainStyle()

function InfiniteMPO(Os::AbstractVector{O}) where {O}
for i in eachindex(Os)
Expand Down
3 changes: 3 additions & 0 deletions src/operators/mpohamiltonian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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(::Type{<:MPOHamiltonian}) = HamiltonianStyle()

const FiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, Vector{O}}
Base.isfinite(::Type{<:FiniteMPOHamiltonian}) = true
GeometryStyle(::Type{<:FiniteMPOHamiltonian}) = FiniteChainStyle()

function FiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor}
for i in eachindex(Ws)[1:(end - 1)]
Expand All @@ -45,6 +47,7 @@ end

const InfiniteMPOHamiltonian{O <: MPOTensor} = MPOHamiltonian{O, PeriodicVector{O}}
Base.isfinite(::Type{<:InfiniteMPOHamiltonian}) = false
GeometryStyle(::Type{<:InfiniteMPOHamiltonian}) = InfiniteChainStyle()

function InfiniteMPOHamiltonian(Ws::AbstractVector{O}) where {O <: MPOTensor}
for i in eachindex(Ws)
Expand Down
1 change: 1 addition & 0 deletions src/states/abstractmps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 2 additions & 1 deletion src/states/finitemps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +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
Base.isfinite(::Type{<:FiniteMPS}) = true
GeometryStyle(::Type{<:FiniteMPS}) = FiniteChainStyle()

Base.eachindex(ψ::FiniteMPS) = eachindex(ψ.AL)
Base.eachindex(l::IndexStyle, ψ::FiniteMPS) = eachindex(l, ψ.AL)
Expand Down
3 changes: 2 additions & 1 deletion src/states/infinitemps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +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
Base.isfinite(::Type{<:InfiniteMPS}) = false
GeometryStyle(::Type{<:InfiniteMPS}) = InfiniteChainStyle()

Base.copy(ψ::InfiniteMPS) = InfiniteMPS(copy(ψ.AL), copy(ψ.AR), copy(ψ.C), copy(ψ.AC))
function Base.copy!(ψ::InfiniteMPS, ϕ::InfiniteMPS)
Expand Down
2 changes: 1 addition & 1 deletion src/states/multilinemps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +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
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)
Expand Down
2 changes: 2 additions & 0 deletions src/states/quasiparticle_state.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,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)

Expand Down
7 changes: 7 additions & 0 deletions src/utility/multiline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)))

Expand All @@ -54,6 +55,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)
Expand Down
37 changes: 37 additions & 0 deletions src/utility/styles.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
abstract type OperatorStyle
OperatorStyle(x)
OperatorStyle(::Type{T})

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))
OperatorStyle(T::Type) = throw(MethodError(OperatorStyle, T)) # avoid stackoverflow if not defined

struct MPOStyle <: OperatorStyle end
struct HamiltonianStyle <: OperatorStyle end

@doc (@doc OperatorStyle) MPOStyle
@doc (@doc OperatorStyle) HamiltonianStyle

"""
abstract type GeometryStyle
GeometryStyle(x)
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.
"""
abstract type GeometryStyle end
GeometryStyle(x) = GeometryStyle(typeof(x))
GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverflow if not defined

struct FiniteChainStyle <: GeometryStyle end
struct InfiniteChainStyle <: GeometryStyle end

@doc (@doc GeometryStyle) FiniteChainStyle
@doc (@doc GeometryStyle) InfiniteChainStyle
39 changes: 39 additions & 0 deletions test/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module TestOperators
using MPSKit
using MPSKit: _transpose_front, _transpose_tail, C_hamiltonian, AC_hamiltonian,
AC2_hamiltonian
using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, OperatorStyle, MPOStyle,
HamiltonianStyle
using TensorKit
using TensorKit: ℙ
using VectorInterface: One
Expand All @@ -32,6 +34,13 @@ module TestOperators
mpo₂ = FiniteMPO(O₂)
mpo₃ = FiniteMPO(O₃)

@test isfinite(mpo₁)
@test isfinite(typeof(mpo₁))
@test GeometryStyle(typeof(mpo₁)) == FiniteChainStyle()
@test GeometryStyle(mpo₁) == FiniteChainStyle()
@test OperatorStyle(typeof(mpo₁)) == MPOStyle()


@test @constinferred physicalspace(mpo₁) == fill(V, L)
Vleft = @constinferred left_virtualspace(mpo₁)
Vright = @constinferred right_virtualspace(mpo₂)
Expand Down Expand Up @@ -81,6 +90,22 @@ module TestOperators
end
end

@testset "InfiniteMPO" begin
P = ℂ^2
T = Float64

H1 = randn(T, P ← P)
H1 += H1'
H = InfiniteMPO([H1])

@test !isfinite(H)
@test !isfinite(typeof(H))
@test GeometryStyle(typeof(H)) == InfiniteChainStyle()
@test GeometryStyle(H) == InfiniteChainStyle()
@test OperatorStyle(typeof(H)) == MPOStyle()
@test OperatorStyle(H) == MPOStyle()
end

@testset "MPOHamiltonian constructors" begin
P = ℂ^2
T = Float64
Expand Down Expand Up @@ -109,6 +134,13 @@ 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)) == FiniteChainStyle()
@test GeometryStyle(H) == FiniteChainStyle()
@test OperatorStyle(typeof(H)) == HamiltonianStyle()
@test OperatorStyle(H) == HamiltonianStyle()

# Infinite
Ws = [Wmid]
H = InfiniteMPOHamiltonian(
Expand All @@ -119,6 +151,13 @@ 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)) == InfiniteChainStyle()
@test GeometryStyle(H) == InfiniteChainStyle()
@test OperatorStyle(typeof(H)) == HamiltonianStyle()
@test OperatorStyle(H) == HamiltonianStyle()
end

@testset "Finite MPOHamiltonian" begin
Expand Down
20 changes: 20 additions & 0 deletions test/other.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module TestMiscellaneous
using ..TestSetup
using Test, TestExtras
using MPSKit
using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle, OperatorStyle, MPOStyle,
HamiltonianStyle
using TensorKit
using TensorKit: ℙ
using Plots
Expand Down Expand Up @@ -101,4 +103,22 @@ 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)

@test OperatorStyle(MPO) == MPOStyle()
@test OperatorStyle(InfiniteMPO) == MPOStyle()

@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
31 changes: 31 additions & 0 deletions test/states.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module TestStates
using Test, TestExtras
using MPSKit
using MPSKit: _transpose_front, _transpose_tail
using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle
using MPSKit: TransferMatrix
using TensorKit
using TensorKit: ℙ
Expand All @@ -24,11 +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(ψ)) == 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(ψ))

@test eltype(ψ) == eltype(typeof(ψ))

ovl = dot(ψ, ψ)

@test ovl ≈ norm(ψ.AC[1])^2
Expand Down Expand Up @@ -100,7 +108,14 @@ module TestStates

ψ = InfiniteMPS([rand(elt, D * d, D), rand(elt, D * d, D)]; tol)

@test !isfinite(typeof(ψ))
@test !isfinite(ψ)
@test isfinite(ψ) == isfinite(typeof(ψ))
@test GeometryStyle(typeof(ψ)) == InfiniteChainStyle()
@test GeometryStyle(ψ) == InfiniteChainStyle()

@test eltype(ψ) == eltype(typeof(ψ))

@test physicalspace(ψ) == fill(d, 2)
@test all(x -> x ≾ D, left_virtualspace(ψ))
@test all(x -> x ≾ D, right_virtualspace(ψ))
Expand Down Expand Up @@ -132,6 +147,11 @@ module TestStates
]; tol
)

@test GeometryStyle(typeof(ψ)) == InfiniteChainStyle()
@test GeometryStyle(ψ) == InfiniteChainStyle()

@test !isfinite(typeof(ψ))

@test physicalspace(ψ) == fill(d, 2, 2)
@test all(x -> x ≾ D, left_virtualspace(ψ))
@test all(x -> x ≾ D, right_virtualspace(ψ))
Expand Down Expand Up @@ -170,6 +190,8 @@ module TestStates
# constructor 2 - used to take a "slice" from an infinite mps
window_2 = WindowMPS(gs, 10)

@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)
Expand Down Expand Up @@ -231,9 +253,13 @@ module TestStates
ϕ₁ = LeftGaugedQP(rand, ψ)
ϕ₂ = LeftGaugedQP(rand, ψ)

@test GeometryStyle(ϕ₁) == FiniteChainStyle()
@test GeometryStyle(typeof(ϕ₂)) == FiniteChainStyle()

@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)
Expand Down Expand Up @@ -262,10 +288,15 @@ 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, ψ)

@test GeometryStyle(ϕ₁) == InfiniteChainStyle()
@test GeometryStyle(typeof(ϕ₂)) == InfiniteChainStyle()

@test @constinferred physicalspace(ϕ₁) == physicalspace(ψ)
@test @constinferred left_virtualspace(ϕ₁) == left_virtualspace(ψ)
@test @constinferred right_virtualspace(ϕ₁) == right_virtualspace(ψ)
Expand Down