From 6855d4ac725f7d03f8d6b02732a3bb6400c01add Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 4 Mar 2020 15:21:34 +0100 Subject: [PATCH 1/2] Switch to AbstractMCMC interface --- Project.toml | 17 +++--- README.md | 18 ++++-- src/EllipticalSliceSampling.jl | 18 +++--- src/abstractmcmc.jl | 106 +++++++++++++++++++++++++++++++++ src/distributions.jl | 54 +++++++++++++++++ src/interface.jl | 95 ++++++++++++++++++++--------- src/iterator.jl | 76 ----------------------- src/model.jl | 70 ++++++++++++++++++++++ src/types.jl | 49 --------------- src/utils.jl | 25 -------- test/regression.jl | 8 +-- test/runtests.jl | 5 ++ 12 files changed, 335 insertions(+), 206 deletions(-) create mode 100644 src/abstractmcmc.jl create mode 100644 src/distributions.jl delete mode 100644 src/iterator.jl create mode 100644 src/model.jl delete mode 100644 src/types.jl delete mode 100644 src/utils.jl diff --git a/Project.toml b/Project.toml index 5450959..149628a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,29 +1,30 @@ name = "EllipticalSliceSampling" uuid = "cad2338a-1db2-11e9-3401-43bc07c9ede2" -authors = ["David Widmann "] -version = "0.1.0" +authors = ["David Widmann "] +version = "0.2.0" [deps] +AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001" ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" -Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a" -ProgressLogging = "33c8b6b6-d38a-422a-b730-caa89a2f386c" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] +AbstractMCMC = "0.5" ArrayInterface = "2" -Distributions = "0.21.8" -Parameters = "0.12" -ProgressLogging = "0.1" +Distributions = "0.22" julia = "1" [extras] Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +TerminalLoggers = "5d786b92-1e48-4d6f-9151-6b4477ca9bed" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Distances", "FillArrays", "LinearAlgebra", "SafeTestsets", "Statistics", "Test"] +test = ["Distances", "FillArrays", "LinearAlgebra", "Logging", "SafeTestsets", "Statistics", "TerminalLoggers", "Test"] diff --git a/README.md b/README.md index 9e07e2a..1fab21f 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,22 @@ priors with non-zero means and handle the change of variables internally. Probably most users would like to use the exported function ```julia -ESS_mcmc([rng::AbstracRNG, ]prior, loglikelihood, N::Int[; burnin::Int = 0]) +ESS_mcmc([rng, ]prior, loglikelihood, N[; kwargs...]) ``` which returns a vector of `N` samples for approximating the posterior of a model with a Gaussian prior that allows sampling from the `prior` and -evaluation of the log likelihood `loglikelihood`. The burn-in phase with -`burnin` samples is discarded. +evaluation of the log likelihood `loglikelihood`. If you want to have more control about the sampling procedure (e.g., if you only want to save a subset of samples or want to use another stopping criterion), the function ```julia -ESS_mcmc_sampler([rng::AbstractRNG, ]prior, loglikelihood) +AbstractMCMC.steps!( + [rng,] + EllipticalSliceSampling.Model(prior, loglikelihood), + EllipticalSliceSampling.EllipticalSliceSampler(); + kwargs... +) ``` gives you access to an iterator from which you can generate an unlimited number of samples. @@ -56,9 +60,11 @@ use a custom distribution type `GaussianPrior`, the following methods should be implemented: ```julia # state that the distribution is actually Gaussian -EllipticalSliceSampling.isnormal(::Type{<:GaussianPrior}) = true +EllipticalSliceSampling.isgaussian(::Type{<:GaussianPrior}) = true # define the mean of the distribution +# alternatively implement `proposal(prior, ...)` and +# `proposal!(out, prior, ...)` (only if the samples are mutable) Statistics.mean(dist::GaussianPrior) = ... # define how to sample from the distribution @@ -87,7 +93,7 @@ be useful. ### Progress monitor If you use a package such as [Juno](https://junolab.org/) or -[ConsoleProgressMonitor.jl](https://github.com/tkf/ConsoleProgressMonitor.jl) that supports +[TerminalLoggers.jl](https://github.com/c42f/TerminalLoggers.jl) that supports progress logs created by the [ProgressLogging.jl](https://github.com/JunoLab/ProgressLogging.jl) API, then you can monitor the progress of the sampling algorithm. diff --git a/src/EllipticalSliceSampling.jl b/src/EllipticalSliceSampling.jl index 825210b..81dd653 100644 --- a/src/EllipticalSliceSampling.jl +++ b/src/EllipticalSliceSampling.jl @@ -1,17 +1,17 @@ module EllipticalSliceSampling -using ArrayInterface -using Distributions -using Parameters -using ProgressLogging +import AbstractMCMC +import ArrayInterface +import Distributions -using Random +import Random +import Statistics -export ESS_mcmc, ESS_mcmc_sampler +export ESS_mcmc -include("utils.jl") -include("types.jl") -include("iterator.jl") +include("abstractmcmc.jl") +include("model.jl") +include("distributions.jl") include("interface.jl") end # module diff --git a/src/abstractmcmc.jl b/src/abstractmcmc.jl new file mode 100644 index 0000000..ad34dc7 --- /dev/null +++ b/src/abstractmcmc.jl @@ -0,0 +1,106 @@ +# elliptical slice sampler +struct EllipticalSliceSampler <: AbstractMCMC.AbstractSampler end + +# state of the elliptical slice sampler +struct EllipticalSliceSamplerState{S,L} + "Sample of the elliptical slice sampler." + sample::S + "Log-likelihood of the sample." + loglikelihood::L +end + +# first step of the elliptical slice sampler +function AbstractMCMC.step!( + rng::Random.AbstractRNG, + model::AbstractMCMC.AbstractModel, + ::EllipticalSliceSampler, + N::Integer, + ::Nothing; + kwargs... +) + # initial sample from the Gaussian prior + f = initial_sample(rng, model) + + # compute log-likelihood of the initial sample + loglikelihood = Distributions.loglikelihood(model, f) + + return EllipticalSliceSamplerState(f, loglikelihood) +end + +# subsequent steps of the elliptical slice sampler +function AbstractMCMC.step!( + rng::Random.AbstractRNG, + model::AbstractMCMC.AbstractModel, + ::EllipticalSliceSampler, + N::Integer, + state::EllipticalSliceSamplerState; + kwargs... +) + # sample from Gaussian prior + ν = sample_prior(rng, model) + + # sample log-likelihood threshold + loglikelihood = state.loglikelihood + threshold = loglikelihood - Random.randexp(rng) + + # sample initial angle + θ = 2 * π * rand(rng) + θmin = θ - 2 * π + θmax = θ + + # compute the proposal + f = state.sample + fnext = proposal(model, f, ν, θ) + + # compute the log-likelihood of the proposal + loglikelihood = Distributions.loglikelihood(model, fnext) + + # stop if the log-likelihood threshold is reached + while loglikelihood < threshold + # shrink the bracket + if θ < zero(θ) + θmin = θ + else + θmax = θ + end + + # sample angle + θ = θmin + rand(rng) * (θmax - θmin) + + # recompute the proposal + if ArrayInterface.ismutable(fnext) + proposal!(fnext, model, f, ν, θ) + else + fnext = proposal(model, f, ν, θ) + end + + # compute the log-likelihood of the proposal + loglikelihood = Distributions.loglikelihood(model, fnext) + end + + return EllipticalSliceSamplerState(fnext, loglikelihood) +end + +# only save the samples by default +function AbstractMCMC.transitions_init( + state::EllipticalSliceSamplerState, + model::AbstractMCMC.AbstractModel, + ::EllipticalSliceSampler, + N::Integer; + kwargs... +) + return Vector{typeof(state.sample)}(undef, N) +end + +function AbstractMCMC.transitions_save!( + samples::AbstractVector{S}, + iteration::Integer, + state::EllipticalSliceSamplerState{S}, + model::AbstractMCMC.AbstractModel, + ::EllipticalSliceSampler, + N::Integer; + kwargs... +) where S + samples[iteration] = state.sample + return +end diff --git a/src/distributions.jl b/src/distributions.jl new file mode 100644 index 0000000..b2c8e71 --- /dev/null +++ b/src/distributions.jl @@ -0,0 +1,54 @@ +# define the element type of the samples +randtype(::Type{D}) where {D<:Distributions.MultivariateDistribution} = Vector{eltype(D)} +randtype(::Type{D}) where {D<:Distributions.MatrixDistribution} = Matrix{eltype(D)} +function randtype( + ::Type{D} +) where {D<:Distributions.Sampleable{Distributions.Multivariate}} + return Vector{eltype(D)} +end +function randtype( + ::Type{D} +) where {D<:Distributions.Sampleable{Distributions.Matrixvariate}} + return Matrix{eltype(D)} +end + +# define trait for Gaussian distributions +isgaussian(::Type{<:Distributions.Normal}) = true +isgaussian(::Type{<:Distributions.NormalCanon}) = true +isgaussian(::Type{<:Distributions.AbstractMvNormal}) = true + +# compute the proposal of the next sample +function proposal(prior::Distributions.Normal, f::Real, ν::Real, θ) + sinθ, cosθ = sincos(θ) + μ = prior.μ + if iszero(μ) + return cosθ * f + sinθ * ν + else + a = 1 - (sinθ + cosθ) + return cosθ * f + sinθ * ν + a * μ + end +end + +function proposal( + prior::Distributions.MvNormal, + f::AbstractVector{<:Real}, + ν::AbstractVector{<:Real}, + θ +) + sinθ, cosθ = sincos(θ) + a = 1 - (sinθ + cosθ) + return @. cosθ * f + sinθ * ν + a * prior.μ +end + +function proposal!( + out::AbstractVector{<:Real}, + prior::Distributions.MvNormal, + f::AbstractVector{<:Real}, + ν::AbstractVector{<:Real}, + θ +) + sinθ, cosθ = sincos(θ) + a = 1 - (sinθ + cosθ) + @. out = cosθ * f + sinθ * ν + a * prior.μ + return out +end diff --git a/src/interface.jl b/src/interface.jl index e52cc11..eb595a7 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -1,33 +1,72 @@ -# perform elliptical slice sampling for a fixed number of iterations -ESS_mcmc(prior, loglikelihood, N::Int; kwargs...) = - ESS_mcmc(Random.GLOBAL_RNG, prior, loglikelihood, N; kwargs...) +# public interface -function ESS_mcmc(rng::AbstractRNG, prior, loglikelihood, N::Int; burnin::Int = 0) - # define the internal model +""" + ESS_mcmc([rng, ]prior, loglikelihood, N; kwargs...) + +Create a Markov chain of `N` samples for a model with given `prior` and `loglikelihood` +functions using the elliptical slice sampling algorithm. +""" +function ESS_mcmc( + rng::Random.AbstractRNG, + prior, + loglikelihood, + N::Integer; + kwargs... +) model = Model(prior, loglikelihood) + return AbstractMCMC.sample(rng, model, EllipticalSliceSampler(), N; kwargs...) +end + +function ESS_mcmc(prior, loglikelihood, N::Integer; kwargs...) + return ESS_mcmc(Random.GLOBAL_RNG, prior, loglikelihood, N; kwargs...) +end + +# private interface + +""" + initial_sample(rng, model) + +Return the initial sample for the `model` using the random number generator `rng`. - # create the sampler - sampler = EllipticalSliceSampler(rng, model) - - # create MCMC chain - chain = Vector{eltype(sampler)}(undef, N) - niters = N + burnin - @withprogress name = "Performing elliptical slice sampling" begin - # discard burnin phase - for (i, _) in zip(1:burnin, sampler) - @logprogress i / niters - end - - for (i, f) in zip(1:N, sampler) - @inbounds chain[i] = f - @logprogress (i + burnin) / niters - end - end - - chain +By default, sample from the prior by calling [`sample_prior(rng, model)`](@ref). +""" +function initial_sample(rng::Random.AbstractRNG, model::AbstractMCMC.AbstractModel) + return sample_prior(rng, model) end -# create an elliptical slice sampler -ESS_mcmc_sampler(prior, loglikelihood) = ESS_mcmc_sampler(Random.GLOBAL_RNG, prior, loglikelihood) -ESS_mcmc_sampler(rng::AbstractRNG, prior, loglikelihood) = - EllipticalSliceSampler(rng, Model(prior, loglikelihood)) +""" + sample_prior(rng, model) + +Sample from the prior of the `model` using the random number generator `rng`. +""" +function sample_prior(::Random.AbstractRNG, ::AbstractMCMC.AbstractModel) end + +""" + proposal(model, f, ν, θ) + +Compute the proposal for the next sample in the elliptical slice sampling algorithm for the +`model` from the previous sample `f`, the sample `ν` from the Gaussian prior, and the angle +`θ`. + +Mathematically, the proposal can be computed as +```math +\\cos θ f + ν \\sin θ ν + μ (1 - \\sin θ + \\cos θ), +``` +where ``μ`` is the mean of the Gaussian prior. +""" +function proposal(model::AbstractMCMC.AbstractModel, f, ν, θ) end + +""" + proposal!(out, model, f, ν, θ) + +Compute the proposal for the next sample in the elliptical slice sampling algorithm for the +`model` from the previous sample `f`, the sample `ν` from the Gaussian prior, and the angle +`θ`, and save it to `out`. + +Mathematically, the proposal can be computed as +```math +\\cos θ f + ν \\sin θ ν + μ (1 - \\sin θ + \\cos θ), +``` +where ``μ`` is the mean of the Gaussian prior. +""" +function proposal!(out, model::AbstractMCMC.AbstractModel, f, ν, θ) end diff --git a/src/iterator.jl b/src/iterator.jl deleted file mode 100644 index a31ae30..0000000 --- a/src/iterator.jl +++ /dev/null @@ -1,76 +0,0 @@ -Base.IteratorSize(::Type{<:EllipticalSliceSampler}) = Base.IsInfinite() - -function Base.iterate(ess::EllipticalSliceSampler) - @unpack rng, model = ess - @unpack prior, loglikelihood = model - - # initial sample from the Gaussian prior - f = rand(rng, prior) - - # compute log-likelihood of the initial sample - ℓ = loglikelihood(f) - - f, EllipticalSliceSamplerState(f, ℓ) -end - -function Base.iterate(ess::EllipticalSliceSampler, state::EllipticalSliceSamplerState) - @unpack rng, model, cache = ess - @unpack prior, loglikelihood = model - @unpack f, ℓ = state - - # sample from Gaussian prior - if cache === nothing - ν = rand(rng, prior) - else - rand!(rng, prior, cache) - ν = cache - end - - # sample log-likelihood threshold - logy = ℓ - randexp(rng) - - # sample initial angle - θ = 2 * π * rand(rng) - θₘᵢₙ = θ - 2 * π - θₘₐₓ = θ - - # obtain mean of prior - μ = mean(prior) - - # compute the proposal - # we apply a correction for Gaussian distributions with non-zero mean - sinθ, cosθ = sincos(θ) - a = 1 - (sinθ + cosθ) - fnext = @. f * cosθ + ν * sinθ + a * μ - - # compute the log-likelihood of the proposal - ℓ = loglikelihood(fnext) - - # stop if the log-likelihood threshold is reached - while ℓ < logy - # shrink the bracket - if θ < zero(θ) - θₘᵢₙ = θ - else - θₘₐₓ = θ - end - - # sample angle - θ = θₘᵢₙ + rand(rng) * (θₘₐₓ - θₘᵢₙ) - - # recompute the proposal - # we apply a correction for Gaussian distributions with non-zero mean - sinθ, cosθ = sincos(θ) - a = 1 - (sinθ + cosθ) - if ArrayInterface.ismutable(fnext) - @. fnext = f * cosθ + ν * sinθ + a * μ - else - fnext = @. f * cosθ + ν * sinθ + a * μ - end - - # compute the log-likelihood of the proposal - ℓ = loglikelihood(fnext) - end - - return fnext, EllipticalSliceSamplerState(fnext, ℓ) -end diff --git a/src/model.jl b/src/model.jl new file mode 100644 index 0000000..9232bc2 --- /dev/null +++ b/src/model.jl @@ -0,0 +1,70 @@ +# internal model structure consisting of prior, log-likelihood function, and a cache + +struct Model{P,L,C} <: AbstractMCMC.AbstractModel + "Gaussian prior." + prior::P + "Log likelihood function." + loglikelihood::L + "Cache." + cache::C + + function Model{P,L}(prior::P, loglikelihood::L) where {P,L} + isgaussian(P) || + error("prior distribution has to be a Gaussian distribution") + + # create cache + c = cache(prior) + + new{P,L,typeof(c)}(prior, loglikelihood, c) + end +end + +Model(prior, loglikelihood) = + Model{typeof(prior),typeof(loglikelihood)}(prior, loglikelihood) + +# cache for high-dimensional samplers +function cache(dist) + T = randtype(typeof(dist)) + + # only create a cache if the distribution produces mutable samples + ArrayInterface.ismutable(T) || return nothing + + similar(T, size(dist)) +end + +# test if a distribution is Gaussian +isgaussian(dist) = false + +# unify element type of samplers +randtype(dist) = eltype(dist) + +# evaluate the loglikelihood of a sample +Distributions.loglikelihood(model::Model, f) = model.loglikelihood(f) + +# sample from the prior +initial_sample(rng::Random.AbstractRNG, model::Model) = rand(rng, model.prior) +function sample_prior(rng::Random.AbstractRNG, model::Model) + cache = model.cache + + if cache === nothing + return rand(rng, model.prior) + else + Random.rand!(rng, model.prior, model.cache) + return model.cache + end +end + +# compute the proposal +proposal(model::Model, f, ν, θ) = proposal(model.prior, f, ν, θ) +proposal!(out, model::Model, f, ν, θ) = proposal!(out, model.prior, f, ν, θ) + +# default out-of-place implementation +function proposal(prior, f, ν, θ) + sinθ, cosθ = sincos(θ) + a = 1 - (sinθ + cosθ) + μ = Statistics.mean(prior) + return @. cosθ * f + sinθ * ν + a * μ +end + +# default in-place implementation +proposal!(out, prior, f, ν, θ) = copyto!(out, proposal(prior, f, ν, θ)) diff --git a/src/types.jl b/src/types.jl deleted file mode 100644 index be89c1a..0000000 --- a/src/types.jl +++ /dev/null @@ -1,49 +0,0 @@ -# elliptical slice sampling algorithm - -# internal model structure consisting of prior and log-likelihood function -struct Model{P,L} - "Gaussian prior." - prior::P - "Log likelihood function." - loglikelihood::L - - function Model{P,L}(prior::P, loglikelihood::L) where {P,L} - isnormal(P) || - error("prior distribution has to be a normal distribution") - - new{P,L}(prior, loglikelihood) - end -end - -Model(prior, loglikelihood) = - Model{typeof(prior),typeof(loglikelihood)}(prior, loglikelihood) - -# use custom randtype since behaviour of `eltype` is inconsistent in Distributions -Base.eltype(::Type{<:Model{P}}) where P = randtype(P) - -# elliptical slice sampler -struct EllipticalSliceSampler{M<:Model,R<:AbstractRNG,C} - "Random number generator." - rng::R - "Model." - model::M - "Cache." - cache::C -end - -EllipticalSliceSampler(model::Model) = EllipticalSliceSampler(Random.GLOBAL_RNG, model) -EllipticalSliceSampler(rng::AbstractRNG, model::Model) = - EllipticalSliceSampler(rng, model, cache(model.prior)) - -Base.eltype(::Type{<:EllipticalSliceSampler{M}}) where M = eltype(M) - -# set seed of the sampler -Random.seed!(ess::EllipticalSliceSampler) = Random.seed!(ess.rng) - -# state of the elliptical slice sampler -struct EllipticalSliceSamplerState{F,L} - "Sample of the elliptical slice sampler." - f::F - "Log-likelihood of the sample." - ℓ::L -end diff --git a/src/utils.jl b/src/utils.jl deleted file mode 100644 index eb6127a..0000000 --- a/src/utils.jl +++ /dev/null @@ -1,25 +0,0 @@ -# unify element type of samplers -randtype(dist) = eltype(dist) -randtype(::Type{D}) where {D<:MultivariateDistribution} = Vector{eltype(D)} -randtype(::Type{D}) where {D<:Sampleable{Multivariate}} = Vector{eltype(D)} -randtype(::Type{D}) where {D<:MatrixDistribution} = Matrix{eltype(D)} -randtype(::Type{D}) where {D<:Sampleable{Matrixvariate}} = Matrix{eltype(D)} - -# cache for high-dimensional samplers -function cache(dist) - T = randtype(typeof(dist)) - - # only create a cache if the distribution produces mutable samples - ArrayInterface.ismutable(T) || return nothing - - similar(T, size(dist)) -end - -""" - isnormal(dist) - -Test whether a distribution is normal. -""" -isnormal(dist) = false -isnormal(::Type{<:Normal}) = true -isnormal(::Type{<:AbstractMvNormal}) = true \ No newline at end of file diff --git a/test/regression.jl b/test/regression.jl index db82d64..a50a31e 100644 --- a/test/regression.jl +++ b/test/regression.jl @@ -40,9 +40,8 @@ const σ = 0.3 logpdf(MvNormal(f, σ), observations) end - # run elliptical slice sampling for 100 000 time steps - # drop burn-in phase of 10 000 samples - samples = ESS_mcmc(prior, ℓ, 100_000; burnin = 10_000) + # run elliptical slice sampler for 100 000 time steps + samples = ESS_mcmc(prior, ℓ, 100_000) # compute analytical posterior of GP posterior_Σ = prior_Σ * (I - (prior_Σ + σ^2 * I) \ prior_Σ) @@ -67,8 +66,7 @@ end end # run elliptical slice sampling for 100 000 time steps - # drop burn-in phase of 10 000 samples - samples = ESS_mcmc(prior, ℓ, 100_000; burnin = 10_000) + samples = ESS_mcmc(prior, ℓ, 100_000) # compute analytical posterior posterior_μ = observations / (1 + σ^2) diff --git a/test/runtests.jl b/test/runtests.jl index dcb7172..26c1059 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,9 @@ using SafeTestsets +using TerminalLoggers: TerminalLogger + +using Logging: global_logger + +global_logger(TerminalLogger()) @safetestset "Simple tests" begin include("simple.jl") end @safetestset "GP regression tests" begin include("regression.jl") end From 043564f94674ff00b19bca34a4d728744b1d7071 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 4 Mar 2020 16:02:54 +0100 Subject: [PATCH 2/2] Disable progress logging in tests --- Project.toml | 4 +--- test/regression.jl | 4 ++-- test/runtests.jl | 5 ----- test/simple.jl | 10 +++++----- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/Project.toml b/Project.toml index 149628a..5315a26 100644 --- a/Project.toml +++ b/Project.toml @@ -20,11 +20,9 @@ julia = "1" Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -TerminalLoggers = "5d786b92-1e48-4d6f-9151-6b4477ca9bed" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Distances", "FillArrays", "LinearAlgebra", "Logging", "SafeTestsets", "Statistics", "TerminalLoggers", "Test"] +test = ["Distances", "FillArrays", "LinearAlgebra", "SafeTestsets", "Statistics", "Test"] diff --git a/test/regression.jl b/test/regression.jl index a50a31e..46f96b3 100644 --- a/test/regression.jl +++ b/test/regression.jl @@ -41,7 +41,7 @@ const σ = 0.3 end # run elliptical slice sampler for 100 000 time steps - samples = ESS_mcmc(prior, ℓ, 100_000) + samples = ESS_mcmc(prior, ℓ, 100_000; progress = false) # compute analytical posterior of GP posterior_Σ = prior_Σ * (I - (prior_Σ + σ^2 * I) \ prior_Σ) @@ -66,7 +66,7 @@ end end # run elliptical slice sampling for 100 000 time steps - samples = ESS_mcmc(prior, ℓ, 100_000) + samples = ESS_mcmc(prior, ℓ, 100_000; progress = false) # compute analytical posterior posterior_μ = observations / (1 + σ^2) diff --git a/test/runtests.jl b/test/runtests.jl index 26c1059..dcb7172 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,4 @@ using SafeTestsets -using TerminalLoggers: TerminalLogger - -using Logging: global_logger - -global_logger(TerminalLogger()) @safetestset "Simple tests" begin include("simple.jl") end @safetestset "GP regression tests" begin include("regression.jl") end diff --git a/test/simple.jl b/test/simple.jl index 39ff24f..3d503c4 100644 --- a/test/simple.jl +++ b/test/simple.jl @@ -18,7 +18,7 @@ using Test μ = 0.8 σ² = 0.2 - samples = ESS_mcmc(prior, ℓ, 2_000) + samples = ESS_mcmc(prior, ℓ, 2_000; progress = false) @test mean(samples) ≈ μ atol=0.05 @test var(samples) ≈ σ² atol=0.05 @@ -35,7 +35,7 @@ end μ = 0.9 σ² = 0.2 - samples = ESS_mcmc(prior, ℓ, 2_000) + samples = ESS_mcmc(prior, ℓ, 2_000; progress = false) @test mean(samples) ≈ μ atol=0.05 @test var(samples) ≈ σ² atol=0.05 @@ -53,7 +53,7 @@ end μ = [0.8] σ² = [0.2] - samples = ESS_mcmc(prior, ℓ, 2_000) + samples = ESS_mcmc(prior, ℓ, 2_000; progress = false) @test mean(samples) ≈ μ atol=0.05 @test var(samples) ≈ σ² atol=0.05 @@ -70,8 +70,8 @@ end μ = [0.9] σ² = [0.2] - samples = ESS_mcmc(prior, ℓ, 2_000) + samples = ESS_mcmc(prior, ℓ, 2_000; progress = false) @test mean(samples) ≈ μ atol=0.05 @test var(samples) ≈ σ² atol=0.05 -end \ No newline at end of file +end