1+ using TestEnv;
2+ TestEnv. activate ();
3+
4+ using Test
5+ using TestExtras
6+ using Random
7+ using TensorKit
8+ using Combinatorics
9+ using TensorKit: ProductSector, fusiontensor, pentagon_equation, hexagon_equation
10+ using TensorOperations
11+ using Base. Iterators: take, product
12+ # using SUNRepresentations: SUNIrrep
13+ # const SU3Irrep = SUNIrrep{3}
14+ using LinearAlgebra: LinearAlgebra
15+ using Zygote: Zygote
16+ using MatrixAlgebraKit
17+
18+ const TK = TensorKit
19+
20+ Random. seed! (1234 )
21+
22+ smallset (:: Type{I} ) where {I<: Sector } = take (values (I), 5 )
23+ function smallset (:: Type{ProductSector{Tuple{I1,I2}}} ) where {I1,I2}
24+ iter = product (smallset (I1), smallset (I2))
25+ s = collect (i ⊠ j for (i, j) in iter if dim (i) * dim (j) <= 6 )
26+ return length (s) > 6 ? rand (s, 6 ) : s
27+ end
28+ function smallset (:: Type{ProductSector{Tuple{I1,I2,I3}}} ) where {I1,I2,I3}
29+ iter = product (smallset (I1), smallset (I2), smallset (I3))
30+ s = collect (i ⊠ j ⊠ k for (i, j, k) in iter if dim (i) * dim (j) * dim (k) <= 6 )
31+ return length (s) > 6 ? rand (s, 6 ) : s
32+ end
33+ function randsector (:: Type{I} ) where {I<: Sector }
34+ s = collect (smallset (I))
35+ a = rand (s)
36+ while a == one (a) # don't use trivial label
37+ a = rand (s)
38+ end
39+ return a
40+ end
41+ function hasfusiontensor (I:: Type{<:Sector} )
42+ try
43+ fusiontensor (one (I), one (I), one (I))
44+ return true
45+ catch e
46+ if e isa MethodError
47+ return false
48+ else
49+ rethrow (e)
50+ end
51+ end
52+ end
53+
54+ # spaces
55+ Vtr = (ℂ^ 3 ,
56+ (ℂ^ 4 )' ,
57+ ℂ^ 5 ,
58+ ℂ^ 6 ,
59+ (ℂ^ 7 )' )
60+ Vℤ₂ = (ℂ[Z2Irrep](0 => 1 , 1 => 1 ),
61+ ℂ[Z2Irrep](0 => 1 , 1 => 2 )' ,
62+ ℂ[Z2Irrep](0 => 3 , 1 => 2 )' ,
63+ ℂ[Z2Irrep](0 => 2 , 1 => 3 ),
64+ ℂ[Z2Irrep](0 => 2 , 1 => 5 ))
65+ Vfℤ₂ = (ℂ[FermionParity](0 => 1 , 1 => 1 ),
66+ ℂ[FermionParity](0 => 1 , 1 => 2 )' ,
67+ ℂ[FermionParity](0 => 3 , 1 => 2 )' ,
68+ ℂ[FermionParity](0 => 2 , 1 => 3 ),
69+ ℂ[FermionParity](0 => 2 , 1 => 5 ))
70+ Vℤ₃ = (ℂ[Z3Irrep](0 => 1 , 1 => 2 , 2 => 2 ),
71+ ℂ[Z3Irrep](0 => 3 , 1 => 1 , 2 => 1 ),
72+ ℂ[Z3Irrep](0 => 2 , 1 => 2 , 2 => 1 )' ,
73+ ℂ[Z3Irrep](0 => 1 , 1 => 2 , 2 => 3 ),
74+ ℂ[Z3Irrep](0 => 1 , 1 => 3 , 2 => 3 )' )
75+ VU₁ = (ℂ[U1Irrep](0 => 1 , 1 => 2 , - 1 => 2 ),
76+ ℂ[U1Irrep](0 => 3 , 1 => 1 , - 1 => 1 ),
77+ ℂ[U1Irrep](0 => 2 , 1 => 2 , - 1 => 1 )' ,
78+ ℂ[U1Irrep](0 => 1 , 1 => 2 , - 1 => 3 ),
79+ ℂ[U1Irrep](0 => 1 , 1 => 3 , - 1 => 3 )' )
80+ VfU₁ = (ℂ[FermionNumber](0 => 1 , 1 => 2 , - 1 => 2 ),
81+ ℂ[FermionNumber](0 => 3 , 1 => 1 , - 1 => 1 ),
82+ ℂ[FermionNumber](0 => 2 , 1 => 2 , - 1 => 1 )' ,
83+ ℂ[FermionNumber](0 => 1 , 1 => 2 , - 1 => 3 ),
84+ ℂ[FermionNumber](0 => 1 , 1 => 3 , - 1 => 3 )' )
85+ VCU₁ = (ℂ[CU1Irrep]((0 , 0 ) => 1 , (0 , 1 ) => 2 , 1 => 1 ),
86+ ℂ[CU1Irrep]((0 , 0 ) => 3 , (0 , 1 ) => 0 , 1 => 1 ),
87+ ℂ[CU1Irrep]((0 , 0 ) => 1 , (0 , 1 ) => 0 , 1 => 2 )' ,
88+ ℂ[CU1Irrep]((0 , 0 ) => 2 , (0 , 1 ) => 2 , 1 => 1 ),
89+ ℂ[CU1Irrep]((0 , 0 ) => 2 , (0 , 1 ) => 1 , 1 => 2 )' )
90+ VSU₂ = (ℂ[SU2Irrep](0 => 3 , 1 // 2 => 1 ),
91+ ℂ[SU2Irrep](0 => 2 , 1 => 1 ),
92+ ℂ[SU2Irrep](1 // 2 => 1 , 1 => 1 )' ,
93+ ℂ[SU2Irrep](0 => 2 , 1 // 2 => 2 ),
94+ ℂ[SU2Irrep](0 => 1 , 1 // 2 => 1 , 3 // 2 => 1 )' )
95+ VfSU₂ = (ℂ[FermionSpin](0 => 3 , 1 // 2 => 1 ),
96+ ℂ[FermionSpin](0 => 2 , 1 => 1 ),
97+ ℂ[FermionSpin](1 // 2 => 1 , 1 => 1 )' ,
98+ ℂ[FermionSpin](0 => 2 , 1 // 2 => 2 ),
99+ ℂ[FermionSpin](0 => 1 , 1 // 2 => 1 , 3 // 2 => 1 )' )
1100for V in (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂)# , VSU₃)
2101 V1, V2, V3, V4, V5 = V
102+
3103 @assert V3 * V4 * V2 ≿ V1' * V5' # necessary for leftorth tests
4104 @assert V3 * V4 ≾ V1' * V2' * V5' # necessary for rightorth tests
5105end
@@ -21,33 +121,33 @@ catch
21121 (Vtr, Vℤ₂, Vfℤ₂, Vℤ₃, VU₁, VfU₁, VCU₁, VSU₂, VfSU₂)# , VSU₃)
22122end
23123
24- @timedtestset " Factorizatios with symmetry: $(sectortype (first (V))) " for V in spacelist
124+
125+ function test_leftorth (t, p, alg)
126+ Q, R = @inferred leftorth (t, p; alg)
127+ @test Q * R ≈ permute (t, p)
128+ @test isisometry (Q)
129+ if alg isa Polar
130+ @test isposdef (R)
131+ @test domain (R) == codomain (R) == domain (permute (space (t), p))
132+ end
133+ end
134+ function test_leftnull (t, p, alg)
135+ N = @inferred leftnull (t, p; alg)
136+ @test isisometry (N)
137+ @test norm (N' * permute (t, p)) ≈ 0 atol= 100 * eps (norm (t))
138+ end
139+
140+ # @timedtestset "Factorizations with symmetry: $(sectortype(first(V)))" for V in spacelist
141+ V = collect (spacelist)[2 ]
25142 V1, V2, V3, V4, V5 = V
26143 W = V1 ⊗ V2 ⊗ V3 ⊗ V4 ⊗ V5
27144 for T in (Float32, ComplexF64), adj in (false , true )
28- t = adj ? rand (T, W)' : rand (T, W)
29- @testset " leftorth with $alg " for alg in
30- (TensorKit. QR (), TensorKit. QRpos (),
31- TensorKit. QL (), TensorKit. QLpos (),
32- TensorKit. Polar (), TensorKit. SVD (),
33- TensorKit. SDD ())
34- Q, R = @constinferred leftorth (t, ((3 , 4 , 2 ), (1 , 5 )); alg= alg)
35- QdQ = Q' * Q
36- @test QdQ ≈ one (QdQ)
37- @test Q * R ≈ permute (t, ((3 , 4 , 2 ), (1 , 5 )))
38- if alg isa Polar
39- @test isposdef (R)
40- @test domain (R) == codomain (R) == space (t, 1 )' ⊗ space (t, 5 )'
41- end
145+ t = adj ? rand (T, W)' : rand (T, W);
146+ @testset " leftorth with $alg " for alg in (TensorKit. QR (), TensorKit. QRpos (), TensorKit. QL (), TensorKit. QLpos (), TensorKit. Polar (), TensorKit. SVD (), TensorKit. SDD ())
147+ test_leftorth (t, ((3 , 4 , 2 ), (1 , 5 )), alg)
42148 end
43- @testset " leftnull with $alg " for alg in
44- (TensorKit. QR (), TensorKit. SVD (),
45- TensorKit. SDD ())
46- N = @constinferred leftnull (t, ((3 , 4 , 2 ), (1 , 5 )); alg= alg)
47- NdN = N' * N
48- @test NdN ≈ one (NdN)
49- @test norm (N' * permute (t, ((3 , 4 , 2 ), (1 , 5 )))) <
50- 100 * eps (norm (t))
149+ @testset " leftnull with $alg " for alg in (TensorKit. QR (), TensorKit. SVD (), TensorKit. SDD ())
150+ test_leftnull (t, ((3 , 4 , 2 ), (1 , 5 )), alg)
51151 end
52152 @testset " rightorth with $alg " for alg in
53153 (TensorKit. RQ (), TensorKit. RQpos (),
0 commit comments