Skip to content

Commit 2295e2c

Browse files
committed
split up fusiontree tests
1 parent b4b1377 commit 2295e2c

3 files changed

Lines changed: 488 additions & 696 deletions

File tree

test/symmetries/doubletree.jl

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
using Test, TestExtras
2+
using TensorKit
3+
import TensorKit as TK
4+
using Random: randperm
5+
using TensorOperations
6+
7+
# TODO: remove this once type_repr works for all included types
8+
using TensorKitSectors
9+
10+
11+
@timedtestset "Fusion trees for $(TensorKit.type_repr(I))" verbose = true for I in (fast_tests ? fast_sectorlist : sectorlist)
12+
Istr = TensorKit.type_repr(I)
13+
N = I <: ProductSector ? 3 : 4
14+
15+
if UnitStyle(I) isa SimpleUnit
16+
out = random_fusion(I, Val(N))
17+
numtrees = count(n -> true, fusiontrees((out..., map(dual, out)...)))
18+
while !(0 < numtrees < 100)
19+
out = random_fusion(I, Val(N))
20+
numtrees = count(n -> true, fusiontrees((out..., map(dual, out)...)))
21+
end
22+
incoming = rand(collect((out...)))
23+
f1 = rand(collect(fusiontrees(out, incoming, ntuple(n -> rand(Bool), N))))
24+
f2 = rand(collect(fusiontrees(out[randperm(N)], incoming, ntuple(n -> rand(Bool), N))))
25+
else
26+
out = random_fusion(I, Val(N))
27+
out2 = random_fusion(I, Val(N))
28+
tp = (out...)
29+
tp2 = (out2...)
30+
while isempty(intersect(tp, tp2)) # guarantee fusion to same coloring
31+
out2 = random_fusion(I, Val(N))
32+
tp2 = (out2...)
33+
end
34+
@test_throws ArgumentError fusiontrees((out..., map(dual, out)...))
35+
incoming = rand(collect(intersect(tp, tp2)))
36+
f1 = rand(collect(fusiontrees(out, incoming, ntuple(n -> rand(Bool), N))))
37+
f2 = rand(collect(fusiontrees(out2, incoming, ntuple(n -> rand(Bool), N)))) # no permuting
38+
end
39+
40+
if FusionStyle(I) isa UniqueFusion
41+
f1 = rand(collect(fusiontrees(out, incoming, ntuple(n -> rand(Bool), N))))
42+
f2 = rand(collect(fusiontrees(out[randperm(N)], incoming, ntuple(n -> rand(Bool), N))))
43+
src = (f1, f2)
44+
if (BraidingStyle(I) isa Bosonic) && hasfusiontensor(I)
45+
A = fusiontensor(src)
46+
end
47+
else
48+
src = FusionTreeBlock{I}((out, out), (ntuple(n -> rand(Bool), N), ntuple(n -> rand(Bool), N)))
49+
if (BraidingStyle(I) isa Bosonic) && hasfusiontensor(I)
50+
A = map(fusiontensor, fusiontrees(src))
51+
end
52+
end
53+
54+
@testset "Double fusion tree: bending" begin
55+
# single bend
56+
dst, U = @constinferred TK.bendright(src)
57+
dst2, U2 = @constinferred TK.bendleft(dst)
58+
@test src == dst2
59+
@test _isone(U2 * U)
60+
# double bend
61+
dst1, U1 = @constinferred TK.bendleft(src)
62+
dst2, U2 = @constinferred TK.bendleft(dst1)
63+
dst3, U3 = @constinferred TK.bendright(dst2)
64+
dst4, U4 = @constinferred TK.bendright(dst3)
65+
@test src == dst4
66+
@test _isone(U4 * U3 * U2 * U1)
67+
68+
if (BraidingStyle(I) isa Bosonic) && hasfusiontensor(I)
69+
all_inds = (ntuple(identity, numout(src))..., reverse(ntuple(i -> i + numout(src), numin(src)))...)
70+
p₁ = ntuple(i -> all_inds[i], numout(dst2))
71+
p₂ = reverse(ntuple(i -> all_inds[i + numout(dst2)], numin(dst2)))
72+
U = U2 * U1
73+
if FusionStyle(I) isa UniqueFusion
74+
@test permutedims(A, (p₁..., p₂...)) U * fusiontensor(dst)
75+
else
76+
A′ = map(Base.Fix2(permutedims, (p₁..., p₂...)), A)
77+
A″ = map(fusiontensor, fusiontrees(dst2))
78+
for (i, Ai) in enumerate(A′)
79+
@test Ai sum(A″ .* U[:, i])
80+
end
81+
end
82+
end
83+
end
84+
85+
@testset "Double fusion tree: folding" begin
86+
# single bend
87+
dst, U = @constinferred TK.foldleft(src)
88+
dst2, U2 = @constinferred TK.foldright(dst)
89+
@test src == dst2
90+
@test _isone(U2 * U)
91+
# double bend
92+
dst1, U1 = @constinferred TK.foldright(src)
93+
dst2, U2 = @constinferred TK.foldright(dst1)
94+
dst3, U3 = @constinferred TK.foldleft(dst2)
95+
dst4, U4 = @constinferred TK.foldleft(dst3)
96+
@test src == dst4
97+
@test _isone(U4 * U3 * U2 * U1)
98+
99+
if (BraidingStyle(I) isa Bosonic) && hasfusiontensor(I)
100+
all_inds = TupleTools.circshift((ntuple(identity, numout(src))..., reverse(ntuple(i -> i + numout(src), numin(src)))...), -2)
101+
p₁ = ntuple(i -> all_inds[i], numout(dst2))
102+
p₂ = reverse(ntuple(i -> all_inds[i + numout(dst2)], numin(dst2)))
103+
U = U2 * U1
104+
if FusionStyle(I) isa UniqueFusion
105+
@test permutedims(A, (p₁..., p₂...)) U * fusiontensor(dst2)
106+
else
107+
A′ = map(Base.Fix2(permutedims, (p₁..., p₂...)), A)
108+
A″ = map(fusiontensor, fusiontrees(dst2))
109+
for (i, Ai) in enumerate(A′)
110+
@test Ai sum(A″ .* U[:, i])
111+
end
112+
end
113+
end
114+
end
115+
116+
@testset "Double fusion tree: repartitioning" begin
117+
for n in 0:(2 * N)
118+
dst, U = @constinferred TK.repartition(src, $n)
119+
# @test _isunitary(U)
120+
121+
dst′, U′ = repartition(dst, N)
122+
@test _isone(U * U′)
123+
124+
if (BraidingStyle(I) isa Bosonic) && hasfusiontensor(I)
125+
all_inds = (ntuple(identity, numout(src))..., reverse(ntuple(i -> i + numout(src), numin(src)))...)
126+
p₁ = ntuple(i -> all_inds[i], numout(dst))
127+
p₂ = reverse(ntuple(i -> all_inds[i + numout(dst)], numin(dst)))
128+
if FusionStyle(I) isa UniqueFusion
129+
@test permutedims(A, (p₁..., p₂...)) U * fusiontensor(dst)
130+
else
131+
A′ = map(Base.Fix2(permutedims, (p₁..., p₂...)), A)
132+
A″ = map(fusiontensor, fusiontrees(dst))
133+
for (i, Ai) in enumerate(A′)
134+
@test Ai sum(A″ .* U[:, i])
135+
end
136+
end
137+
end
138+
end
139+
end
140+
141+
@testset "Double fusion tree: transposition" begin
142+
for n in 0:(2N)
143+
i0 = rand(1:(2N))
144+
p = mod1.(i0 .+ (1:(2N)), 2N)
145+
ip = mod1.(-i0 .+ (1:(2N)), 2N)
146+
p′ = tuple(getindex.(Ref(vcat(1:N, (2N):-1:(N + 1))), p)...)
147+
p1, p2 = p′[1:n], p′[(2N):-1:(n + 1)]
148+
ip′ = tuple(getindex.(Ref(vcat(1:n, (2N):-1:(n + 1))), ip)...)
149+
ip1, ip2 = ip′[1:N], ip′[(2N):-1:(N + 1)]
150+
151+
dst, U = @constinferred transpose(src, (p1, p2))
152+
dst′, U′ = @constinferred transpose(dst, (ip1, ip2))
153+
@test _isone(U * U′)
154+
155+
if BraidingStyle(I) isa Bosonic
156+
dst″, U″ = permute(src, (p1, p2))
157+
@test U″ U
158+
end
159+
160+
if (BraidingStyle(I) isa Bosonic) && hasfusiontensor(I)
161+
if FusionStyle(I) isa UniqueFusion
162+
@test permutedims(A, (p1..., p2...)) U * fusiontensor(dst)
163+
else
164+
A′ = map(Base.Fix2(permutedims, (p1..., p2...)), A)
165+
A″ = map(fusiontensor, fusiontrees(dst))
166+
for (i, Ai) in enumerate(A′)
167+
@test Ai sum(U[:, i] .* A″)
168+
end
169+
end
170+
end
171+
end
172+
end
173+
TK.empty_globalcaches!()
174+
end

0 commit comments

Comments
 (0)