@@ -15,46 +15,39 @@ using GradedUnitRanges:
1515 sector_type,
1616 space_isequal
1717using SymmetrySectors: SectorProduct, TrivialSector
18+ using TensorAlgebra: BlockedTuple, tuplemortar
1819
19- struct FusionTensor{T,N,CoDomainAxes,DomainAxes ,Mat,Mapping} <: AbstractArray{T,N}
20+ struct FusionTensor{T,N,Axes ,Mat,Mapping} <: AbstractArray{T,N}
2021 data_matrix:: Mat
21- codomain_axes:: CoDomainAxes
22- domain_axes:: DomainAxes
22+ axes:: Axes
2323 trees_block_mapping:: Mapping
2424
2525 # inner constructor to impose constraints on types
2626 function FusionTensor (
2727 mat:: AbstractMatrix ,
28- codomain_legs:: Tuple{Vararg{AbstractGradedUnitRange}} ,
29- domain_legs:: Tuple{Vararg{AbstractGradedUnitRange}} ,
28+ legs:: BlockedTuple{2,<:Any,<:Tuple{Vararg{AbstractGradedUnitRange}}} ,
3029 trees_block_mapping:: Dict ,
3130 )
3231 S = sector_type (axes (mat, 1 ))
3332 @assert sector_type (axes (mat, 2 )) === S
3433 @assert keytype (trees_block_mapping) < :
3534 Tuple{<: SectorFusionTree{S} ,<: SectorFusionTree{S} }
36- @assert all (sector_type .(codomain_legs) .=== S)
37- @assert all (sector_type .(domain_legs) .=== S)
35+ @assert all (sector_type .(Tuple (legs)) .=== S)
3836 return new{
39- eltype (mat),
40- length (codomain_legs) + length (domain_legs),
41- typeof (codomain_legs),
42- typeof (domain_legs),
43- typeof (mat),
44- typeof (trees_block_mapping),
37+ eltype (mat),length (legs),typeof (legs),typeof (mat),typeof (trees_block_mapping)
4538 }(
46- mat, codomain_legs, domain_legs , trees_block_mapping
39+ mat, legs , trees_block_mapping
4740 )
4841 end
4942end
5043
5144# getters
5245data_matrix (ft:: FusionTensor ) = ft. data_matrix
53- codomain_axes (ft:: FusionTensor ) = ft. codomain_axes
54- domain_axes (ft:: FusionTensor ) = ft. domain_axes
5546trees_block_mapping (ft:: FusionTensor ) = ft. trees_block_mapping
5647
5748# misc access
49+ codomain_axes (ft:: FusionTensor ) = first (blocks (axes (ft)))
50+ domain_axes (ft:: FusionTensor ) = last (blocks (axes (ft)))
5851ndims_codomain (ft:: FusionTensor ) = length (codomain_axes (ft))
5952ndims_domain (ft:: FusionTensor ) = length (domain_axes (ft))
6053
6861
6962# GradedUnitRanges interface
7063function GradedUnitRanges. sector_type (
71- :: Type {<: FusionTensor{<:Any,<:Any,<:Any,<:Any,<:Any,<: Dict{<:Tuple{<:Any,F}}} }
64+ :: Type {<: FusionTensor{<:Any,<:Any,<:Any,<:Any,<:Dict{<:Tuple{<:Any,F}}} }
7265) where {F}
7366 return sector_type (F)
7467end
@@ -91,16 +84,10 @@ function sanitize_axes(raw_legs::Tuple{Vararg{AbstractGradedUnitRange}})
9184 @assert all (check_unique_blocklabels .(legs))
9285 return legs
9386end
94- sanitize_axes (:: Tuple{} , :: Tuple{} ) = TrivialSector, (), ()
95- function sanitize_axes (
96- codomain_legs_raw:: Tuple{Vararg{AbstractGradedUnitRange}} ,
97- domain_legs_raw:: Tuple{Vararg{AbstractGradedUnitRange}} ,
98- )
99- legs = sanitize_axes ((codomain_legs_raw... , domain_legs_raw... ))
100- S = sector_type (first (legs))
101- codomain_legs = legs[begin : length (codomain_legs_raw)]
102- domain_legs = legs[(length (codomain_legs_raw) + 1 ): end ]
103- return S, domain_legs, codomain_legs
87+ sanitize_axes (legs:: BlockedTuple{2,(0, 0)} ) = TrivialSector, legs
88+ function sanitize_axes (raw_legs:: BlockedTuple{2} )
89+ flat_legs = sanitize_axes (Tuple (raw_legs))
90+ return sector_type (first (flat_legs)), BlockedTuple (flat_legs, Val (blocklengths (raw_legs)))
10491end
10592
10693function check_unique_blocklabels (g:: AbstractGradedUnitRange )
@@ -131,12 +118,16 @@ end
131118
132119# initialize with already computed data_matrix
133120function FusionTensor (
134- mat :: AbstractMatrix ,
121+ x ,
135122 codomain_legs:: Tuple{Vararg{AbstractGradedUnitRange}} ,
136123 domain_legs:: Tuple{Vararg{AbstractGradedUnitRange}} ,
137124)
125+ return FusionTensor (x, tuplemortar ((codomain_legs, domain_legs)))
126+ end
127+
128+ function FusionTensor (mat:: AbstractMatrix , legs:: BlockedTuple{2} )
138129 # init with empty data_matrix to construct trees_block_mapping
139- ft = FusionTensor (eltype (mat), codomain_legs, domain_legs )
130+ ft = FusionTensor (eltype (mat), legs )
140131 @assert space_isequal (matrix_row_axis (ft), axes (mat, 1 ))
141132 @assert space_isequal (matrix_column_axis (ft), axes (mat, 2 ))
142133 for b in eachblockstoredindex (mat)
@@ -147,21 +138,17 @@ function FusionTensor(
147138end
148139
149140# empty matrix
150- function FusionTensor (
151- elt:: Type ,
152- codomain_legs_raw:: Tuple{Vararg{AbstractGradedUnitRange}} ,
153- domain_legs_raw:: Tuple{Vararg{AbstractGradedUnitRange}} ,
154- )
155- S, domain_legs, codomain_legs = sanitize_axes (codomain_legs_raw, domain_legs_raw)
141+ function FusionTensor (elt:: Type , raw_legs:: BlockedTuple{2} )
142+ S, legs = sanitize_axes (raw_legs)
156143
157- row_axis, codomain_trees_to_ranges_mapping = fuse_axes (S, codomain_legs )
158- nondual_col_axis, domain_trees_to_ranges_mapping = fuse_axes (S, dual .(domain_legs ))
144+ row_axis, codomain_trees_to_ranges_mapping = fuse_axes (S, first ( blocks (legs)) )
145+ nondual_col_axis, domain_trees_to_ranges_mapping = fuse_axes (S, dual .(last ( blocks (legs)) ))
159146
160147 mat = initialize_data_matrix (elt, row_axis, nondual_col_axis)
161148 tree_to_block_mapping = intersect_codomain_domain (
162149 codomain_trees_to_ranges_mapping, domain_trees_to_ranges_mapping
163150 )
164- return FusionTensor (mat, codomain_legs, domain_legs , tree_to_block_mapping)
151+ return FusionTensor (mat, legs , tree_to_block_mapping)
165152end
166153
167154function fuse_axes (:: Type{S} , :: Tuple{} ) where {S<: AbstractSector }
@@ -178,14 +165,19 @@ end
178165function fusion_trees_external_multiplicities (
179166 outer_legs:: Tuple{Vararg{AbstractGradedUnitRange}}
180167)
181- tree_arrows = isdual .(outer_legs)
182168 return mapreduce (vcat, CartesianIndices (blocklength .(outer_legs))) do it
183- block_sectors = map ((g, i) -> blocklabels (g)[i], outer_legs, Tuple (it))
184- block_mult = mapreduce ((g, i) -> blocklengths (g)[i], * , outer_legs, Tuple (it); init= 1 )
185- return build_trees (block_sectors, tree_arrows) .=> block_mult
169+ return fusion_trees_external_multiplicities (outer_legs, Tuple (it))
186170 end
187171end
188172
173+ function fusion_trees_external_multiplicities (
174+ outer_legs:: NTuple{N,AbstractGradedUnitRange} , indices:: NTuple{N,Int}
175+ ) where {N}
176+ block_sectors = map ((g, i) -> blocklabels (g)[i], outer_legs, indices)
177+ block_mult = mapreduce ((g, i) -> blocklengths (g)[i], * , outer_legs, indices; init= 1 )
178+ return build_trees (block_sectors, isdual .(outer_legs)) .=> block_mult
179+ end
180+
189181function compute_inner_ranges (
190182 fusion_trees_mult:: AbstractVector{<:Pair{<:SectorFusionTree,<:Integer}}
191183)
0 commit comments