Skip to content

Commit 0f485a2

Browse files
committed
clean-up categories_fusion_rule
1 parent 2684005 commit 0f485a2

File tree

2 files changed

+46
-19
lines changed

2 files changed

+46
-19
lines changed

NDTensors/src/lib/Sectors/src/category_product.jl

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
using BlockArrays: blocklengths
55
using ..LabelledNumbers: LabelledInteger, label, labelled, unlabel
6-
using ..GradedAxes: GradedAxes, dual
6+
using ..GradedAxes: AbstractGradedUnitRange, GradedAxes, dual
77

88
# ===================================== Definition =======================================
99
struct CategoryProduct{Categories} <: AbstractCategory
@@ -67,13 +67,6 @@ end
6767
# - ordered-like with a Tuple
6868
# - dictionary-like with a NamedTuple
6969

70-
function categories_fusion_rule(cats1, cats2)
71-
diff_cat = CategoryProduct(categories_diff(cats1, cats2))
72-
shared1, shared2 = categories_common(cats1, cats2)
73-
fused = map(fusion_rule, values(shared1), values(shared2))
74-
return recover_key(typeof(shared1), fused) × diff_cat
75-
end
76-
7770
# get clean results when mixing implementations
7871
categories_isequal(::Tuple, ::NamedTuple) = false
7972
categories_isequal(::NamedTuple, ::Tuple) = false
@@ -83,20 +76,50 @@ categories_isless(::Tuple, ::NamedTuple) = throw(ArgumentError("Not implemented"
8376

8477
categories_type(::Type{<:CategoryProduct{T}}) where {T} = T
8578

86-
recover_key(T::Type, t::Tuple{Vararg{AbstractCategory}}) = sector(T, t)
87-
recover_key(T::Type, c::AbstractCategory) = recover_key(T, (c,))
88-
recover_key(T::Type, c::CategoryProduct) = recover_key(T, categories(c))
89-
function recover_key(T::Type, fused::Tuple)
79+
function categories_fusion_rule(cats1, cats2)
80+
diff_cat = CategoryProduct(categories_diff(cats1, cats2))
81+
shared1, shared2 = categories_common(cats1, cats2)
82+
fused = map(fusion_rule, values(shared1), values(shared2))
83+
factorized = factorize_gradedaxes(fused)
84+
type_fixed = recover_category_product_type(typeof(shared1), factorized)
85+
return type_fixed × diff_cat
86+
end
87+
88+
# abelian case: there is no gradedaxis
89+
factorize_gradedaxes(fused::Tuple{Vararg{AbstractCategory}}) = fused
90+
91+
# non-abelian case
92+
function factorize_gradedaxes(fused::Tuple)
9093
# here fused contains at least one GradedOneTo
9194
g0 = reduce(×, fused)
9295
# convention: keep unsorted blocklabels as produced by F order loops in ×
93-
new_labels = recover_key.(T, blocklabels(g0))
96+
return g0
97+
end
98+
99+
function recover_category_product_type(T::Type, g0::AbstractGradedUnitRange)
100+
new_labels = recover_category_product_type.(T, blocklabels(g0))
94101
new_blocklengths = labelled.(unlabel.(blocklengths(g0)), new_labels)
95102
return gradedrange(new_blocklengths)
96103
end
97104

98-
sector(T::Type{<:CategoryProduct}, cats::Tuple) = sector(categories_type(T), cats)
99-
sector(T::Type, cats::Tuple) = sector(T(cats)) # recover NamedTuple
105+
function recover_category_product_type(T::Type, c::AbstractCategory)
106+
return recover_category_product_type(T, CategoryProduct(c))
107+
end
108+
109+
function recover_category_product_type(T::Type, c::CategoryProduct)
110+
return recover_category_product_type(T, categories(c))
111+
end
112+
113+
function recover_category_product_type(
114+
T::Type{<:CategoryProduct}, cats::Tuple{Vararg{AbstractCategory}}
115+
)
116+
return recover_category_product_type(categories_type(T), cats)
117+
end
118+
119+
function recover_category_product_type(T::Type, cats::Tuple{Vararg{AbstractCategory}})
120+
return CategoryProduct(T(cats))
121+
end
122+
100123
sector(args...; kws...) = CategoryProduct(args...; kws...)
101124

102125
# ================================= Cartesian Product ====================================

NDTensors/src/lib/Sectors/test/test_category_product.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ using NDTensors.Sectors:
1111
block_dimensions,
1212
categories,
1313
quantum_dimension,
14+
recover_category_product_type,
1415
sector,
1516
trivial
1617
using NDTensors.GradedAxes: dual, fusion_product, gradedisequal, gradedrange
@@ -48,8 +49,9 @@ end
4849
@test categories(s)[2] == SU2(1//2)
4950
@test categories(s)[3] == U1(3)
5051
@test (@inferred_latest trivial(s)) == sector(U1(0), SU2(0), U1(0))
51-
@test (@inferred sector(typeof(categories(s)), categories(s))) == s
52-
@test (@inferred sector(typeof(s), categories(s))) == s
52+
@test (@inferred recover_category_product_type(typeof(categories(s)), categories(s))) ==
53+
s
54+
@test (@inferred recover_category_product_type(typeof(s), categories(s))) == s
5355

5456
s = U1(3) × SU2(1//2) × Fib("τ")
5557
@test length(categories(s)) == 3
@@ -288,8 +290,10 @@ end
288290
@test (@inferred quantum_dimension(s)) == 5
289291
@test (@inferred dual(s)) == (A=U1(-1),) × (B=SU2(2),)
290292
@test (@inferred_latest trivial(s)) == (A=U1(0),) × (B=SU2(0),)
291-
@test (@inferred sector(typeof(categories(s)), Tuple(categories(s)))) == s
292-
@test (@inferred sector(typeof(s), Tuple(categories(s)))) == s
293+
@test (@inferred recover_category_product_type(
294+
typeof(categories(s)), Tuple(categories(s))
295+
)) == s
296+
@test (@inferred recover_category_product_type(typeof(s), Tuple(categories(s)))) == s
293297

294298
s = s × (C=Ising("ψ"),)
295299
@test length(categories(s)) == 3

0 commit comments

Comments
 (0)