Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "BlockTensorKit"
uuid = "5f87ffc2-9cf1-4a46-8172-465d160bd8cd"
version = "0.3.18"
version = "0.3.19"
authors = ["Lukas Devos <ldevos98@gmail.com> and contributors"]

[deps]
Expand Down Expand Up @@ -36,7 +36,7 @@ MatrixAlgebraKit = "0.6"
Random = "1"
SafeTestsets = "0.1"
Strided = "2.3.3"
TensorKit = "0.17"
TensorKit = "0.17.2"
TensorOperations = "5"
Test = "1"
TestExtras = "0.2, 0.3"
Expand Down
12 changes: 12 additions & 0 deletions src/vectorspaces/sumspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,18 @@ function TensorKit.rightunitspace(S::SumSpace)
end
TensorKit.isunitspace(S::SumSpace) = !isempty(S) && all(isunitspace, S.spaces)

# a `SumSpace` must, as a whole, be homogeneously colored: all of its sectors (across all
# components) share a single left and right unit, exactly like a plain `GradedSpace`.
function TK._leftrightunit(S::SumSpace)
s = sectors(S)
isempty(s) && return (nothing, nothing)
c = first(s)
l, r = TK.leftunit(c), TK.rightunit(c)
all(x -> TK.leftunit(x) == l && TK.rightunit(x) == r, s) ||
throw(SpaceMismatch(lazy"components of $S do not share a single left and right unit"))
return (l, r)
end

# Promotion and conversion
# ------------------------
Base.promote_rule(::Type{S}, ::Type{SumSpace{S}}) where {S <: ElementarySpace} = SumSpace{S}
Expand Down
44 changes: 26 additions & 18 deletions test/vectorspaces/sumspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ end
using Test, TestExtras

using TensorKit: hassector
using BlockTensorKit: ⊕

I = IsingBimodule

Expand All @@ -186,7 +185,9 @@ end
@test @constinferred(dual(V)) == @constinferred(conj(V)) == @constinferred(adjoint(V))
@test field(V) == ℂ

@test unitspace(V) == unitspace(V1)
@test_throws ArgumentError unitspace(V1)
@test_throws ArgumentError unitspace(V)
@test_throws ArgumentError unitspace(SumSpace(V1))

@test @constinferred(sectortype(V)) == sectortype(V1)
@test ((@constinferred sectors(V))...,) == (C0, C1, M, D0, D1) # sorted order
Expand All @@ -208,20 +209,26 @@ end
for W in [WC, WD]
@test isunitspace(W)
@test W == @constinferred(leftunitspace(W)) == @constinferred(rightunitspace(W))
@test unitspace(typeof(W)) == ⊞(Vect[IsingBimodule]((1, 1, 0) => 1, (2, 2, 0) => 1))
@test_throws ArgumentError unitspace(typeof(W))
end

@test_throws ArgumentError leftunitspace(V)
@test_throws ArgumentError rightunitspace(V)
@test leftunitspace(SumSpace(V1, V3)) == WC
@test rightunitspace(SumSpace(V2, V3)) == WD
# a `SumSpace` is only well-defined as a single left/right unit when ALL of its
# components, taken together, are homogeneously colored -- exactly like a plain
# `GradedSpace`. Combinations that mix components with different left and/or right
# units are rejected, even if they happen to agree on one side.
@test_throws SpaceMismatch leftunitspace(V)
@test_throws SpaceMismatch rightunitspace(V)
@test_throws SpaceMismatch leftunitspace(SumSpace(V1, V3))
@test_throws SpaceMismatch rightunitspace(SumSpace(V2, V3))
@test leftunitspace(WMop) == WD && rightunitspace(WMop) == WC
@test leftunitspace(WM) == WC && rightunitspace(WM) == WD
@test unitspace(WM) == unitspace(WMop) == ⊞(Vect[IsingBimodule]((1, 1, 0) => 1, (2, 2, 0) => 1))
@test_throws ArgumentError unitspace(WM)
@test_throws ArgumentError unitspace(WMop)

Wempty = SumSpace(Vect[I]())
Wzero = zerospace(V)
@test unitspace(Wempty) == unitspace(Wzero)
@test_throws ArgumentError unitspace(Wempty)
@test_throws ArgumentError unitspace(Wzero)
for f in (leftunitspace, rightunitspace)
@test_throws ArgumentError f(Wempty)
end
Expand All @@ -231,9 +238,9 @@ end
VMD = SumSpace(V2, V3)

@test @constinferred(⊞(V, V)) == SumSpace(vcat(V.spaces, V.spaces))
@test @constinferred(⊞(VCM, unitspace(VCM))) == SumSpace(vcat(VCM.spaces, unitspace(VCM).spaces))
@test @constinferred(⊞(VCM, leftunitspace(VCM))) == SumSpace(vcat(VCM.spaces, leftunitspace(VCM).spaces))
@test @constinferred(⊞(VMD, rightunitspace(VMD))) == SumSpace(vcat(VMD.spaces, rightunitspace(VMD).spaces))
@test_throws ArgumentError unitspace(VCM)
@test_throws SpaceMismatch leftunitspace(VCM)
@test_throws SpaceMismatch rightunitspace(VMD)

@test @constinferred(⊞(V, V, V, V)) == SumSpace(repeat(V.spaces, 4))
@test @constinferred(fuse(VC, VC)) ≅ SumSpace(Vect[I](C0 => 8, C1 => 8))
Expand All @@ -243,18 +250,19 @@ end
@test flip(V) ≅ V
@test flip(V) ≾ V
@test flip(V) ≿ V
@test V ≺ ⊕(V, V)
@test !(V ≻ ⊕(V, V))
@test V ≺ ⊞(V, V)
@test !(V ≻ ⊞(V, V))

# blocksectors tests
@test issetequal(@constinferred(blocksectors(one(V) ← one(V))), (C0, D0))
@test issetequal(@constinferred(blocksectors(V ← V)), sectors(V))
@test_throws SpaceMismatch V ← V # `V` itself is not homogeneously colored
@test @constinferred(blocksectors(one(V))) == [C0, D0]
for v in [VC, VCM, VMD]
@test issetequal(@constinferred(blocksectors(v^2)), blocksectors(v ← v))
@test issetequal(@constinferred(blocksectors(VC^2)), blocksectors(VC ← VC))
for v in [VCM, VMD]
@test_throws SpaceMismatch v^2 # not homogeneously colored
end
for v in [WM, WMop]
@test isempty(@constinferred(blocksectors(v^2)))
@test_throws SpaceMismatch v^2
@test issetequal(@constinferred(blocksectors(v ← v)), blocksectors(v))
end
end
Loading