Skip to content

Commit 7715732

Browse files
committed
Fix deprecated Gibbs constructors. Add HISTORY entry.
1 parent 58ebb25 commit 7715732

File tree

3 files changed

+44
-11
lines changed

3 files changed

+44
-11
lines changed

HISTORY.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
# Release 0.35.0
2+
3+
## Breaking changes
4+
5+
0.35.0 introduces a new Gibbs sampler. It's been included in several previous releases as `Turing.Experimental.Gibbs`, but now takes over the old Gibbs sampler, which gets removed completely.
6+
7+
The new Gibbs sampler supports the same user-facing interface as the old one. However, given
8+
that the internals of it having been completely rewritten in a very different manner, there
9+
may be accidental breakage that we haven't anticipated. Please report any you find.
10+
11+
`GibbsConditional` has also been removed. It was never very user-facing, but it was exported, so technically this is breaking.
12+
13+
The old Gibbs constructor relied on being called with several subsamplers, and each of the constructors of the subsamplers would take as arguments the symbols for the variables that they are to sample, e.g. `Gibbs(HMC(:x), MH(:y))`. This constructor has been deprecated, and will be removed in the future. The new constructor works by assigning samplers to either symbols or `VarNames`, e.g. `Gibbs(; x=HMC(), y=MH())` or `Gibbs(@varname(x) => HMC(), @varname(y) => MH())`. This allows more granular specification of which sampler to use for which variable.
14+
15+
Likewise, the old constructor for calling one subsampler more often than another, `Gibbs((HMC(:x), 2), (MH(:y), 1))` has been deprecated. The new way to achieve this effect is to list the same sampler multiple times, e.g. as `hmc = HMC(); mh = MH(); Gibbs(@varname(x) => hmc, @varname(x) => hmc, @varname(y) => mh)`.
16+
117
# Release 0.33.0
218

319
## Breaking changes

src/mcmc/gibbs.jl

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -279,24 +279,39 @@ function Gibbs(algs::Pair...)
279279
return Gibbs(map(first, algs), map(wrap_algorithm_maybe, map(last, algs)))
280280
end
281281

282-
# The below constructor only serves to provide backwards compatibility with the constructor
283-
# of the old Gibbs sampler. It is deprecated and will be removed in the future.
282+
# The below two constructors only provide backwards compatibility with the constructor of
283+
# the old Gibbs sampler. They are deprecated and will be removed in the future.
284284
function Gibbs(algs::InferenceAlgorithm...)
285-
alg_dict = Dict{Any,InferenceAlgorithm}()
286-
for alg in algs
285+
varnames = map(algs) do alg
287286
space = getspace(alg)
288-
space_vns = if (space isa Symbol || space isa VarName)
287+
if (space isa VarName)
289288
space
289+
elseif (space isa Symbol)
290+
VarName{space}()
290291
else
291292
tuple((s isa Symbol ? VarName{s}() : s for s in space)...)
292293
end
293-
alg_dict[space_vns] = alg
294294
end
295-
Base.depwarn(
296-
"Specifying which sampler to use with which variable using syntax like `Gibbs(NUTS(:x), MH(:y))` is deprecated and will be removed in the future. Please use `Gibbs(; x=NUTS(), y=MH())` instead.",
297-
:Gibbs,
295+
msg = (
296+
"Specifying which sampler to use with which variable using syntax like " *
297+
"`Gibbs(NUTS(:x), MH(:y))` is deprecated and will be removed in the future. " *
298+
"Please use `Gibbs(; x=NUTS(), y=MH())` instead. If you want different iteration " *
299+
"counts for different subsamplers, use e.g. " *
300+
"`Gibbs(@varname(x) => NUTS(), @varname(x) => NUTS(), @varname(y) => MH())`"
298301
)
299-
return Gibbs(alg_dict)
302+
Base.depwarn(msg, :Gibbs)
303+
return Gibbs(varnames, map(wrap_algorithm_maybe, algs))
304+
end
305+
306+
function Gibbs(algs_with_iters::Tuple{<:InferenceAlgorithm,Int}...)
307+
algs = Iterators.map(first, algs_with_iters)
308+
iters = Iterators.map(last, algs_with_iters)
309+
algs_duplicated = Iterators.flatten((
310+
Iterators.repeated(alg, iter) for (alg, iter) in zip(algs, iters)
311+
))
312+
# This calls the other deprecated constructor from above, hence no need for a depwarn
313+
# here.
314+
return Gibbs(algs_duplicated...)
300315
end
301316

302317
# TODO: Remove when no longer needed.

test/mcmc/gibbs.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ has_dot_assume(::DynamicPPL.Model) = true
5252
@test_deprecated s4 = Gibbs(PG(3, :s), HMC(0.4, 8, :m; adtype=adbackend))
5353
@test_deprecated s5 = Gibbs(CSMC(3, :s), HMC(0.4, 8, :m; adtype=adbackend))
5454
@test_deprecated s6 = Gibbs(HMC(0.1, 5, :s; adtype=adbackend), ESS(:m))
55-
for s in (s1, s2, s3, s4, s5, s6)
55+
@test_deprecated s7 = Gibbs((HMC(0.1, 5, :s; adtype=adbackend), 2), (ESS(:m), 3))
56+
for s in (s1, s2, s3, s4, s5, s6, s7)
5657
@test DynamicPPL.alg_str(Turing.Sampler(s, gdemo_default)) == "Gibbs"
5758
end
5859

@@ -63,6 +64,7 @@ has_dot_assume(::DynamicPPL.Model) = true
6364
sample(gdemo_default, s4, N)
6465
sample(gdemo_default, s5, N)
6566
sample(gdemo_default, s6, N)
67+
sample(gdemo_default, s7, N)
6668

6769
g = Turing.Sampler(s3, gdemo_default)
6870
@test sample(gdemo_default, g, N) isa MCMCChains.Chains

0 commit comments

Comments
 (0)