Skip to content

Commit cad8945

Browse files
authored
Standardized SectorProductIterator (#30)
* Add SectorProductIterator * replace `DNIrrepProdIterator` * Add `show` for SectorProductIterator * replace `CU1ProdIterator` * Replace `SU2IrrepProdIterator` * test printing * Replace `FibonacciIterator` * Replace `IsingIterator` * Replace `IsingBimoduleIterator` * some slight reorganization
1 parent 6178240 commit cad8945

File tree

7 files changed

+97
-57
lines changed

7 files changed

+97
-57
lines changed

src/anyons.jl

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,12 @@ FusionStyle(::Type{FibonacciAnyon}) = SimpleFusion()
8181
BraidingStyle(::Type{FibonacciAnyon}) = Anyonic()
8282
Base.isreal(::Type{FibonacciAnyon}) = false
8383

84-
(a::FibonacciAnyon, b::FibonacciAnyon) = FibonacciIterator(a, b)
84+
const FibonacciAnyonProdIterator = SectorProductIterator{FibonacciAnyon}
8585

86-
struct FibonacciIterator
87-
a::FibonacciAnyon
88-
b::FibonacciAnyon
89-
end
90-
Base.IteratorSize(::Type{FibonacciIterator}) = Base.HasLength()
91-
Base.IteratorEltype(::Type{FibonacciIterator}) = Base.HasEltype()
92-
Base.length(iter::FibonacciIterator) = (isunit(iter.a) || isunit(iter.b)) ? 1 : 2
93-
Base.eltype(::Type{FibonacciIterator}) = FibonacciAnyon
94-
function Base.iterate(iter::FibonacciIterator, state = 1)
86+
Base.IteratorSize(::Type{FibonacciAnyonProdIterator}) = Base.HasLength()
87+
Base.length(iter::FibonacciAnyonProdIterator) = (isunit(iter.a) || isunit(iter.b)) ? 1 : 2
88+
89+
function Base.iterate(iter::FibonacciAnyonProdIterator, state = 1)
9590
I = FibonacciAnyon(:I)
9691
τ = FibonacciAnyon()
9792
if state == 1 # first iteration
@@ -200,23 +195,15 @@ FusionStyle(::Type{IsingAnyon}) = SimpleFusion()
200195
BraidingStyle(::Type{IsingAnyon}) = Anyonic()
201196
Base.isreal(::Type{IsingAnyon}) = false
202197

203-
(a::IsingAnyon, b::IsingAnyon) = IsingIterator(a, b)
204-
205-
struct IsingIterator
206-
a::IsingAnyon
207-
b::IsingAnyon
208-
end
209-
210-
Base.IteratorSize(::Type{IsingIterator}) = Base.HasLength()
211-
Base.IteratorEltype(::Type{IsingIterator}) = Base.HasEltype()
212-
Base.eltype(::Type{IsingIterator}) = IsingAnyon
198+
const IsingAnyonProdIterator = SectorProductIterator{IsingAnyon}
213199

214-
function Base.length(iter::IsingIterator)
200+
Base.IteratorSize(::Type{IsingAnyonProdIterator}) = Base.HasLength()
201+
function Base.length(iter::IsingAnyonProdIterator)
215202
σ = IsingAnyon()
216203
return (iter.a == σ && iter.b == σ) ? 2 : 1
217204
end
218205

219-
function Base.iterate(iter::IsingIterator, state = 1)
206+
function Base.iterate(iter::IsingAnyonProdIterator, state = 1)
220207
I, σ, ψ = all_isinganyons
221208
if state == 1 # first iteration
222209
iter.a == I && return (iter.b, 2)

src/irreps/cu1irrep.jl

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,20 @@ Base.convert(::Type{CU1Irrep}, js::Tuple{Real, Int}) = CU1Irrep(js...)
6969
unit(::Type{CU1Irrep}) = CU1Irrep(zero(HalfInt), 0)
7070
dual(c::CU1Irrep) = c
7171

72-
struct CU1ProdIterator
73-
a::CU1Irrep
74-
b::CU1Irrep
72+
const CU1IrrepProdIterator = SectorProductIterator{CU1Irrep}
73+
74+
Base.IteratorSize(::Type{CU1IrrepProdIterator}) = Base.HasLength()
75+
function Base.length(p::CU1IrrepProdIterator)
76+
if p.a.j == zero(HalfInt) || p.b.j == zero(HalfInt)
77+
return 1
78+
elseif p.a == p.b
79+
return 3
80+
else
81+
return 2
82+
end
7583
end
76-
function Base.iterate(p::CU1ProdIterator, s::Int = 1)
84+
85+
function Base.iterate(p::CU1IrrepProdIterator, s::Int = 1)
7786
if s == 1
7887
if p.a.j == p.b.j == zero(HalfInt)
7988
return CU1Irrep(zero(HalfInt), xor(p.a.s, p.b.s)), 4
@@ -94,18 +103,6 @@ function Base.iterate(p::CU1ProdIterator, s::Int = 1)
94103
return nothing
95104
end
96105
end
97-
function Base.length(p::CU1ProdIterator)
98-
if p.a.j == zero(HalfInt) || p.b.j == zero(HalfInt)
99-
return 1
100-
elseif p.a == p.b
101-
return 3
102-
else
103-
return 2
104-
end
105-
end
106-
Base.eltype(::Type{CU1ProdIterator}) = CU1Irrep
107-
108-
(a::CU1Irrep, b::CU1Irrep) = CU1ProdIterator(a, b)
109106

110107
dim(c::CU1Irrep) = ifelse(c.j == zero(HalfInt), 1, 2)
111108

src/irreps/dnirrep.jl

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,11 @@ end
102102

103103
# Product iterator
104104
# ----------------
105-
struct DNIrrepProdIterator{N}
106-
a::DNIrrep{N}
107-
b::DNIrrep{N}
108-
end
109105

110-
(a::DNIrrep{N}, b::DNIrrep{N}) where {N} = a <= b ? DNIrrepProdIterator(a, b) : DNIrrepProdIterator(b, a)
106+
const DNIrrepProdIterator{N} = SectorProductIterator{DNIrrep{N}}
107+
(a::DNIrrep{N}, b::DNIrrep{N}) where {N} = SectorProductIterator((a <= b ? (a, b) : (b, a))...)
111108

112-
Base.eltype(::Type{DNIrrepProdIterator{N}}) where {N} = DNIrrep{N}
113-
Base.IteratorSize(x::DNIrrepProdIterator) = Base.HasLength()
109+
Base.IteratorSize(::Type{DNIrrepProdIterator{N}}) where {N} = Base.HasLength()
114110
function Base.length(x::DNIrrepProdIterator{N}) where {N}
115111
a, b = x.a, x.b
116112
if a.j == 0 || b.j == 0 || (N == 2 * a.j) || (N == 2 * b.j)

src/irreps/su2irrep.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,15 @@ Base.convert(::Type{SU2Irrep}, j::Real) = SU2Irrep(j)
3232
const _su2one = SU2Irrep(zero(HalfInt))
3333
unit(::Type{SU2Irrep}) = _su2one
3434
dual(s::SU2Irrep) = s
35-
(s1::SU2Irrep, s2::SU2Irrep) = SectorSet{SU2Irrep}(abs(s1.j - s2.j):(s1.j + s2.j))
35+
36+
const SU2IrrepProdIterator = SectorProductIterator{SU2Irrep}
37+
38+
Base.IteratorSize(::Type{SU2IrrepProdIterator}) = Base.HasLength()
39+
Base.length(it::SU2IrrepProdIterator) = length(abs(it.a.j - it.b.j):(it.a.j + it.b.j))
40+
41+
function Base.iterate(it::SU2IrrepProdIterator, state = abs(it.a.j - it.b.j))
42+
return state > (it.a.j + it.b.j) ? nothing : (SU2Irrep(state), state + 1)
43+
end
3644

3745
Base.IteratorSize(::Type{SectorValues{SU2Irrep}}) = IsInfinite()
3846
Base.iterate(::SectorValues{SU2Irrep}, i::Int = 0) = (SU2Irrep(half(i)), i + 1)

src/multifusion.jl

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,12 @@ Base.IteratorSize(::Type{SectorValues{IsingBimodule}}) = Base.SizeUnknown()
2727
Base.iterate(::SectorValues{IsingBimodule}, i = 1) = iterate(all_isingbimod_objects, i)
2828
Base.length(::SectorValues{IsingBimodule}) = length(all_isingbimod_objects)
2929

30-
(a::IsingBimodule, b::IsingBimodule) = IsingBimoduleIterator(a, b)
30+
const IsingBimoduleProdIterator = SectorProductIterator{IsingBimodule}
31+
(a::IsingBimodule, b::IsingBimodule) = SectorProductIterator(a, b)
3132

32-
struct IsingBimoduleIterator
33-
a::IsingBimodule
34-
b::IsingBimodule
35-
end
36-
37-
Base.IteratorSize(::Type{IsingBimoduleIterator}) = Base.SizeUnknown()
38-
Base.IteratorEltype(::Type{IsingBimoduleIterator}) = Base.HasEltype()
39-
Base.eltype(::Type{IsingBimoduleIterator}) = IsingBimodule
33+
Base.IteratorSize(::Type{IsingBimoduleProdIterator}) = Base.SizeUnknown()
4034

41-
function Base.iterate(iter::IsingBimoduleIterator, state = 0)
35+
function Base.iterate(iter::IsingBimoduleProdIterator, state = 0)
4236
a, b = iter.a, iter.b
4337
a.col == b.row || return nothing
4438

src/sectors.jl

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,54 @@ const otimes = ⊗
206206
end
207207
end
208208

209+
"""
210+
SectorProductIterator(a::I, b::I) where {I <: Sector}
211+
212+
Custom iterator to represent the (unique) fusion outputs of ``a ⊗ b``.
213+
214+
Custom sectors that aim to use this have to provide the following functionality:
215+
216+
* `Base.iterate(::SectorProductIterator{I}, state...) where {I <: Sector}`: iterate over
217+
the fusion outputs of `a ⊗ b`
218+
219+
If desired and it is possible to easily compute the number of unique fusion outputs, it is also
220+
possible to define `Base.IteratorSize(::Type{SectorProductIterator{I}}) = Base.HasLength()`, in which
221+
case `Base.length(::SectorProductIterator{I})` has to be implemented.
222+
223+
See also [`⊗`](@ref).
224+
"""
225+
struct SectorProductIterator{I <: Sector}
226+
a::I
227+
b::I
228+
end
229+
230+
(a::I, b::I) where {I <: Sector} = SectorProductIterator(a, b)
231+
232+
Base.IteratorSize(::Type{SectorProductIterator{I}}) where {I} = Base.SizeUnknown()
233+
Base.IteratorEltype(::Type{SectorProductIterator{I}}) where {I} = Base.HasEltype()
234+
Base.eltype(::Type{SectorProductIterator{I}}) where {I} = I
235+
236+
function Base.show(io::IO, it::SectorProductIterator)
237+
show(io, it.a)
238+
print(io, "")
239+
show(io, it.b)
240+
return nothing
241+
end
242+
243+
function Base.show(io::IO, mime::MIME"text/plain", ab::SectorProductIterator)
244+
show(io, ab.a)
245+
print(io, "")
246+
show(io, ab.b)
247+
get(io, :compact, false) && return nothing
248+
print(io, ":")
249+
ioc = IOContext(io, :typeinfo => eltype(ab))
250+
for c in ab
251+
print(io, "\n ")
252+
show(ioc, mime, c)
253+
end
254+
return nothing
255+
end
256+
209257
"""
210258
Nsymbol(a::I, b::I, c::I) where {I<:Sector} -> Integer
211259
@@ -535,7 +583,7 @@ function hexagon_equation(a::I, b::I, c::I; kwargs...) where {I <: Sector}
535583
end
536584

537585
# SectorSet:
538-
#-------------------------------------------------------------------------------
586+
#-------------------------------------------------------------------------------------------
539587
# Custom generator to represent sets of sectors with type inference
540588
struct SectorSet{I <: Sector, F, S}
541589
f::F

test/runtests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ end
8888
@test size(Rsymbol(a, b, c)) == (0, 0)
8989
end
9090

91+
@testset "SectorProduct printing" begin
92+
a = SU2Irrep(1)
93+
@test repr(a a) == "Irrep[SU₂](1) ⊗ Irrep[SU₂](1)"
94+
@test repr("text/plain", a a) == "Irrep[SU₂](1) ⊗ Irrep[SU₂](1):\n 0\n 1\n 2"
95+
96+
b = D4Irrep(1)
97+
@test repr(b b) == "Irrep[D₄](1, false) ⊗ Irrep[D₄](1, false)"
98+
@test repr("text/plain", b b) == "Irrep[D₄](1, false) ⊗ Irrep[D₄](1, false):\n (0, false)\n (0, true)\n (2, false)\n (2, true)"
99+
end
100+
91101
include("multifusion.jl")
92102

93103
@testset "Aqua" begin

0 commit comments

Comments
 (0)