diff --git a/Project.toml b/Project.toml index 134b04f..40ba612 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SymmetrySectors" uuid = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e" authors = ["ITensor developers and contributors"] -version = "0.1.5" +version = "0.2.0" [deps] BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" @@ -11,7 +11,7 @@ LabelledNumbers = "f856a3a6-4152-4ec4-b2a7-02c1a55d7993" [compat] BlockArrays = "1.2.0" -GradedUnitRanges = "0.1.1" +GradedUnitRanges = "0.2.0" HalfIntegers = "1.6.0" LabelledNumbers = "0.1.0" julia = "1.10" diff --git a/src/SymmetrySectors.jl b/src/SymmetrySectors.jl index 64e4591..c637c9e 100644 --- a/src/SymmetrySectors.jl +++ b/src/SymmetrySectors.jl @@ -4,6 +4,8 @@ export U1, Z, dual include("symmetry_style.jl") include("abstractsector.jl") +include("dualsector.jl") + include("sector_definitions/fib.jl") include("sector_definitions/ising.jl") include("sector_definitions/o2.jl") diff --git a/src/dualsector.jl b/src/dualsector.jl new file mode 100644 index 0000000..42bf32f --- /dev/null +++ b/src/dualsector.jl @@ -0,0 +1,68 @@ +# This file defines type DualSector + +using GradedUnitRanges: dual, isdual, nondual, nondual_type + +struct DualSector{NonDualSector<:AbstractSector} <: AbstractSector + nondual::NonDualSector + + function DualSector(s::AbstractSector) + return new{typeof(s)}(s) + end +end + +GradedUnitRanges.nondual(s::DualSector) = s.nondual +GradedUnitRanges.nondual(s::AbstractSector) = s + +# =================================== Base interface ===================================== +function Base.:(==)(s1::DualSector, s2::DualSector) + return ==(nondual(s1), nondual(s2)) +end + +function Base.isless(s1::S, s2::S) where {S<:DualSector} + return isless(nondual(s1), nondual(s2)) +end + +function Base.show(io::IO, s::DualSector) + show(io, nondual(s)) + return print(io, "'") +end + +# ================================ GradedUnitRanges interface ============================ +GradedUnitRanges.dual(s::AbstractSector) = DualSector(s) +GradedUnitRanges.dual(s::DualSector) = nondual(s) + +GradedUnitRanges.dual_type(S::Type{<:AbstractSector}) = DualSector{S} +function GradedUnitRanges.dual_type( + ::Type{<:DualSector{NonDualSector}} +) where {NonDualSector} + return NonDualSector +end + +GradedUnitRanges.flip(s::AbstractSector) = dual(label_dual(s)) +GradedUnitRanges.flip(s::DualSector) = label_dual(nondual(s)) + +GradedUnitRanges.isdual(::Type{<:DualSector}) = true + +GradedUnitRanges.sector_type(DS::Type{<:DualSector}) = nondual_type(DS) + +# ============================= SymmetrySectors interface ================================ +label_dual(s::DualSector) = dual(label_dual(dual(s))) + +SymmetryStyle(DS::Type{<:DualSector}) = SymmetryStyle(nondual_type(DS)) + +function quantum_dimension(::NotAbelianStyle, s::DualSector) + return quantum_dimension(NotAbelianStyle(), nondual(s)) +end + +trivial(DS::Type{<:DualSector}) = trivial(nondual_type(DS)) + +×(s1::DualSector, s2::DualSector) = dual(nondual(s1) × nondual(s2)) +×(s1::DualSector, s2::AbstractSector) = throw("Not implemented") +×(s1::AbstractSector, s2::DualSector) = throw("Not implemented") + +# =============================== Fusion rule interface ================================== +fusion_rule(c1::DualSector, c2::AbstractSector) = fusion_rule(label_dual(nondual(c1)), c2) +fusion_rule(c1::AbstractSector, c2::DualSector) = fusion_rule(c1, label_dual(nondual(c2))) +function fusion_rule(c1::DualSector, c2::DualSector) + return fusion_rule(label_dual(nondual(c1)), label_dual(nondual(c2))) +end diff --git a/src/sector_definitions/fib.jl b/src/sector_definitions/fib.jl index bc90174..3064749 100644 --- a/src/sector_definitions/fib.jl +++ b/src/sector_definitions/fib.jl @@ -21,7 +21,7 @@ end SymmetryStyle(::Type{Fib}) = NotAbelianStyle() -GradedUnitRanges.dual(f::Fib) = f +label_dual(f::Fib) = f sector_label(f::Fib) = f.l diff --git a/src/sector_definitions/ising.jl b/src/sector_definitions/ising.jl index e8b79c6..a7acb44 100644 --- a/src/sector_definitions/ising.jl +++ b/src/sector_definitions/ising.jl @@ -21,7 +21,7 @@ end SymmetryStyle(::Type{Ising}) = NotAbelianStyle() -GradedUnitRanges.dual(i::Ising) = i +label_dual(i::Ising) = i sector_label(i::Ising) = i.l diff --git a/src/sector_definitions/o2.jl b/src/sector_definitions/o2.jl index 34e12a2..0933b71 100644 --- a/src/sector_definitions/o2.jl +++ b/src/sector_definitions/o2.jl @@ -36,7 +36,7 @@ iszero_odd(l::HalfInteger) = l == sector_label(zero_odd(O2)) quantum_dimension(::NotAbelianStyle, s::O2) = 2 - is_zero_even_or_odd(s) -GradedUnitRanges.dual(s::O2) = s +label_dual(s::O2) = s function Base.show(io::IO, s::O2) if iszero_odd(s) diff --git a/src/sector_definitions/su.jl b/src/sector_definitions/su.jl index 83d95b4..ac57f26 100644 --- a/src/sector_definitions/su.jl +++ b/src/sector_definitions/su.jl @@ -43,7 +43,7 @@ function quantum_dimension(::NotAbelianStyle, s::SU) return Int(d) end -function GradedUnitRanges.dual(s::SU) +function label_dual(s::SU) l = sector_label(s) nl = reverse(cumsum((l[begin:(end - 1)] .- l[(begin + 1):end]..., l[end]))) return typeof(s)(nl) @@ -87,7 +87,7 @@ end # optimize implementation quantum_dimension(s::SU{2}) = sector_label(s)[1] + 1 -GradedUnitRanges.dual(s::SU{2}) = s +label_dual(s::SU{2}) = s function label_fusion_rule(::Type{<:SU{2}}, s1, s2) irreps = [SU{2}((i,)) for i in (abs(s1[1] - s2[1])):2:(s1[1] + s2[1])] diff --git a/src/sector_definitions/su2k.jl b/src/sector_definitions/su2k.jl index 3e10ef5..af61307 100644 --- a/src/sector_definitions/su2k.jl +++ b/src/sector_definitions/su2k.jl @@ -11,7 +11,7 @@ end SymmetryStyle(::Type{<:su2}) = NotAbelianStyle() -GradedUnitRanges.dual(s::su2) = s +label_dual(s::su2) = s sector_label(s::su2) = s.j diff --git a/src/sector_definitions/trivial.jl b/src/sector_definitions/trivial.jl index 78af09d..96673ce 100644 --- a/src/sector_definitions/trivial.jl +++ b/src/sector_definitions/trivial.jl @@ -12,7 +12,7 @@ SymmetryStyle(::Type{TrivialSector}) = AbelianStyle() trivial(::Type{TrivialSector}) = TrivialSector() -GradedUnitRanges.dual(::TrivialSector) = TrivialSector() +label_dual(::TrivialSector) = TrivialSector() # TrivialSector acts as trivial on any AbstractSector function fusion_rule(::NotAbelianStyle, ::TrivialSector, c::AbstractSector) @@ -36,6 +36,9 @@ Base.:(==)(c::AbstractSector, ::TrivialSector) = istrivial(c) Base.:(==)(::TrivialSector, c::AbstractSector) = istrivial(c) Base.:(==)(::TrivialSector, ::TrivialSector) = true +Base.:(==)(c::DualSector, ::TrivialSector) = false +Base.:(==)(::TrivialSector, c::DualSector) = false + # sorts as trivial for any Sector Base.isless(c::AbstractSector, ::TrivialSector) = c < trivial(c) Base.isless(::TrivialSector, c::AbstractSector) = trivial(c) < c diff --git a/src/sector_definitions/u1.jl b/src/sector_definitions/u1.jl index 5e030e4..1a80568 100644 --- a/src/sector_definitions/u1.jl +++ b/src/sector_definitions/u1.jl @@ -14,7 +14,7 @@ SymmetryStyle(::Type{<:U1}) = AbelianStyle() sector_label(u::U1) = u.n set_sector_label(s::U1, sector_label) = typeof(s)(sector_label) -GradedUnitRanges.dual(s::U1) = set_sector_label(s, -sector_label(s)) +label_dual(s::U1) = set_sector_label(s, -sector_label(s)) trivial(::Type{U1}) = trivial(U1{Int}) trivial(::Type{U1{T}}) where {T} = U1(zero(T)) diff --git a/src/sector_definitions/zn.jl b/src/sector_definitions/zn.jl index d3446a0..ae4caf9 100644 --- a/src/sector_definitions/zn.jl +++ b/src/sector_definitions/zn.jl @@ -16,7 +16,7 @@ SymmetryStyle(::Type{<:Z}) = AbelianStyle() sector_label(c::Z) = c.m set_sector_label(s::Z, sector_label) = typeof(s)(sector_label) -GradedUnitRanges.dual(s::Z) = set_sector_label(s, -sector_label(s)) +label_dual(s::Z) = set_sector_label(s, -sector_label(s)) trivial(sector_type::Type{<:Z}) = sector_type(0) diff --git a/src/sector_product.jl b/src/sector_product.jl index 175d53e..0e6c1c2 100644 --- a/src/sector_product.jl +++ b/src/sector_product.jl @@ -14,6 +14,7 @@ end SectorProduct(c::SectorProduct) = _SectorProduct(arguments(c)) arguments(s::SectorProduct) = s.arguments +arguments(s::DualSector{<:SectorProduct}) = map(dual, arguments(nondual(s))) # need map in NamedTuple # ================================= Sectors interface ==================================== function SymmetryStyle(T::Type{<:SectorProduct}) @@ -25,7 +26,7 @@ function quantum_dimension(::NotAbelianStyle, s::SectorProduct) end # use map instead of broadcast to support both Tuple and NamedTuple -GradedUnitRanges.dual(s::SectorProduct) = SectorProduct(map(dual, arguments(s))) +label_dual(s::SectorProduct) = SectorProduct(map(label_dual, arguments(s))) function trivial(type::Type{<:SectorProduct}) return SectorProduct(arguments_trivial(arguments_type(type))) diff --git a/test/test_fusion_rules.jl b/test/test_fusion_rules.jl index cf36854..6ff36cc 100644 --- a/test/test_fusion_rules.jl +++ b/test/test_fusion_rules.jl @@ -1,5 +1,5 @@ using GradedUnitRanges: - dual, fusion_product, space_isequal, gradedrange, flip, tensor_product + dual, fusion_product, labelled_isequal, gradedrange, flip, tensor_product using SymmetrySectors: ⊗, Fib, @@ -32,13 +32,13 @@ using TestExtras: @constinferred @test (@constinferred z1 ⊗ q) == z1 # using GradedUnitRanges interface - @test space_isequal(fusion_product(z0, z0), gradedrange([z0 => 1])) - @test space_isequal(fusion_product(z0, z1), gradedrange([z1 => 1])) + @test labelled_isequal(fusion_product(z0, z0), gradedrange([z0 => 1])) + @test labelled_isequal(fusion_product(z0, z1), gradedrange([z1 => 1])) # test different input number - @test space_isequal(fusion_product(z0), gradedrange([z0 => 1])) - @test space_isequal(fusion_product(z0, z0, z0), gradedrange([z0 => 1])) - @test space_isequal(fusion_product(z0, z0, z0, z0), gradedrange([z0 => 1])) + @test labelled_isequal(fusion_product(z0), gradedrange([z0 => 1])) + @test labelled_isequal(fusion_product(z0, z0, z0), gradedrange([z0 => 1])) + @test labelled_isequal(fusion_product(z0, z0, z0, z0), gradedrange([z0 => 1])) @test (@constinferred block_dimensions(gradedrange([z1 => 1]))) == [1] end @testset "U(1) fusion rules" begin @@ -50,6 +50,10 @@ using TestExtras: @constinferred @test q1 ⊗ q2 == U1(3) @test q2 ⊗ q1 == U1(3) @test (@constinferred q1 ⊗ q2) == q3 + + @test dual(q1) ⊗ q1 == U1(0) + @test q1 ⊗ dual(q1) == U1(0) + @test dual(q1) ⊗ dual(q1) == U1(-2) end @testset "O2 fusion rules" begin @@ -59,20 +63,22 @@ using TestExtras: @constinferred s1 = O2(1) q = TrivialSector() - @test space_isequal((@constinferred s0e ⊗ q), gradedrange([s0e => 1])) - @test space_isequal((@constinferred q ⊗ s0o), gradedrange([s0o => 1])) - - @test space_isequal((@constinferred s0e ⊗ s0e), gradedrange([s0e => 1])) - @test space_isequal((@constinferred s0o ⊗ s0e), gradedrange([s0o => 1])) - @test space_isequal((@constinferred s0o ⊗ s0e), gradedrange([s0o => 1])) - @test space_isequal((@constinferred s0o ⊗ s0o), gradedrange([s0e => 1])) - - @test space_isequal((@constinferred s0e ⊗ s12), gradedrange([s12 => 1])) - @test space_isequal((@constinferred s0o ⊗ s12), gradedrange([s12 => 1])) - @test space_isequal((@constinferred s12 ⊗ s0e), gradedrange([s12 => 1])) - @test space_isequal((@constinferred s12 ⊗ s0o), gradedrange([s12 => 1])) - @test space_isequal((@constinferred s12 ⊗ s1), gradedrange([s12 => 1, O2(3//2) => 1])) - @test space_isequal( + @test labelled_isequal((@constinferred s0e ⊗ q), gradedrange([s0e => 1])) + @test labelled_isequal((@constinferred q ⊗ s0o), gradedrange([s0o => 1])) + + @test labelled_isequal((@constinferred s0e ⊗ s0e), gradedrange([s0e => 1])) + @test labelled_isequal((@constinferred s0o ⊗ s0e), gradedrange([s0o => 1])) + @test labelled_isequal((@constinferred s0o ⊗ s0e), gradedrange([s0o => 1])) + @test labelled_isequal((@constinferred s0o ⊗ s0o), gradedrange([s0e => 1])) + + @test labelled_isequal((@constinferred s0e ⊗ s12), gradedrange([s12 => 1])) + @test labelled_isequal((@constinferred s0o ⊗ s12), gradedrange([s12 => 1])) + @test labelled_isequal((@constinferred s12 ⊗ s0e), gradedrange([s12 => 1])) + @test labelled_isequal((@constinferred s12 ⊗ s0o), gradedrange([s12 => 1])) + @test labelled_isequal( + (@constinferred s12 ⊗ s1), gradedrange([s12 => 1, O2(3//2) => 1]) + ) + @test labelled_isequal( (@constinferred s12 ⊗ s12), gradedrange([s0o => 1, s0e => 1, s1 => 1]) ) @@ -87,27 +93,27 @@ using TestExtras: @constinferred j4 = SU2(3//2) j5 = SU2(2) - @test space_isequal(j1 ⊗ j2, gradedrange([j2 => 1])) - @test space_isequal(j2 ⊗ j2, gradedrange([j1 => 1, j3 => 1])) - @test space_isequal(j2 ⊗ j3, gradedrange([j2 => 1, j4 => 1])) - @test space_isequal(j3 ⊗ j3, gradedrange([j1 => 1, j3 => 1, j5 => 1])) - @test space_isequal((@constinferred j1 ⊗ j2), gradedrange([j2 => 1])) + @test labelled_isequal(j1 ⊗ j2, gradedrange([j2 => 1])) + @test labelled_isequal(j2 ⊗ j2, gradedrange([j1 => 1, j3 => 1])) + @test labelled_isequal(j2 ⊗ j3, gradedrange([j2 => 1, j4 => 1])) + @test labelled_isequal(j3 ⊗ j3, gradedrange([j1 => 1, j3 => 1, j5 => 1])) + @test labelled_isequal((@constinferred j1 ⊗ j2), gradedrange([j2 => 1])) @test (@constinferred quantum_dimension(j1 ⊗ j2)) == 2 @test (@constinferred block_dimensions(j1 ⊗ j2)) == [2] - @test space_isequal(fusion_product(j2), gradedrange([j2 => 1])) - @test space_isequal(fusion_product(j2, j1), gradedrange([j2 => 1])) - @test space_isequal(fusion_product(j2, j1, j1), gradedrange([j2 => 1])) + @test labelled_isequal(fusion_product(j2), gradedrange([j2 => 1])) + @test labelled_isequal(fusion_product(j2, j1), gradedrange([j2 => 1])) + @test labelled_isequal(fusion_product(j2, j1, j1), gradedrange([j2 => 1])) end @testset "Fibonacci fusion rules" begin ı = Fib("1") τ = Fib("τ") - @test space_isequal(ı ⊗ ı, gradedrange([ı => 1])) - @test space_isequal(ı ⊗ τ, gradedrange([τ => 1])) - @test space_isequal(τ ⊗ ı, gradedrange([τ => 1])) - @test space_isequal((@constinferred τ ⊗ τ), gradedrange([ı => 1, τ => 1])) + @test labelled_isequal(ı ⊗ ı, gradedrange([ı => 1])) + @test labelled_isequal(ı ⊗ τ, gradedrange([τ => 1])) + @test labelled_isequal(τ ⊗ ı, gradedrange([τ => 1])) + @test labelled_isequal((@constinferred τ ⊗ τ), gradedrange([ı => 1, τ => 1])) @test (@constinferred quantum_dimension(gradedrange([ı => 1, ı => 1]))) == 2.0 end @@ -116,16 +122,16 @@ using TestExtras: @constinferred σ = Ising("σ") ψ = Ising("ψ") - @test space_isequal(ı ⊗ ı, gradedrange([ı => 1])) - @test space_isequal(ı ⊗ σ, gradedrange([σ => 1])) - @test space_isequal(σ ⊗ ı, gradedrange([σ => 1])) - @test space_isequal(ı ⊗ ψ, gradedrange([ψ => 1])) - @test space_isequal(ψ ⊗ ı, gradedrange([ψ => 1])) - @test space_isequal(σ ⊗ σ, gradedrange([ı => 1, ψ => 1])) - @test space_isequal(σ ⊗ ψ, gradedrange([σ => 1])) - @test space_isequal(ψ ⊗ σ, gradedrange([σ => 1])) - @test space_isequal(ψ ⊗ ψ, gradedrange([ı => 1])) - @test space_isequal((@constinferred ψ ⊗ ψ), gradedrange([ı => 1])) + @test labelled_isequal(ı ⊗ ı, gradedrange([ı => 1])) + @test labelled_isequal(ı ⊗ σ, gradedrange([σ => 1])) + @test labelled_isequal(σ ⊗ ı, gradedrange([σ => 1])) + @test labelled_isequal(ı ⊗ ψ, gradedrange([ψ => 1])) + @test labelled_isequal(ψ ⊗ ı, gradedrange([ψ => 1])) + @test labelled_isequal(σ ⊗ σ, gradedrange([ı => 1, ψ => 1])) + @test labelled_isequal(σ ⊗ ψ, gradedrange([σ => 1])) + @test labelled_isequal(ψ ⊗ σ, gradedrange([σ => 1])) + @test labelled_isequal(ψ ⊗ ψ, gradedrange([ı => 1])) + @test labelled_isequal((@constinferred ψ ⊗ ψ), gradedrange([ı => 1])) @test (@constinferred quantum_dimension(σ ⊗ σ)) == 2.0 end end @@ -133,15 +139,17 @@ end @testset "Trivial GradedUnitRange" begin g1 = gradedrange([U1(0) => 1]) g2 = gradedrange([SU2(0) => 1]) - @test space_isequal(trivial(g1), g1) - @test space_isequal(trivial(dual(g1)), g1) # trivial returns nondual - @test space_isequal(trivial(typeof(g2)), g2) + @test labelled_isequal(trivial(g1), g1) + @test labelled_isequal(trivial(dual(g1)), g1) # trivial returns nondual + @test labelled_isequal(trivial(typeof(g2)), g2) end @testset "GradedUnitRange abelian tensor/fusion product" begin g1 = gradedrange([U1(-1) => 1, U1(0) => 1, U1(1) => 2]) g2 = gradedrange([U1(-2) => 2, U1(0) => 1, U1(1) => 2]) - @test space_isequal(flip(dual(g1)), gradedrange([U1(1) => 1, U1(0) => 1, U1(-1) => 2])) + @test labelled_isequal( + flip(dual(g1)), gradedrange([U1(1) => 1, U1(0) => 1, U1(-1) => 2]) + ) @test (@constinferred block_dimensions(g1)) == [1, 1, 2] gt = gradedrange([ @@ -158,8 +166,8 @@ end gf = gradedrange([ U1(-3) => 2, U1(-2) => 2, U1(-1) => 5, U1(0) => 3, U1(1) => 4, U1(2) => 4 ]) - @test space_isequal((@constinferred tensor_product(g1, g2)), gt) - @test space_isequal((@constinferred fusion_product(g1, g2)), gf) + @test labelled_isequal((@constinferred tensor_product(g1, g2)), gt) + @test labelled_isequal((@constinferred fusion_product(g1, g2)), gf) gtd1 = gradedrange([ U1(-1) => 2, @@ -175,8 +183,8 @@ end gfd1 = gradedrange([ U1(-3) => 4, U1(-2) => 2, U1(-1) => 4, U1(0) => 5, U1(1) => 3, U1(2) => 2 ]) - @test space_isequal((@constinferred tensor_product(dual(g1), g2)), gtd1) - @test space_isequal((@constinferred fusion_product(dual(g1), g2)), gfd1) + @test labelled_isequal((@constinferred tensor_product(dual(g1), g2)), gtd1) + @test labelled_isequal((@constinferred fusion_product(dual(g1), g2)), gfd1) gtd2 = gradedrange([ U1(1) => 2, @@ -192,8 +200,8 @@ end gfd2 = gradedrange([ U1(-2) => 2, U1(-1) => 3, U1(0) => 5, U1(1) => 4, U1(2) => 2, U1(3) => 4 ]) - @test space_isequal((@constinferred tensor_product(g1, dual(g2))), gtd2) - @test space_isequal((@constinferred fusion_product(g1, dual(g2))), gfd2) + @test labelled_isequal((@constinferred tensor_product(g1, dual(g2))), gtd2) + @test labelled_isequal((@constinferred fusion_product(g1, dual(g2))), gfd2) gtd = gradedrange([ U1(3) => 2, @@ -209,8 +217,8 @@ end gfd = gradedrange([ U1(-2) => 4, U1(-1) => 4, U1(0) => 3, U1(1) => 5, U1(2) => 2, U1(3) => 2 ]) - @test space_isequal((@constinferred tensor_product(dual(g1), dual(g2))), gtd) - @test space_isequal((@constinferred fusion_product(dual(g1), dual(g2))), gfd) + @test labelled_isequal((@constinferred tensor_product(dual(g1), dual(g2))), gtd) + @test labelled_isequal((@constinferred fusion_product(dual(g1), dual(g2))), gfd) # test different (non-product) sectors cannot be fused @test_throws MethodError fusion_product(gradedrange([Z{2}(0) => 1]), g1) @@ -234,10 +242,10 @@ end SU2(2) => 2, ]) - @test space_isequal(tensor_product(g3, g4), g34) + @test labelled_isequal(tensor_product(g3, g4), g34) - @test space_isequal(dual(flip(g3)), g3) # trivial for SU(2) - @test space_isequal( + @test labelled_isequal(dual(flip(g3)), g3) # trivial for SU(2) + @test labelled_isequal( (@constinferred fusion_product(g3, g4)), gradedrange([SU2(0) => 4, SU2(1//2) => 6, SU2(1) => 6, SU2(3//2) => 5, SU2(2) => 2]), ) @@ -251,19 +259,19 @@ end g5 = gradedrange([s1 => 1, f3 => 1]) g6 = gradedrange([s1 => 1, c3 => 1]) - @test space_isequal(dual(flip(g5)), g6) - @test space_isequal( + @test labelled_isequal(dual(flip(g5)), g6) + @test labelled_isequal( fusion_product(g5, g6), gradedrange([s1 => 2, f3 => 1, c3 => 1, ad8 => 1]) ) - @test space_isequal( + @test labelled_isequal( fusion_product(dual(g5), g6), gradedrange([s1 => 1, f3 => 1, c3 => 2, SU{3}((2, 2)) => 1]), ) - @test space_isequal( + @test labelled_isequal( fusion_product(g5, dual(g6)), gradedrange([s1 => 1, f3 => 2, c3 => 1, SU{3}((2, 0)) => 1]), ) - @test space_isequal( + @test labelled_isequal( fusion_product(dual(g5), dual(g6)), gradedrange([s1 => 2, f3 => 1, c3 => 1, ad8 => 1]) ) end @@ -271,13 +279,13 @@ end @testset "Mixed GradedUnitRange - Sector fusion rules" begin g1 = gradedrange([U1(1) => 1, U1(2) => 2]) g2 = gradedrange([U1(2) => 1, U1(3) => 2]) - @test space_isequal((@constinferred fusion_product(g1, U1(1))), g2) - @test space_isequal((@constinferred fusion_product(U1(1), g1)), g2) + @test labelled_isequal((@constinferred fusion_product(g1, U1(1))), g2) + @test labelled_isequal((@constinferred fusion_product(U1(1), g1)), g2) g3 = gradedrange([SU2(0) => 1, SU2(1//2) => 2]) g4 = gradedrange([SU2(0) => 2, SU2(1//2) => 1, SU2(1) => 2]) - @test space_isequal((@constinferred fusion_product(g3, SU2(1//2))), g4) - @test space_isequal((@constinferred fusion_product(SU2(1//2), g3)), g4) + @test labelled_isequal((@constinferred fusion_product(g3, SU2(1//2))), g4) + @test labelled_isequal((@constinferred fusion_product(SU2(1//2), g3)), g4) # test different simple sectors cannot be fused @test_throws MethodError Z{2}(0) ⊗ U1(1) diff --git a/test/test_sector_product.jl b/test/test_sector_product.jl index 7ff846e..872f24f 100644 --- a/test/test_sector_product.jl +++ b/test/test_sector_product.jl @@ -10,10 +10,12 @@ using SymmetrySectors: U1, Z, block_dimensions, - quantum_dimension, arguments, + label_dual, + quantum_dimension, trivial -using GradedUnitRanges: dual, fusion_product, space_isequal, gradedrange, sector_type +using GradedUnitRanges: + dual, flip, fusion_product, gradedrange, isdual, labelled_isequal, sector_type using Test: @test, @testset, @test_throws using TestExtras: @constinferred @@ -22,14 +24,14 @@ using TestExtras: @constinferred s = SectorProduct(U1(1)) @test length(arguments(s)) == 1 @test (@constinferred quantum_dimension(s)) == 1 - @test (@constinferred dual(s)) == SectorProduct(U1(-1)) + @test (@constinferred label_dual(s)) == SectorProduct(U1(-1)) @test arguments(s)[1] == U1(1) @test (@constinferred trivial(s)) == SectorProduct(U1(0)) s = SectorProduct(U1(1), U1(2)) @test length(arguments(s)) == 2 @test (@constinferred quantum_dimension(s)) == 1 - @test (@constinferred dual(s)) == SectorProduct(U1(-1), U1(-2)) + @test (@constinferred label_dual(s)) == SectorProduct(U1(-1), U1(-2)) @test arguments(s)[1] == U1(1) @test arguments(s)[2] == U1(2) @test (@constinferred trivial(s)) == SectorProduct(U1(0), U1(0)) @@ -37,7 +39,7 @@ using TestExtras: @constinferred s = U1(1) × SU2(1//2) × U1(3) @test length(arguments(s)) == 3 @test (@constinferred quantum_dimension(s)) == 2 - @test (@constinferred dual(s)) == U1(-1) × SU2(1//2) × U1(-3) + @test (@constinferred label_dual(s)) == U1(-1) × SU2(1//2) × U1(-3) @test arguments(s)[1] == U1(1) @test arguments(s)[2] == SU2(1//2) @test arguments(s)[3] == U1(3) @@ -46,7 +48,7 @@ using TestExtras: @constinferred s = U1(3) × SU2(1//2) × Fib("τ") @test length(arguments(s)) == 3 @test (@constinferred quantum_dimension(s)) == 1.0 + √5 - @test dual(s) == U1(-3) × SU2(1//2) × Fib("τ") + @test label_dual(s) == U1(-3) × SU2(1//2) × Fib("τ") @test arguments(s)[1] == U1(3) @test arguments(s)[2] == SU2(1//2) @test arguments(s)[3] == Fib("τ") @@ -55,9 +57,11 @@ using TestExtras: @constinferred s = TrivialSector() × U1(3) × SU2(1 / 2) @test length(arguments(s)) == 3 @test (@constinferred quantum_dimension(s)) == 2 - @test dual(s) == TrivialSector() × U1(-3) × SU2(1//2) + @test label_dual(s) == TrivialSector() × U1(-3) × SU2(1//2) @test (@constinferred trivial(s)) == SectorProduct(TrivialSector(), U1(0), SU2(0)) @test s > trivial(s) + + @test arguments(dual(s)) == dual.(arguments(s)) end @testset "Ordered comparisons" begin @@ -155,15 +159,15 @@ using TestExtras: @constinferred @testset "Fusion of NonAbelian products" begin p0 = SectorProduct(SU2(0)) ph = SectorProduct(SU2(1//2)) - @test space_isequal( + @test labelled_isequal( (@constinferred p0 ⊗ TrivialSector()), gradedrange([SectorProduct(SU2(0)) => 1]) ) - @test space_isequal( + @test labelled_isequal( (@constinferred TrivialSector() ⊗ ph), gradedrange([SectorProduct(SU2(1//2)) => 1]) ) phh = SU2(1//2) × SU2(1//2) - @test space_isequal( + @test labelled_isequal( phh ⊗ phh, gradedrange([ (SU2(0) × SU2(0)) => 1, @@ -172,7 +176,7 @@ using TestExtras: @constinferred (SU2(1) × SU2(1)) => 1, ]), ) - @test space_isequal( + @test labelled_isequal( phh ⊗ phh, gradedrange([ (SU2(0) × SU2(0)) => 1, @@ -187,10 +191,10 @@ using TestExtras: @constinferred ı = Fib("1") τ = Fib("τ") s = ı × ı - @test space_isequal(s ⊗ s, gradedrange([s => 1])) + @test labelled_isequal(s ⊗ s, gradedrange([s => 1])) s = τ × τ - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([(ı × ı) => 1, (τ × ı) => 1, (ı × τ) => 1, (τ × τ) => 1]) ) @@ -200,18 +204,18 @@ using TestExtras: @constinferred g = gradedrange([ (ı × Ising("1")) => 1, (τ × Ising("1")) => 1, (ı × ψ) => 1, (τ × ψ) => 1 ]) - @test space_isequal(s ⊗ s, g) + @test labelled_isequal(s ⊗ s, g) end @testset "Fusion of mixed Abelian and NonAbelian products" begin p2h = U1(2) × SU2(1//2) p1h = U1(1) × SU2(1//2) - @test space_isequal( + @test labelled_isequal( p2h ⊗ p1h, gradedrange([(U1(3) × SU2(0)) => 1, (U1(3) × SU2(1)) => 1]) ) p1h1 = U1(1) × SU2(1//2) × Z{2}(1) - @test space_isequal( + @test labelled_isequal( p1h1 ⊗ p1h1, gradedrange([(U1(2) × SU2(0) × Z{2}(0)) => 1, (U1(2) × SU2(1) × Z{2}(0)) => 1]), ) @@ -219,7 +223,7 @@ using TestExtras: @constinferred @testset "Fusion of fully mixed products" begin s = U1(1) × SU2(1//2) × Ising("σ") - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([ (U1(2) × SU2(0) × Ising("1")) => 1, @@ -232,7 +236,7 @@ using TestExtras: @constinferred ı = Fib("1") τ = Fib("τ") s = SU2(1//2) × U1(1) × τ - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([ (SU2(0) × U1(2) × ı) => 1, @@ -243,22 +247,22 @@ using TestExtras: @constinferred ) s = U1(1) × ı × τ - @test space_isequal(s ⊗ s, gradedrange([(U1(2) × ı × ı) => 1, (U1(2) × ı × τ) => 1])) + @test labelled_isequal(s ⊗ s, gradedrange([(U1(2) × ı × ı) => 1, (U1(2) × ı × τ) => 1])) end @testset "Fusion of different length Categories" begin @test SectorProduct(U1(1) × U1(0)) ⊗ SectorProduct(U1(1)) == SectorProduct(U1(2) × U1(0)) - @test space_isequal( + @test labelled_isequal( (@constinferred SectorProduct(SU2(0) × SU2(0)) ⊗ SectorProduct(SU2(1))), gradedrange([SectorProduct(SU2(1) × SU2(0)) => 1]), ) - @test space_isequal( + @test labelled_isequal( (@constinferred SectorProduct(SU2(1) × U1(1)) ⊗ SectorProduct(SU2(0))), gradedrange([SectorProduct(SU2(1) × U1(1)) => 1]), ) - @test space_isequal( + @test labelled_isequal( (@constinferred SectorProduct(U1(1) × SU2(1)) ⊗ SectorProduct(U1(2))), gradedrange([SectorProduct(U1(3) × SU2(1)) => 1]), ) @@ -274,11 +278,52 @@ using TestExtras: @constinferred s2 = U1(0) × SU2(1//2) × Ising("1") g1 = gradedrange([s1 => 2]) g2 = gradedrange([s2 => 1]) - @test space_isequal( + @test labelled_isequal( fusion_product(g1, g2), gradedrange([U1(1) × SU2(0) × Ising("σ") => 2, U1(1) × SU2(1) × Ising("σ") => 2]), ) end + + @testset "Ordered dual" begin + s1 = U1(1) + s2 = SU2(1//2) + s12 = s1 × s2 + s12b = dual(s12) + + @test !isdual(s12) + @test isdual(s12b) + @test s12 != s12b + @test s12b == s12b + @test s12b < dual(U1(1) × SU2(1)) + @test flip(s12) == dual(U1(-1) × SU2(1//2)) + @test flip(s12b) == U1(-1) × SU2(1//2) + + @test_throws error s1 × dual(s2) + @test_throws error dual(s1) × s2 + @test s12b == dual(s1) × dual(s2) + + @test labelled_isequal( + s12b ⊗ s12, gradedrange([ + U1(0) × SU2(0) => 1 + U1(0) × SU2(1) => 1 + ]) + ) + @test labelled_isequal( + s12 ⊗ s12b, gradedrange([ + U1(0) × SU2(0) => 1 + U1(0) × SU2(1) => 1 + ]) + ) + @test labelled_isequal( + s12b ⊗ s12b, gradedrange([ + U1(-2) × SU2(0) => 1 + U1(-2) × SU2(1) => 1 + ]) + ) + + s123b = s12b × dual(Fib(0)) + @test (@constinferred quantum_dimension(s123b)) == 2.0 + end end @testset "Test Named Sector Products" begin @@ -288,7 +333,7 @@ end @test arguments(s)[:A] == U1(1) @test arguments(s)[:B] == Z{2}(0) @test (@constinferred quantum_dimension(s)) == 1 - @test (@constinferred dual(s)) == (A=U1(-1),) × (B=Z{2}(0),) + @test (@constinferred label_dual(s)) == (A=U1(-1),) × (B=Z{2}(0),) @test (@constinferred trivial(s)) == (A=U1(0),) × (B=Z{2}(0),) s = (A=U1(1),) × (B=SU2(2),) @@ -296,7 +341,7 @@ end @test arguments(s)[:A] == U1(1) @test arguments(s)[:B] == SU2(2) @test (@constinferred quantum_dimension(s)) == 5 - @test (@constinferred dual(s)) == (A=U1(-1),) × (B=SU2(2),) + @test (@constinferred label_dual(s)) == (A=U1(-1),) × (B=SU2(2),) @test (@constinferred trivial(s)) == (A=U1(0),) × (B=SU2(0),) @test s == (B=SU2(2),) × (A=U1(1),) @@ -304,7 +349,9 @@ end @test length(arguments(s)) == 3 @test arguments(s)[:C] == Ising("ψ") @test (@constinferred quantum_dimension(s)) == 5.0 - @test (@constinferred dual(s)) == (A=U1(-1),) × (B=SU2(2),) × (C=Ising("ψ"),) + @test (@constinferred label_dual(s)) == (A=U1(-1),) × (B=SU2(2),) × (C=Ising("ψ"),) + + @test arguments(dual(s)) == map(dual, arguments(s)) s1 = (A=U1(1),) × (B=Z{2}(0),) s2 = (A=U1(1),) × (C=Z{2}(0),) @@ -320,7 +367,7 @@ end @test arguments(s)[:A] == U1(2) @test s == SectorProduct(; A=U1(2)) @test (@constinferred quantum_dimension(s)) == 1 - @test (@constinferred dual(s)) == SectorProduct("A" => U1(-2)) + @test (@constinferred label_dual(s)) == SectorProduct("A" => U1(-2)) @test (@constinferred trivial(s)) == SectorProduct(; A=U1(0)) s = SectorProduct("B" => Ising("ψ"), :C => Z{2}(1)) @@ -428,15 +475,15 @@ end phb = SectorProduct(; B=SU2(1//2)) phab = SectorProduct(; A=SU2(1//2), B=SU2(1//2)) - @test space_isequal( + @test labelled_isequal( (@constinferred pha ⊗ pha), gradedrange([SectorProduct(; A=SU2(0)) => 1, SectorProduct(; A=SU2(1)) => 1]), ) - @test space_isequal((@constinferred pha ⊗ p0), gradedrange([pha => 1])) - @test space_isequal((@constinferred p0 ⊗ phb), gradedrange([phb => 1])) - @test space_isequal((@constinferred pha ⊗ phb), gradedrange([phab => 1])) + @test labelled_isequal((@constinferred pha ⊗ p0), gradedrange([pha => 1])) + @test labelled_isequal((@constinferred p0 ⊗ phb), gradedrange([phb => 1])) + @test labelled_isequal((@constinferred pha ⊗ phb), gradedrange([phab => 1])) - @test space_isequal( + @test labelled_isequal( phab ⊗ phab, gradedrange([ SectorProduct(; A=SU2(0), B=SU2(0)) => 1, @@ -451,10 +498,10 @@ end ı = Fib("1") τ = Fib("τ") s = SectorProduct(; A=ı, B=ı) - @test space_isequal(s ⊗ s, gradedrange([s => 1])) + @test labelled_isequal(s ⊗ s, gradedrange([s => 1])) s = SectorProduct(; A=τ, B=τ) - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([ SectorProduct(; A=ı, B=ı) => 1, @@ -473,7 +520,7 @@ end SectorProduct(; A=ı, B=ψ) => 1, SectorProduct(; A=τ, B=ψ) => 1, ]) - @test space_isequal(s ⊗ s, g) + @test labelled_isequal(s ⊗ s, g) end @testset "Fusion of mixed Abelian and NonAbelian products" begin @@ -487,15 +534,15 @@ end q21 = (N=U1(2),) × (J=SU2(1),) q22 = (N=U1(2),) × (J=SU2(2),) - @test space_isequal(q1h ⊗ q1h, gradedrange([q20 => 1, q21 => 1])) - @test space_isequal(q10 ⊗ q1h, gradedrange([q2h => 1])) - @test space_isequal((@constinferred q0h ⊗ q1h), gradedrange([q10 => 1, q11 => 1])) - @test space_isequal(q11 ⊗ q11, gradedrange([q20 => 1, q21 => 1, q22 => 1])) + @test labelled_isequal(q1h ⊗ q1h, gradedrange([q20 => 1, q21 => 1])) + @test labelled_isequal(q10 ⊗ q1h, gradedrange([q2h => 1])) + @test labelled_isequal((@constinferred q0h ⊗ q1h), gradedrange([q10 => 1, q11 => 1])) + @test labelled_isequal(q11 ⊗ q11, gradedrange([q20 => 1, q21 => 1, q22 => 1])) end @testset "Fusion of fully mixed products" begin s = SectorProduct(; A=U1(1), B=SU2(1//2), C=Ising("σ")) - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([ SectorProduct(; A=U1(2), B=SU2(0), C=Ising("1")) => 1, @@ -508,7 +555,7 @@ end ı = Fib("1") τ = Fib("τ") s = SectorProduct(; A=SU2(1//2), B=U1(1), C=τ) - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([ SectorProduct(; A=SU2(0), B=U1(2), C=ı) => 1, @@ -519,7 +566,7 @@ end ) s = SectorProduct(; A=τ, B=U1(1), C=ı) - @test space_isequal( + @test labelled_isequal( s ⊗ s, gradedrange([ SectorProduct(; B=U1(2), A=ı, C=ı) => 1, SectorProduct(; B=U1(2), A=τ, C=ı) => 1 @@ -533,14 +580,14 @@ end g2 = gradedrange([s2 => 1]) s3 = SectorProduct(; A=U1(1), B=SU2(0), C=Ising("σ")) s4 = SectorProduct(; A=U1(1), B=SU2(1), C=Ising("σ")) - @test space_isequal(fusion_product(g1, g2), gradedrange([s3 => 2, s4 => 2])) + @test labelled_isequal(fusion_product(g1, g2), gradedrange([s3 => 2, s4 => 2])) sA = SectorProduct(; A=U1(1)) sB = SectorProduct(; B=SU2(1//2)) sAB = SectorProduct(; A=U1(1), B=SU2(1//2)) gA = gradedrange([sA => 2]) gB = gradedrange([sB => 1]) - @test space_isequal(fusion_product(gA, gB), gradedrange([sAB => 2])) + @test labelled_isequal(fusion_product(gA, gB), gradedrange([sAB => 2])) end end @@ -574,12 +621,12 @@ end @test (@constinferred s ⊗ SectorProduct(())) == s @test (@constinferred s ⊗ SectorProduct((;))) == s - @test (@constinferred dual(s)) == s + @test (@constinferred label_dual(s)) == s @test (@constinferred trivial(s)) == s @test (@constinferred quantum_dimension(s)) == 1 g0 = gradedrange([s => 2]) - @test space_isequal((@constinferred fusion_product(g0, g0)), gradedrange([s => 4])) + @test labelled_isequal((@constinferred fusion_product(g0, g0)), gradedrange([s => 4])) @test (@constinferred s × U1(1)) == st1 @test (@constinferred U1(1) × s) == st1 @@ -622,4 +669,44 @@ end @test !(s < SectorProduct(; A=U1(0))) @test !(s > SectorProduct(; A=U1(0))) end + + @testset "NamedTuple dual" begin + s1 = SectorProduct("A" => U1(1)) + s2 = SectorProduct("B" => SU2(1//2)) + + s12 = s1 × s2 + s12b = dual(s12) + + @test !isdual(s12) + @test isdual(s12b) + @test s12 != s12b + @test s12b == s12b + @test s12b < dual(SectorProduct("A" => U1(1)) × SectorProduct("B" => SU2(1))) + @test flip(s12) == dual(SectorProduct("A" => U1(-1)) × SectorProduct("B" => SU2(1//2))) + @test flip(s12b) == SectorProduct("A" => U1(-1)) × SectorProduct("B" => SU2(1//2)) + + @test_throws error s1 × dual(s2) + @test_throws error dual(s1) × s2 + @test s12b == dual(s1) × dual(s2) + + @test labelled_isequal( + s12b ⊗ s12, gradedrange([ + (A=U1(0),) × (B=SU2(0),) => 1 + (A=U1(0),) × (B=SU2(1),) => 1 + ]) + ) + @test labelled_isequal( + s12 ⊗ s12b, gradedrange([ + (A=U1(0),) × (B=SU2(0),) => 1 + (A=U1(0),) × (B=SU2(1),) => 1 + ]) + ) + @test labelled_isequal( + s12b ⊗ s12b, + gradedrange([ + (A=U1(-2),) × (B=SU2(0),) => 1 + (A=U1(-2),) × (B=SU2(1),) => 1 + ]), + ) + end end diff --git a/test/test_simple_sectors.jl b/test/test_simple_sectors.jl index a80a2bb..a9af8aa 100644 --- a/test/test_simple_sectors.jl +++ b/test/test_simple_sectors.jl @@ -1,4 +1,4 @@ -using GradedUnitRanges: dual, sector_type +using GradedUnitRanges: dual, flip, isdual, nondual, sector_type using SymmetrySectors: Fib, Ising, @@ -6,11 +6,13 @@ using SymmetrySectors: SU, SU2, TrivialSector, + DualSector, U1, Z, quantum_dimension, fundamental, istrivial, + label_dual, trivial using Test: @test, @testset, @test_throws using TestExtras: @constinferred @@ -26,8 +28,22 @@ using TestExtras: @constinferred @test trivial(q) == q @test istrivial(q) - @test dual(q) == q + @test label_dual(q) == q @test !isless(q, q) + + qb = dual(q) + @test qb isa DualSector + @test sector_type(qb) === TrivialSector + @test isdual(qb) + @test !isdual(q) + @test qb == qb + @test q != qb + @test nondual(qb) == q + @test dual(qb) == q + @test !isless(qb, qb) + @test flip(q) == qb + @test flip(qb) == q + @test (@constinferred quantum_dimension(qb)) == 1 end @testset "U(1)" begin @@ -45,7 +61,7 @@ using TestExtras: @constinferred @test trivial(U1) == U1(0) @test istrivial(U1(0)) - @test dual(U1(2)) == U1(-2) + @test label_dual(U1(2)) == U1(-2) @test isless(U1(1), U1(2)) @test !isless(U1(2), U1(1)) @test U1(Int8(1)) == U1(1) @@ -56,12 +72,31 @@ using TestExtras: @constinferred @test U1(-1) < TrivialSector() @test TrivialSector() < U1(1) @test U1(Int8(1)) < U1(Int32(2)) + + q2b = dual(q2) + @test q2b isa DualSector + @test isdual(q2b) + @test !isdual(q2) + @test q2b == q2b + @test q2b != q2 + @test q2b != U1(-2) + @test nondual(q2b) == q2 + @test dual(q2b) == q2 + @test !isless(q2b, q2b) + @test dual(q1) < q2b + @test flip(q2) == dual(U1(-2)) + @test flip(q2b) == U1(-2) end @testset "Z₂" begin z0 = Z{2}(0) z1 = Z{2}(1) + @test z0 == z0 + @test z0 != z1 + @test !(z0 < z0) + @test !(z1 < z1) + @test z0 < z1 @test trivial(Z{2}) == Z{2}(0) @test istrivial(Z{2}(0)) @@ -69,10 +104,10 @@ using TestExtras: @constinferred @test quantum_dimension(z1) == 1 @test (@constinferred quantum_dimension(z0)) == 1 - @test dual(z0) == z0 - @test dual(z1) == z1 + @test label_dual(z0) == z0 + @test label_dual(z1) == z1 - @test dual(Z{2}(1)) == Z{2}(1) + @test label_dual(Z{2}(1)) == Z{2}(1) @test isless(Z{2}(0), Z{2}(1)) @test !isless(Z{2}(1), Z{2}(0)) @test Z{2}(0) == z0 @@ -84,6 +119,13 @@ using TestExtras: @constinferred @test Z{2}(0) != Z{2}(1) @test Z{2}(0) != Z{3}(0) @test Z{2}(0) != U1(0) + + z1b = dual(z1) + @test z1b isa DualSector + @test z1b == z1b + @test z1 != z1b + @test flip(z1) == z1b + @test flip(z1b) == z1 end @testset "O(2)" begin @@ -100,15 +142,23 @@ using TestExtras: @constinferred @test (@constinferred quantum_dimension(s12)) == 2 @test (@constinferred quantum_dimension(s1)) == 2 - @test (@constinferred dual(s0e)) == s0e - @test (@constinferred dual(s0o)) == s0o - @test (@constinferred dual(s12)) == s12 - @test (@constinferred dual(s1)) == s1 + @test (@constinferred label_dual(s0e)) == s0e + @test (@constinferred label_dual(s0o)) == s0o + @test (@constinferred label_dual(s12)) == s12 + @test (@constinferred label_dual(s1)) == s1 @test s0o < s0e < s12 < s1 @test s0e == TrivialSector() @test s0o < TrivialSector() @test TrivialSector() < s12 + + s1b = dual(s1) + @test s1b isa DualSector + @test s1b == s1b + @test s1b != s1 + @test flip(s1) == s1b + @test flip(s1b) == s1 + @test (@constinferred quantum_dimension(s1b)) == 2 end @testset "SU(2)" begin @@ -137,10 +187,10 @@ using TestExtras: @constinferred @test quantum_dimension(j4) == 4 @test (@constinferred quantum_dimension(j1)) == 1 - @test dual(j1) == j1 - @test dual(j2) == j2 - @test dual(j3) == j3 - @test dual(j4) == j4 + @test label_dual(j1) == j1 + @test label_dual(j2) == j2 + @test label_dual(j3) == j3 + @test label_dual(j4) == j4 @test j1 < j2 < j3 < j4 @test SU2(0) == TrivialSector() @@ -164,10 +214,10 @@ using TestExtras: @constinferred @test fundamental(SU{3}) == f3 @test fundamental(SU{4}) == f4 - @test dual(f3) == SU{3}((1, 1)) - @test dual(f4) == SU{4}((1, 1, 1)) - @test dual(ad3) == ad3 - @test dual(ad4) == ad4 + @test label_dual(f3) == SU{3}((1, 1)) + @test label_dual(f4) == SU{4}((1, 1, 1)) + @test label_dual(ad3) == ad3 + @test label_dual(ad4) == ad4 @test quantum_dimension(f3) == 3 @test quantum_dimension(f4) == 4 @@ -188,8 +238,8 @@ using TestExtras: @constinferred @test istrivial(ı) @test ı == TrivialSector() - @test dual(ı) == ı - @test dual(τ) == τ + @test label_dual(ı) == ı + @test label_dual(τ) == τ @test (@constinferred quantum_dimension(ı)) == 1.0 @test (@constinferred quantum_dimension(τ)) == ((1 + √5) / 2) @@ -206,9 +256,9 @@ using TestExtras: @constinferred @test istrivial(ı) @test ı == TrivialSector() - @test dual(ı) == ı - @test dual(σ) == σ - @test dual(ψ) == ψ + @test label_dual(ı) == ı + @test label_dual(σ) == σ + @test label_dual(ψ) == ψ @test (@constinferred quantum_dimension(ı)) == 1.0 @test (@constinferred quantum_dimension(σ)) == √2