-
Notifications
You must be signed in to change notification settings - Fork 1
/
runtests.jl
183 lines (159 loc) · 5.74 KB
/
runtests.jl
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using Test
using WignerFamilies
using HalfIntegers
import WignerSymbols # only a test-dep, for comparisons
@testset "f: nonclassical" begin
j₂ = 100
j₃ = 60
m₂ = 70
m₃ = -55
m₁ = -m₂ - m₃
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
j_array = collect(eachindex(w3j))
reference = [WignerSymbols.wigner3j(Float64, j, j₂, j₃, m₁, m₂) for j in j_array]
for (i, j) in enumerate(j_array)
@test w3j[j] ≈ reference[i]
end
# also test specifying different types
w3j = wigner3j_f(BigFloat, j₂, j₃, m₂, m₃)
for (i, j) in enumerate(j_array)
@test w3j[j] ≈ reference[i]
end
w3j = wigner3j_f(j₂, j₃, m₂, m₃)
for (i, j) in enumerate(j_array)
@test w3j[j] ≈ reference[i]
end
end
##
@testset "f: all low j" begin
tol = 10*eps()
j₂ₘₐₓ = 10
j₃ₘₐₓ = 10
for j₂=0:j₂ₘₐₓ, j₃=0:j₃ₘₐₓ, m₂=-j₂:j₂, m₃=-j₃:j₃
m₁ = -m₂ - m₃
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
j_array = eachindex(w3j)
reference = [WignerSymbols.wigner3j(Float64, j, j₂, j₃, m₁, m₂)
for j in j_array]
for (i, j) in enumerate(j_array)
@test w3j[j] ≈ reference[i] atol=tol
end
# also test specifying different types
w3j = wigner3j_f(BigFloat, j₂, j₃, m₂, m₃)
for (i, j) in enumerate(j_array)
@test w3j[j] ≈ reference[i] atol=tol
end
w3j = wigner3j_f(j₂, j₃, m₂, m₃)
for (i, j) in enumerate(j_array)
@test w3j[j] ≈ reference[i] atol=tol
end
end
end
##
@testset "f: mᵢ = 0 special case" begin
j₂, j₃, m₂, m₃ = 5000, 5002, 0, 0
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
j_array = collect(eachindex(w3j))
for j in [j_array[i] for i in [collect(1:100)..., 5001, 7001, 10001-50, 10001]]
@test w3j[j] ≈ Float64(WignerSymbols.wigner3j(BigFloat, j, j₂, j₃, -m₂-m₃, m₂))
end
j₂, j₃, m₂, m₃ = 5000, 5001, 0, 0
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
j_array = collect(eachindex(w3j))
for j in [j_array[i] for i in [collect(1:100)..., 5001, 7001, 10001-50, 10001]]
@test w3j[j] ≈ Float64(WignerSymbols.wigner3j(BigFloat, j, j₂, j₃, -m₂-m₃, m₂))
end
for j₂ in 0:100
j₃, m₂, m₃ = 10, 0, 0
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
j_array = collect(eachindex(w3j))
for j in j_array
@test w3j[j] ≈ Float64(WignerSymbols.wigner3j(BigFloat, j, j₂, j₃, -m₂-m₃, m₂))
end
end
for j₂ in 0:100
j₃, m₂, m₃ = 11, 0, 0
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
j_array = collect(eachindex(w3j))
for j in j_array
@test w3j[j] ≈ Float64(WignerSymbols.wigner3j(BigFloat, j, j₂, j₃, -m₂-m₃, m₂))
end
end
end
##
@testset "f: edge cases" begin
j₂, j₃, m₂, m₃ = 2, 2, 4, 4
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
@test length(w3j) == 0
j₂, j₃, m₂, m₃ = 2, 2, HalfInt(0.5), HalfInt(0.5)
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
@test length(w3j) == 0
@test wigner3j_f(Float64, 1, 0, 0, 0)[1] ≈ -sqrt(1/3)
@test wigner3j_f(Float64, 0, 0, 0, 0)[0] ≈ 1.0
@test wigner3j_f(Float64, 1, 1, 0, 0)[2] ≈ sqrt(2/15)
end
## bottom of page 14 of Raynal et al. On the zeros of 3j coefficients: polynomial degree
# versus recurrence order is an example of sequence of nontrivial zeros
@testset "f: nontrivial zeros" begin
tol = eps()
for (X₀, Y₀) in ((43, 25), (109, 63))
j₂, j₃, m₂, m₃ = Int128.((5000, 5002, 0, 0))
X(n) = iszero(n) ? X₀ : 7X(n-1) + 12Y(n-1)
Y(n) = iszero(n) ? Y₀ : 4(n-1) + 7Y(n-1)
for n_seq in 0:1
j₂, j₃, m₂, m₃ = (2X(n_seq)+1)/6, (X(n_seq)+2)/6, HalfInt(3/2), HalfInt(3/2)
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
for j in eachindex(w3j)
@test (abs(w3j[j] -
Float64(WignerSymbols.wigner3j(BigFloat, j, j₂, j₃, -m₂-m₃, m₂))) < tol)
end
end
end
end
##
@testset "f: regression test for selection rules, large negative m" begin
j₂ = 48
j₃ = 48
m₂ = -48
m₃ = 48
w3j = wigner3j_f(Float64, j₂, j₃, m₂, m₃)
for j in eachindex(w3j)
@test abs(w3j[j] - WignerSymbols.wigner3j(j, j₂, j₃, -m₂-m₃, m₂)) < 1e-11
end
end
##
@testset "f: half-integer spin" begin
w = WignerF( HalfInt(5/2), 5, HalfInt(1/2), HalfInt(-1) )
m₁ = -w.m₂ - w.m₃
w3j = get_wigner_array(w)
wigner3j_f!(w, w3j)
reference = [WignerSymbols.wigner3j(Float64, j, w.j₂, w.j₃, m₁, w.m₂)
for j in eachindex(w3j)]
for (i, j) in enumerate(eachindex(w3j))
@test w3j[j] ≈ reference[i]
end
end
## tests for the Rasch and Yu c index
function confirm_symmetry(maxj)
j₁, j₂ = rand(0:maxj, 2)
j₃ = rand(abs(j₁ - j₂):(j₁ + j₂))
if isodd(j₁ + j₂ + j₃)
j₃ += 1
end
m₁, m₂, m₃ = 0, 0, 0
c1 = rasch_yu_index(Int128, j₁, j₂, j₃, m₁, m₂, m₃)
c2 = rasch_yu_index(Int128,
j₁, (j₂ + j₃ - m₁)/2, (j₂ + j₃ + m₁)/2,
j₃ - j₂, (j₂ - j₃ - m₁)/2 - m₃, (j₂ - j₃ + m₁)/2 + m₃)
c1, c2
end
@testset "Rasch & Yu c: Regge symmetry" begin
for i in 1:2000
c1, c2 = confirm_symmetry(100)
@test c1 == c2
end
end
@testset "utils" begin
@test all(WignerFamilies.swap_triangular(1:6) .== [1,6,2,5,3,4])
@test all(WignerFamilies.swap_triangular(2:6) .== [2,6,3,5,4])
end