-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmultifusion.jl
More file actions
153 lines (131 loc) · 5.82 KB
/
multifusion.jl
File metadata and controls
153 lines (131 loc) · 5.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
I = IsingBimodule
Istr = TensorKitSectors.type_repr(I)
@testset "$Istr sector" begin
@testset "Basic type properties" begin
@test eval(Meta.parse(sprint(show, I))) == I
@test eval(Meta.parse(TensorKitSectors.type_repr(I))) == I
prodsec = I ⊠ Z2Irrep
@test UnitStyle(prodsec) isa GenericUnit
@test FusionStyle(prodsec) isa SimpleFusion
@test FusionDataStyle(prodsec) isa NonTrivialFusionData
@test_throws DomainError unit(prodsec)
@test length(allunits(prodsec)) == 2
end
M = IsingBimodule(1, 2, 0)
Mop = IsingBimodule(2, 1, 0)
C0 = IsingBimodule(1, 1, 0)
C1 = IsingBimodule(1, 1, 1)
D0 = IsingBimodule(2, 2, 0)
D1 = IsingBimodule(2, 2, 1)
C = rand([C0, C1])
D = rand([D0, D1])
s = rand((M, Mop, C, D))
@testset "Basic properties" begin
@test @constinferred(unit(C1)) == @constinferred(leftunit(C1)) ==
@constinferred(rightunit(C1))
@test unit(D1) == leftunit(D1) == rightunit(D1)
@test unit(C1) == leftunit(M) == rightunit(Mop)
@test unit(D1) == rightunit(M) == leftunit(Mop)
@test @constinferred(isunit(C0))
@test isunit(D0)
@test !isunit(C1) && !isunit(D1) && !isunit(M) && !isunit(Mop)
@test length(allunits(I)) == 2
@test allunits(I) == (C0, D0)
@test !isunit(C0 ⊠ C1)
@test !isunit(C0 ⊠ D1)
@test isunit(C0 ⊠ C0)
@test isunit(D0 ⊠ D0)
@test isunit(C0 ⊠ D0)
@test length(allunits(I ⊠ I)) == 4
@test leftunit(M ⊠ Mop) == C0 ⊠ D0 == rightunit(Mop ⊠ M)
@test eval(Meta.parse(sprint(show, s))) == s
@test @constinferred(hash(s)) == hash(deepcopy(s))
@constinferred dual(s)
@test dual(dual(s)) == s
@constinferred dim(s)
@constinferred frobenius_schur_phase(s)
@constinferred convert(IsingAnyon, s)
@constinferred Bsymbol(C, C, C)
@constinferred Fsymbol(D, D, D, D, D, D)
end
@testset "$Istr: Value iterator" begin
@test eltype(values(I)) == I
@test_throws ArgumentError unit(I)
sprev = C0 # first in SectorValues
for (i, s) in enumerate(values(I))
@test !isless(s, sprev) # confirm compatibility with sort order
@test s == @constinferred (values(I)[i])
@test findindex(values(I), s) == i
sprev = s
i >= 10 && break
end
@test C0 == first(values(I))
@test (@constinferred findindex(values(I), C0)) == 1
for s in collect(values(I))
@test (@constinferred values(I)[findindex(values(I), s)]) == s
end
end
@testset "$Istr: Printing and errors" begin
@test eval(Meta.parse(sprint(show, C))) == C
@test eval(Meta.parse(sprint(show, M))) == M
@test eval(Meta.parse(sprint(show, Mop))) == Mop
@test eval(Meta.parse(sprint(show, D))) == D
@test_throws DomainError unit(M)
@test_throws DomainError unit(Mop)
end
@testset "$Istr Fusion rules and F-symbols" begin
argerr = ArgumentError("invalid fusion channel")
# forbidden fusions
for obs in [(C, D), (D, C), (M, M), (Mop, Mop), (D, M), (M, C), (Mop, D), (C, Mop)]
@test isempty(⊗(obs...))
@test_throws argerr Nsymbol(obs..., s)
end
# allowed fusions
for obs in [(C, C), (D, D), (M, Mop), (Mop, M), (C, M), (Mop, C), (M, D), (D, Mop)]
@test !isempty(⊗(obs...))
end
@test Nsymbol(C, C, unit(C)) == Nsymbol(D, D, unit(D)) == 1
@test Nsymbol(C, M, M) == Nsymbol(Mop, C, Mop) == 1
@test Nsymbol(M, D, M) == Nsymbol(D, Mop, Mop) == 1
@test_throws argerr Nsymbol(M, Mop, D)
@test_throws argerr Nsymbol(Mop, M, C)
@test Nsymbol(M, Mop, C) == Nsymbol(Mop, M, D) == 1
# non-trivial F-symbol checks
@test Fsymbol(Mop, M, D1, D0, D0, M) == 0 # ℳᵒᵖ x ℳ x 𝒟 → ℳ allowed, but 𝒟-labels mismatch
@test Fsymbol(Mop, M, D1, D0, D1, M) == 1
@test Fsymbol(M, Mop, C1, C0, C0, Mop) == 0
@test Fsymbol(M, Mop, C1, C0, C1, Mop) == 1
@test Fsymbol(C, M, D, M, M, M) == (C.label * D.label == 0 ? 1 : -1) # 𝒞 x ℳ x 𝒟 → ℳ allowed
@test_throws argerr Fsymbol(M, Mop, M, Mop, C, D) == 0 # IsingAnyon conversion would give non-zero
@test_throws argerr Fsymbol(Mop, M, Mop, M, D, C) == 0
@test Fsymbol(M, Mop, M, M, C, D) ==
(C.label * D.label == 0 ? inv(sqrt(2)) : -inv(sqrt(2))) # ℳ x ℳᵒᵖ x ℳ → ℳ allowed
@test Fsymbol(Mop, M, Mop, Mop, D, C) ==
(C.label * D.label == 0 ? inv(sqrt(2)) : -inv(sqrt(2))) # ℳᵒᵖ x ℳ x ℳᵒᵖ → ℳᵒᵖ allowed
@test_throws argerr Fsymbol(M, Mop, M, Mop, C, D)
end
@testset "$Istr: Unitarity of F-move" begin
objects = collect(values(I))
for a in objects, b in objects, c in objects
for d in ⊗(a, b, c)
es = collect(intersect(⊗(a, b), map(dual, ⊗(c, dual(d)))))
fs = collect(intersect(⊗(b, c), map(dual, ⊗(dual(d), a))))
@test length(es) == length(fs)
F = [Fsymbol(a, b, c, d, e, f) for e in es, f in fs]
@test isapprox(F' * F, one(F); atol = 1.0e-12, rtol = 1.0e-12)
end
end
end
@testset "$Istr: Triangle equation" begin
for a in smallset(I), b in smallset(I)
@test triangle_equation(a, b; atol = 1.0e-12, rtol = 1.0e-12)
end
end
@testset "$Istr: Pentagon equation" begin
objects = collect(values(I))
for a in objects, b in objects, c in objects, d in objects
# compatibility checks built in Fsymbol
@test pentagon_equation(a, b, c, d; atol = 1.0e-12, rtol = 1.0e-12)
end
end
end