1
1
2
2
"""
3
- StereographicSlice(; max_proposals)
3
+ StereographicSlice(invscale ; max_proposals)
4
4
5
5
Stereographic slice sampling algorithm by Bell, Latuszynski, and Roberts[^BLR2024].
6
6
7
7
# Keyword Arguments
8
- - `max_proposals::Int`: Maximum number of proposals allowed until throwing an error (default: `$(DEFAULT_MAX_PROPOSALS) `).
8
+ - `invscale::Real`: Inverse scale of the stereographic projection.
9
+ - `max_proposals::Int`: Maximum number of proposals allowed until throwing an error (default: `$(100 * DEFAULT_MAX_PROPOSALS) `).
9
10
"""
10
- @kwdef struct StereographicSlice <: AbstractMultivariateSliceSampling
11
- max_proposals:: Int = DEFAULT_MAX_PROPOSALS
11
+ struct StereographicSlice{S<: Real } <: AbstractMultivariateSliceSampling
12
+ invscale:: S
13
+ max_proposals:: Int
14
+ end
15
+
16
+ function StereographicSlice (invscale:: Real ; max_proposals:: Int = 100 * DEFAULT_MAX_PROPOSALS)
17
+ @assert invscale > 0
18
+ StereographicSlice {typeof(invscale)} (invscale, max_proposals)
12
19
end
13
20
14
21
function AbstractMCMC. setparams!! (
@@ -29,17 +36,18 @@ function rand_uniform_sphere_orthogonal_subspace(
29
36
return v_orth / norm (v_orth)
30
37
end
31
38
32
- function stereographic_projection (z:: AbstractVector )
39
+ function stereographic_projection (z:: AbstractVector{T} , R :: T ) where {T <: Real }
33
40
d = length (z) - 1
34
- return z[1 : d] ./ (1 - z[d + 1 ])
41
+ return R * z[1 : d] ./ (1 - z[d + 1 ])
35
42
end
36
43
37
- function stereographic_inverse_projection (x:: AbstractVector{T} ) where {T<: Real }
44
+ function stereographic_inverse_projection (x:: AbstractVector{T} , R :: T ) where {T<: Real }
38
45
d = length (x)
46
+ R2 = R* R
39
47
z = zeros (T, d + 1 )
40
48
x_norm2 = sum (abs2, x)
41
- z[1 : d] = 2 * x / (x_norm2 + 1 )
42
- z[d + 1 ] = (x_norm2 - 1 ) / (x_norm2 + 1 )
49
+ z[1 : d] = 2 * R * x / (x_norm2 + R2 )
50
+ z[d + 1 ] = (x_norm2 - R2 ) / (x_norm2 + R2 )
43
51
return z
44
52
end
45
53
@@ -57,9 +65,9 @@ function AbstractMCMC.step(
57
65
return t, t
58
66
end
59
67
60
- function logdensity_sphere (ℓπ:: Real , x:: AbstractVector )
68
+ function logdensity_sphere (ℓπ:: Real , x:: AbstractVector{T} , R :: T ) where {T <: Real }
61
69
d = length (x)
62
- return ℓπ + d * log (1 + sum (abs2, x))
70
+ return ℓπ + d * log (R * R + sum (abs2, x))
63
71
end
64
72
65
73
function AbstractMCMC. step (
@@ -74,22 +82,23 @@ function AbstractMCMC.step(
74
82
75
83
ℓp = state. lp
76
84
x = state. params
77
- z = stereographic_inverse_projection (x)
85
+ R = convert (eltype (x), sampler. invscale)
86
+ z = stereographic_inverse_projection (x, R)
78
87
v = rand_uniform_sphere_orthogonal_subspace (rng, z)
79
- ℓp_sphere = logdensity_sphere (ℓp, x)
88
+ ℓp_sphere = logdensity_sphere (ℓp, x, R )
80
89
ℓw = ℓp_sphere - Random. randexp (rng, eltype (x))
81
90
82
- θ = convert (eltype (x), 2 π) * rand (eltype (x), rng )
91
+ θ = convert (eltype (x), 2 π) * rand (rng, eltype (x))
83
92
θ_max = θ
84
93
θ_min = θ - convert (eltype (x), 2 π)
85
94
86
95
props = 0
87
96
while true
88
97
props += 1
89
98
90
- x_prop = stereographic_projection (z * cos (θ) + v * sin (θ))
99
+ x_prop = stereographic_projection (z * cos (θ) + v * sin (θ), R )
91
100
ℓp_prop = LogDensityProblems. logdensity (logdensitymodel, x_prop)
92
- ℓp_sphere_prop = logdensity_sphere (ℓp_prop, x_prop)
101
+ ℓp_sphere_prop = logdensity_sphere (ℓp_prop, x_prop, R )
93
102
94
103
if ℓw < ℓp_sphere_prop
95
104
ℓp = ℓp_prop
@@ -98,6 +107,7 @@ function AbstractMCMC.step(
98
107
end
99
108
100
109
if props > max_proposals
110
+ println (logdensitymodel)
101
111
exceeded_max_prop (max_proposals)
102
112
end
103
113
@@ -106,8 +116,7 @@ function AbstractMCMC.step(
106
116
else
107
117
θ_max = θ
108
118
end
109
-
110
- θ = (θ_max - θ_min) * rand (rng)
119
+ θ = (θ_max - θ_min) * rand (rng, eltype (x))
111
120
end
112
121
t = Transition (x, ℓp, (num_proposals= props,))
113
122
return t, t
0 commit comments