diff --git a/NAMESPACE b/NAMESPACE index 24b0286..8cb0443 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,13 +2,14 @@ export(barker_proposal) export(chain_state) +export(dual_averaging_scale_adapter) export(example_gaussian_stan_model) export(hamiltonian_proposal) export(langevin_proposal) export(random_walk_proposal) export(robust_shape_adapter) export(sample_chain) -export(scale_adapter) +export(simple_scale_adapter) export(target_distribution_from_stan_model) export(trace_function_from_stan_model) -export(variance_adapter) +export(variance_shape_adapter) diff --git a/R/adaptation.R b/R/adaptation.R index 28abb3e..05f317d 100644 --- a/R/adaptation.R +++ b/R/adaptation.R @@ -1,4 +1,5 @@ -#' Create object to adapt proposal scale to coerce average acceptance rate. +#' Create object to adapt proposal scale to coerce average acceptance rate using +#' a Robbins and Monro (1951) scheme. #' #' @param initial_scale Initial value to use for scale parameter. If not set #' explicitly a proposal and dimension dependent default will be used. @@ -25,9 +26,9 @@ #' grad_log_density = function(x) -x #' ) #' proposal <- barker_proposal(target_distribution) -#' adapter <- scale_adapter(initial_scale = 1., target_accept_prob = 0.4) +#' adapter <- simple_scale_adapter(initial_scale = 1., target_accept_prob = 0.4) #' adapter$initialize(proposal, chain_state(c(0, 0))) -scale_adapter <- function( +simple_scale_adapter <- function( initial_scale = NULL, target_accept_prob = NULL, kappa = 0.6) { log_scale <- NULL initialize <- function(proposal, initial_state) { @@ -41,9 +42,9 @@ scale_adapter <- function( if (is.null(target_accept_prob)) { target_accept_prob <- proposal$default_target_accept_prob() } - gamma <- sample_index^(-kappa) + beta <- sample_index^(-kappa) accept_prob <- state_and_statistics$statistics$accept_prob - log_scale <<- log_scale + gamma * (accept_prob - target_accept_prob) + log_scale <<- log_scale + beta * (accept_prob - target_accept_prob) proposal$update(scale = exp(log_scale)) } list( @@ -54,12 +55,95 @@ scale_adapter <- function( ) } +#' Create object to adapt proposal scale to coerce average acceptance rate +#' using dual averaging scheme of Nesterov (2009) and Hoffman and Gelman (2014). +#' +#' @inherit simple_scale_adapter params return +#' +#' @param gamma Regularization coefficient for (log) scale in dual averaging +#' algorithm. Controls amount of regularization of (log) scale towards `mu`. +#' Should be set to a non-negative value. Defaults to value recommended in +#' Hoffman and Gelman (2014). +#' @param iteration_offset Offset to chain iteration used for the iteration +#' based weighting of the adaptation statistic error estimate. Should be set +#' to a non-negative value. A value greater than zero has the effect of +#' stabilizing early iterations. Defaults to value recommended in +#' Hoffman and Gelman (2014). +#' @param mu Value to regularize (log) scale towards. If `NULL` (the default), +#' `mu` will be set to `log(10 * initial_scale)`, as recommended in Hoffman +#' and Gelman (2014). +#' +#' @export +#' +#' @examples +#' target_distribution <- list( +#' log_density = function(x) -sum(x^2) / 2, +#' grad_log_density = function(x) -x +#' ) +#' proposal <- barker_proposal(target_distribution) +#' adapter <- dual_averaging_scale_adapter( +#' initial_scale = 1., target_accept_prob = 0.4 +#' ) +#' adapter$initialize(proposal, chain_state(c(0, 0))) +dual_averaging_scale_adapter <- function( + initial_scale = NULL, + target_accept_prob = NULL, + kappa = 0.75, + gamma = 0.05, + iteration_offset = 10, + mu = NULL) { + log_scale <- NULL + smoothed_log_scale <- 0 + accept_prob_error <- 0 + initialize <- function(proposal, initial_state) { + if (is.null(initial_scale)) { + initial_scale <- proposal$default_initial_scale(initial_state$dimension()) + } + if (is.null(mu)) { + mu <<- log(10 * initial_scale) + } + log_scale <<- log(initial_scale) + proposal$update(scale = initial_scale) + } + update <- function(proposal, sample_index, state_and_statistics) { + if (is.null(target_accept_prob)) { + target_accept_prob <- proposal$default_target_accept_prob() + } + accept_prob <- state_and_statistics$statistics$accept_prob + offset_sample_index <- sample_index + iteration_offset + accept_prob_error <<- ( + (1 - 1 / offset_sample_index) * accept_prob_error + ( + target_accept_prob - accept_prob + ) / offset_sample_index + ) + log_scale <<- mu - sqrt(sample_index) * accept_prob_error / gamma + beta <- sample_index^(-kappa) + smoothed_log_scale <<- beta * log_scale + (1 - beta) * smoothed_log_scale + proposal$update(scale = exp(log_scale)) + } + finalize <- function(proposal) { + proposal$update(scale = exp(smoothed_log_scale)) + } + list( + initialize = initialize, + update = update, + finalize = finalize, + state = function() { + list( + log_scale = log_scale, + smoothed_log_scale = smoothed_log_scale, + accept_prob_error = accept_prob_error + ) + } + ) +} + #' Create object to adapt proposal with per dimension scales based on estimates #' of target distribution variances. #' #' @param kappa Decay rate exponent in `[0.5, 1]` for adaptation learning rate. #' -#' @inherit scale_adapter return +#' @inherit simple_scale_adapter return #' #' @export #' @examples @@ -68,9 +152,9 @@ scale_adapter <- function( #' grad_log_density = function(x) -x #' ) #' proposal <- barker_proposal(target_distribution) -#' adapter <- variance_adapter() +#' adapter <- variance_shape_adapter() #' adapter$initialize(proposal, chain_state(c(0, 0))) -variance_adapter <- function(kappa = 0.6) { +variance_shape_adapter <- function(kappa = 0.6) { mean_estimate <- NULL variance_estimate <- NULL initialize <- function(proposal, initial_state) { @@ -78,10 +162,12 @@ variance_adapter <- function(kappa = 0.6) { variance_estimate <<- rep(1., initial_state$dimension()) } update <- function(proposal, sample_index, state_and_statistics) { - gamma <- sample_index^(-kappa) + # Offset sample_index by 1 so that initial unity variance_estimate acts as + # regularizer + beta <- (sample_index + 1)^(-kappa) position <- state_and_statistics$state$position() - mean_estimate <<- mean_estimate + gamma * (position - mean_estimate) - variance_estimate <<- variance_estimate + gamma * ( + mean_estimate <<- mean_estimate + beta * (position - mean_estimate) + variance_estimate <<- variance_estimate + beta * ( (position - mean_estimate)^2 - variance_estimate ) proposal$update(shape = sqrt(variance_estimate)) @@ -107,9 +193,9 @@ variance_adapter <- function(kappa = 0.6) { #' coerced acceptance rate. _Statistics and Computing_, 22, 997-1008. #' #' -#' @inheritParams scale_adapter +#' @inheritParams simple_scale_adapter #' -#' @inherit scale_adapter return +#' @inherit simple_scale_adapter return #' #' @export #' @@ -139,7 +225,7 @@ robust_shape_adapter <- function( momentum <- state_and_statistics$proposed_state$momentum() accept_prob <- state_and_statistics$statistics$accept_prob shape <<- ramcmc::adapt_S( - shape, momentum, accept_prob, sample_index - 1, target_accept_prob, kappa + shape, momentum, accept_prob, sample_index, target_accept_prob, kappa ) proposal$update(shape = shape) } diff --git a/R/chains.R b/R/chains.R index 7abbf80..12bd2a8 100644 --- a/R/chains.R +++ b/R/chains.R @@ -181,7 +181,7 @@ chain_loop <- function( state, target_distribution, proposal ) for (adapter in adapters) { - adapter$update(proposal, chain_iteration + 1, state_and_statistics) + adapter$update(proposal, chain_iteration, state_and_statistics) } state <- state_and_statistics$state if (record_traces_and_statistics) { diff --git a/README.Rmd b/README.Rmd index ad1f428..c44f7ba 100644 --- a/README.Rmd +++ b/README.Rmd @@ -59,7 +59,7 @@ results <- sample_chain( initial_state = rnorm(dimension), n_warm_up_iteration = 1000, n_main_iteration = 1000, - adapters = list(scale_adapter(), variance_adapter()) + adapters = list(simple_scale_adapter(), variance_shape_adapter()) ) mean_accept_prob <- mean(results$statistics[, "accept_prob"]) adapted_shape <- proposal$parameters()$shape diff --git a/README.md b/README.md index 6352590..8b05381 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ results <- sample_chain( initial_state = rnorm(dimension), n_warm_up_iteration = 1000, n_main_iteration = 1000, - adapters = list(scale_adapter(), variance_adapter()) + adapters = list(simple_scale_adapter(), variance_shape_adapter()) ) mean_accept_prob <- mean(results$statistics[, "accept_prob"]) adapted_shape <- proposal$parameters()$shape @@ -66,7 +66,7 @@ cat( sprintf("Adapter scale est.: %s", toString(adapted_shape)), sep = "\n" ) -#> Average acceptance probability is 0.40 +#> Average acceptance probability is 0.41 #> True target scales: 1.50538046096953, 1.37774732725824, 0.277038897322645 -#> Adapter scale est.: 1.35010920408606, 1.5140138215658, 0.248974800274054 +#> Adapter scale est.: 1.2489768457131, 1.23111560302158, 0.215024121396933 ``` diff --git a/man/dual_averaging_scale_adapter.Rd b/man/dual_averaging_scale_adapter.Rd new file mode 100644 index 0000000..4efd54c --- /dev/null +++ b/man/dual_averaging_scale_adapter.Rd @@ -0,0 +1,69 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/adaptation.R +\name{dual_averaging_scale_adapter} +\alias{dual_averaging_scale_adapter} +\title{Create object to adapt proposal scale to coerce average acceptance rate +using dual averaging scheme of Nesterov (2009) and Hoffman and Gelman (2014).} +\usage{ +dual_averaging_scale_adapter( + initial_scale = NULL, + target_accept_prob = NULL, + kappa = 0.75, + gamma = 0.05, + iteration_offset = 10, + mu = NULL +) +} +\arguments{ +\item{initial_scale}{Initial value to use for scale parameter. If not set +explicitly a proposal and dimension dependent default will be used.} + +\item{target_accept_prob}{Target value for average accept probability for +chain. If not set a proposal dependent default will be used.} + +\item{kappa}{Decay rate exponent in \verb{[0.5, 1]} for adaptation learning rate.} + +\item{gamma}{Regularization coefficient for (log) scale in dual averaging +algorithm. Controls amount of regularization of (log) scale towards \code{mu}. +Should be set to a non-negative value. Defaults to value recommended in +Hoffman and Gelman (2014).} + +\item{iteration_offset}{Offset to chain iteration used for the iteration +based weighting of the adaptation statistic error estimate. Should be set +to a non-negative value. A value greater than zero has the effect of +stabilizing early iterations. Defaults to value recommended in +Hoffman and Gelman (2014).} + +\item{mu}{Value to regularize (log) scale towards. If \code{NULL} (the default), +\code{mu} will be set to \code{log(10 * initial_scale)}, as recommended in Hoffman +and Gelman (2014).} +} +\value{ +List of functions with entries +\itemize{ +\item \code{initialize}, a function for initializing adapter state and proposal +parameters at beginning of chain, +\item \code{update} a function for updating adapter state and proposal parameters on +each chain iteration, +\item \code{finalize} a function for performing any final updates to adapter state and +proposal parameters on completion of chain sampling (may be \code{NULL} if +unused). +\item \code{state} a zero-argument function for accessing current values of adapter +state variables. +} +} +\description{ +Create object to adapt proposal scale to coerce average acceptance rate +using dual averaging scheme of Nesterov (2009) and Hoffman and Gelman (2014). +} +\examples{ +target_distribution <- list( + log_density = function(x) -sum(x^2) / 2, + grad_log_density = function(x) -x +) +proposal <- barker_proposal(target_distribution) +adapter <- dual_averaging_scale_adapter( + initial_scale = 1., target_accept_prob = 0.4 +) +adapter$initialize(proposal, chain_state(c(0, 0))) +} diff --git a/man/scale_adapter.Rd b/man/simple_scale_adapter.Rd similarity index 80% rename from man/scale_adapter.Rd rename to man/simple_scale_adapter.Rd index fcd0847..24e96fd 100644 --- a/man/scale_adapter.Rd +++ b/man/simple_scale_adapter.Rd @@ -1,10 +1,15 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/adaptation.R -\name{scale_adapter} -\alias{scale_adapter} -\title{Create object to adapt proposal scale to coerce average acceptance rate.} +\name{simple_scale_adapter} +\alias{simple_scale_adapter} +\title{Create object to adapt proposal scale to coerce average acceptance rate using +a Robbins and Monro (1951) scheme.} \usage{ -scale_adapter(initial_scale = NULL, target_accept_prob = NULL, kappa = 0.6) +simple_scale_adapter( + initial_scale = NULL, + target_accept_prob = NULL, + kappa = 0.6 +) } \arguments{ \item{initial_scale}{Initial value to use for scale parameter. If not set @@ -30,7 +35,8 @@ state variables. } } \description{ -Create object to adapt proposal scale to coerce average acceptance rate. +Create object to adapt proposal scale to coerce average acceptance rate using +a Robbins and Monro (1951) scheme. } \examples{ target_distribution <- list( @@ -38,6 +44,6 @@ target_distribution <- list( grad_log_density = function(x) -x ) proposal <- barker_proposal(target_distribution) -adapter <- scale_adapter(initial_scale = 1., target_accept_prob = 0.4) +adapter <- simple_scale_adapter(initial_scale = 1., target_accept_prob = 0.4) adapter$initialize(proposal, chain_state(c(0, 0))) } diff --git a/man/variance_adapter.Rd b/man/variance_shape_adapter.Rd similarity index 90% rename from man/variance_adapter.Rd rename to man/variance_shape_adapter.Rd index e901d23..20fd260 100644 --- a/man/variance_adapter.Rd +++ b/man/variance_shape_adapter.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/adaptation.R -\name{variance_adapter} -\alias{variance_adapter} +\name{variance_shape_adapter} +\alias{variance_shape_adapter} \title{Create object to adapt proposal with per dimension scales based on estimates of target distribution variances.} \usage{ -variance_adapter(kappa = 0.6) +variance_shape_adapter(kappa = 0.6) } \arguments{ \item{kappa}{Decay rate exponent in \verb{[0.5, 1]} for adaptation learning rate.} @@ -34,6 +34,6 @@ target_distribution <- list( grad_log_density = function(x) -x ) proposal <- barker_proposal(target_distribution) -adapter <- variance_adapter() +adapter <- variance_shape_adapter() adapter$initialize(proposal, chain_state(c(0, 0))) } diff --git a/tests/testthat/test-adaptation.R b/tests/testthat/test-adaptation.R index 7c455b1..bfc2465 100644 --- a/tests/testthat/test-adaptation.R +++ b/tests/testthat/test-adaptation.R @@ -30,19 +30,62 @@ dummy_proposal_with_shape_parameter <- function(shape = NULL) { ) } +check_scale_adapter_coerces_to_target_accept_prob <- function( + adapter, proposal, target_accept_prob, initial_scale) { + # For a smooth decreasing relation between accept probability and + # scale should adapt over long run to give close to target accept + # probability + scale <- initial_scale + for (sample_index in 1:2000) { + accept_prob <- exp(-scale) + adapter$update( + proposal, + sample_index, + list(statistics = list(accept_prob = accept_prob)) + ) + scale <- proposal$parameters()$scale + } + if (!is.null(adapter$finalize)) { + adapter$finalize(proposal) + scale <- proposal$parameters()$scale + } + expect_equal(scale, -log(target_accept_prob), tolerance = 1e-2) +} + +check_scale_adapter_with_default_args_works <- function( + adapter, dimension, check_adapter_state) { + check_adapter(adapter) + proposal <- dummy_proposal_with_scale_parameter() + adapter$initialize(proposal, chain_state(rep(0, dimension))) + adapter_state <- adapter$state() + check_adapter_state(adapter_state) + expected_log_scale <- log(proposal$default_initial_scale(dimension)) + expect_equal(adapter_state$log_scale, expected_log_scale) + adapter$update( + proposal, 1, list(statistics = list(accept_prob = 1.)) + ) + adapter_state <- adapter$state() + expect_gte(adapter_state$log_scale, expected_log_scale) +} + +check_simple_scale_adapter_state <- function(adapter_state) { + expect_named(adapter_state, c("log_scale")) + expect_length(adapter_state$log_scale, 1) +} + for (target_accept_prob in c(0.2, 0.4, 0.6)) { for (initial_scale in c(0.5, 1., 2.)) { for (kappa in c(0.5, 0.6, 0.8)) { test_that( sprintf( paste0( - "Scale adapter works with target_accept_prob %.1f ", + "Simple scale adapter works with target_accept_prob %.1f ", "initial_scale %.1f kappa %.1f" ), target_accept_prob, initial_scale, kappa ), { - adapter <- scale_adapter( + adapter <- simple_scale_adapter( initial_scale = initial_scale, target_accept_prob = target_accept_prob, kappa = kappa @@ -51,13 +94,14 @@ for (target_accept_prob in c(0.2, 0.4, 0.6)) { proposal <- dummy_proposal_with_scale_parameter() adapter$initialize(proposal, chain_state(rep(0, dimension))) adapter_state <- adapter$state() - expect_named(adapter_state, "log_scale") - expect_length(adapter_state$log_scale, 1) + check_simple_scale_adapter_state(adapter_state) old_scale <- initial_scale # If accept probability higher than target scale should be increased for (sample_index in 1:2) { adapter$update( - proposal, sample_index, list(statistics = list(accept_prob = target_accept_prob + 0.1)) + proposal, + sample_index, + list(statistics = list(accept_prob = target_accept_prob + 0.1)) ) expect_type(adapter$state(), "list") scale <- proposal$parameters()$scale @@ -65,25 +109,21 @@ for (target_accept_prob in c(0.2, 0.4, 0.6)) { old_scale <- scale } # If accept probability lower than target scale should be decreased - for (sample_index in 3:4) { + adapter$initialize(proposal, chain_state(rep(0, dimension))) + old_scale <- initial_scale + for (sample_index in 1:2) { adapter$update( - proposal, sample_index, list(statistics = list(accept_prob = target_accept_prob - 0.1)) + proposal, + sample_index, + list(statistics = list(accept_prob = target_accept_prob - 0.1)) ) scale <- proposal$parameters()$scale expect_lt(scale, old_scale) old_scale <- scale } - # For a smooth decreasing relation between accept probability and - # scale should adapt over long run to give close to target accept - # probability - for (sample_index in 5:2000) { - accept_prob <- exp(-scale) - adapter$update( - proposal, sample_index, list(statistics = list(accept_prob = accept_prob)) - ) - scale <- proposal$parameters()$scale - } - expect_equal(scale, -log(target_accept_prob), tolerance = 1e-2) + check_scale_adapter_coerces_to_target_accept_prob( + adapter, proposal, target_accept_prob, initial_scale + ) } ) } @@ -93,23 +133,72 @@ for (target_accept_prob in c(0.2, 0.4, 0.6)) { for (dimension in c(1L, 2L, 5L)) { test_that( sprintf( - "Scale adapter with only proposal specified works in dimension %i", + "Simple scale adapter with default args works in dimension %i", dimension + ), + { + check_scale_adapter_with_default_args_works( + simple_scale_adapter(), dimension, check_simple_scale_adapter_state + ) + } + ) +} + +check_dual_averaging_scale_adapter_state <- function(adapter_state) { + expect_named( + adapter_state, + c("log_scale", "smoothed_log_scale", "accept_prob_error") + ) + expect_length(adapter_state$log_scale, 1) + expect_length(adapter_state$smoothed_log_scale, 1) + expect_length(adapter_state$accept_prob_error, 1) +} + +for (target_accept_prob in c(0.2, 0.4, 0.6)) { + for (initial_scale in c(0.5, 1., 2.)) { + for (kappa in c(0.6, 0.8)) { + for (gamma in c(0.01, 0.05)) { + test_that( + sprintf( + paste0( + "Dual averaging scale adapter works with target_accept_prob %.1f ", + "initial_scale %.1f kappa %.1f gamma %.2f" + ), + target_accept_prob, initial_scale, kappa, gamma + ), + { + adapter <- dual_averaging_scale_adapter( + initial_scale = initial_scale, + target_accept_prob = target_accept_prob, + kappa = kappa, + gamma = gamma + ) + check_adapter(adapter) + proposal <- dummy_proposal_with_scale_parameter() + adapter$initialize(proposal, chain_state(rep(0, dimension))) + adapter_state <- adapter$state() + check_dual_averaging_scale_adapter_state(adapter_state) + check_scale_adapter_coerces_to_target_accept_prob( + adapter, proposal, target_accept_prob, initial_scale + ) + } + ) + } + } + } +} + +for (dimension in c(1L, 2L, 5L)) { + test_that( + sprintf( + "Dual averaging scale adapter with default args works in dimension %i", dimension ), { - adapter <- scale_adapter() - check_adapter(adapter) - proposal <- dummy_proposal_with_scale_parameter() - adapter$initialize(proposal, chain_state(rep(0, dimension))) - adapter_state <- adapter$state() - expect_named(adapter_state, "log_scale") - expect_length(adapter_state$log_scale, 1) - expect_equal(adapter_state$log_scale, -log(dimension) / 2) - adapter$update( - proposal, 1, list(statistics = list(accept_prob = 1.)) + check_scale_adapter_with_default_args_works( + dual_averaging_scale_adapter(), + dimension, + check_dual_averaging_scale_adapter_state ) - adapter_state <- adapter$state() - expect_gte(adapter_state$log_scale, -log(dimension) / 2) } ) } @@ -127,7 +216,7 @@ for (dimension in c(1L, 2L, 5L)) { ), { proposal <- dummy_proposal_with_shape_parameter() - adapter <- variance_adapter(kappa = kappa) + adapter <- variance_shape_adapter(kappa = kappa) check_adapter(adapter) withr::local_seed(default_seed()) target_scales <- exp(2 * rnorm(dimension)) @@ -184,8 +273,7 @@ for (dimension in c(1L, 2L, 3L)) { ) proposal <- random_walk_proposal(target_distribution) adapter <- robust_shape_adapter( - initial_scale = 1., - kappa = 2 / 3, + kappa = 0.6, target_accept_prob = target_accept_prob ) check_adapter(adapter) @@ -224,8 +312,7 @@ for (dimension in c(1L, 2L, 3L)) { for (dimension in c(1L, 2L, 5L)) { test_that( sprintf( - "Robust shape adapter with only proposal specified works in dimension %i", - dimension + "Robust shape adapter default args works in dimension %i", dimension ), { adapter <- robust_shape_adapter() @@ -240,7 +327,7 @@ for (dimension in c(1L, 2L, 5L)) { expect_equal(initial_shape, diag(dimension) / sqrt(dimension)) adapter$update( proposal, - 2, + 1, list( proposed_state = chain_state( position = NULL, momentum = rep(1, dimension) diff --git a/tests/testthat/test-chains.R b/tests/testthat/test-chains.R index 727f8fc..b08e7d3 100644 --- a/tests/testthat/test-chains.R +++ b/tests/testthat/test-chains.R @@ -23,7 +23,7 @@ for (n_warm_up_iteration in c(0, 1, 10)) { target_distribution <- standard_normal_target_distribution() barker_proposal(target_distribution) proposal <- barker_proposal(target_distribution) - adapters <- list(scale_adapter(initial_scale = 1.)) + adapters <- list(simple_scale_adapter(initial_scale = 1.)) withr::with_seed(default_seed(), { position <- rnorm(dimension) }) diff --git a/vignettes/barker-proposal.Rmd b/vignettes/barker-proposal.Rmd index 6be5608..900a9b5 100644 --- a/vignettes/barker-proposal.Rmd +++ b/vignettes/barker-proposal.Rmd @@ -73,11 +73,11 @@ Below we instantiate a list of adapters to ```{r} adapters <- list( - scale_adapter( + simple_scale_adapter( initial_scale = 2.38^2 / dimension^(1 / 3), target_accept_prob = 0.4 ), - variance_adapter() + variance_shape_adapter() ) ``` @@ -199,7 +199,7 @@ cat( To sample a chain using a Langevin proposal, we can simple use `langevin_proposal` in place of `baker_proposal`. -Here we create a new set of adapters using the default arguments to `scale_adapter` which will set the target acceptance rate to the Langevin proposal specific value of 0.574 following the results in @roberts2001optimal. +Here we create a new set of adapters using the default arguments to `simple_scale_adapter` which will set the target acceptance rate to the Langevin proposal specific value of 0.574 following the results in @roberts2001optimal. ```{r} mala_results <- sample_chain( @@ -208,7 +208,7 @@ mala_results <- sample_chain( initial_state = initial_state, n_warm_up_iteration = n_warm_up_iteration, n_main_iteration = n_main_iteration, - adapters = list(scale_adapter(), variance_adapter()), + adapters = list(simple_scale_adapter(), variance_shape_adapter()), trace_warm_up = TRUE ) ```