From da7aaf8cc66fc179a51b56ef8e5a0ad44568cc73 Mon Sep 17 00:00:00 2001 From: Lukas Devos Date: Thu, 3 Apr 2025 11:03:03 -0400 Subject: [PATCH 1/2] Add TensorKitSectors dependency --- Project.toml | 2 ++ src/lib/SymmetrySectors/SymmetrySectors.jl | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Project.toml b/Project.toml index 47205b4..1422b9c 100644 --- a/Project.toml +++ b/Project.toml @@ -10,6 +10,7 @@ FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" +TensorKitSectors = "13a9c161-d5da-41f0-bcbd-e1a08ae0647f" TensorProducts = "decf83d6-1968-43f4-96dc-fdb3fe15fc6d" [compat] @@ -19,5 +20,6 @@ FillArrays = "1.13.0" HalfIntegers = "1.6.0" Random = "1.10.0" SplitApplyCombine = "1.2.3" +TensorKitSectors = "0.1.4" TensorProducts = "0.1.3" julia = "1.10" diff --git a/src/lib/SymmetrySectors/SymmetrySectors.jl b/src/lib/SymmetrySectors/SymmetrySectors.jl index 060eb20..830b796 100644 --- a/src/lib/SymmetrySectors/SymmetrySectors.jl +++ b/src/lib/SymmetrySectors/SymmetrySectors.jl @@ -1,5 +1,7 @@ module SymmetrySectors +using TensorKitSectors + export U1, Z, dual include("symmetry_style.jl") From fa1d0b60affaee4ae90fdefab238cabb681fb8a0 Mon Sep 17 00:00:00 2001 From: Lukas Devos Date: Thu, 3 Apr 2025 12:48:09 -0400 Subject: [PATCH 2/2] initial attempt --- src/lib/SymmetrySectors/SymmetrySectors.jl | 13 +-- .../SymmetrySectors/sector_definitions/su.jl | 2 +- .../sector_definitions/tensorkitsector.jl | 98 +++++++++++++++++++ test/test_symmetrysectors_fusion_rules.jl | 3 +- 4 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 src/lib/SymmetrySectors/sector_definitions/tensorkitsector.jl diff --git a/src/lib/SymmetrySectors/SymmetrySectors.jl b/src/lib/SymmetrySectors/SymmetrySectors.jl index 830b796..90f7cc9 100644 --- a/src/lib/SymmetrySectors/SymmetrySectors.jl +++ b/src/lib/SymmetrySectors/SymmetrySectors.jl @@ -1,19 +1,20 @@ module SymmetrySectors -using TensorKitSectors +using TensorKitSectors: TensorKitSectors export U1, Z, dual include("symmetry_style.jl") include("abstractsector.jl") -include("sector_definitions/fib.jl") -include("sector_definitions/ising.jl") -include("sector_definitions/o2.jl") +include("sector_definitions/tensorkitsector.jl") +# include("sector_definitions/fib.jl") +# include("sector_definitions/ising.jl") +# include("sector_definitions/o2.jl") include("sector_definitions/trivial.jl") include("sector_definitions/su.jl") include("sector_definitions/su2k.jl") -include("sector_definitions/u1.jl") -include("sector_definitions/zn.jl") +# include("sector_definitions/u1.jl") +# include("sector_definitions/zn.jl") include("namedtuple_operations.jl") include("sector_product.jl") diff --git a/src/lib/SymmetrySectors/sector_definitions/su.jl b/src/lib/SymmetrySectors/sector_definitions/su.jl index 83d95b4..d198808 100644 --- a/src/lib/SymmetrySectors/sector_definitions/su.jl +++ b/src/lib/SymmetrySectors/sector_definitions/su.jl @@ -96,7 +96,7 @@ function label_fusion_rule(::Type{<:SU{2}}, s1, s2) end # define angular momentum-like interface using half-integers -SU2(h::Number) = SU{2}((twice(HalfInteger(h)),)) +# SU2(h::Number) = SU{2}((twice(HalfInteger(h)),)) # display SU2 using half-integers function Base.show(io::IO, s::SU{2}) diff --git a/src/lib/SymmetrySectors/sector_definitions/tensorkitsector.jl b/src/lib/SymmetrySectors/sector_definitions/tensorkitsector.jl new file mode 100644 index 0000000..597761a --- /dev/null +++ b/src/lib/SymmetrySectors/sector_definitions/tensorkitsector.jl @@ -0,0 +1,98 @@ +# Generic wrapper +# --------------- +struct TensorKitSector{I<:TensorKitSectors.Sector} <: AbstractSector + sector::I +end + +function SymmetryStyle(::Type{TensorKitSector{I}}) where {I} + if TensorKitSectors.FusionStyle(I) == TensorKitSectors.UniqueFusion() + return AbelianStyle() + else + return NotAbelianStyle() + end +end + +trivial(::Type{TensorKitSector{I}}) where {I} = TensorKitSector(one(I)) +GradedUnitRanges.dual(s::TensorKitSector) = TensorKitSector(TensorKitSectors.dual(s.sector)) + +quantum_dimension(x::TensorKitSector) = TensorKitSectors.dim(x.sector) + +function nsymbol(s1::I, s2::I, s3::I) where {I<:TensorKitSector} + return TensorKitSectors.Nsymbol(s1.sector, s2.sector, s3.sector) +end + +function fusion_rule(::AbelianStyle, c1::I, c2::I) where {I<:TensorKitSector} + return TensorKitSector(only(TensorKitSectors.otimes(c1.sector, c2.sector))) +end +function fusion_rule(::NotAbelianStyle, c1::I, c2::I) where {I<:TensorKitSector} + return gradedrange([ + TensorKitSector(c) => nsymbol(c1, c2, TensorKitSector(c)) for + c in TensorKitSectors.otimes(c1.sector, c2.sector) + ]) +end + +Base.:(==)(s1::TensorKitSector, s2::TensorKitSector) = s1.sector == s2.sector +Base.isless(s1::TensorKitSector, s2::TensorKitSector) = isless(s1.sector, s2.sector) + +# Specific implementations +# ------------------------ +const U1 = TensorKitSector{TensorKitSectors.U1Irrep} +sector_label(s::U1) = s.sector.charge +Base.isless(s1::U1, s2::U1) = s1.sector.charge < s2.sector.charge + +const Z{N} = TensorKitSector{TensorKitSectors.ZNIrrep{N}} +sector_label(s::Z) = s.sector.n + +const O2 = TensorKitSector{TensorKitSectors.CU1Irrep} +sector_label(s::O2) = s.sector.s == 1 ? Half(-1) : Half(s.sector.j) +function O2(s::Int) + return s == -1 ? O2(TensorKitSectors.CU1Irrep(0, 1)) : O2(TensorKitSectors.CU1Irrep(s)) +end + +const SU2 = TensorKitSector{TensorKitSectors.SU2Irrep} +sector_label(s::SU2) = s.sector.j + +const Fib = TensorKitSector{TensorKitSectors.FibonacciAnyon} +Fib(s::AbstractString) = Fib( + if s == "1" + :I + elseif s == "τ" + :τ + else + error() + end, +) + +const Ising = TensorKitSector{TensorKitSectors.IsingAnyon} +function sector_label(s::Ising) + label = s.sector.s + return if label === :I + Half(0) + elseif label === :σ + Half(1//2) + else + Half(1) + end +end +Ising(s::AbstractString) = Ising( + if s == "1" + :I + elseif s == "σ" + :σ + elseif s == "ψ" + :ψ + else + error() + end, +) +Ising(s::Number) = Ising( + if s == 0 + :I + elseif s == 1//2 + :σ + elseif s == 1 + :ψ + else + error() + end, +) diff --git a/test/test_symmetrysectors_fusion_rules.jl b/test/test_symmetrysectors_fusion_rules.jl index 053ad99..0fffdf4 100644 --- a/test/test_symmetrysectors_fusion_rules.jl +++ b/test/test_symmetrysectors_fusion_rules.jl @@ -74,7 +74,8 @@ using TestExtras: @constinferred @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( - (@constinferred s12 ⊗ s12), gradedrange([s0o => 1, s0e => 1, s1 => 1]) + (@constinferred s12 ⊗ s12), + gradedrange([s0e => 1, s0o => 1, s1 => 1]), ) @test (@constinferred quantum_dimension(s0o ⊗ s1)) == 2