Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ uuid = "80f14c24-f653-4e6a-9b94-39d6b0f70001"
keywords = ["markov chain monte carlo", "probabilistic programming"]
license = "MIT"
desc = "A lightweight interface for common MCMC methods."
version = "5.14.0"
version = "5.15.0"

[deps]
BangBang = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
Expand All @@ -18,7 +18,6 @@ ProgressLogging = "33c8b6b6-d38a-422a-b730-caa89a2f386c"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
TerminalLoggers = "5d786b92-1e48-4d6f-9151-6b4477ca9bed"
Transducers = "28d57a85-8fef-5791-bfe6-a80928e7c999"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[weakdeps]
Expand All @@ -42,7 +41,6 @@ Statistics = "1"
StatsBase = "0.32, 0.33, 0.34"
TensorBoardLogger = "0.1"
TerminalLoggers = "0.1"
Transducers = "0.4.30"
UUIDs = "<0.0.1, 1"
julia = "1.10"

Expand Down
9 changes: 1 addition & 8 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ AbstractMCMC.steps(::AbstractRNG, ::AbstractMCMC.AbstractModel, ::AbstractMCMC.A
AbstractMCMC.steps(::AbstractRNG, ::Any, ::AbstractMCMC.AbstractSampler)
```

### Transducer

```@docs
AbstractMCMC.Sample(::AbstractRNG, ::AbstractMCMC.AbstractModel, ::AbstractMCMC.AbstractSampler)
AbstractMCMC.Sample(::AbstractRNG, ::Any, ::AbstractMCMC.AbstractSampler)
```

## Sampling multiple chains in parallel

```@docs
Expand Down Expand Up @@ -87,7 +80,7 @@ Common keyword arguments for regular and parallel sampling are:
is passed `initial_state` as the `state` argument.

!!! info
The common keyword arguments `progress`, `chain_type`, and `callback` are not supported by the iterator [`AbstractMCMC.steps`](@ref) and the transducer [`AbstractMCMC.Sample`](@ref).
The common keyword arguments `progress`, `chain_type`, and `callback` are not supported by the iterator [`AbstractMCMC.steps`](@ref).

There is no "official" way for providing initial parameter values yet.
However, multiple packages such as [EllipticalSliceSampling.jl](https://github.com/TuringLang/EllipticalSliceSampling.jl) and [AdvancedMH.jl](https://github.com/TuringLang/AdvancedMH.jl) support an `initial_params` keyword argument for setting the initial values when sampling a single chain.
Expand Down
57 changes: 21 additions & 36 deletions docs/src/design.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
# Design

This page explains the default implementations and design choices of AbstractMCMC.
It is not intended for users but for developers that want to implement the AbstractMCMC
interface for Markov chain Monte Carlo sampling. The user-facing API is explained in
[API](@ref).
It is not intended for users but for developers that want to implement the AbstractMCMC interface for Markov chain Monte Carlo sampling.
The user-facing API is explained in [API](@ref).

## Overview

AbstractMCMC provides a default implementation of the user-facing interface described
in [API](@ref). You can completely neglect these and define your own implementation of the
interface. However, as described below, in most use cases the default implementation
allows you to obtain support of parallel sampling, progress logging, callbacks, iterators,
and transducers for free by just defining the sampling step of your inference algorithm,
drastically reducing the amount of code you have to write. In general, the docstrings
of the functions described below might be helpful if you intend to make use of the default
implementations.
AbstractMCMC provides a default implementation of the user-facing interface described in [API](@ref).
You can completely neglect these and define your own implementation of the interface.
However, as described below, in most use cases the default implementation allows you to obtain support of parallel sampling, progress logging, callbacks, and iterators for free by just defining the sampling step of your inference algorithm, drastically reducing the amount of code you have to write.
In general, the docstrings of the functions described below might be helpful if you intend to make use of the default implementations.

## Basic structure

The simplified structure for regular sampling (the actual implementation contains
some additional error checks and support for progress logging and callbacks) is
The simplified structure for regular sampling (the actual implementation contains some additional error checks and support for progress logging and callbacks) is

```julia
StatsBase.sample(
Expand Down Expand Up @@ -50,14 +44,12 @@ StatsBase.sample(
end
```

All other default implementations make use of the same structure and in particular
call the same methods.
All other default implementations make use of the same structure and in particular call the same methods.

## Sampling step

The only method for which no default implementation is provided (and hence which
downstream packages *have* to implement) is [`AbstractMCMC.step`](@ref). It defines
the sampling step of the inference method.
The only method for which no default implementation is provided (and hence which downstream packages *have* to implement) is [`AbstractMCMC.step`](@ref).
It defines the sampling step of the inference method.

```@docs
AbstractMCMC.step
Expand All @@ -69,47 +61,40 @@ If one also has some special handling of the warmup-stage of sampling, then this
AbstractMCMC.step_warmup
```

which will be used for the first `num_warmup` iterations, as specified as a keyword argument to [`AbstractMCMC.sample`](@ref).
which will be used for the first `num_warmup` iterations, as specified as a keyword argument to [`AbstractMCMC.sample`](@ref).
Note that this is optional; by default it simply calls [`AbstractMCMC.step`](@ref) from above.

## Collecting samples

!!! note
This section does not apply to the iterator and transducer interface.
This section does not apply to the iterator interface.

After the initial sample is obtained, the default implementations for regular and parallel sampling
(not for the iterator and the transducer since it is not needed there) create a container for all
samples (the initial one and all subsequent samples) using `AbstractMCMC.samples`.
After the initial sample is obtained, the default implementations for regular and parallel sampling (not for the iterator since it is not needed there) create a container for all samples (the initial one and all subsequent samples) using `AbstractMCMC.samples`.

```@docs
AbstractMCMC.samples
```

In each step, the sample is saved in the container by `AbstractMCMC.save!!`. The notation `!!`
follows the convention of the package [BangBang.jl](https://github.com/JuliaFolds/BangBang.jl)
which is used in the default implementation of `AbstractMCMC.save!!`. It indicates that the
sample is pushed to the container but a "widening" fallback is used if the container type
does not allow saving the sample. Therefore `AbstractMCMC.save!!` *always has* to return the container.
In each step, the sample is saved in the container by `AbstractMCMC.save!!`.
The notation `!!` follows the convention of the package [BangBang.jl](https://github.com/JuliaFolds/BangBang.jl) which is used in the default implementation of `AbstractMCMC.save!!`.
It indicates that the sample is pushed to the container but a "widening" fallback is used if the container type does not allow saving the sample.
Therefore `AbstractMCMC.save!!` *always has* to return the container.

```@docs
AbstractMCMC.save!!
```

For most use cases the default implementation of `AbstractMCMC.samples` and `AbstractMCMC.save!!`
should work out of the box and hence need not be overloaded in downstream code.
For most use cases the default implementation of `AbstractMCMC.samples` and `AbstractMCMC.save!!` should work out of the box and hence need not be overloaded in downstream code.

## Creating chains

!!! note
This section does not apply to the iterator and transducer interface.
This section does not apply to the iterator interface.

At the end of the sampling procedure for regular and parallel sampling we transform
the collection of samples to the desired output type by calling `AbstractMCMC.bundle_samples`.
At the end of the sampling procedure for regular and parallel sampling we transform the collection of samples to the desired output type by calling `AbstractMCMC.bundle_samples`.

```@docs
AbstractMCMC.bundle_samples
```

The default implementation should be fine in most use cases, but downstream packages
could, e.g., save the final state of the sampler as well if they overload
`AbstractMCMC.bundle_samples`.
The default implementation should be fine in most use cases, but downstream packages could, e.g., save the final state of the sampler as well if they overload `AbstractMCMC.bundle_samples`.
9 changes: 3 additions & 6 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
*Abstract types and interfaces for Markov chain Monte Carlo methods.*

AbstractMCMC defines an interface for sampling and combining Markov chains.
It comes with a default sampling algorithm that provides support of progress
bars, parallel sampling (multithreaded and multicore), and user-provided callbacks
out of the box. Typically developers only have to define the sampling step
of their inference method in an iterator-like fashion to make use of this
functionality. Additionally, the package defines an iterator and a transducer
for sampling Markov chains based on the interface.
It comes with a default sampling algorithm that provides support of progress bars, parallel sampling (multithreaded and multicore), and user-provided callbacks out of the box.
Typically developers only have to define the sampling step of their inference method in an iterator-like fashion to make use of this functionality.
Additionally, the package defines an iterator interface for obtaining successive samples from Markov chains.
2 changes: 0 additions & 2 deletions src/AbstractMCMC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ using LoggingExtras: LoggingExtras
using ProgressLogging: ProgressLogging
using StatsBase: StatsBase
using TerminalLoggers: TerminalLoggers
using Transducers: Transducers
using FillArrays: FillArrays

using Distributed: Distributed
Expand Down Expand Up @@ -197,7 +196,6 @@ include("logging.jl")
include("interface.jl")
include("sample.jl")
include("stepper.jl")
include("transducer.jl")
include("logdensityproblems.jl")
include("callbacks.jl")

Expand Down
102 changes: 0 additions & 102 deletions src/transducer.jl

This file was deleted.

8 changes: 0 additions & 8 deletions test/logdensityproblems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,6 @@
@test length(samples4) == N
@test all(x.a == y.a && x.b == y.b for (x, y) in zip(samples, samples4))

# Same chain if sampling is performed with transducer
Random.seed!(1234)
xf = AbstractMCMC.Sample(ℓ, MySampler())
samples5 = collect(xf(1:N))
@test length(samples5) == N
@test all(x.a == y.a && x.b == y.b for (x, y) in zip(samples, samples5))

# Parallel sampling
for alg in (MCMCSerial(), MCMCDistributed(), MCMCThreads())
chains = sample(ℓ, MySampler(), alg, N, 2)
Expand All @@ -91,7 +84,6 @@
mylogdensity, MySampler(), MCMCDistributed(), N, 2
)
@test_throws ArgumentError AbstractMCMC.steps(mylogdensity, MySampler())
@test_throws ArgumentError AbstractMCMC.Sample(mylogdensity, MySampler())
end

# Remove workers
Expand Down
2 changes: 0 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ using LogDensityProblems
using LoggingExtras: TeeLogger, EarlyFilteredLogger
using TerminalLoggers: TerminalLogger
using FillArrays: FillArrays
using Transducers

using Distributed
using Logging: Logging
Expand All @@ -23,7 +22,6 @@ include("utils.jl")
@testset "AbstractMCMC" begin
include("sample.jl")
include("stepper.jl")
include("transducer.jl")
include("logdensityproblems.jl")
end

Expand Down
Loading
Loading