Skip to content

Commit b281788

Browse files
committed
split up fusiontree tests
1 parent b4b1377 commit b281788

3 files changed

Lines changed: 490 additions & 696 deletions

File tree

test/symmetries/doubletree.jl

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

0 commit comments

Comments
 (0)