Skip to content

Commit

Permalink
refactor shared_product_sectors_fusion_rule
Browse files Browse the repository at this point in the history
  • Loading branch information
ogauthe committed Oct 21, 2024
1 parent 00fd5f8 commit 435f775
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 68 deletions.
44 changes: 13 additions & 31 deletions NDTensors/src/lib/SymmetrySectors/src/sector_product.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,33 +122,6 @@ product_sectors_fusion_rule(::NamedTuple{()}, sects::Tuple) = SectorProduct(sect
product_sectors_fusion_rule(sects::NamedTuple, ::Tuple{}) = SectorProduct(sects)
product_sectors_fusion_rule(::Tuple{}, sects::NamedTuple) = SectorProduct(sects)

function fix_fused_product_type(Sectors::Type, fused)
return fix_fused_product_type(product_sectors_symmetrystyle(Sectors), Sectors, fused)
end

function fix_fused_product_type(::AbelianStyle, Sectors::Type, fused)
return recover_sector_product_type(Sectors, fused)
end

function fix_fused_product_type(::NotAbelianStyle, Sectors::Type, fused)
# convert e.g. Tuple{GradedUnitRange{SU2}, GradedUnitRange{SU2}} into GradedUnitRange{SU2×SU2}
g = reduce(×, fused)
# convention: keep unsorted blocklabels as produced by F order loops in ×
return recover_gradedaxis_product_type(Sectors, g)
end

function recover_gradedaxis_product_type(Sectors::Type, g0::AbstractGradedUnitRange)
old_labels = blocklabels(g0)
old_sects = product_sectors.(SectorProduct.(old_labels))
new_labels = recover_sector_product_type.(Sectors, old_sects)
new_blocklengths = labelled.(unlabel.(blocklengths(g0)), new_labels)
return gradedrange(new_blocklengths)
end

function recover_sector_product_type(Sectors::Type, sects)
return SectorProduct(Sectors(sects))
end

# ================================= Cartesian Product ====================================
×(c1::AbstractSector, c2::AbstractSector) = ×(SectorProduct(c1), SectorProduct(c2))
function ×(p1::SectorProduct, p2::SectorProduct)
Expand Down Expand Up @@ -228,8 +201,13 @@ function product_sectors_diff(t1::Tuple, t2::Tuple)
end

function shared_product_sectors_fusion_rule(shared1::T, shared2::T) where {T<:Tuple}
fused = map(fusion_rule, shared1, shared2)
return fix_fused_product_type(T, fused)
return mapreduce(
to_gradedrange fusion_rule,
×,
shared1,
shared2;
init=to_gradedrange(SectorProduct(())),
)
end

function product_sectors_insert_unspecified(t1::Tuple, t2::Tuple)
Expand Down Expand Up @@ -282,7 +260,11 @@ end

product_sectors_diff(nt1::NamedTuple, nt2::NamedTuple) = symdiff_keys(nt1, nt2)

function map_blocklabels(f, r::AbstractUnitRange)
return gradedrange(labelled.(unlabel.(blocklengths(r)), f.(blocklabels(r))))
end

function shared_product_sectors_fusion_rule(shared1::NT, shared2::NT) where {NT<:NamedTuple}
fused = map(fusion_rule, values(shared1), values(shared2))
return fix_fused_product_type(NT, fused)
tuple_fused = shared_product_sectors_fusion_rule(values(shared1), values(shared2))
return map_blocklabels(SectorProduct NT product_sectors SectorProduct, tuple_fused)
end
64 changes: 27 additions & 37 deletions NDTensors/src/lib/SymmetrySectors/test/test_sector_product.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ using NDTensors.SymmetrySectors:
Z,
block_dimensions,
quantum_dimension,
recover_sector_product_type,
product_sectors,
trivial
using NDTensors.GradedAxes: dual, fusion_product, space_isequal, gradedrange
Expand Down Expand Up @@ -43,9 +42,6 @@ using Test: @inferred, @test, @testset, @test_throws
@test product_sectors(s)[2] == SU2(1//2)
@test product_sectors(s)[3] == U1(3)
@test (@inferred trivial(s)) == SectorProduct(U1(0), SU2(0), U1(0))
@test (@inferred recover_sector_product_type(
typeof(product_sectors(s)), product_sectors(s)
)) == s

s = U1(3) × SU2(1//2) × Fib("τ")
@test length(product_sectors(s)) == 3
Expand Down Expand Up @@ -146,14 +142,14 @@ using Test: @inferred, @test, @testset, @test_throws
@test (@inferred p1 p2) == SectorProduct(U1(3))

p11 = U1(1) × U1(1)
@test (@inferred p11 p11) == U1(2) × U1(2)
@test p11 p11 == U1(2) × U1(2)

p123 = U1(1) × U1(2) × U1(3)
@test (@inferred p123 p123) == U1(2) × U1(4) × U1(6)
@test p123 p123 == U1(2) × U1(4) × U1(6)

s1 = SectorProduct(U1(1), Z{2}(1))
s2 = SectorProduct(U1(0), Z{2}(0))
@test (@inferred s1 s2) == U1(1) × Z{2}(1)
@test s1 s2 == U1(1) × Z{2}(1)
end

@testset "Fusion of NonAbelian products" begin
Expand All @@ -177,7 +173,7 @@ using Test: @inferred, @test, @testset, @test_throws
]),
)
@test space_isequal(
(@inferred phh phh),
phh phh,
gradedrange([
(SU2(0) × SU2(0)) => 1,
(SU2(1) × SU2(0)) => 1,
Expand All @@ -191,12 +187,11 @@ using Test: @inferred, @test, @testset, @test_throws
ı = Fib("1")
τ = Fib("τ")
s = ı × ı
@test space_isequal((@inferred s s), gradedrange([s => 1]))
@test space_isequal(s s, gradedrange([s => 1]))

s = τ × τ
@test space_isequal(
(@inferred s s),
gradedrange([(ı × ı) => 1, (τ × ı) => 1, (ı × τ) => 1, (τ × τ) => 1]),
s s, gradedrange([(ı × ı) => 1, (τ × ı) => 1, (ı × τ) => 1, (τ × τ) => 1])
)

σ = Ising("σ")
Expand All @@ -205,27 +200,27 @@ using Test: @inferred, @test, @testset, @test_throws
g = gradedrange([
× Ising("1")) => 1, (τ × Ising("1")) => 1, (ı × ψ) => 1, (τ × ψ) => 1
])
@test space_isequal((@inferred s s), g)
@test space_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(
(@inferred p2h p1h), gradedrange([(U1(3) × SU2(0)) => 1, (U1(3) × SU2(1)) => 1])
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(
(@inferred p1h1 p1h1),
p1h1 p1h1,
gradedrange([(U1(2) × SU2(0) × Z{2}(0)) => 1, (U1(2) × SU2(1) × Z{2}(0)) => 1]),
)
end

@testset "Fusion of fully mixed products" begin
s = U1(1) × SU2(1//2) × Ising("σ")
@test space_isequal(
(@inferred s s),
s s,
gradedrange([
(U1(2) × SU2(0) × Ising("1")) => 1,
(U1(2) × SU2(1) × Ising("1")) => 1,
Expand All @@ -238,7 +233,7 @@ using Test: @inferred, @test, @testset, @test_throws
τ = Fib("τ")
s = SU2(1//2) × U1(1) × τ
@test space_isequal(
(@inferred s s),
s s,
gradedrange([
(SU2(0) × U1(2) × ı) => 1,
(SU2(1) × U1(2) × ı) => 1,
Expand All @@ -248,9 +243,7 @@ using Test: @inferred, @test, @testset, @test_throws
)

s = U1(1) × ı × τ
@test space_isequal(
(@inferred s s), gradedrange([(U1(2) × ı × ı) => 1, (U1(2) × ı × τ) => 1])
)
@test space_isequal(s s, gradedrange([(U1(2) × ı × ı) => 1, (U1(2) × ı × τ) => 1]))
end

@testset "Fusion of different length Categories" begin
Expand Down Expand Up @@ -282,7 +275,7 @@ using Test: @inferred, @test, @testset, @test_throws
g1 = gradedrange([s1 => 2])
g2 = gradedrange([s2 => 1])
@test space_isequal(
(@inferred fusion_product(g1, g2)),
fusion_product(g1, g2),
gradedrange([U1(1) × SU2(0) × Ising("σ") => 2, U1(1) × SU2(1) × Ising("σ") => 2]),
)
end
Expand All @@ -305,9 +298,6 @@ end
@test (@inferred quantum_dimension(s)) == 5
@test (@inferred dual(s)) == (A=U1(-1),) × (B=SU2(2),)
@test (@inferred trivial(s)) == (A=U1(0),) × (B=SU2(0),)
@test (@inferred recover_sector_product_type(
typeof(product_sectors(s)), Tuple(product_sectors(s))
)) == s
@test s == (B=SU2(2),) × (A=U1(1),)

s = s × (C=Ising("ψ"),)
Expand Down Expand Up @@ -418,15 +408,15 @@ end
@test (@inferred q01 q00) == q01
@test (@inferred q00 q01) == q01
@test (@inferred q10 q01) == q11
@test (@inferred q11 q11) == SectorProduct(; A=U1(2), B=U1(2))
@test q11 q11 == SectorProduct(; A=U1(2), B=U1(2))

s11 = SectorProduct(; A=U1(1), B=Z{2}(1))
s10 = SectorProduct(; A=U1(1))
s01 = SectorProduct(; B=Z{2}(1))
@test (@inferred s01 q00) == s01
@test (@inferred q00 s01) == s01
@test (@inferred s10 s01) == s11
@test (@inferred s11 s11) == SectorProduct(; A=U1(2), B=Z{2}(0))
@test s11 s11 == SectorProduct(; A=U1(2), B=Z{2}(0))
end

@testset "Fusion of NonAbelian products" begin
Expand All @@ -444,7 +434,7 @@ end
@test space_isequal((@inferred pha phb), gradedrange([phab => 1]))

@test space_isequal(
(@inferred phab phab),
phab phab,
gradedrange([
SectorProduct(; A=SU2(0), B=SU2(0)) => 1,
SectorProduct(; A=SU2(1), B=SU2(0)) => 1,
Expand All @@ -458,11 +448,11 @@ end
ı = Fib("1")
τ = Fib("τ")
s = SectorProduct(; A=ı, B=ı)
@test space_isequal((@inferred s s), gradedrange([s => 1]))
@test space_isequal(s s, gradedrange([s => 1]))

s = SectorProduct(; A=τ, B=τ)
@test space_isequal(
(@inferred s s),
s s,
gradedrange([
SectorProduct(; A=ı, B=ı) => 1,
SectorProduct(; A=τ, B=ı) => 1,
Expand All @@ -480,7 +470,7 @@ end
SectorProduct(; A=ı, B=ψ) => 1,
SectorProduct(; A=τ, B=ψ) => 1,
])
@test space_isequal((@inferred s s), g)
@test space_isequal(s s, g)
end

@testset "Fusion of mixed Abelian and NonAbelian products" begin
Expand All @@ -494,16 +484,16 @@ end
q21 = (N=U1(2),) × (J=SU2(1),)
q22 = (N=U1(2),) × (J=SU2(2),)

@test space_isequal((@inferred q1h q1h), gradedrange([q20 => 1, q21 => 1]))
@test space_isequal((@inferred q10 q1h), gradedrange([q2h => 1]))
@test space_isequal(q1h q1h, gradedrange([q20 => 1, q21 => 1]))
@test space_isequal(q10 q1h, gradedrange([q2h => 1]))
@test space_isequal((@inferred q0h q1h), gradedrange([q10 => 1, q11 => 1]))
@test space_isequal((@inferred q11 q11), gradedrange([q20 => 1, q21 => 1, q22 => 1]))
@test space_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(
(@inferred s s),
s s,
gradedrange([
SectorProduct(; A=U1(2), B=SU2(0), C=Ising("1")) => 1,
SectorProduct(; A=U1(2), B=SU2(1), C=Ising("1")) => 1,
Expand All @@ -516,7 +506,7 @@ end
τ = Fib("τ")
s = SectorProduct(; A=SU2(1//2), B=U1(1), C=τ)
@test space_isequal(
(@inferred s s),
s s,
gradedrange([
SectorProduct(; A=SU2(0), B=U1(2), C=ı) => 1,
SectorProduct(; A=SU2(1), B=U1(2), C=ı) => 1,
Expand All @@ -527,7 +517,7 @@ end

s = SectorProduct(; A=τ, B=U1(1), C=ı)
@test space_isequal(
(@inferred s s),
s s,
gradedrange([
SectorProduct(; B=U1(2), A=ı, C=ı) => 1, SectorProduct(; B=U1(2), A=τ, C=ı) => 1
]),
Expand All @@ -540,14 +530,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((@inferred fusion_product(g1, g2)), gradedrange([s3 => 2, s4 => 2]))
@test space_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((@inferred fusion_product(gA, gB)), gradedrange([sAB => 2]))
@test space_isequal(fusion_product(gA, gB), gradedrange([sAB => 2]))
end
end

Expand Down

0 comments on commit 435f775

Please sign in to comment.