From ba74b6576fcc5b2c5297711411e8610688ce8756 Mon Sep 17 00:00:00 2001 From: TahminaMojumder Date: Fri, 3 Nov 2023 15:18:50 +0100 Subject: [PATCH 01/10] createPrior table --- BayesianTools/inst/examples/createPrior.R | 17 ++++++++++++++++- BayesianTools/man/createBetaPrior.Rd | 15 +++++++++++++++ BayesianTools/man/createPrior.Rd | 15 +++++++++++++++ BayesianTools/man/createPriorDensity.Rd | 15 +++++++++++++++ BayesianTools/man/createTruncatedNormalPrior.Rd | 15 +++++++++++++++ BayesianTools/man/createUniformPrior.Rd | 15 +++++++++++++++ 6 files changed, 91 insertions(+), 1 deletion(-) diff --git a/BayesianTools/inst/examples/createPrior.R b/BayesianTools/inst/examples/createPrior.R index f32fbb3..191d04f 100644 --- a/BayesianTools/inst/examples/createPrior.R +++ b/BayesianTools/inst/examples/createPrior.R @@ -1,7 +1,22 @@ -# the BT package includes a number of convenience functions to specify +# The BT package includes a number of convenience functions to specify # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: +# +# The prior we choose depends on the prior information we have. For example, if +# we have no prior information, we can choose a uniform prior. The normal +# distribution is often used to model a wide range of phenomena in statistics, +# such as the distribution of heights or weights in a population. Beta +# distribution, on the other hand, is defined on the interval [0,1]. +# It is often used to model random variables that represent proportions, +# probabilities or other values that are constrained to lie within this interval. + +# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +# | :----------:|:---------------:|:------------------:|:--------------------------:| +# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| + + + prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createBetaPrior.Rd b/BayesianTools/man/createBetaPrior.Rd index adf3bc6..4cea245 100644 --- a/BayesianTools/man/createBetaPrior.Rd +++ b/BayesianTools/man/createBetaPrior.Rd @@ -29,6 +29,21 @@ for details see \code{\link{createPrior}} # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: +# +# The prior we choose depends on the prior information we have. For example, if +# we have no prior information, we can choose a uniform prior. The normal +# distribution is often used to model a wide range of phenomena in statistics, +# such as the distribution of heights or weights in a population. Beta +# distribution, on the other hand, is defined on the interval [0,1]. +# It is often used to model random variables that represent proportions, +# probabilities or other values that are constrained to lie within this interval. + +# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +# | :----------:|:---------------:|:------------------:|:--------------------------:| +# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| + + + prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createPrior.Rd b/BayesianTools/man/createPrior.Rd index 666dd9b..4d5c7d4 100644 --- a/BayesianTools/man/createPrior.Rd +++ b/BayesianTools/man/createPrior.Rd @@ -37,6 +37,21 @@ min and max truncate, but not re-normalize the prior density (so, if a pdf that # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: +# +# The prior we choose depends on the prior information we have. For example, if +# we have no prior information, we can choose a uniform prior. The normal +# distribution is often used to model a wide range of phenomena in statistics, +# such as the distribution of heights or weights in a population. Beta +# distribution, on the other hand, is defined on the interval [0,1]. +# It is often used to model random variables that represent proportions, +# probabilities or other values that are constrained to lie within this interval. + +# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +# | :----------:|:---------------:|:------------------:|:--------------------------:| +# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| + + + prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createPriorDensity.Rd b/BayesianTools/man/createPriorDensity.Rd index 0ddde68..a007287 100644 --- a/BayesianTools/man/createPriorDensity.Rd +++ b/BayesianTools/man/createPriorDensity.Rd @@ -51,6 +51,21 @@ For that reason, it is usually recommended to not update the posterior with this # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: +# +# The prior we choose depends on the prior information we have. For example, if +# we have no prior information, we can choose a uniform prior. The normal +# distribution is often used to model a wide range of phenomena in statistics, +# such as the distribution of heights or weights in a population. Beta +# distribution, on the other hand, is defined on the interval [0,1]. +# It is often used to model random variables that represent proportions, +# probabilities or other values that are constrained to lie within this interval. + +# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +# | :----------:|:---------------:|:------------------:|:--------------------------:| +# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| + + + prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createTruncatedNormalPrior.Rd b/BayesianTools/man/createTruncatedNormalPrior.Rd index ce093f2..dc78824 100644 --- a/BayesianTools/man/createTruncatedNormalPrior.Rd +++ b/BayesianTools/man/createTruncatedNormalPrior.Rd @@ -26,6 +26,21 @@ for details see \code{\link{createPrior}} # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: +# +# The prior we choose depends on the prior information we have. For example, if +# we have no prior information, we can choose a uniform prior. The normal +# distribution is often used to model a wide range of phenomena in statistics, +# such as the distribution of heights or weights in a population. Beta +# distribution, on the other hand, is defined on the interval [0,1]. +# It is often used to model random variables that represent proportions, +# probabilities or other values that are constrained to lie within this interval. + +# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +# | :----------:|:---------------:|:------------------:|:--------------------------:| +# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| + + + prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createUniformPrior.Rd b/BayesianTools/man/createUniformPrior.Rd index e6c60b9..25d422f 100644 --- a/BayesianTools/man/createUniformPrior.Rd +++ b/BayesianTools/man/createUniformPrior.Rd @@ -24,6 +24,21 @@ for details see \code{\link{createPrior}} # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: +# +# The prior we choose depends on the prior information we have. For example, if +# we have no prior information, we can choose a uniform prior. The normal +# distribution is often used to model a wide range of phenomena in statistics, +# such as the distribution of heights or weights in a population. Beta +# distribution, on the other hand, is defined on the interval [0,1]. +# It is often used to model random variables that represent proportions, +# probabilities or other values that are constrained to lie within this interval. + +# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +# | :----------:|:---------------:|:------------------:|:--------------------------:| +# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| + + + prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) From 46bcaee279f42c27e954244ad120d96910da3d1d Mon Sep 17 00:00:00 2001 From: TahminaMojumder Date: Fri, 3 Nov 2023 15:38:45 +0100 Subject: [PATCH 02/10] create density function for different priors --- Development/Figures/figures.R | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Development/Figures/figures.R diff --git a/Development/Figures/figures.R b/Development/Figures/figures.R new file mode 100644 index 0000000..35ecc58 --- /dev/null +++ b/Development/Figures/figures.R @@ -0,0 +1,9 @@ +png(filename = "/man/figures/betaDensity.png", width = 400, height = 300) +plot(density(rbeta(10000000,10,3)), main = "Beta Density with a = 10, b = 3") +dev.off() +png(filename = "/BayesianTools/Bayesiantools/man/figures/normalDensity.png", width = 400, height = 300) +plot(density(rnorm(10000000,0,1)), main = "Normal Density with mean = 0, sd = 1") +dev.off() +png(filename = "/BayesianTools/Bayesiantools/man/figures/uniformDensity.png", width = 400, height = 300) +plot(density(runif(10000000)), main = "Uniform Density") +dev.off() \ No newline at end of file From 8b496966b70f3281657a45215c9e6007b5ab0bc0 Mon Sep 17 00:00:00 2001 From: TahminaMojumder Date: Fri, 3 Nov 2023 17:53:41 +0100 Subject: [PATCH 03/10] update --- BayesianTools/R/classPrior.R | 23 ++++++++++- BayesianTools/inst/examples/createPrior.R | 15 ------- BayesianTools/man/createBetaPrior.Rd | 17 +------- BayesianTools/man/createPrior.Rd | 39 +++++++++--------- BayesianTools/man/createPriorDensity.Rd | 17 +------- .../man/createTruncatedNormalPrior.Rd | 17 +------- BayesianTools/man/createUniformPrior.Rd | 17 +------- BayesianTools/man/figures/betaDensity.png | Bin 0 -> 13489 bytes BayesianTools/man/figures/normalDensity.png | Bin 0 -> 13559 bytes BayesianTools/man/figures/uniformDensity.png | Bin 0 -> 11764 bytes BayesianTools/vignettes/BayesianTools.Rmd | 10 +++++ Development/Figures/figures.R | 8 ++-- 12 files changed, 59 insertions(+), 104 deletions(-) create mode 100644 BayesianTools/man/figures/betaDensity.png create mode 100644 BayesianTools/man/figures/normalDensity.png create mode 100644 BayesianTools/man/figures/uniformDensity.png diff --git a/BayesianTools/R/classPrior.R b/BayesianTools/R/classPrior.R index efb0215..e03ec53 100644 --- a/BayesianTools/R/classPrior.R +++ b/BayesianTools/R/classPrior.R @@ -1,11 +1,30 @@ -#' Creates a standardized prior class +#' Creates a user-defined prior class +#' @description This function creates a general user-defined prior class. Note that there are specialized function available for specific prior classes, see details. #' @author Florian Hartig #' @param density Prior density #' @param sampler Sampling function for density (optional) #' @param lower vector with lower bounds of parameters #' @param upper vector with upper bounds of parameter #' @param best vector with "best" parameter values -#' @details This is the general prior generator. It is highly recommended to not only implement the density, but also the sampler function. If this is not done, the user will have to provide explicit starting values for many of the MCMC samplers. Note the existing, more specialized prior function. If your prior can be created by those, they are preferred. Note also that priors can be created from an existing MCMC output from BT, or another MCMC sample, via \code{\link{createPriorDensity}}. +#' @details This is the general prior generator. It is highly recommended to not only implement the density, but also the sampler function. If this is not done, the user will have to provide explicit starting values for many of the MCMC samplers. +#' +#' Note the existing, more specialized prior function. If your prior can be created by those functions, they are preferred. Note also that priors can be created from an existing MCMC output from BT, or another MCMC sample, via \code{\link{createPriorDensity}}. +#' +#' The prior we choose depends on the prior information we have. For example, if +#' we have no prior information, we can choose a uniform prior. The normal +#' distribution is often used to model a wide range of phenomena in statistics, +#' such as the distribution of heights or weights in a population. Beta +#' distribution, on the other hand, is defined on the interval 0, 1. +#' It is often used to model random variables that represent proportions, +#' probabilities or other values that are constrained to lie within this interval. +#' | | | | | +#' |:-------------------------------------------------:|:-------------------------------------------------------:|:-----------------------------------------------------------:|:-------------------------------------------------------------:| +#' | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +#' | Any density provided by the user | Beta density | Uniform density | Normal density | +#' | |![](betaDensity.png "Density plot for Beta distribution")|![](normalDensity.png "Density plot for Normal distribution")|![](uniformDensity.png "Density plot for Uniform distribution")| +#' | createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | + + #' @note min and max truncate, but not re-normalize the prior density (so, if a pdf that integrated to one is truncated, the integral will in general be smaller than one). For MCMC sampling, this doesn't make a difference, but if absolute values of the prior density are a concern, one should provide a truncated density function for the prior. #' @export #' @seealso \code{\link{createPriorDensity}} \cr diff --git a/BayesianTools/inst/examples/createPrior.R b/BayesianTools/inst/examples/createPrior.R index 191d04f..4692e2d 100644 --- a/BayesianTools/inst/examples/createPrior.R +++ b/BayesianTools/inst/examples/createPrior.R @@ -2,21 +2,6 @@ # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: -# -# The prior we choose depends on the prior information we have. For example, if -# we have no prior information, we can choose a uniform prior. The normal -# distribution is often used to model a wide range of phenomena in statistics, -# such as the distribution of heights or weights in a population. Beta -# distribution, on the other hand, is defined on the interval [0,1]. -# It is often used to model random variables that represent proportions, -# probabilities or other values that are constrained to lie within this interval. - -# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -# | :----------:|:---------------:|:------------------:|:--------------------------:| -# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| - - - prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createBetaPrior.Rd b/BayesianTools/man/createBetaPrior.Rd index 4cea245..da1efa1 100644 --- a/BayesianTools/man/createBetaPrior.Rd +++ b/BayesianTools/man/createBetaPrior.Rd @@ -25,25 +25,10 @@ This creates a beta prior, assuming that lower / upper values for parameters are for details see \code{\link{createPrior}} } \examples{ -# the BT package includes a number of convenience functions to specify +# The BT package includes a number of convenience functions to specify # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: -# -# The prior we choose depends on the prior information we have. For example, if -# we have no prior information, we can choose a uniform prior. The normal -# distribution is often used to model a wide range of phenomena in statistics, -# such as the distribution of heights or weights in a population. Beta -# distribution, on the other hand, is defined on the interval [0,1]. -# It is often used to model random variables that represent proportions, -# probabilities or other values that are constrained to lie within this interval. - -# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -# | :----------:|:---------------:|:------------------:|:--------------------------:| -# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| - - - prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createPrior.Rd b/BayesianTools/man/createPrior.Rd index 4d5c7d4..d8c28ab 100644 --- a/BayesianTools/man/createPrior.Rd +++ b/BayesianTools/man/createPrior.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/classPrior.R \name{createPrior} \alias{createPrior} -\title{Creates a standardized prior class} +\title{Creates a user-defined prior class} \usage{ createPrior( density = NULL, @@ -24,34 +24,35 @@ createPrior( \item{best}{vector with "best" parameter values} } \description{ -Creates a standardized prior class +This function creates a general user-defined prior class. Note that there are specialized function available for specific prior classes, see details. } \details{ -This is the general prior generator. It is highly recommended to not only implement the density, but also the sampler function. If this is not done, the user will have to provide explicit starting values for many of the MCMC samplers. Note the existing, more specialized prior function. If your prior can be created by those, they are preferred. Note also that priors can be created from an existing MCMC output from BT, or another MCMC sample, via \code{\link{createPriorDensity}}. +This is the general prior generator. It is highly recommended to not only implement the density, but also the sampler function. If this is not done, the user will have to provide explicit starting values for many of the MCMC samplers. + +Note the existing, more specialized prior function. If your prior can be created by those functions, they are preferred. Note also that priors can be created from an existing MCMC output from BT, or another MCMC sample, via \code{\link{createPriorDensity}}. + +The prior we choose depends on the prior information we have. For example, if +we have no prior information, we can choose a uniform prior. The normal +distribution is often used to model a wide range of phenomena in statistics, +such as the distribution of heights or weights in a population. Beta +distribution, on the other hand, is defined on the interval 0, 1. +It is often used to model random variables that represent proportions, +probabilities or other values that are constrained to lie within this interval.\tabular{cccc}{ + \tab \tab \tab \cr + createPrior \tab createBetaPrior \tab createUniformPrior \tab createTruncatedNormalPrior \cr + Any density provided by the user \tab Beta density \tab Uniform density \tab Normal density \cr + \tab \figure{betaDensity.png}{Density plot for Beta distribution} \tab \figure{normalDensity.png}{Density plot for Normal distribution} \tab \figure{uniformDensity.png}{Density plot for Uniform distribution} \cr + createPrior(density, sampler, lower, upper, best) \tab createBetaPrior(a, b, lower, upper) \tab createUniformPrior(lower, upper, best) \tab createTruncatedNormalPrior(mean, sd, lower, upper). \cr +} } \note{ min and max truncate, but not re-normalize the prior density (so, if a pdf that integrated to one is truncated, the integral will in general be smaller than one). For MCMC sampling, this doesn't make a difference, but if absolute values of the prior density are a concern, one should provide a truncated density function for the prior. } \examples{ -# the BT package includes a number of convenience functions to specify +# The BT package includes a number of convenience functions to specify # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: -# -# The prior we choose depends on the prior information we have. For example, if -# we have no prior information, we can choose a uniform prior. The normal -# distribution is often used to model a wide range of phenomena in statistics, -# such as the distribution of heights or weights in a population. Beta -# distribution, on the other hand, is defined on the interval [0,1]. -# It is often used to model random variables that represent proportions, -# probabilities or other values that are constrained to lie within this interval. - -# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -# | :----------:|:---------------:|:------------------:|:--------------------------:| -# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| - - - prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createPriorDensity.Rd b/BayesianTools/man/createPriorDensity.Rd index a007287..fa658e1 100644 --- a/BayesianTools/man/createPriorDensity.Rd +++ b/BayesianTools/man/createPriorDensity.Rd @@ -47,25 +47,10 @@ For that reason, it is usually recommended to not update the posterior with this } } \examples{ -# the BT package includes a number of convenience functions to specify +# The BT package includes a number of convenience functions to specify # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: -# -# The prior we choose depends on the prior information we have. For example, if -# we have no prior information, we can choose a uniform prior. The normal -# distribution is often used to model a wide range of phenomena in statistics, -# such as the distribution of heights or weights in a population. Beta -# distribution, on the other hand, is defined on the interval [0,1]. -# It is often used to model random variables that represent proportions, -# probabilities or other values that are constrained to lie within this interval. - -# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -# | :----------:|:---------------:|:------------------:|:--------------------------:| -# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| - - - prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createTruncatedNormalPrior.Rd b/BayesianTools/man/createTruncatedNormalPrior.Rd index dc78824..200a28c 100644 --- a/BayesianTools/man/createTruncatedNormalPrior.Rd +++ b/BayesianTools/man/createTruncatedNormalPrior.Rd @@ -22,25 +22,10 @@ Convenience function to create a truncated normal prior for details see \code{\link{createPrior}} } \examples{ -# the BT package includes a number of convenience functions to specify +# The BT package includes a number of convenience functions to specify # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: -# -# The prior we choose depends on the prior information we have. For example, if -# we have no prior information, we can choose a uniform prior. The normal -# distribution is often used to model a wide range of phenomena in statistics, -# such as the distribution of heights or weights in a population. Beta -# distribution, on the other hand, is defined on the interval [0,1]. -# It is often used to model random variables that represent proportions, -# probabilities or other values that are constrained to lie within this interval. - -# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -# | :----------:|:---------------:|:------------------:|:--------------------------:| -# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| - - - prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/createUniformPrior.Rd b/BayesianTools/man/createUniformPrior.Rd index 25d422f..f709a4f 100644 --- a/BayesianTools/man/createUniformPrior.Rd +++ b/BayesianTools/man/createUniformPrior.Rd @@ -20,25 +20,10 @@ Convenience function to create a simple uniform prior distribution for details see \code{\link{createPrior}} } \examples{ -# the BT package includes a number of convenience functions to specify +# The BT package includes a number of convenience functions to specify # prior distributions, including createUniformPrior, createTruncatedNormalPrior # etc. If you want to specify a prior that corresponds to one of these # distributions, you should use these functions, e.g.: -# -# The prior we choose depends on the prior information we have. For example, if -# we have no prior information, we can choose a uniform prior. The normal -# distribution is often used to model a wide range of phenomena in statistics, -# such as the distribution of heights or weights in a population. Beta -# distribution, on the other hand, is defined on the interval [0,1]. -# It is often used to model random variables that represent proportions, -# probabilities or other values that are constrained to lie within this interval. - -# | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -# | :----------:|:---------------:|:------------------:|:--------------------------:| -# |Any distribution provided by the user|Beta distribution|Uniform distribution|Normal distribution| - - - prior <- createUniformPrior(lower = c(0,0), upper = c(0.4,5)) diff --git a/BayesianTools/man/figures/betaDensity.png b/BayesianTools/man/figures/betaDensity.png new file mode 100644 index 0000000000000000000000000000000000000000..5c482db6b67bab376584e01fd62758484aa25e17 GIT binary patch literal 13489 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 k1QpcW0P^Tvlsht9>? Date: Wed, 8 Nov 2023 14:34:37 +0100 Subject: [PATCH 04/10] update table for priors --- BayesianTools/R/classPrior.R | 7 +- BayesianTools/doc/BayesianTools.R | 348 +++++++++ BayesianTools/doc/BayesianTools.Rmd | 714 ++++++++++++++++++ BayesianTools/doc/InterfacingAModel.R | 113 +++ BayesianTools/doc/InterfacingAModel.Rmd | 300 ++++++++ BayesianTools/man/createPrior.Rd | 6 +- BayesianTools/vignettes/BayesianTools.Rmd | 244 +++--- BayesianTools/vignettes/InterfacingAModel.Rmd | 110 ++- BayesianTools/vignettes/betaDensity.png | Bin 0 -> 9746 bytes BayesianTools/vignettes/normalDensity.png | Bin 0 -> 9825 bytes BayesianTools/vignettes/uniformDensity.png | Bin 0 -> 8374 bytes Development/Figures/figures.R | 12 + 12 files changed, 1633 insertions(+), 221 deletions(-) create mode 100644 BayesianTools/doc/BayesianTools.R create mode 100644 BayesianTools/doc/BayesianTools.Rmd create mode 100644 BayesianTools/doc/InterfacingAModel.R create mode 100644 BayesianTools/doc/InterfacingAModel.Rmd create mode 100644 BayesianTools/vignettes/betaDensity.png create mode 100644 BayesianTools/vignettes/normalDensity.png create mode 100644 BayesianTools/vignettes/uniformDensity.png diff --git a/BayesianTools/R/classPrior.R b/BayesianTools/R/classPrior.R index e03ec53..1840dd4 100644 --- a/BayesianTools/R/classPrior.R +++ b/BayesianTools/R/classPrior.R @@ -19,11 +19,14 @@ #' probabilities or other values that are constrained to lie within this interval. #' | | | | | #' |:-------------------------------------------------:|:-------------------------------------------------------:|:-----------------------------------------------------------:|:-------------------------------------------------------------:| -#' | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +#' | \strong{createPrior} | \strong{createBetaPrior} | \strong{createUniformPrior} | \strong{createTruncatedNormalPrior} | +#' |---------------------------------------------------|---------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------| #' | Any density provided by the user | Beta density | Uniform density | Normal density | +#' |---------------------------------------------------|---------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------| #' | |![](betaDensity.png "Density plot for Beta distribution")|![](normalDensity.png "Density plot for Normal distribution")|![](uniformDensity.png "Density plot for Uniform distribution")| +#' |---------------------------------------------------|---------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------| #' | createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | - +#' |---------------------------------------------------|---------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------| #' @note min and max truncate, but not re-normalize the prior density (so, if a pdf that integrated to one is truncated, the integral will in general be smaller than one). For MCMC sampling, this doesn't make a difference, but if absolute values of the prior density are a concern, one should provide a truncated density function for the prior. #' @export diff --git a/BayesianTools/doc/BayesianTools.R b/BayesianTools/doc/BayesianTools.R new file mode 100644 index 0000000..9bb0bd8 --- /dev/null +++ b/BayesianTools/doc/BayesianTools.R @@ -0,0 +1,348 @@ +## ----global_options, include=FALSE-------------------------------------------- +knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) + +## ----echo = F, message = F---------------------------------------------------- +set.seed(123) + +## ----eval = F----------------------------------------------------------------- +# install.packages("BayesianTools") + +## ----------------------------------------------------------------------------- +library(BayesianTools) +citation("BayesianTools") + +## ----------------------------------------------------------------------------- +set.seed(123) + +## ----eval = F----------------------------------------------------------------- +# sessionInfo() + +## ----------------------------------------------------------------------------- +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +## ----------------------------------------------------------------------------- +iter = 10000 +settings = list(iterations = iter, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + +## ----------------------------------------------------------------------------- +print(out) +summary(out) + +## ----------------------------------------------------------------------------- +plot(out) # plot internally calls tracePlot(out) +correlationPlot(out) +marginalPlot(out, prior = TRUE) + +## ----------------------------------------------------------------------------- +marginalLikelihood(out) +DIC(out) +MAP(out) + +## ----eval = F----------------------------------------------------------------- +# getSample(out, start = 100, end = NULL, thin = 5, whichParameters = 1:2) + +## ----echo = T----------------------------------------------------------------- +iter = 1000 +settings = list(iterations = iter, nrChains = 3, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + + +## ----------------------------------------------------------------------------- +print(out) +summary(out) + +## ----------------------------------------------------------------------------- +plot(out) + +## ----------------------------------------------------------------------------- +#getSample(out, coda = F) +gelmanDiagnostics(out, plot = T) + +## ----eval = F----------------------------------------------------------------- +# ll = logDensity(x) + +## ----------------------------------------------------------------------------- +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +## ----eval = FALSE------------------------------------------------------------- +# ## Definition of likelihood function +# likelihood <- function(matrix){ +# # Calculate likelihood in parallel +# # Return vector of likelihood valus +# } +# +# ## Create Bayesian Setup +# BS <- createBayesianSetup(likelihood, parallel = "external", ...) +# +# ## Run MCMC +# runMCMC(BS, sampler = "SMC", ...) + +## ----eval = FALSE------------------------------------------------------------- +# ## n = Number of cores +# n=2 +# x <- c(1:10) +# likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) +# bayesianSetup <- createBayesianSetup(likelihood, parallel = n, lower = -5, upper = 5) +# +# ## give runMCMC a matrix with n rows of proposals as startValues or sample n times from the previous created sampler +# out <- runMCMC(bayesianSetup, settings = list(iterations = 1000)) + +## ----eval = FALSE------------------------------------------------------------- +# ### Create cluster with n cores +# cl <- parallel::makeCluster(n) +# +# ## Definition of the likelihood +# likelihood <- function(X) sum(dnorm(c(1:10), mean = X, log = T)) +# +# ## Definition of the likelihood which will be calculated in parallel. Instead of the parApply function, we could also define a costly parallelized likelihood +# pLikelihood <- function(param) parallel::parApply(cl = cl, X = param, MARGIN = 1, FUN = likelihood) +# +# ## export functions, dlls, libraries +# # parallel::clusterEvalQ(cl, library(BayesianTools)) +# parallel::clusterExport(cl, varlist = list(likelihood)) +# +# ## create BayesianSetup +# bayesianSetup <- createBayesianSetup(pLikelihood, lower = -10, upper = 10, parallel = 'external') +# +# ## For this case we want to parallelize the internal chains, therefore we create a n row matrix with startValues, if you parallelize a model in the likelihood, do not set a n*row Matrix for startValue +# settings = list(iterations = 100, nrChains = 1, startValue = bayesianSetup$prior$sampler(n)) +# +# ## runMCMC +# out <- runMCMC(bayesianSetup, settings, sampler = "DEzs") + +## ----eval = FALSE------------------------------------------------------------- +# ### Create cluster with n cores +# cl <- parallel::makeCluster(n) +# +# ## export your model +# # parallel::clusterExport(cl, varlist = list(complexModel)) +# +# ## Definition of the likelihood +# likelihood <- function(param) { +# # ll <- complexModel(param) +# # return(ll) +# } +# +# ## create BayesianSetup and settings +# bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = 'external') +# settings = list(iterations = 100, nrChains = 1) +# +# ## runMCMC +# out <- runMCMC(bayesianSetup, settings) +# + +## ----eval = FALSE------------------------------------------------------------- +# ### Definition of likelihood function +# x <- c(1:10) +# likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) +# +# ## Create BayesianSetup and settings +# bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = F) +# settings = list(iterations = 100000) +# +# ## Start cluster with n cores for n chains and export BayesianTools library +# cl <- parallel::makeCluster(n) +# parallel::clusterEvalQ(cl, library(BayesianTools)) +# +# ## calculate parallel n chains, for each chain the likelihood will be calculated on one core +# out <- parallel::parLapply(cl, 1:n, fun = function(X, bayesianSetup, settings) runMCMC(bayesianSetup, settings, sampler = "DEzs"), bayesianSetup, settings) +# +# ## Combine the chains +# out <- createMcmcSamplerList(out) + +## ----------------------------------------------------------------------------- +# Create a BayesianSetup +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +settings = list(iterations = 2500, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) + + +newPrior = createPriorDensity(out, method = "multivariate", eps = 1e-10, lower = rep(-10, 3), upper = rep(10, 3), best = NULL) +bayesianSetup <- createBayesianSetup(likelihood = ll, prior = newPrior) + +settings = list(iterations = 1000, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) + +## ----message = F-------------------------------------------------------------- + +ll <- generateTestDensityMultiNormal(sigma = "no correlation") + +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +settings = list(iterations = 10000, nrChains= 3, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + +plot(out) +marginalPlot(out, prior = T) +correlationPlot(out) +gelmanDiagnostics(out, plot=T) + +# option to restart the sampler + +settings = list(iterations = 1000, nrChains= 1, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + +out2 <- runMCMC(bayesianSetup = out) + +out3 <- runMCMC(bayesianSetup = out2) + +#plot(out) +#plot(out3) + +# create new prior from posterior sample + +newPriorFromPosterior <- createPriorDensity(out2) + + +## ----------------------------------------------------------------------------- +iter = 10000 + +## ----------------------------------------------------------------------------- +applySettingsDefault(sampler = "Metropolis") + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = F, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, adapt = F, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, adapt = T, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = c(1,0.5,0), temperingFunction = NULL, optimize = T, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# temperingFunction <- function(x) 5 * exp(-0.01*x) + 1 +# settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = c(1,1,0), temperingFunction = temperingFunction, optimize = T, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DE", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(iterations = iter, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAM", settings = settings) +# plot(out) + +## ----results = 'hide', eval = FALSE------------------------------------------- +# settings <- list(iterations = iter, message = FALSE) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAMzs", settings = settings) +# plot(out) + +## ----eval = F----------------------------------------------------------------- +# settings = list(iterations = iter, message = FALSE) +# +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Twalk", settings = settings) + +## ----eval = T----------------------------------------------------------------- +settings <- list(iterations = iter, nrChains = 3, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) + +#chain = getSample(out, coda = T) +gelmanDiagnostics(out, plot = F) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(initialParticles = iter, iterations= 1) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) +# plot(out) + +## ----results = 'hide', eval = F----------------------------------------------- +# settings <- list(initialParticles = iter, iterations= 10) +# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) +# plot(out) + +## ----------------------------------------------------------------------------- +sampleSize = 30 +x <- (-(sampleSize-1)/2):((sampleSize-1)/2) +y <- 1 * x + 1*x^2 + rnorm(n=sampleSize,mean=0,sd=10) +plot(x,y, main="Test Data") + +## ----------------------------------------------------------------------------- +likelihood1 <- function(param){ + pred = param[1] + param[2]*x + param[3] * x^2 + singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) + return(sum(singlelikelihoods)) +} + +likelihood2 <- function(param){ + pred = param[1] + param[2]*x + singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[3]^2), log = T) + return(sum(singlelikelihoods)) +} + +## ----------------------------------------------------------------------------- +setUp1 <- createBayesianSetup(likelihood1, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) + +setUp2 <- createBayesianSetup(likelihood2, lower = c(-5,-5,0.01), upper = c(5,5,30)) + +## ----results = 'hide'--------------------------------------------------------- +settings = list(iterations = 15000, message = FALSE) +out1 <- runMCMC(bayesianSetup = setUp1, sampler = "Metropolis", settings = settings) +#tracePlot(out1, start = 5000) +M1 = marginalLikelihood(out1) +M1 + +settings = list(iterations = 15000, message = FALSE) +out2 <- runMCMC(bayesianSetup = setUp2, sampler = "Metropolis", settings = settings) +#tracePlot(out2, start = 5000) +M2 = marginalLikelihood(out2) +M2 + +## ----------------------------------------------------------------------------- +exp(M1$ln.ML - M2$ln.ML) + +## ----------------------------------------------------------------------------- +exp(M1$ln.ML) / ( exp(M1$ln.ML) + exp(M2$ln.ML)) + +## ----------------------------------------------------------------------------- +DIC(out1)$DIC +DIC(out2)$DIC + +## ----------------------------------------------------------------------------- +# This will not work, since likelihood1 has no sum argument +# WAIC(out1) + +# likelihood with sum argument +likelihood3 <- function(param, sum = TRUE){ + pred <- param[1] + param[2]*x + param[3] * x^2 + singlelikelihoods <- dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) + return(if (sum == TRUE) sum(singlelikelihoods) else singlelikelihoods) +} +setUp3 <- createBayesianSetup(likelihood3, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) +out3 <- runMCMC(bayesianSetup = setUp3, sampler = "Metropolis", settings = settings) + +WAIC(out3) + diff --git a/BayesianTools/doc/BayesianTools.Rmd b/BayesianTools/doc/BayesianTools.Rmd new file mode 100644 index 0000000..e76bea3 --- /dev/null +++ b/BayesianTools/doc/BayesianTools.Rmd @@ -0,0 +1,714 @@ +--- +title: "Bayesian Tools - General-Purpose MCMC and SMC Samplers and Tools for Bayesian Statistics" +output: + rmarkdown::html_vignette: + toc: true +vignette: > + %\VignetteIndexEntry{Manual for the BayesianTools R package} + %\VignetteEngine{knitr::rmarkdown} + \usepackage[utf8]{inputenc} +abstract: "The BayesianTools (BT) package supports model analysis (including sensitivity analysis and uncertainty analysis), Bayesian model calibration, as well as model selection and multi-model inference techniques for system models." +--- + +```{r global_options, include=FALSE} +knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) +``` + +```{r, echo = F, message = F} +set.seed(123) +``` + +# Quick start + +The purpose of this first section is to give you a quick overview of the most important functions of the BayesianTools (BT) package. For a more detailed description, see the later sections + +## Installing, loading and citing the package + +If you haven't installed the package yet, either run + +```{r, eval = F} +install.packages("BayesianTools") +``` + +Or follow the instructions on to install a development or an older version. + +Loading and citation + +```{r} +library(BayesianTools) +citation("BayesianTools") +``` + +Note: BayesianTools calls a number of secondary packages. Particular important is coda, which is used on a number of plots and summary statistics. If you make heavy use of the summary statistics and diagnostics plots, it would be nice to cite coda as well! + +Pro-tip: if you are running a stochastic algorithms such as an MCMC, you should always set or record your random seed to make your results reproducible (otherwise, results will change slightly every time you run the code) + +```{r} +set.seed(123) +``` + +In a real application, to ensure reproducibility, it would also be useful to record the session info, + +```{r, eval = F} +sessionInfo() +``` + +which lists the version number of R and all loaded packages. + +## The Bayesian Setup + +The central object in the BT package is the BayesianSetup. This class contains the information about the model to be fit (likelihood), and the priors for the model parameters. + +A BayesianSetup is created by the createBayesianSetup function. The function expects a log-likelihood and (optional) a log-prior. It then automatically creates the posterior and various convenience functions for the samplers. + +Advantages of the BayesianSetup include 1. support for automatic parallelization 2. functions are wrapped in try-catch statements to avoid crashes during long MCMC evaluations 3. and the posterior checks if the parameter is outside the prior first, in which case the likelihood is not evaluated (makes the algorithms faster for slow likelihoods). + +If no prior information is provided, an unbounded flat prior is created. If no explicit prior, but lower and upper values are provided, a standard uniform prior with the respective bounds is created, including the option to sample from this prior, which is useful for SMC and also for getting starting values. This option is used in the following example, which creates a multivariate normal likelihood density and a uniform prior for 3 parameters. + +```{r} +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) +``` + +See later more detailed description about the BayesianSetup. + +**Hint:** for an example how to run this steps for dynamic ecological model, see ?VSEM + +## Running MCMC and SMC functions + +Once you have your setup, you may want to run a calibration. The runMCMC function is the main wrapper for all other implemented MCMC/SMC functions. It always takes the following arguments + +- A bayesianSetup (alternatively, the log target function) +- The sampler name +- A list with settings - if a parameter is not provided, the default will be used + +As an example, choosing the sampler name "Metropolis" calls a versatile Metropolis-type MCMC with options for covariance adaptation, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the the later reference on MCMC samplers. This is how we would call this sampler with default settings + +```{r} +iter = 10000 +settings = list(iterations = iter, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +``` + +#### Summarizing outputs + +All samplers can be plotted and summarized via the console with the standard print, and summary commands + +```{r} +print(out) +summary(out) +``` + +and plottted with several plot functions. The marginalPlot can either be plotted as histograms with density overlay, which is also the default, or as a violin plot (see "?marginalPlot"). + +```{r} +plot(out) # plot internally calls tracePlot(out) +correlationPlot(out) +marginalPlot(out, prior = TRUE) +``` + +Other Functions that can be applied to all samplers include model selection scores such as the DIC and the marginal Likelihood (for the calculation of the Bayes factor, see later section for more details), and the Maximum Aposteriori Value (MAP). For the marginal likelihood calculation it is possible to chose from a set of methods (see "?marginalLikelihood"). + +```{r} +marginalLikelihood(out) +DIC(out) +MAP(out) +``` + +You can extract (a part of) the sampled parameter values by + +```{r, eval = F} +getSample(out, start = 100, end = NULL, thin = 5, whichParameters = 1:2) +``` + +For all samplers, you can conveniently perform multiple runs via the nrChains argument + +```{r, echo = T} +iter = 1000 +settings = list(iterations = iter, nrChains = 3, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + +``` + +The result is an object of mcmcSamplerList, which should allow to do everything one can do with an mcmcSampler object (with slightly different output sometimes). + +```{r} +print(out) +summary(out) +``` + +For example, in the plot you now see 3 chains. + +```{r} +plot(out) +``` + +There are a few additional functions that may only be available for lists, for example convergence checks + +```{r} +#getSample(out, coda = F) +gelmanDiagnostics(out, plot = T) +``` + +#### Which sampler to choose? + +The BT package provides a large class of different MCMC samplers, and it depends on the particular application which is most suitable. + +In the absence of further information, we currently recommend the DEzs sampler. This is also the default in the runMCMC function. + +# BayesianSetup Reference + +## Reference on creating likelihoods + +The likelihood should be provided as a log density function. + +```{r, eval = F} +ll = logDensity(x) +``` + +See options for parallelization below. We will use a simple 3-d multivariate normal density for this demonstration. + +```{r} +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) +``` + +#### Parallelization of the likelihood evaluations + +Likelihoods are often costly to compute. If that is the case for you, you should think about parallelization possibilities. The 'createBayesianSetup' function has the input variable 'parallel', with the following options + +- F / FALSE means no parallelization should be used +- T / TRUE means that automatic parallelization options from R are used (careful: this will not work if your likelihood writes to file, or uses global variables or functions - see general R help on parallelization) +- "external", assumed that the likelihood is already parallelized. In this case, the function needs to accept a matrix with parameters as columns, and rows as the different model runs you want to evaluate. This is the most likely option to use if you have a complicated setup (file I/O, HPC cluster) that cannot be treated with the standard R parallelization. + +Algorithms in the BayesianTools package can make use of parallel computing if this option is specified in the BayesianSetup. Note that currently, parallelization is used by the following algorithms: SMC, DEzs and DREAMzs sampler. It can also be used through the BayesianSetup with the functions of the sensitivity package. + +Here some more details on the parallelization + +#### 1. In-build parallelization: + +The in-build parallelization is the easiest way to make use of parallel computing. In the "parallel" argument you can choose the number of cores used for parallelization. Alternatively for TRUE or "auto" all available cores except for one will be used. Now the proposals are evaluated in parallel. Technically, the in-build parallelization uses an R cluster to evaluate the posterior density function. The input for the parallel function is a matrix, where each column represents a parameter and each row a proposal. In this way, the proposals can be evaluated in parallel. For sampler, where only one proposal is evaluated at a time (namely the Metropolis based algorithms as well as DE/DREAM without the zs extension), no parallelization can be used. + +#### 2. External parallelization + +The second option is to use an external parallelization. Here, a parallelization is attempted in the user defined likelihood function. To make use of external parallelization, the likelihood function needs to take a matrix of proposals and return a vector of likelihood values. In the proposal matrix each row represents one proposal, each column a parameter. Further, you need to specify the "external" parallelization in the "parallel" argument. In simplified terms the use of external parallelization uses the following steps: + +```{r, eval = FALSE} +## Definition of likelihood function +likelihood <- function(matrix){ + # Calculate likelihood in parallel + # Return vector of likelihood valus +} + +## Create Bayesian Setup +BS <- createBayesianSetup(likelihood, parallel = "external", ...) + +## Run MCMC +runMCMC(BS, sampler = "SMC", ...) +``` + +#### 3. Multi-core and cluster calculations + +If you want to run your calculations on a cluster there are several ways to achieve it. + +In the first case you want to parallize n internal (not overall chains) on n cores. The argument "parallel = T" in "createBayesianSetup" allows only at most parallelization on 3 cores for the SMC, DEzs and DreamsSamplers. But by setting "parallel = n" to n cores in the "createBayesianSetup", the internal chains of DEzs and DREAMzs will be parallelized on n cores. This works only for the DEzs and DREAMzs samplers. + +```{r, eval = FALSE} +## n = Number of cores +n=2 +x <- c(1:10) +likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) +bayesianSetup <- createBayesianSetup(likelihood, parallel = n, lower = -5, upper = 5) + +## give runMCMC a matrix with n rows of proposals as startValues or sample n times from the previous created sampler +out <- runMCMC(bayesianSetup, settings = list(iterations = 1000)) +``` + +In the second case you want to parallize n internal chains on n cores with a external parallilzed likelihood function. Unlike the previous case, that way DEzs, DREAMzs, and SMC samplers can be parallelized. + +```{r, eval = FALSE} +### Create cluster with n cores +cl <- parallel::makeCluster(n) + +## Definition of the likelihood +likelihood <- function(X) sum(dnorm(c(1:10), mean = X, log = T)) + +## Definition of the likelihood which will be calculated in parallel. Instead of the parApply function, we could also define a costly parallelized likelihood +pLikelihood <- function(param) parallel::parApply(cl = cl, X = param, MARGIN = 1, FUN = likelihood) + +## export functions, dlls, libraries +# parallel::clusterEvalQ(cl, library(BayesianTools)) +parallel::clusterExport(cl, varlist = list(likelihood)) + +## create BayesianSetup +bayesianSetup <- createBayesianSetup(pLikelihood, lower = -10, upper = 10, parallel = 'external') + +## For this case we want to parallelize the internal chains, therefore we create a n row matrix with startValues, if you parallelize a model in the likelihood, do not set a n*row Matrix for startValue +settings = list(iterations = 100, nrChains = 1, startValue = bayesianSetup$prior$sampler(n)) + +## runMCMC +out <- runMCMC(bayesianSetup, settings, sampler = "DEzs") +``` + +In a another case your likelihood requires a parallized model. Start your cluster and export your model, the required libraries, and dlls. Now you can start your calculations with the argument "parallel = external" in createBayesianSetup. + +```{r, eval = FALSE} +### Create cluster with n cores +cl <- parallel::makeCluster(n) + +## export your model +# parallel::clusterExport(cl, varlist = list(complexModel)) + +## Definition of the likelihood +likelihood <- function(param) { + # ll <- complexModel(param) + # return(ll) +} + +## create BayesianSetup and settings +bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = 'external') +settings = list(iterations = 100, nrChains = 1) + +## runMCMC +out <- runMCMC(bayesianSetup, settings) + +``` + +In the last case you can parallize over whole chain calculations. However, here the likelihood itself will not be parallelized. Each chain will be run on one core and the likelihood will be calculated on that core. + +```{r, eval = FALSE} +### Definition of likelihood function +x <- c(1:10) +likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) + +## Create BayesianSetup and settings +bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = F) +settings = list(iterations = 100000) + +## Start cluster with n cores for n chains and export BayesianTools library +cl <- parallel::makeCluster(n) +parallel::clusterEvalQ(cl, library(BayesianTools)) + +## calculate parallel n chains, for each chain the likelihood will be calculated on one core +out <- parallel::parLapply(cl, 1:n, fun = function(X, bayesianSetup, settings) runMCMC(bayesianSetup, settings, sampler = "DEzs"), bayesianSetup, settings) + +## Combine the chains +out <- createMcmcSamplerList(out) +``` + +\*\* Remark: even though parallelization can significantly reduce the computation time, it is not always useful because of the so-called communication overhead (computational time for distributing and retrieving infos from the parallel cores). For models with low computational cost, this procedure can take more time than the actual evaluation of the likelihood. If in doubt, make a small comparison of the runtime before starting your large sampling. \*\* + +## Reference on creating priors + +The prior in the BayesianSetup consists of four parts + +- A log density function +- An (optional) sampling function (must be a function without parameters, that returns a draw from the prior) +- lower / upper boundaries +- Additional info - best values, names of the parameters, ... + +These information can be passed by first creating an a extra object, via createPrior, or through the the createBayesianSetup function. + +#### Creating priors + +You have 5 options to create a prior + +- Do not set a prior - in this case, an infinite prior will be created +- Set min/max values - a bounded flat prior and the corresponding sampling function will be created +- Use one of the pre-definded priors, see ?createPrior for a list. One of the options here is to use a previous MCMC output as new prior. Pre-defined priors will usually come with a sampling function +- Use a user-define prior, see ?createPrior +- Create a prior from a previous MCMC sample + +The prior we choose depends on the prior information we have. For example, if we have no prior information, we can choose a uniform prior. The normal distribution is often used to model a wide range of phenomena in statistics, such as the distribution of heights or weights in a population. Beta distribution, on the other hand, is defined on the interval 0, 1. It is often used to model random variables that represent proportions, probabilities or other values that are constrained to lie within this interval. + +| | | | | +|:----------------:|:----------------:|:----------------:|:----------------:| +| createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | +| Any density provided by the user | Beta density | Uniform density | Normal density | +| | ![](betaDensity.png "Density plot for Beta distribution") | ![](normalDensity.png "Density plot for Normal distribution") | ![](uniformDensity.png "Density plot for Uniform distribution") | +| createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | + +#### Creating user-defined priors + +If creating a user-defined prior, the following information can/should be provided to createPrior: + +- A log density function, as a function of a parameter vector x, same syntax as the likelihood +- Additionally, you should consider providing a function that samples from the prior, because many samplers (SMC, DE, DREAM) can make use of this function for initial conditions. If you use one of the pre-defined priors, the sampling function is already implemented +- lower / upper boundaries (can be set on top of any prior, to create truncation) +- Additional info - best values, names of the parameters, ... + +#### Creating a prior from a previous MCMC sample + +The following example from the help shows how this works + +```{r} +# Create a BayesianSetup +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +settings = list(iterations = 2500, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) + + +newPrior = createPriorDensity(out, method = "multivariate", eps = 1e-10, lower = rep(-10, 3), upper = rep(10, 3), best = NULL) +bayesianSetup <- createBayesianSetup(likelihood = ll, prior = newPrior) + +settings = list(iterations = 1000, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) +``` + +# MCMC sampler reference + +## The runMCMC() function + +The runMCMC function is the central function for starting MCMC algorithms in the BayesianTools package. It requires a bayesianSetup, a choice of sampler (standard is DEzs), and optionally changes to the standard settings of the chosen sampler. + +runMCMC(bayesianSetup, sampler = "DEzs", settings = NULL) + +One optional argument that you can always use is nrChains - the default is 1. If you choose more, the runMCMC will perform several runs. + +```{r, message = F} + +ll <- generateTestDensityMultiNormal(sigma = "no correlation") + +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +settings = list(iterations = 10000, nrChains= 3, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + +plot(out) +marginalPlot(out, prior = T) +correlationPlot(out) +gelmanDiagnostics(out, plot=T) + +# option to restart the sampler + +settings = list(iterations = 1000, nrChains= 1, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) + +out2 <- runMCMC(bayesianSetup = out) + +out3 <- runMCMC(bayesianSetup = out2) + +#plot(out) +#plot(out3) + +# create new prior from posterior sample + +newPriorFromPosterior <- createPriorDensity(out2) + +``` + +## The different MCMC samplers + +For convenience we define a number of iterations + +```{r} +iter = 10000 +``` + +### The Metropolis MCMC class + +The BayesianTools package is able to run a large number of Metropolis-Hastings (MH) based algorithms All of these samplers can be accessed by the "Metropolis" sampler in the runMCMC function by specifying the sampler's settings. + +The following code gives an overview about the default settings of the MH sampler. + +```{r} +applySettingsDefault(sampler = "Metropolis") +``` + +The following examples show how the different settings can be used. As you will see different options can be activated singly or in combination. + +#### Standard MH MCMC + +The following settings will run the standard Metropolis Hastings MCMC. + +Refernences: Hastings, W. K. (1970). Monte carlo sampling methods using markov chains and their applications. Biometrika 57 (1), 97-109. + +Metropolis, N., A. W. Rosenbluth, M. N. Rosenbluth, A. H. Teller, and E. Teller (1953). Equation of state calculations by fast computing machines. The journal of chemical physics 21 (6), 1087 - 1092. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = F, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +#### Standard MH MCMC, prior optimization + +This sampler uses an optimization step prior to the sampling process. The optimization aims at improving the starting values and the covariance of the proposal distribution. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +#### Adaptive MCMC, prior optimization + +In the adaptive Metropolis sampler (AM) the information already acquired in the sampling process is used to improve (or adapt) the proposal function. In the BayesianTools package the history of the chain is used to adapt the covariance of the propoasal distribution. + +References: Haario, H., E. Saksman, and J. Tamminen (2001). An adaptive metropolis algorithm. Bernoulli , 223-242. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +#### Standard MCMC, prior optimization, delayed rejection + +Even though rejection is an essential step of a MCMC algorithm it can also mean that the proposal distribution is (locally) badly tuned to the target distribution. In a delayed rejection (DR) sampler a second (or third, etc.) proposal is made before rejection. This proposal is usually drawn from a different distribution, allowing for a greater flexibility of the sampler. In the BayesianTools package the number of delayed rejection steps as well as the scaling of the proposals can be determined. \*\* Note that the current version only supports two delayed rejection steps. \*\* + +References: Green, Peter J., and Antonietta Mira. "Delayed rejection in reversible jump Metropolis-Hastings." Biometrika (2001): 1035-1053. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, adapt = F, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +#### Adaptive MCMC, prior optimization, delayed rejection + +The delayed rejection adaptive Metropolis (DRAM) sampler is merely a combination of the two previous sampler (DR and AM). + +References: Haario, Heikki, et al. "DRAM: efficient adaptive MCMC." Statistics and Computing 16.4 (2006): 339-354. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, adapt = T, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +#### Standard MCMC, prior optimization, Gibbs updating + +To reduce the dimensions of the target function a Metropolis-within-Gibbs sampler can be run with the BayesianTools package. This means in each iteration only a subset of the parameter vector is updated. In the example below at most two (of the three) parameters are updated each step, and it is double as likely to vary one than varying two. + +\*\* Note that currently adaptive cannot be mixed with Gibbs updating! \*\* + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = c(1,0.5,0), temperingFunction = NULL, optimize = T, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +#### Standard MCMC, prior optimization, gibbs updating, tempering + +Simulated tempering is closely related to simulated annealing (e.g. Bélisle, 1992) in optimization algorithms. The idea of tempering is to increase the acceptance rate during burn-in. This should result in a faster initial scanning of the target function. To include this a tempering function needs to be supplied by the user. The function describes how the acceptance rate is influenced during burn-in. In the example below an exponential decline approaching 1 (= no influece on the acceptance rate)is used. + +References: Bélisle, C. J. (1992). Convergence theorems for a class of simulated annealing algorithms on rd. Journal of Applied Probability, 885--895. + +C. J. Geyer (2011) Importance sampling, simulated tempering, and umbrella sampling, in the Handbook of Markov Chain Monte Carlo, S. P. Brooks, et al (eds), Chapman & Hall/CRC. + +```{r, results = 'hide', eval = F} +temperingFunction <- function(x) 5 * exp(-0.01*x) + 1 +settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = c(1,1,0), temperingFunction = temperingFunction, optimize = T, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) +``` + +### Differential Evolution MCMC + +The BT package implements two versions of the differential evolution MCMC. In doubt, you should use the DEzs option. + +The first is the normal DE MCMC, corresponding to Ter Braak, Cajo JF. "A Markov Chain Monte Carlo version of the genetic algorithm Differential Evolution: easy Bayesian computing for real parameter spaces." Statistics and Computing 16.3 (2006): 239-249. In this sampler multiple chains are run in parallel (but not in the sense of parallel computing). The main difference to the Metropolis based algorithms is the creation of the proposal. Generally all samplers use the current positin of the chain and add a step in the parameter space to generate a new proposal. Whereas in the Metropolis based sampler this step is usually drawn from a multivariate normal distribution (yet every distribution is possible), the DE sampler uses the current position of two other chains to generate the step for each chain. For sucessful sampling at least 2\*d chains, with d being the number of parameters, need to be run in parallel. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DE", settings = settings) +plot(out) +``` + +The second is the Differential Evolution MCMC with snooker update and sampling from past states, corresponding to ter Braak, Cajo JF, and Jasper A. Vrugt. "Differential evolution Markov chain with snooker updater and fewer chains." Statistics and Computing 18.4 (2008): 435-446. This extension covers two differences to the normal DE MCMC. First a snooker update is used based on a user defined probability. Second also past states of other chains are respected in the creation of the proposal. These extensions allow for fewer chains (i.e. 3 chains are usually enough for up to 200 parameters) and parallel computing as the current position of each chain is only dependent on the past states of the other chains. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) +plot(out) +``` + +### DREAM sampler + +Also for the DREAM sampler, there are two versions included. First of all, the standard DREAM sampler, see Vrugt, Jasper A., et al. "Accelerating Markov chain Monte Carlo simulation by differential evolution with self-adaptive randomized subspace sampling." International Journal of Nonlinear Sciences and Numerical Simulation 10.3 (2009): 273-290. + +This sampler is largely build on the DE sampler with some significant differences: 1) More than two chains can be used to generate a proposal. 2) A randomized subspace sampling can be used to enhance the efficiency for high dimensional posteriors. Each dimension is updated with a crossover probalitity CR. To speed up the exploration of the posterior DREAM adapts the distribution of CR values during burn-in to favor large jumps over small ones. 3) Outlier chains can be removed during burn-in. + +```{r, results = 'hide', eval = F} +settings <- list(iterations = iter, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAM", settings = settings) +plot(out) +``` + +The second implementation uses the same extension as the DEzs sampler. Namely sampling from past states and a snooker update. Also here this extension allows for the use of fewer chains and parallel computing. + +Again, in doubt you should prefer "DREAMzs". + +```{r, results = 'hide', eval = FALSE} +settings <- list(iterations = iter, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAMzs", settings = settings) +plot(out) +``` + +### T-walk + +The T-walk is a MCMC algorithm developed by Christen, J. Andrés, and Colin Fox. "A general purpose sampling algorithm for continuous distributions (the t-walk)." Bayesian Analysis 5.2 (2010): 263-281. In the sampler two independent points are used to explore the posterior space. Based on probabilities four different moves are used to generate proposals for the two points. As for the DE sampler this procedure requires no tuning of the proposal distribution for efficient sampling in complex posterior distributions. + +```{r, eval = F} +settings = list(iterations = iter, message = FALSE) + +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Twalk", settings = settings) +``` + +### Convergence checks for MCMCs + +All MCMCs should be checked for convergence. We recommend the standard procedure of Gelmal-Rubin. This procedure requires running several MCMCs (we recommend 3). This can be achieved either directly in the runMCMC (nrChains = 3), or, for runtime reasons, by combining the results of three independent runMCMC evaluations with nrChains = 1. + +```{r, eval = T} +settings <- list(iterations = iter, nrChains = 3, message = FALSE) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) +plot(out) + +#chain = getSample(out, coda = T) +gelmanDiagnostics(out, plot = F) +``` + +## Non-MCMC sampling algorithms + +MCMCs sample the posterior space by creating a chain in parameter space. While this allows "learning" from past steps, it does not permit the parallel execution of a large number of posterior values at the same time. + +An alternative to MCMCs are particle filters, aka Sequential Monte-Carlo (SMC) algorithms. See Hartig, F.; Calabrese, J. M.; Reineking, B.; Wiegand, T. & Huth, A. Statistical inference for stochastic simulation models - theory and application Ecol. Lett., 2011, 14, 816-827 + +### Rejection samling + +The easiest option is to simply sample a large number of parameters and accept them according to their posterior value. This option can be emulated with the implemented SMC, setting iterations to 1. + +```{r, results = 'hide', eval = F} +settings <- list(initialParticles = iter, iterations= 1) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) +plot(out) +``` + +### Sequential Monte Carlo (SMC) + +The more sophisticated option is using the implemented SMC, which is basically a particle filter that applies several filter steps. + +```{r, results = 'hide', eval = F} +settings <- list(initialParticles = iter, iterations= 10) +out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) +plot(out) +``` + +Note that the use of a number for initialParticles requires that the bayesianSetup includes the possibility to sample from the prior. + +# Bayesian model comparison and averaging + +There are a number of Bayesian model selection and model comparison methods. The BT implements three of the most common of them, the DIC, the WAIC, and the Bayes factor. + +- On the Bayes factor, see Kass, R. E. & Raftery, A. E. Bayes Factors J. Am. Stat. Assoc., Amer Statist Assn, 1995, 90, 773-795 + +- An overview on DIC and WAIC is given in Gelman, A.; Hwang, J. & Vehtari, A. (2014) Understanding predictive information criteria for Bayesian models. Statistics and Computing, 24, 997-1016-. On DIC, see also the original reference by Spiegelhalter, D. J.; Best, N. G.; Carlin, B. P. & van der Linde, A. (2002) Bayesian measures of model complexity and fit. J. Roy. Stat. Soc. B, 64, 583-639. + +The Bayes factor relies on the calculation of marginal likelihoods, which is numerically not without problems. The BT package currently implements three methods + +- The recommended way is the method "Chib" (Chib and Jeliazkov, 2001). which is based on MCMC samples, but performs additional calculations. Despite being the current recommendation, note there are some numeric issues with this algorithm that may limit reliability for larger dimensions. + +- The harmonic mean approximation, is implemented only for comparison. Note that the method is numerically unrealiable and usually should not be used. + +- The third method is simply sampling from the prior. While in principle unbiased, it will only converge for a large number of samples, and is therefore numerically inefficient. + +## Example + +Data linear Regression with quadratic and linear effect + +```{r} +sampleSize = 30 +x <- (-(sampleSize-1)/2):((sampleSize-1)/2) +y <- 1 * x + 1*x^2 + rnorm(n=sampleSize,mean=0,sd=10) +plot(x,y, main="Test Data") +``` + +Likelihoods for both + +```{r} +likelihood1 <- function(param){ + pred = param[1] + param[2]*x + param[3] * x^2 + singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) + return(sum(singlelikelihoods)) +} + +likelihood2 <- function(param){ + pred = param[1] + param[2]*x + singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[3]^2), log = T) + return(sum(singlelikelihoods)) +} +``` + +Posterior definitions + +```{r} +setUp1 <- createBayesianSetup(likelihood1, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) + +setUp2 <- createBayesianSetup(likelihood2, lower = c(-5,-5,0.01), upper = c(5,5,30)) +``` + +MCMC and marginal likelihood calculation + +```{r, results = 'hide'} +settings = list(iterations = 15000, message = FALSE) +out1 <- runMCMC(bayesianSetup = setUp1, sampler = "Metropolis", settings = settings) +#tracePlot(out1, start = 5000) +M1 = marginalLikelihood(out1) +M1 + +settings = list(iterations = 15000, message = FALSE) +out2 <- runMCMC(bayesianSetup = setUp2, sampler = "Metropolis", settings = settings) +#tracePlot(out2, start = 5000) +M2 = marginalLikelihood(out2) +M2 +``` + +### Model comparison via Bayes factor + +Bayes factor (need to reverse the log) + +```{r} +exp(M1$ln.ML - M2$ln.ML) +``` + +BF \> 1 means the evidence is in favor of M1. See Kass, R. E. & Raftery, A. E. (1995) Bayes Factors. J. Am. Stat. Assoc., Amer Statist Assn, 90, 773-795. + +Assuming equal prior weights on all models, we can calculate the posterior weight of M1 as + +```{r} +exp(M1$ln.ML) / ( exp(M1$ln.ML) + exp(M2$ln.ML)) +``` + +If models have different model priors, multiply with the prior probabilities of each model. + +### Model comparison via DIC + +The Deviance information criterion is a commonly applied method to summarize the fit of an MCMC chain. It can be obtained via + +```{r} +DIC(out1)$DIC +DIC(out2)$DIC +``` + +### Model comparison via WAIC + +The Watanabe--Akaike information criterion is another criterion for model comparison. To be able to calculate the WAIC, the model must implement a log-likelihood that density that allows to calculate the log-likelihood point-wise (the likelihood functions requires a "sum" argument that determines whether the summed log-likelihood should be returned). It can be obtained via + +```{r} +# This will not work, since likelihood1 has no sum argument +# WAIC(out1) + +# likelihood with sum argument +likelihood3 <- function(param, sum = TRUE){ + pred <- param[1] + param[2]*x + param[3] * x^2 + singlelikelihoods <- dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) + return(if (sum == TRUE) sum(singlelikelihoods) else singlelikelihoods) +} +setUp3 <- createBayesianSetup(likelihood3, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) +out3 <- runMCMC(bayesianSetup = setUp3, sampler = "Metropolis", settings = settings) + +WAIC(out3) +``` diff --git a/BayesianTools/doc/InterfacingAModel.R b/BayesianTools/doc/InterfacingAModel.R new file mode 100644 index 0000000..0ea45a8 --- /dev/null +++ b/BayesianTools/doc/InterfacingAModel.R @@ -0,0 +1,113 @@ +## ----global_options, include=FALSE-------------------------------------------- +knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) + +## ----echo = F, message = F---------------------------------------------------- +set.seed(123) + +## ----eval = F----------------------------------------------------------------- +# runMyModel(par) + +## ----eval = F----------------------------------------------------------------- +# dyn.load(model) +# +# runMyModel(par){ +# out = # model call here +# # process out +# return(out) +# } + +## ----eval = F----------------------------------------------------------------- +# runMyModel(par){ +# +# # Create here a string with what you would write to call the model from the command line +# systemCall <- paste("model.exe", par[1], par[2]) +# +# out = system(systemCall, intern = TRUE) # intern indicates whether to capture the output of the command as an R character vector +# +# # write here to convert out in the apprpriate R classes +# +# } + +## ----eval = F----------------------------------------------------------------- +# runMyModel(par, returnData = NULL){ +# +# writeParameters(par) +# +# system("Model.exe") +# +# if(! is.null(returnData)) return(readData(returnData)) # The readData function will be defined later +# +# } +# +# writeParameters(par){ +# +# # e.g. +# # read template parameter fil +# # replace strings in template file +# # write parameter file +# } + +## ----eval = F----------------------------------------------------------------- +# setUpModel <- function(parameterTemplate, site, localConditions){ +# +# # create the runModel, readData functions (see later) here +# +# return(list(runModel, readData)) +# +# } + +## ----eval = F----------------------------------------------------------------- +# getData(type = X){ +# +# read.csv(xxx) +# +# # do some transformation +# +# # return data in desidered format +# } + +## ----eval = F----------------------------------------------------------------- +# par = c(1,2,3,4 ..) +# +# runMyModel(par) +# +# output <- getData(type = DesiredType) +# +# plot(output) + +## ----------------------------------------------------------------------------- +mymodel<-function(x){ + output<-0.2*x+0.1^x + return(output) +} + +## ----eval = F----------------------------------------------------------------- +# +# library(parallel) +# cl <- makeCluster(2) +# +# runParallel<- function(parList){ +# parSapply(cl, parList, mymodel) +# } +# +# runParallel(c(1,2)) + +## ----eval = F----------------------------------------------------------------- +# library(BayesianTools) +# parModel <- generateParallelExecuter(mymodel) + +## ----------------------------------------------------------------------------- +library(BayesianTools) + +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup <- createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +settings = list(iterations = 200) + +# run the several MCMCs chains either in seperate R sessions, or via R parallel packages +out1 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) +out2 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) + +res <- createMcmcSamplerList(list(out1, out2)) +plot(res) + diff --git a/BayesianTools/doc/InterfacingAModel.Rmd b/BayesianTools/doc/InterfacingAModel.Rmd new file mode 100644 index 0000000..636490d --- /dev/null +++ b/BayesianTools/doc/InterfacingAModel.Rmd @@ -0,0 +1,300 @@ +--- +title: "Interfacing your model with R" +output: + rmarkdown::html_vignette: + toc: true +vignette: > + %\VignetteIndexEntry{Interfacing your model with R} + \usepackage[utf8]{inputenc} + %\VignetteEngine{knitr::rmarkdown} +abstract: "This tutorial discusses how to interface models written in other programming languages with R, so that they can be fit with BayesianTools" +author: Florian Hartig +editor_options: + chunk_output_type: console +--- + +```{r global_options, include=FALSE} +knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) +``` + +```{r, echo = F, message = F} +set.seed(123) +``` + +# Interfacing a model with BT - step-by-step guide + +## Step 1: Create a runModel(par) function + +A basic requirement to allow calibration in BT is that we need to be able to execute the model with a given set of parameters. Strictly speaking, BT will not see the model as such, but requires a likelihood function with interface likelihood(par), where par is a vector, but in this function, you will then probably run the model with parameters par, where par could stay a vector, or be transformed to another format, e.g. data.frame, matrix or list. + +What happens now depends on how your model is programmed - I have listed the steps in order of convenience / speed. If your model has never been interfaced with R you will likely have to move down to the last option. + +\begin{enumerate} +\item Model in R, or R interface existing +\item Model can be compiled and linked as a dll +\item Model is in C/C++ and can be interfaced with RCPP +\item Model can be compiled as executable and accepts parameters via the command line +\item Model can be compiled as executable reads parameters via parameter file +\item Model parameters are hard-coded in the executable +\end{enumerate} + +### Case 1 - model programmed in R + +Usually, you will have to do nothing. Just make sure you can call your model a in + +```{r, eval = F} +runMyModel(par) +``` + +Typically this function will directly return the model outputs, so step 2 can be skipped. + +### Case 2 - compiled dll, parameters are set via dll interface + +If you have your model prepared as a dll, or you can prepare it that way, you can use the \ref{https://stat.ethz.ch/R-manual/R-devel/library/base/html/dynload.html}{dyn.load()} function to link R to your model + +```{r, eval = F} +dyn.load(model) + +runMyModel(par){ + out = # model call here + # process out + return(out) +} +``` + +Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. + +The tricky thing in this approach is that you have to code the interface to your dll, which technically means in most programming languages to set your variables as external or something similar, so that they can be accessed from the outside. How this works will depend on the programming language. + + +### Case 3 - model programmed in C / C++, interfaced with RCPP + +RCPP is a highly flexible environment to interface between R and C/C++. If your model is coded in C / C++, RCPP offers the most save and powerful way to connect with R (much more flexible than with command line or dll). + +However, doing the interface may need some adjustments to the code, and there can be technical problems that are difficult to solve for beginners. I do not recommend to attempt interfacing an existing C/C++ model unless you have RCPP experience, or at least very food C/C++ experience. + +Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. + +### Case 4 - compiled executable, parameters set via command line (std I/O) + +If your model is written in a compiled or interpreted language, and accepts parameters via std I/O, wrapping is usually nothing more than writing the system call in an R function. An example would be + +```{r, eval = F} +runMyModel(par){ + + # Create here a string with what you would write to call the model from the command line + systemCall <- paste("model.exe", par[1], par[2]) + + out = system(systemCall, intern = TRUE) # intern indicates whether to capture the output of the command as an R character vector + + # write here to convert out in the apprpriate R classes + +} +``` + +Note: If you have problems with the system command, try system2. If the model returns the output via std.out, you can catch this and convert it and skip step 2. If your model writes to file, go to step 2. + +### Case 5 - compiled model, parameters set via parameter file or in any other method + +Many models read parameters with a parameter file. In this case you want to do something like this + +```{r, eval = F} +runMyModel(par, returnData = NULL){ + + writeParameters(par) + + system("Model.exe") + + if(! is.null(returnData)) return(readData(returnData)) # The readData function will be defined later + +} + +writeParameters(par){ + + # e.g. + # read template parameter fil + # replace strings in template file + # write parameter file +} +``` + +Depending on your problem, it can also make sense to define a setup function such as + +```{r, eval = F} +setUpModel <- function(parameterTemplate, site, localConditions){ + + # create the runModel, readData functions (see later) here + + return(list(runModel, readData)) + +} +``` + +How you do the write parameter function depends on the file format you use for the parameters. In general, you probably want to create a template parameter file that you use as a base and from which you change parameters + +* If your parameter file is in an *.xml format*, check out the xml functions in R +* If your parameter file is in a *general text format*, the best option may be to create a template parameter file, place a unique string at the locations of the parameters that you want to replace, and then use string replace functions in R, e.g. [grep](https://stat.ethz.ch/R-manual/R-devel/library/base/html/grep.html) to replace this string. + +### Case 6 - compiled model, parameters cannot be changed + +You have to change your model code to achieve one of the former options. If the model is in C/C++, going directly to RCPP seems the best alternative. + +## Step 2: Reading back data + +If your model returns the output directly (which is highly preferable, ), you can skip this step. + +For simple models, you might consider returning the model output directly with the runMyModel function. This is probably so for cases a) and b) above, i.e. model is already in R, or accepts parameters via command line. + +More complicated models, however, produce a large number of outputs and you typically don't need all of them. It is therefore more useful to make on or several separate readData or getDate function. The only two different cases I will consider here is + +* via dll / RCPP +* via file ouputs + +*Model is a dll* If the model is a dll file, the best thing would probably be to implement appropriate getData functions in the source code that can then be called from R. If your model is in C and in a dll, interfacing this via RCPP would probably be easier, because you can directly return R dataframes and other data structures. + + +*Model writes file output* If the model writes file output, write a getData function that reads in the model outputs and returns the data in the desired format, typically the same that you would use to represent your field data. + + +```{r, eval = F} +getData(type = X){ + + read.csv(xxx) + + # do some transformation + + # return data in desidered format +} +``` + + +\subsection{Testing the approach} + + +From R, you should now be able to do something like that + + +```{r, eval = F} +par = c(1,2,3,4 ..) + +runMyModel(par) + +output <- getData(type = DesiredType) + +plot(output) +``` + + + + +## Step 3 (optional) - creating an R package from your code + +The last step is optional, but we recommend that you take it from the start, because there is really no downside to it. You work with R code in several files that you run by hand, or diretly put all code into an R package. Creating and managing R packages is very easy, and it's easier to pass on your code because everything, including help, is in on package. To create an R package, follow the tutorial \href{http://biometry.github.io/APES/R/R70-PackageDevelopment.html}{here}. Remember to create a good documentation using Roxygen. + + +# Speed optimization and parallelization + +For running sensitivity analyses or calibrations, runtime is often an issue. Before you parallelize, make sure your model is as fast as possible. + +## Easy things + +* Are you compiling with maximum optimization (e.g. -o3 in cpp) +* If you have a spin-up phase, could you increase the time-step during this phase? +* Could you increase the time step generally +* Do you write unnecessary outputs that you could turn off (harddisk I/O is often slow)? + +## Difficult things + +* Make the model directly callable (RCPPor dll) to avoid harddisk I/O +* Is it possible to reduce initialization time (not only spin-up, but also for reading in the forcings / drivers) by avoid ending the model executable after each run, but rather keep it "waiting" for a new run. +* Code optimization: did you use a profiler? Read up on code optimization +* Check for unnecessary calculations in your code / introduce compiler flags where appropriate + +## Parallelization + +A possibility to speed up the run time of your model is to run it on multiple cores (CPU's). To do so, you have two choices: + +1. Parallelize the model itself +2. Parallelize the model call, so that BT can do several model evaluations in parallel + +Which of the two makes more sense depends a lot on your problem. To parallelize the model itself will be interesting in particular for very large models, which could otherwise not be calibrated with MCMCs. However, this approach will typically require to write parallel C/C++ code and require advanced programming skills, which is the reason why we will not further discuss it here. + +The usual advice in parallel computing is anyway to parallelize the outer loops first, to minimize communication overhead, which would suggest to start with parallelizing model evaluations. This is also much easier to program. Even within this, there are two levels of parallelization possible: + +1. Parallelize the call of several MCMC / SMC samplers +2. Parallelize within the MCMC / SMC samplers + +Currently, BT only supports parallelization within MCMCs / SMCs, but it easy to also implement between sampler parallelization by hand. Both approaches are describe below. + +### Within sampler parallelization + +Within-sampler parallelization is particular useful for algorithms that can use a large number of cores in parallel, e.g. sensitivity analyses or SMC sampling. For the MCMCs, it depends on the settings and the algorithm how much parallelization they can make use of. In general, MCMCs are Markovian, as the name says, i.e. the set up a chain of sequential model evaluations, and those calls can therefore not be fully parallelized. However, a number of MCMCs in the BT package uses MCMC algorithms that can be partly parallelized, in particular the population MCMC algorithms DE/DEzs/DREAM/DREAMzs. For all these cases, BT will automatically use parallelization of the BT setup indicates that this is implemented. + +How to do this? A first requirement to do so is to to have your model wrapped into an R function (see PREVIOUS SECTION). If that is the case, R offers a number of options to run functions in parallel. The easiest is to use the parallel package that comes with the R core. For other packages, see the internet and the CRAN task view on [High Performance Computing](https://CRAN.R-project.org/view=HighPerformanceComputing) + +As an example, assume we have the following, very simple model: + +```{r} +mymodel<-function(x){ + output<-0.2*x+0.1^x + return(output) +} +``` + +To start a parallel computation, we will first need to create a cluster object. Here we will initiate a cluster with 2 CPU's. + +```{r, eval = F} + +library(parallel) +cl <- makeCluster(2) + +runParallel<- function(parList){ + parSapply(cl, parList, mymodel) +} + +runParallel(c(1,2)) +``` + +You could use this principle to build your own parallelized likelihood. However, something very similar to the previous loop is automatized in BayesianTools. You can directly create a parallel model evaluation function with the function generateParallelExecuter, or alternatively directly in the createBayesianSetup + +```{r, eval = F} +library(BayesianTools) +parModel <- generateParallelExecuter(mymodel) +``` + +If your model is tread-safe, you should be able to run this out of the box. I therefore recommend using the hand-coded paraellelization only of the model is not thread-safe. + +### Running several MCMCs in parallel + +Additionally to the within-chain parallelization, you can also run several MCMCs in parallel, and combine them later to a single McmcSamplerList + +```{r} +library(BayesianTools) + +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup <- createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) + +settings = list(iterations = 200) + +# run the several MCMCs chains either in seperate R sessions, or via R parallel packages +out1 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) +out2 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) + +res <- createMcmcSamplerList(list(out1, out2)) +plot(res) +``` + + + +### Thread safety + +Thread safety quite generally means that you can execute multiple instances of your code on your hardware. There are various things that can limit Thread safety, for example + +* writing outputs to file (several threads might write to the same file at the same time) + + + + + + + diff --git a/BayesianTools/man/createPrior.Rd b/BayesianTools/man/createPrior.Rd index d8c28ab..ebcd962 100644 --- a/BayesianTools/man/createPrior.Rd +++ b/BayesianTools/man/createPrior.Rd @@ -39,10 +39,14 @@ distribution, on the other hand, is defined on the interval 0, 1. It is often used to model random variables that represent proportions, probabilities or other values that are constrained to lie within this interval.\tabular{cccc}{ \tab \tab \tab \cr - createPrior \tab createBetaPrior \tab createUniformPrior \tab createTruncatedNormalPrior \cr + \strong{createPrior} \tab \strong{createBetaPrior} \tab \strong{createUniformPrior} \tab \strong{createTruncatedNormalPrior} \cr + --------------------------------------------------- \tab --------------------------------------------------------- \tab ------------------------------------------------------------- \tab --------------------------------------------------------------- \cr Any density provided by the user \tab Beta density \tab Uniform density \tab Normal density \cr + --------------------------------------------------- \tab --------------------------------------------------------- \tab ------------------------------------------------------------- \tab --------------------------------------------------------------- \cr \tab \figure{betaDensity.png}{Density plot for Beta distribution} \tab \figure{normalDensity.png}{Density plot for Normal distribution} \tab \figure{uniformDensity.png}{Density plot for Uniform distribution} \cr + --------------------------------------------------- \tab --------------------------------------------------------- \tab ------------------------------------------------------------- \tab --------------------------------------------------------------- \cr createPrior(density, sampler, lower, upper, best) \tab createBetaPrior(a, b, lower, upper) \tab createUniformPrior(lower, upper, best) \tab createTruncatedNormalPrior(mean, sd, lower, upper). \cr + --------------------------------------------------- \tab --------------------------------------------------------- \tab ------------------------------------------------------------- \tab --------------------------------------------------------------- \cr } } \note{ diff --git a/BayesianTools/vignettes/BayesianTools.Rmd b/BayesianTools/vignettes/BayesianTools.Rmd index 134c16d..e6c284f 100644 --- a/BayesianTools/vignettes/BayesianTools.Rmd +++ b/BayesianTools/vignettes/BayesianTools.Rmd @@ -18,7 +18,6 @@ knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) set.seed(123) ``` - # Quick start The purpose of this first section is to give you a quick overview of the most important functions of the BayesianTools (BT) package. For a more detailed description, see the later sections @@ -31,7 +30,7 @@ If you haven't installed the package yet, either run install.packages("BayesianTools") ``` -Or follow the instructions on [https://github.com/florianhartig/BayesianTools](https://github.com/florianhartig/BayesianTools) to install a development or an older version. +Or follow the instructions on to install a development or an older version. Loading and citation @@ -54,18 +53,15 @@ In a real application, to ensure reproducibility, it would also be useful to rec sessionInfo() ``` -which lists the version number of R and all loaded packages. +which lists the version number of R and all loaded packages. ## The Bayesian Setup -The central object in the BT package is the BayesianSetup. This class contains the information about the model to be fit (likelihood), and the priors for the model parameters. +The central object in the BT package is the BayesianSetup. This class contains the information about the model to be fit (likelihood), and the priors for the model parameters. -A BayesianSetup is created by the createBayesianSetup function. The function expects a log-likelihood and (optional) a log-prior. It then automatically creates the posterior and various convenience functions for the samplers. +A BayesianSetup is created by the createBayesianSetup function. The function expects a log-likelihood and (optional) a log-prior. It then automatically creates the posterior and various convenience functions for the samplers. -Advantages of the BayesianSetup include -1. support for automatic parallelization -2. functions are wrapped in try-catch statements to avoid crashes during long MCMC evaluations -3. and the posterior checks if the parameter is outside the prior first, in which case the likelihood is not evaluated (makes the algorithms faster for slow likelihoods). +Advantages of the BayesianSetup include 1. support for automatic parallelization 2. functions are wrapped in try-catch statements to avoid crashes during long MCMC evaluations 3. and the posterior checks if the parameter is outside the prior first, in which case the likelihood is not evaluated (makes the algorithms faster for slow likelihoods). If no prior information is provided, an unbounded flat prior is created. If no explicit prior, but lower and upper values are provided, a standard uniform prior with the respective bounds is created, including the option to sample from this prior, which is useful for SMC and also for getting starting values. This option is used in the following example, which creates a multivariate normal likelihood density and a uniform prior for 3 parameters. @@ -74,17 +70,17 @@ ll <- generateTestDensityMultiNormal(sigma = "no correlation") bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) ``` -See later more detailed description about the BayesianSetup. +See later more detailed description about the BayesianSetup. **Hint:** for an example how to run this steps for dynamic ecological model, see ?VSEM ## Running MCMC and SMC functions -Once you have your setup, you may want to run a calibration. The runMCMC function is the main wrapper for all other implemented MCMC/SMC functions. It always takes the following arguments +Once you have your setup, you may want to run a calibration. The runMCMC function is the main wrapper for all other implemented MCMC/SMC functions. It always takes the following arguments -* A bayesianSetup (alternatively, the log target function) -* The sampler name -* A list with settings - if a parameter is not provided, the default will be used +- A bayesianSetup (alternatively, the log target function) +- The sampler name +- A list with settings - if a parameter is not provided, the default will be used As an example, choosing the sampler name "Metropolis" calls a versatile Metropolis-type MCMC with options for covariance adaptation, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the the later reference on MCMC samplers. This is how we would call this sampler with default settings @@ -103,7 +99,7 @@ print(out) summary(out) ``` -and plottted with several plot functions. The marginalPlot can either be plotted as histograms with density overlay, which is also the default, or as a violin plot (see "?marginalPlot"). +and plottted with several plot functions. The marginalPlot can either be plotted as histograms with density overlay, which is also the default, or as a violin plot (see "?marginalPlot"). ```{r} plot(out) # plot internally calls tracePlot(out) @@ -134,14 +130,14 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = ``` -The result is an object of mcmcSamplerList, which should allow to do everything one can do with an mcmcSampler object (with slightly different output sometimes). +The result is an object of mcmcSamplerList, which should allow to do everything one can do with an mcmcSampler object (with slightly different output sometimes). ```{r} print(out) summary(out) ``` -For example, in the plot you now see 3 chains. +For example, in the plot you now see 3 chains. ```{r} plot(out) @@ -154,26 +150,23 @@ There are a few additional functions that may only be available for lists, for e gelmanDiagnostics(out, plot = T) ``` +#### Which sampler to choose? -#### Which sampler to choose? - -The BT package provides a large class of different MCMC samplers, and it depends on the particular application which is most suitable. - -In the absence of further information, we currently recommend the DEzs sampler. This is also the default in the runMCMC function. +The BT package provides a large class of different MCMC samplers, and it depends on the particular application which is most suitable. +In the absence of further information, we currently recommend the DEzs sampler. This is also the default in the runMCMC function. # BayesianSetup Reference +## Reference on creating likelihoods -## Reference on creating likelihoods - -The likelihood should be provided as a log density function. +The likelihood should be provided as a log density function. ```{r, eval = F} ll = logDensity(x) ``` -See options for parallelization below. We will use a simple 3-d multivariate normal density for this demonstration. +See options for parallelization below. We will use a simple 3-d multivariate normal density for this demonstration. ```{r} ll <- generateTestDensityMultiNormal(sigma = "no correlation") @@ -184,17 +177,17 @@ bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper Likelihoods are often costly to compute. If that is the case for you, you should think about parallelization possibilities. The 'createBayesianSetup' function has the input variable 'parallel', with the following options -* F / FALSE means no parallelization should be used -* T / TRUE means that automatic parallelization options from R are used (careful: this will not work if your likelihood writes to file, or uses global variables or functions - see general R help on parallelization) -* "external", assumed that the likelihood is already parallelized. In this case, the function needs to accept a matrix with parameters as columns, and rows as the different model runs you want to evaluate. This is the most likely option to use if you have a complicated setup (file I/O, HPC cluster) that cannot be treated with the standard R parallelization. +- F / FALSE means no parallelization should be used +- T / TRUE means that automatic parallelization options from R are used (careful: this will not work if your likelihood writes to file, or uses global variables or functions - see general R help on parallelization) +- "external", assumed that the likelihood is already parallelized. In this case, the function needs to accept a matrix with parameters as columns, and rows as the different model runs you want to evaluate. This is the most likely option to use if you have a complicated setup (file I/O, HPC cluster) that cannot be treated with the standard R parallelization. -Algorithms in the BayesianTools package can make use of parallel computing if this option is specified in the BayesianSetup. Note that currently, parallelization is used by the following algorithms: SMC, DEzs and DREAMzs sampler. It can also be used through the BayesianSetup with the functions of the sensitivity package. +Algorithms in the BayesianTools package can make use of parallel computing if this option is specified in the BayesianSetup. Note that currently, parallelization is used by the following algorithms: SMC, DEzs and DREAMzs sampler. It can also be used through the BayesianSetup with the functions of the sensitivity package. Here some more details on the parallelization #### 1. In-build parallelization: -The in-build parallelization is the easiest way to make use of parallel computing. In the "parallel" argument you can choose the number of cores used for parallelization. Alternatively for TRUE or "auto" all available cores except for one will be used. Now the proposals are evaluated in parallel. Technically, the in-build parallelization uses an R cluster to evaluate the posterior density function. The input for the parallel function is a matrix, where each column represents a parameter and each row a proposal. In this way, the proposals can be evaluated in parallel. For sampler, where only one proposal is evaluated at a time (namely the Metropolis based algorithms as well as DE/DREAM without the zs extension), no parallelization can be used. +The in-build parallelization is the easiest way to make use of parallel computing. In the "parallel" argument you can choose the number of cores used for parallelization. Alternatively for TRUE or "auto" all available cores except for one will be used. Now the proposals are evaluated in parallel. Technically, the in-build parallelization uses an R cluster to evaluate the posterior density function. The input for the parallel function is a matrix, where each column represents a parameter and each row a proposal. In this way, the proposals can be evaluated in parallel. For sampler, where only one proposal is evaluated at a time (namely the Metropolis based algorithms as well as DE/DREAM without the zs extension), no parallelization can be used. #### 2. External parallelization @@ -214,9 +207,8 @@ BS <- createBayesianSetup(likelihood, parallel = "external", ...) runMCMC(BS, sampler = "SMC", ...) ``` - - #### 3. Multi-core and cluster calculations + If you want to run your calculations on a cluster there are several ways to achieve it. In the first case you want to parallize n internal (not overall chains) on n cores. The argument "parallel = T" in "createBayesianSetup" allows only at most parallelization on 3 cores for the SMC, DEzs and DreamsSamplers. But by setting "parallel = n" to n cores in the "createBayesianSetup", the internal chains of DEzs and DREAMzs will be parallelized on n cores. This works only for the DEzs and DREAMzs samplers. @@ -232,7 +224,7 @@ bayesianSetup <- createBayesianSetup(likelihood, parallel = n, lower = -5, upper out <- runMCMC(bayesianSetup, settings = list(iterations = 1000)) ``` -In the second case you want to parallize n internal chains on n cores with a external parallilzed likelihood function. Unlike the previous case, that way DEzs, DREAMzs, and SMC samplers can be parallelized. +In the second case you want to parallize n internal chains on n cores with a external parallilzed likelihood function. Unlike the previous case, that way DEzs, DREAMzs, and SMC samplers can be parallelized. ```{r, eval = FALSE} ### Create cluster with n cores @@ -304,51 +296,46 @@ out <- parallel::parLapply(cl, 1:n, fun = function(X, bayesianSetup, settings) r out <- createMcmcSamplerList(out) ``` +\*\* Remark: even though parallelization can significantly reduce the computation time, it is not always useful because of the so-called communication overhead (computational time for distributing and retrieving infos from the parallel cores). For models with low computational cost, this procedure can take more time than the actual evaluation of the likelihood. If in doubt, make a small comparison of the runtime before starting your large sampling. \*\* - -** Remark: even though parallelization can significantly reduce the computation time, it is not always useful because of the so-called communication overhead (computational time for distributing and retrieving infos from the parallel cores). For models with low computational cost, this procedure can take more time than the actual evaluation of the likelihood. If in doubt, make a small comparison of the runtime before starting your large sampling. ** - - - -## Reference on creating priors +## Reference on creating priors The prior in the BayesianSetup consists of four parts -* A log density function -* An (optional) sampling function (must be a function without parameters, that returns a draw from the prior) -* lower / upper boundaries -* Additional info - best values, names of the parameters, ... +- A log density function +- An (optional) sampling function (must be a function without parameters, that returns a draw from the prior) +- lower / upper boundaries +- Additional info - best values, names of the parameters, ... -These information can be passed by first creating an a extra object, via createPrior, or through the the createBayesianSetup function. +These information can be passed by first creating an a extra object, via createPrior, or through the the createBayesianSetup function. #### Creating priors You have 5 options to create a prior -* Do not set a prior - in this case, an infinite prior will be created -* Set min/max values - a bounded flat prior and the corresponding sampling function will be created -* Use one of the pre-definded priors, see ?createPrior for a list. One of the options here is to use a previous MCMC output as new prior. Pre-defined priors will usually come with a sampling function -* Use a user-define prior, see ?createPrior -* Create a prior from a previous MCMC sample +- Do not set a prior - in this case, an infinite prior will be created +- Set min/max values - a bounded flat prior and the corresponding sampling function will be created +- Use one of the pre-definded priors, see ?createPrior for a list. One of the options here is to use a previous MCMC output as new prior. Pre-defined priors will usually come with a sampling function +- Use a user-define prior, see ?createPrior +- Create a prior from a previous MCMC sample - The prior we choose depends on the prior information we have. For example, if we have no prior information, we can choose a uniform prior. The normal distribution is often used to model a wide range of phenomena in statistics, such as the distribution of heights or weights in a population. Beta distribution, on the other hand, is defined on the interval 0, 1. It is often used to model random variables that represent proportions, probabilities or other values that are constrained to lie within this interval. - | | | | | - |:-------------------------------------------------:|:-------------------------------------------------------:|:-----------------------------------------------------------:|:-------------------------------------------------------------:| - | createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | - | Any density provided by the user | Beta density | Uniform density | Normal density | - | |![](betaDensity.png "Density plot for Beta distribution")|![](normalDensity.png "Density plot for Normal distribution")|![](uniformDensity.png "Density plot for Uniform distribution")| - | createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | +| | | | | +|:----------------:|:----------------:|:----------------:|:----------------:| +|$\color{darkgreen}{\text{createPrior}}$ |$\color{darkgreen}{\text{createBetaPrior}}$ |$\color{darkgreen}{\text{createUniformPrior}}$ |$\color{darkgreen}{\text{createTruncatedNormalPrior}}$ | +| Any density provided by the user | Beta density | Uniform density | Normal density | +| | ![](betaDensity.png "Density plot for Beta distribution") | ![](normalDensity.png "Density plot for Normal distribution") | ![](uniformDensity.png "Density plot for Uniform distribution") | +| createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | #### Creating user-defined priors If creating a user-defined prior, the following information can/should be provided to createPrior: -* A log density function, as a function of a parameter vector x, same syntax as the likelihood -* Additionally, you should consider providing a function that samples from the prior, because many samplers (SMC, DE, DREAM) can make use of this function for initial conditions. If you use one of the pre-defined priors, the sampling function is already implemented -* lower / upper boundaries (can be set on top of any prior, to create truncation) -* Additional info - best values, names of the parameters, ... +- A log density function, as a function of a parameter vector x, same syntax as the likelihood +- Additionally, you should consider providing a function that samples from the prior, because many samplers (SMC, DE, DREAM) can make use of this function for initial conditions. If you use one of the pre-defined priors, the sampling function is already implemented +- lower / upper boundaries (can be set on top of any prior, to create truncation) +- Additional info - best values, names of the parameters, ... #### Creating a prior from a previous MCMC sample @@ -370,9 +357,6 @@ settings = list(iterations = 1000, message = FALSE) out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) ``` - - - # MCMC sampler reference ## The runMCMC() function @@ -415,7 +399,6 @@ newPriorFromPosterior <- createPriorDensity(out2) ``` - ## The different MCMC samplers For convenience we define a number of iterations @@ -429,23 +412,20 @@ iter = 10000 The BayesianTools package is able to run a large number of Metropolis-Hastings (MH) based algorithms All of these samplers can be accessed by the "Metropolis" sampler in the runMCMC function by specifying the sampler's settings. The following code gives an overview about the default settings of the MH sampler. + ```{r} applySettingsDefault(sampler = "Metropolis") ``` -The following examples show how the different settings can be used. As you will see different options can be activated singly or in combination. +The following examples show how the different settings can be used. As you will see different options can be activated singly or in combination. #### Standard MH MCMC -The following settings will run the standard Metropolis Hastings MCMC. -Refernences: -Hastings, W. K. (1970). Monte carlo sampling methods using markov chains -and their applications. Biometrika 57 (1), 97-109. +The following settings will run the standard Metropolis Hastings MCMC. -Metropolis, N., A. W. Rosenbluth, M. N. Rosenbluth, A. H. Teller, and E. Teller -(1953). Equation of state calculations by fast computing machines. The journal -of chemical physics 21 (6), 1087 - 1092. +Refernences: Hastings, W. K. (1970). Monte carlo sampling methods using markov chains and their applications. Biometrika 57 (1), 97-109. +Metropolis, N., A. W. Rosenbluth, M. N. Rosenbluth, A. H. Teller, and E. Teller (1953). Equation of state calculations by fast computing machines. The journal of chemical physics 21 (6), 1087 - 1092. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = F, message = FALSE) @@ -453,11 +433,9 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = plot(out) ``` - #### Standard MH MCMC, prior optimization -This sampler uses an optimization step prior to the sampling process. -The optimization aims at improving the starting values and the covariance of the proposal distribution. +This sampler uses an optimization step prior to the sampling process. The optimization aims at improving the starting values and the covariance of the proposal distribution. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) @@ -465,13 +443,11 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = plot(out) ``` - #### Adaptive MCMC, prior optimization + In the adaptive Metropolis sampler (AM) the information already acquired in the sampling process is used to improve (or adapt) the proposal function. In the BayesianTools package the history of the chain is used to adapt the covariance of the propoasal distribution. -References: -Haario, H., E. Saksman, and J. Tamminen (2001). An adaptive metropolis -algorithm. Bernoulli , 223-242. +References: Haario, H., E. Saksman, and J. Tamminen (2001). An adaptive metropolis algorithm. Bernoulli , 223-242. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) @@ -480,12 +456,10 @@ plot(out) ``` #### Standard MCMC, prior optimization, delayed rejection -Even though rejection is an essential step of a MCMC algorithm it can also mean that the proposal distribution is (locally) badly tuned to the target distribution. In a delayed rejection (DR) sampler a second (or third, etc.) proposal is made before rejection. This proposal is usually drawn from a different distribution, allowing for a greater flexibility of the sampler. In the BayesianTools package the number of delayed rejection steps as well as the scaling of the proposals can be determined. -** Note that the current version only supports two delayed rejection steps. ** +Even though rejection is an essential step of a MCMC algorithm it can also mean that the proposal distribution is (locally) badly tuned to the target distribution. In a delayed rejection (DR) sampler a second (or third, etc.) proposal is made before rejection. This proposal is usually drawn from a different distribution, allowing for a greater flexibility of the sampler. In the BayesianTools package the number of delayed rejection steps as well as the scaling of the proposals can be determined. \*\* Note that the current version only supports two delayed rejection steps. \*\* -References: -Green, Peter J., and Antonietta Mira. "Delayed rejection in reversible jump Metropolis-Hastings." Biometrika (2001): 1035-1053. +References: Green, Peter J., and Antonietta Mira. "Delayed rejection in reversible jump Metropolis-Hastings." Biometrika (2001): 1035-1053. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, adapt = F, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) @@ -493,13 +467,11 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = plot(out) ``` - - #### Adaptive MCMC, prior optimization, delayed rejection -The delayed rejection adaptive Metropolis (DRAM) sampler is merely a combination of the two previous sampler (DR and AM). -References: -Haario, Heikki, et al. "DRAM: efficient adaptive MCMC." Statistics and Computing 16.4 (2006): 339-354. +The delayed rejection adaptive Metropolis (DRAM) sampler is merely a combination of the two previous sampler (DR and AM). + +References: Haario, Heikki, et al. "DRAM: efficient adaptive MCMC." Statistics and Computing 16.4 (2006): 339-354. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, adapt = T, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) @@ -507,12 +479,11 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = plot(out) ``` - #### Standard MCMC, prior optimization, Gibbs updating -To reduce the dimensions of the target function a Metropolis-within-Gibbs sampler -can be run with the BayesianTools package. This means in each iteration only a subset of the parameter vector is updated. In the example below at most two (of the three) parameters are updated each step, and it is double as likely to vary one than varying two. -** Note that currently adaptive cannot be mixed with Gibbs updating! ** +To reduce the dimensions of the target function a Metropolis-within-Gibbs sampler can be run with the BayesianTools package. This means in each iteration only a subset of the parameter vector is updated. In the example below at most two (of the three) parameters are updated each step, and it is double as likely to vary one than varying two. + +\*\* Note that currently adaptive cannot be mixed with Gibbs updating! \*\* ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = c(1,0.5,0), temperingFunction = NULL, optimize = T, message = FALSE) @@ -520,18 +491,13 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = plot(out) ``` - #### Standard MCMC, prior optimization, gibbs updating, tempering -Simulated tempering is closely related to simulated annealing (e.g. Bélisle, 1992) in optimization algorithms. -The idea of tempering is to increase the acceptance rate during burn-in. This should result in a faster initial scanning of the target function. -To include this a tempering function needs to be supplied by the user. -The function describes how the acceptance rate is influenced during burn-in. In the example below an exponential decline approaching 1 (= no influece on the acceptance rate)is used. -References: -Bélisle, C. J. (1992). Convergence theorems for a class of simulated -annealing algorithms on rd. Journal of Applied Probability, 885–895. +Simulated tempering is closely related to simulated annealing (e.g. Bélisle, 1992) in optimization algorithms. The idea of tempering is to increase the acceptance rate during burn-in. This should result in a faster initial scanning of the target function. To include this a tempering function needs to be supplied by the user. The function describes how the acceptance rate is influenced during burn-in. In the example below an exponential decline approaching 1 (= no influece on the acceptance rate)is used. -C. J. Geyer (2011) Importance sampling, simulated tempering, and umbrella sampling, in the Handbook of Markov Chain Monte Carlo, S. P. Brooks, et al (eds), Chapman & Hall/CRC. +References: Bélisle, C. J. (1992). Convergence theorems for a class of simulated annealing algorithms on rd. Journal of Applied Probability, 885--895. + +C. J. Geyer (2011) Importance sampling, simulated tempering, and umbrella sampling, in the Handbook of Markov Chain Monte Carlo, S. P. Brooks, et al (eds), Chapman & Hall/CRC. ```{r, results = 'hide', eval = F} temperingFunction <- function(x) 5 * exp(-0.01*x) + 1 @@ -540,16 +506,11 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = plot(out) ``` - - ### Differential Evolution MCMC -The BT package implements two versions of the differential evolution MCMC. In doubt, you should use the DEzs option. - -The first is the normal DE MCMC, corresponding to Ter Braak, Cajo JF. "A Markov Chain Monte Carlo version of the genetic algorithm Differential Evolution: easy Bayesian computing for real parameter spaces." Statistics and Computing 16.3 (2006): 239-249. -In this sampler multiple chains are run in parallel (but not in the sense of parallel computing). The main difference to the Metropolis based algorithms is the creation of the proposal. Generally all samplers use the current positin of the chain and add a step in the parameter space to generate a new proposal. Whereas in the Metropolis based sampler this step is usually drawn from a multivariate normal distribution (yet every distribution is possible), the DE sampler uses the current position of two other chains to generate the step for each chain. For sucessful sampling at least 2*d chains, with d being the number of parameters, need to be run in parallel. - +The BT package implements two versions of the differential evolution MCMC. In doubt, you should use the DEzs option. +The first is the normal DE MCMC, corresponding to Ter Braak, Cajo JF. "A Markov Chain Monte Carlo version of the genetic algorithm Differential Evolution: easy Bayesian computing for real parameter spaces." Statistics and Computing 16.3 (2006): 239-249. In this sampler multiple chains are run in parallel (but not in the sense of parallel computing). The main difference to the Metropolis based algorithms is the creation of the proposal. Generally all samplers use the current positin of the chain and add a step in the parameter space to generate a new proposal. Whereas in the Metropolis based sampler this step is usually drawn from a multivariate normal distribution (yet every distribution is possible), the DE sampler uses the current position of two other chains to generate the step for each chain. For sucessful sampling at least 2\*d chains, with d being the number of parameters, need to be run in parallel. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, message = FALSE) @@ -557,9 +518,7 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DE", settings = setting plot(out) ``` -The second is the Differential Evolution MCMC with snooker update and sampling from past states, corresponding to ter Braak, Cajo JF, and Jasper A. Vrugt. "Differential evolution Markov chain with snooker updater and fewer chains." Statistics and Computing 18.4 (2008): 435-446. -This extension covers two differences to the normal DE MCMC. First a snooker update is used based on a user defined probability. Second also past states of other chains are respected in the creation of the proposal. These extensions allow for fewer chains (i.e. 3 chains are usually enough for up to 200 parameters) and parallel computing as the current position of each chain is only dependent on the past states of the other chains. - +The second is the Differential Evolution MCMC with snooker update and sampling from past states, corresponding to ter Braak, Cajo JF, and Jasper A. Vrugt. "Differential evolution Markov chain with snooker updater and fewer chains." Statistics and Computing 18.4 (2008): 435-446. This extension covers two differences to the normal DE MCMC. First a snooker update is used based on a user defined probability. Second also past states of other chains are respected in the creation of the proposal. These extensions allow for fewer chains (i.e. 3 chains are usually enough for up to 200 parameters) and parallel computing as the current position of each chain is only dependent on the past states of the other chains. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, message = FALSE) @@ -567,16 +526,11 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = setti plot(out) ``` - ### DREAM sampler Also for the DREAM sampler, there are two versions included. First of all, the standard DREAM sampler, see Vrugt, Jasper A., et al. "Accelerating Markov chain Monte Carlo simulation by differential evolution with self-adaptive randomized subspace sampling." International Journal of Nonlinear Sciences and Numerical Simulation 10.3 (2009): 273-290. -This sampler is largely build on the DE sampler with some significant differences: -1) More than two chains can be used to generate a proposal. -2) A randomized subspace sampling can be used to enhance the efficiency for high dimensional posteriors. Each dimension is updated with a crossover probalitity CR. To speed up the exploration of the posterior DREAM adapts the distribution of CR values during burn-in to favor large jumps over small ones. -3) Outlier chains can be removed during burn-in. - +This sampler is largely build on the DE sampler with some significant differences: 1) More than two chains can be used to generate a proposal. 2) A randomized subspace sampling can be used to enhance the efficiency for high dimensional posteriors. Each dimension is updated with a crossover probalitity CR. To speed up the exploration of the posterior DREAM adapts the distribution of CR values during burn-in to favor large jumps over small ones. 3) Outlier chains can be removed during burn-in. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, message = FALSE) @@ -586,7 +540,7 @@ plot(out) The second implementation uses the same extension as the DEzs sampler. Namely sampling from past states and a snooker update. Also here this extension allows for the use of fewer chains and parallel computing. -Again, in doubt you should prefer "DREAMzs". +Again, in doubt you should prefer "DREAMzs". ```{r, results = 'hide', eval = FALSE} settings <- list(iterations = iter, message = FALSE) @@ -594,15 +548,9 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAMzs", settings = se plot(out) ``` - - ### T-walk -The T-walk is a MCMC algorithm developed by Christen, J. Andrés, and Colin Fox. "A general purpose sampling algorithm for continuous distributions (the t-walk)." Bayesian Analysis 5.2 (2010): 263-281. -In the sampler two independent points are used to explore the posterior space. -Based on probabilities four different moves are used to generate proposals for the two points. As for the DE sampler this procedure requires no tuning of the proposal distribution for efficient sampling in complex posterior distributions. - - +The T-walk is a MCMC algorithm developed by Christen, J. Andrés, and Colin Fox. "A general purpose sampling algorithm for continuous distributions (the t-walk)." Bayesian Analysis 5.2 (2010): 263-281. In the sampler two independent points are used to explore the posterior space. Based on probabilities four different moves are used to generate proposals for the two points. As for the DE sampler this procedure requires no tuning of the proposal distribution for efficient sampling in complex posterior distributions. ```{r, eval = F} settings = list(iterations = iter, message = FALSE) @@ -610,7 +558,6 @@ settings = list(iterations = iter, message = FALSE) out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Twalk", settings = settings) ``` - ### Convergence checks for MCMCs All MCMCs should be checked for convergence. We recommend the standard procedure of Gelmal-Rubin. This procedure requires running several MCMCs (we recommend 3). This can be achieved either directly in the runMCMC (nrChains = 3), or, for runtime reasons, by combining the results of three independent runMCMC evaluations with nrChains = 1. @@ -624,17 +571,15 @@ plot(out) gelmanDiagnostics(out, plot = F) ``` +## Non-MCMC sampling algorithms -## Non-MCMC sampling algorithms - -MCMCs sample the posterior space by creating a chain in parameter space. While this allows "learning" from past steps, it does not permit the parallel execution of a large number of posterior values at the same time. +MCMCs sample the posterior space by creating a chain in parameter space. While this allows "learning" from past steps, it does not permit the parallel execution of a large number of posterior values at the same time. An alternative to MCMCs are particle filters, aka Sequential Monte-Carlo (SMC) algorithms. See Hartig, F.; Calabrese, J. M.; Reineking, B.; Wiegand, T. & Huth, A. Statistical inference for stochastic simulation models - theory and application Ecol. Lett., 2011, 14, 816-827 - ### Rejection samling -The easiest option is to simply sample a large number of parameters and accept them according to their posterior value. This option can be emulated with the implemented SMC, setting iterations to 1. +The easiest option is to simply sample a large number of parameters and accept them according to their posterior value. This option can be emulated with the implemented SMC, setting iterations to 1. ```{r, results = 'hide', eval = F} settings <- list(initialParticles = iter, iterations= 1) @@ -644,7 +589,7 @@ plot(out) ### Sequential Monte Carlo (SMC) -The more sophisticated option is using the implemented SMC, which is basically a particle filter that applies several filter steps. +The more sophisticated option is using the implemented SMC, which is basically a particle filter that applies several filter steps. ```{r, results = 'hide', eval = F} settings <- list(initialParticles = iter, iterations= 10) @@ -652,27 +597,23 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settin plot(out) ``` - -Note that the use of a number for initialParticles requires that the bayesianSetup includes the possibility to sample from the prior. - +Note that the use of a number for initialParticles requires that the bayesianSetup includes the possibility to sample from the prior. # Bayesian model comparison and averaging -There are a number of Bayesian model selection and model comparison methods. The BT implements three of the most common of them, the DIC, the WAIC, and the Bayes factor. - -* On the Bayes factor, see Kass, R. E. & Raftery, A. E. Bayes Factors J. Am. Stat. Assoc., Amer Statist Assn, 1995, 90, 773-795 +There are a number of Bayesian model selection and model comparison methods. The BT implements three of the most common of them, the DIC, the WAIC, and the Bayes factor. -* An overview on DIC and WAIC is given in Gelman, A.; Hwang, J. & Vehtari, A. (2014) Understanding predictive information criteria for Bayesian models. Statistics and Computing, 24, 997-1016-. On DIC, see also the original reference by Spiegelhalter, D. J.; Best, N. G.; Carlin, B. P. & van der Linde, A. (2002) Bayesian measures of model complexity and fit. J. Roy. Stat. Soc. B, 64, 583-639. +- On the Bayes factor, see Kass, R. E. & Raftery, A. E. Bayes Factors J. Am. Stat. Assoc., Amer Statist Assn, 1995, 90, 773-795 +- An overview on DIC and WAIC is given in Gelman, A.; Hwang, J. & Vehtari, A. (2014) Understanding predictive information criteria for Bayesian models. Statistics and Computing, 24, 997-1016-. On DIC, see also the original reference by Spiegelhalter, D. J.; Best, N. G.; Carlin, B. P. & van der Linde, A. (2002) Bayesian measures of model complexity and fit. J. Roy. Stat. Soc. B, 64, 583-639. The Bayes factor relies on the calculation of marginal likelihoods, which is numerically not without problems. The BT package currently implements three methods -* The recommended way is the method "Chib" (Chib and Jeliazkov, 2001). which is based on MCMC samples, but performs additional calculations. Despite being the current recommendation, note there are some numeric issues with this algorithm that may limit reliability for larger dimensions. - -* The harmonic mean approximation, is implemented only for comparison. Note that the method is numerically unrealiable and usually should not be used. +- The recommended way is the method "Chib" (Chib and Jeliazkov, 2001). which is based on MCMC samples, but performs additional calculations. Despite being the current recommendation, note there are some numeric issues with this algorithm that may limit reliability for larger dimensions. -* The third method is simply sampling from the prior. While in principle unbiased, it will only converge for a large number of samples, and is therefore numerically inefficient. +- The harmonic mean approximation, is implemented only for comparison. Note that the method is numerically unrealiable and usually should not be used. +- The third method is simply sampling from the prior. While in principle unbiased, it will only converge for a large number of samples, and is therefore numerically inefficient. ## Example @@ -701,10 +642,8 @@ likelihood2 <- function(param){ } ``` - Posterior definitions - ```{r} setUp1 <- createBayesianSetup(likelihood1, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) @@ -713,8 +652,6 @@ setUp2 <- createBayesianSetup(likelihood2, lower = c(-5,-5,0.01), upper = c(5,5, MCMC and marginal likelihood calculation - - ```{r, results = 'hide'} settings = list(iterations = 15000, message = FALSE) out1 <- runMCMC(bayesianSetup = setUp1, sampler = "Metropolis", settings = settings) @@ -737,16 +674,15 @@ Bayes factor (need to reverse the log) exp(M1$ln.ML - M2$ln.ML) ``` -BF > 1 means the evidence is in favor of M1. See Kass, R. E. & Raftery, A. E. (1995) Bayes Factors. J. Am. Stat. Assoc., Amer Statist Assn, 90, 773-795. +BF \> 1 means the evidence is in favor of M1. See Kass, R. E. & Raftery, A. E. (1995) Bayes Factors. J. Am. Stat. Assoc., Amer Statist Assn, 90, 773-795. -Assuming equal prior weights on all models, we can calculate the posterior weight of M1 as +Assuming equal prior weights on all models, we can calculate the posterior weight of M1 as ```{r} exp(M1$ln.ML) / ( exp(M1$ln.ML) + exp(M2$ln.ML)) ``` -If models have different model priors, multiply with the prior probabilities of each model. - +If models have different model priors, multiply with the prior probabilities of each model. ### Model comparison via DIC @@ -756,10 +692,10 @@ The Deviance information criterion is a commonly applied method to summarize the DIC(out1)$DIC DIC(out2)$DIC ``` - + ### Model comparison via WAIC -The Watanabe–Akaike information criterion is another criterion for model comparison. To be able to calculate the WAIC, the model must implement a log-likelihood that density that allows to calculate the log-likelihood point-wise (the likelihood functions requires a "sum" argument that determines whether the summed log-likelihood should be returned). It can be obtained via +The Watanabe--Akaike information criterion is another criterion for model comparison. To be able to calculate the WAIC, the model must implement a log-likelihood that density that allows to calculate the log-likelihood point-wise (the likelihood functions requires a "sum" argument that determines whether the summed log-likelihood should be returned). It can be obtained via ```{r} # This will not work, since likelihood1 has no sum argument diff --git a/BayesianTools/vignettes/InterfacingAModel.Rmd b/BayesianTools/vignettes/InterfacingAModel.Rmd index 636490d..6c69513 100644 --- a/BayesianTools/vignettes/InterfacingAModel.Rmd +++ b/BayesianTools/vignettes/InterfacingAModel.Rmd @@ -25,10 +25,11 @@ set.seed(123) ## Step 1: Create a runModel(par) function -A basic requirement to allow calibration in BT is that we need to be able to execute the model with a given set of parameters. Strictly speaking, BT will not see the model as such, but requires a likelihood function with interface likelihood(par), where par is a vector, but in this function, you will then probably run the model with parameters par, where par could stay a vector, or be transformed to another format, e.g. data.frame, matrix or list. +A basic requirement to allow calibration in BT is that we need to be able to execute the model with a given set of parameters. Strictly speaking, BT will not see the model as such, but requires a likelihood function with interface likelihood(par), where par is a vector, but in this function, you will then probably run the model with parameters par, where par could stay a vector, or be transformed to another format, e.g. data.frame, matrix or list. -What happens now depends on how your model is programmed - I have listed the steps in order of convenience / speed. If your model has never been interfaced with R you will likely have to move down to the last option. +What happens now depends on how your model is programmed - I have listed the steps in order of convenience / speed. If your model has never been interfaced with R you will likely have to move down to the last option. +```{=tex} \begin{enumerate} \item Model in R, or R interface existing \item Model can be compiled and linked as a dll @@ -37,7 +38,7 @@ What happens now depends on how your model is programmed - I have listed the ste \item Model can be compiled as executable reads parameters via parameter file \item Model parameters are hard-coded in the executable \end{enumerate} - +``` ### Case 1 - model programmed in R Usually, you will have to do nothing. Just make sure you can call your model a in @@ -46,7 +47,7 @@ Usually, you will have to do nothing. Just make sure you can call your model a i runMyModel(par) ``` -Typically this function will directly return the model outputs, so step 2 can be skipped. +Typically this function will directly return the model outputs, so step 2 can be skipped. ### Case 2 - compiled dll, parameters are set via dll interface @@ -62,22 +63,21 @@ runMyModel(par){ } ``` -Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. - -The tricky thing in this approach is that you have to code the interface to your dll, which technically means in most programming languages to set your variables as external or something similar, so that they can be accessed from the outside. How this works will depend on the programming language. +Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. +The tricky thing in this approach is that you have to code the interface to your dll, which technically means in most programming languages to set your variables as external or something similar, so that they can be accessed from the outside. How this works will depend on the programming language. ### Case 3 - model programmed in C / C++, interfaced with RCPP -RCPP is a highly flexible environment to interface between R and C/C++. If your model is coded in C / C++, RCPP offers the most save and powerful way to connect with R (much more flexible than with command line or dll). +RCPP is a highly flexible environment to interface between R and C/C++. If your model is coded in C / C++, RCPP offers the most save and powerful way to connect with R (much more flexible than with command line or dll). -However, doing the interface may need some adjustments to the code, and there can be technical problems that are difficult to solve for beginners. I do not recommend to attempt interfacing an existing C/C++ model unless you have RCPP experience, or at least very food C/C++ experience. +However, doing the interface may need some adjustments to the code, and there can be technical problems that are difficult to solve for beginners. I do not recommend to attempt interfacing an existing C/C++ model unless you have RCPP experience, or at least very food C/C++ experience. -Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. +Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. ### Case 4 - compiled executable, parameters set via command line (std I/O) -If your model is written in a compiled or interpreted language, and accepts parameters via std I/O, wrapping is usually nothing more than writing the system call in an R function. An example would be +If your model is written in a compiled or interpreted language, and accepts parameters via std I/O, wrapping is usually nothing more than writing the system call in an R function. An example would be ```{r, eval = F} runMyModel(par){ @@ -92,7 +92,7 @@ runMyModel(par){ } ``` -Note: If you have problems with the system command, try system2. If the model returns the output via std.out, you can catch this and convert it and skip step 2. If your model writes to file, go to step 2. +Note: If you have problems with the system command, try system2. If the model returns the output via std.out, you can catch this and convert it and skip step 2. If your model writes to file, go to step 2. ### Case 5 - compiled model, parameters set via parameter file or in any other method @@ -130,31 +130,29 @@ setUpModel <- function(parameterTemplate, site, localConditions){ } ``` -How you do the write parameter function depends on the file format you use for the parameters. In general, you probably want to create a template parameter file that you use as a base and from which you change parameters +How you do the write parameter function depends on the file format you use for the parameters. In general, you probably want to create a template parameter file that you use as a base and from which you change parameters -* If your parameter file is in an *.xml format*, check out the xml functions in R -* If your parameter file is in a *general text format*, the best option may be to create a template parameter file, place a unique string at the locations of the parameters that you want to replace, and then use string replace functions in R, e.g. [grep](https://stat.ethz.ch/R-manual/R-devel/library/base/html/grep.html) to replace this string. +- If your parameter file is in an *.xml format*, check out the xml functions in R +- If your parameter file is in a *general text format*, the best option may be to create a template parameter file, place a unique string at the locations of the parameters that you want to replace, and then use string replace functions in R, e.g. [grep](https://stat.ethz.ch/R-manual/R-devel/library/base/html/grep.html) to replace this string. ### Case 6 - compiled model, parameters cannot be changed -You have to change your model code to achieve one of the former options. If the model is in C/C++, going directly to RCPP seems the best alternative. +You have to change your model code to achieve one of the former options. If the model is in C/C++, going directly to RCPP seems the best alternative. ## Step 2: Reading back data -If your model returns the output directly (which is highly preferable, ), you can skip this step. +If your model returns the output directly (which is highly preferable, ), you can skip this step. -For simple models, you might consider returning the model output directly with the runMyModel function. This is probably so for cases a) and b) above, i.e. model is already in R, or accepts parameters via command line. +For simple models, you might consider returning the model output directly with the runMyModel function. This is probably so for cases a) and b) above, i.e. model is already in R, or accepts parameters via command line. -More complicated models, however, produce a large number of outputs and you typically don't need all of them. It is therefore more useful to make on or several separate readData or getDate function. The only two different cases I will consider here is +More complicated models, however, produce a large number of outputs and you typically don't need all of them. It is therefore more useful to make on or several separate readData or getDate function. The only two different cases I will consider here is -* via dll / RCPP -* via file ouputs +- via dll / RCPP +- via file ouputs -*Model is a dll* If the model is a dll file, the best thing would probably be to implement appropriate getData functions in the source code that can then be called from R. If your model is in C and in a dll, interfacing this via RCPP would probably be easier, because you can directly return R dataframes and other data structures. - - -*Model writes file output* If the model writes file output, write a getData function that reads in the model outputs and returns the data in the desired format, typically the same that you would use to represent your field data. +*Model is a dll* If the model is a dll file, the best thing would probably be to implement appropriate getData functions in the source code that can then be called from R. If your model is in C and in a dll, interfacing this via RCPP would probably be easier, because you can directly return R dataframes and other data structures. +*Model writes file output* If the model writes file output, write a getData function that reads in the model outputs and returns the data in the desired format, typically the same that you would use to represent your field data. ```{r, eval = F} getData(type = X){ @@ -167,13 +165,10 @@ getData(type = X){ } ``` - -\subsection{Testing the approach} - +\subsection{Testing the approach} From R, you should now be able to do something like that - ```{r, eval = F} par = c(1,2,3,4 ..) @@ -184,51 +179,47 @@ output <- getData(type = DesiredType) plot(output) ``` - - - ## Step 3 (optional) - creating an R package from your code -The last step is optional, but we recommend that you take it from the start, because there is really no downside to it. You work with R code in several files that you run by hand, or diretly put all code into an R package. Creating and managing R packages is very easy, and it's easier to pass on your code because everything, including help, is in on package. To create an R package, follow the tutorial \href{http://biometry.github.io/APES/R/R70-PackageDevelopment.html}{here}. Remember to create a good documentation using Roxygen. - +The last step is optional, but we recommend that you take it from the start, because there is really no downside to it. You work with R code in several files that you run by hand, or diretly put all code into an R package. Creating and managing R packages is very easy, and it's easier to pass on your code because everything, including help, is in on package. To create an R package, follow the tutorial \href{http://biometry.github.io/APES/R/R70-PackageDevelopment.html}{here}. Remember to create a good documentation using Roxygen. # Speed optimization and parallelization -For running sensitivity analyses or calibrations, runtime is often an issue. Before you parallelize, make sure your model is as fast as possible. +For running sensitivity analyses or calibrations, runtime is often an issue. Before you parallelize, make sure your model is as fast as possible. ## Easy things -* Are you compiling with maximum optimization (e.g. -o3 in cpp) -* If you have a spin-up phase, could you increase the time-step during this phase? -* Could you increase the time step generally -* Do you write unnecessary outputs that you could turn off (harddisk I/O is often slow)? +- Are you compiling with maximum optimization (e.g. -o3 in cpp) +- If you have a spin-up phase, could you increase the time-step during this phase? +- Could you increase the time step generally +- Do you write unnecessary outputs that you could turn off (harddisk I/O is often slow)? ## Difficult things -* Make the model directly callable (RCPPor dll) to avoid harddisk I/O -* Is it possible to reduce initialization time (not only spin-up, but also for reading in the forcings / drivers) by avoid ending the model executable after each run, but rather keep it "waiting" for a new run. -* Code optimization: did you use a profiler? Read up on code optimization -* Check for unnecessary calculations in your code / introduce compiler flags where appropriate +- Make the model directly callable (RCPPor dll) to avoid harddisk I/O +- Is it possible to reduce initialization time (not only spin-up, but also for reading in the forcings / drivers) by avoid ending the model executable after each run, but rather keep it "waiting" for a new run. +- Code optimization: did you use a profiler? Read up on code optimization +- Check for unnecessary calculations in your code / introduce compiler flags where appropriate ## Parallelization A possibility to speed up the run time of your model is to run it on multiple cores (CPU's). To do so, you have two choices: -1. Parallelize the model itself -2. Parallelize the model call, so that BT can do several model evaluations in parallel +1. Parallelize the model itself +2. Parallelize the model call, so that BT can do several model evaluations in parallel -Which of the two makes more sense depends a lot on your problem. To parallelize the model itself will be interesting in particular for very large models, which could otherwise not be calibrated with MCMCs. However, this approach will typically require to write parallel C/C++ code and require advanced programming skills, which is the reason why we will not further discuss it here. +Which of the two makes more sense depends a lot on your problem. To parallelize the model itself will be interesting in particular for very large models, which could otherwise not be calibrated with MCMCs. However, this approach will typically require to write parallel C/C++ code and require advanced programming skills, which is the reason why we will not further discuss it here. -The usual advice in parallel computing is anyway to parallelize the outer loops first, to minimize communication overhead, which would suggest to start with parallelizing model evaluations. This is also much easier to program. Even within this, there are two levels of parallelization possible: +The usual advice in parallel computing is anyway to parallelize the outer loops first, to minimize communication overhead, which would suggest to start with parallelizing model evaluations. This is also much easier to program. Even within this, there are two levels of parallelization possible: -1. Parallelize the call of several MCMC / SMC samplers -2. Parallelize within the MCMC / SMC samplers +1. Parallelize the call of several MCMC / SMC samplers +2. Parallelize within the MCMC / SMC samplers -Currently, BT only supports parallelization within MCMCs / SMCs, but it easy to also implement between sampler parallelization by hand. Both approaches are describe below. +Currently, BT only supports parallelization within MCMCs / SMCs, but it easy to also implement between sampler parallelization by hand. Both approaches are describe below. -### Within sampler parallelization +### Within sampler parallelization -Within-sampler parallelization is particular useful for algorithms that can use a large number of cores in parallel, e.g. sensitivity analyses or SMC sampling. For the MCMCs, it depends on the settings and the algorithm how much parallelization they can make use of. In general, MCMCs are Markovian, as the name says, i.e. the set up a chain of sequential model evaluations, and those calls can therefore not be fully parallelized. However, a number of MCMCs in the BT package uses MCMC algorithms that can be partly parallelized, in particular the population MCMC algorithms DE/DEzs/DREAM/DREAMzs. For all these cases, BT will automatically use parallelization of the BT setup indicates that this is implemented. +Within-sampler parallelization is particular useful for algorithms that can use a large number of cores in parallel, e.g. sensitivity analyses or SMC sampling. For the MCMCs, it depends on the settings and the algorithm how much parallelization they can make use of. In general, MCMCs are Markovian, as the name says, i.e. the set up a chain of sequential model evaluations, and those calls can therefore not be fully parallelized. However, a number of MCMCs in the BT package uses MCMC algorithms that can be partly parallelized, in particular the population MCMC algorithms DE/DEzs/DREAM/DREAMzs. For all these cases, BT will automatically use parallelization of the BT setup indicates that this is implemented. How to do this? A first requirement to do so is to to have your model wrapped into an R function (see PREVIOUS SECTION). If that is the case, R offers a number of options to run functions in parallel. The easiest is to use the parallel package that comes with the R core. For other packages, see the internet and the CRAN task view on [High Performance Computing](https://CRAN.R-project.org/view=HighPerformanceComputing) @@ -262,7 +253,7 @@ library(BayesianTools) parModel <- generateParallelExecuter(mymodel) ``` -If your model is tread-safe, you should be able to run this out of the box. I therefore recommend using the hand-coded paraellelization only of the model is not thread-safe. +If your model is tread-safe, you should be able to run this out of the box. I therefore recommend using the hand-coded paraellelization only of the model is not thread-safe. ### Running several MCMCs in parallel @@ -284,17 +275,8 @@ res <- createMcmcSamplerList(list(out1, out2)) plot(res) ``` - - ### Thread safety -Thread safety quite generally means that you can execute multiple instances of your code on your hardware. There are various things that can limit Thread safety, for example - -* writing outputs to file (several threads might write to the same file at the same time) - - - - - - +Thread safety quite generally means that you can execute multiple instances of your code on your hardware. There are various things that can limit Thread safety, for example +- writing outputs to file (several threads might write to the same file at the same time) diff --git a/BayesianTools/vignettes/betaDensity.png b/BayesianTools/vignettes/betaDensity.png new file mode 100644 index 0000000000000000000000000000000000000000..5407e41a93b4dd9780500bf8b094d7207f6c7c99 GIT binary patch literal 9746 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

AYUGb66 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 FzW_sqwD14` literal 0 HcmV?d00001 diff --git a/BayesianTools/vignettes/normalDensity.png b/BayesianTools/vignettes/normalDensity.png new file mode 100644 index 0000000000000000000000000000000000000000..a20c422a5a50d897a821537ef80737587fce09cc GIT binary patch literal 9825 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 literal 0 HcmV?d00001 diff --git a/BayesianTools/vignettes/uniformDensity.png b/BayesianTools/vignettes/uniformDensity.png new file mode 100644 index 0000000000000000000000000000000000000000..9afb95aeda1dc587eaf5de5748f5b5e5fddcb741 GIT binary patch literal 8374 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 Date: Fri, 10 Nov 2023 13:20:55 +0100 Subject: [PATCH 05/10] deleted vignette file in doc folder --- BayesianTools/doc/BayesianTools.R | 348 ------------ BayesianTools/doc/BayesianTools.Rmd | 714 ------------------------ BayesianTools/doc/InterfacingAModel.R | 113 ---- BayesianTools/doc/InterfacingAModel.Rmd | 300 ---------- 4 files changed, 1475 deletions(-) delete mode 100644 BayesianTools/doc/BayesianTools.R delete mode 100644 BayesianTools/doc/BayesianTools.Rmd delete mode 100644 BayesianTools/doc/InterfacingAModel.R delete mode 100644 BayesianTools/doc/InterfacingAModel.Rmd diff --git a/BayesianTools/doc/BayesianTools.R b/BayesianTools/doc/BayesianTools.R deleted file mode 100644 index 9bb0bd8..0000000 --- a/BayesianTools/doc/BayesianTools.R +++ /dev/null @@ -1,348 +0,0 @@ -## ----global_options, include=FALSE-------------------------------------------- -knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) - -## ----echo = F, message = F---------------------------------------------------- -set.seed(123) - -## ----eval = F----------------------------------------------------------------- -# install.packages("BayesianTools") - -## ----------------------------------------------------------------------------- -library(BayesianTools) -citation("BayesianTools") - -## ----------------------------------------------------------------------------- -set.seed(123) - -## ----eval = F----------------------------------------------------------------- -# sessionInfo() - -## ----------------------------------------------------------------------------- -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -## ----------------------------------------------------------------------------- -iter = 10000 -settings = list(iterations = iter, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -## ----------------------------------------------------------------------------- -print(out) -summary(out) - -## ----------------------------------------------------------------------------- -plot(out) # plot internally calls tracePlot(out) -correlationPlot(out) -marginalPlot(out, prior = TRUE) - -## ----------------------------------------------------------------------------- -marginalLikelihood(out) -DIC(out) -MAP(out) - -## ----eval = F----------------------------------------------------------------- -# getSample(out, start = 100, end = NULL, thin = 5, whichParameters = 1:2) - -## ----echo = T----------------------------------------------------------------- -iter = 1000 -settings = list(iterations = iter, nrChains = 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - - -## ----------------------------------------------------------------------------- -print(out) -summary(out) - -## ----------------------------------------------------------------------------- -plot(out) - -## ----------------------------------------------------------------------------- -#getSample(out, coda = F) -gelmanDiagnostics(out, plot = T) - -## ----eval = F----------------------------------------------------------------- -# ll = logDensity(x) - -## ----------------------------------------------------------------------------- -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -## ----eval = FALSE------------------------------------------------------------- -# ## Definition of likelihood function -# likelihood <- function(matrix){ -# # Calculate likelihood in parallel -# # Return vector of likelihood valus -# } -# -# ## Create Bayesian Setup -# BS <- createBayesianSetup(likelihood, parallel = "external", ...) -# -# ## Run MCMC -# runMCMC(BS, sampler = "SMC", ...) - -## ----eval = FALSE------------------------------------------------------------- -# ## n = Number of cores -# n=2 -# x <- c(1:10) -# likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) -# bayesianSetup <- createBayesianSetup(likelihood, parallel = n, lower = -5, upper = 5) -# -# ## give runMCMC a matrix with n rows of proposals as startValues or sample n times from the previous created sampler -# out <- runMCMC(bayesianSetup, settings = list(iterations = 1000)) - -## ----eval = FALSE------------------------------------------------------------- -# ### Create cluster with n cores -# cl <- parallel::makeCluster(n) -# -# ## Definition of the likelihood -# likelihood <- function(X) sum(dnorm(c(1:10), mean = X, log = T)) -# -# ## Definition of the likelihood which will be calculated in parallel. Instead of the parApply function, we could also define a costly parallelized likelihood -# pLikelihood <- function(param) parallel::parApply(cl = cl, X = param, MARGIN = 1, FUN = likelihood) -# -# ## export functions, dlls, libraries -# # parallel::clusterEvalQ(cl, library(BayesianTools)) -# parallel::clusterExport(cl, varlist = list(likelihood)) -# -# ## create BayesianSetup -# bayesianSetup <- createBayesianSetup(pLikelihood, lower = -10, upper = 10, parallel = 'external') -# -# ## For this case we want to parallelize the internal chains, therefore we create a n row matrix with startValues, if you parallelize a model in the likelihood, do not set a n*row Matrix for startValue -# settings = list(iterations = 100, nrChains = 1, startValue = bayesianSetup$prior$sampler(n)) -# -# ## runMCMC -# out <- runMCMC(bayesianSetup, settings, sampler = "DEzs") - -## ----eval = FALSE------------------------------------------------------------- -# ### Create cluster with n cores -# cl <- parallel::makeCluster(n) -# -# ## export your model -# # parallel::clusterExport(cl, varlist = list(complexModel)) -# -# ## Definition of the likelihood -# likelihood <- function(param) { -# # ll <- complexModel(param) -# # return(ll) -# } -# -# ## create BayesianSetup and settings -# bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = 'external') -# settings = list(iterations = 100, nrChains = 1) -# -# ## runMCMC -# out <- runMCMC(bayesianSetup, settings) -# - -## ----eval = FALSE------------------------------------------------------------- -# ### Definition of likelihood function -# x <- c(1:10) -# likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) -# -# ## Create BayesianSetup and settings -# bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = F) -# settings = list(iterations = 100000) -# -# ## Start cluster with n cores for n chains and export BayesianTools library -# cl <- parallel::makeCluster(n) -# parallel::clusterEvalQ(cl, library(BayesianTools)) -# -# ## calculate parallel n chains, for each chain the likelihood will be calculated on one core -# out <- parallel::parLapply(cl, 1:n, fun = function(X, bayesianSetup, settings) runMCMC(bayesianSetup, settings, sampler = "DEzs"), bayesianSetup, settings) -# -# ## Combine the chains -# out <- createMcmcSamplerList(out) - -## ----------------------------------------------------------------------------- -# Create a BayesianSetup -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 2500, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) - - -newPrior = createPriorDensity(out, method = "multivariate", eps = 1e-10, lower = rep(-10, 3), upper = rep(10, 3), best = NULL) -bayesianSetup <- createBayesianSetup(likelihood = ll, prior = newPrior) - -settings = list(iterations = 1000, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) - -## ----message = F-------------------------------------------------------------- - -ll <- generateTestDensityMultiNormal(sigma = "no correlation") - -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 10000, nrChains= 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -plot(out) -marginalPlot(out, prior = T) -correlationPlot(out) -gelmanDiagnostics(out, plot=T) - -# option to restart the sampler - -settings = list(iterations = 1000, nrChains= 1, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -out2 <- runMCMC(bayesianSetup = out) - -out3 <- runMCMC(bayesianSetup = out2) - -#plot(out) -#plot(out3) - -# create new prior from posterior sample - -newPriorFromPosterior <- createPriorDensity(out2) - - -## ----------------------------------------------------------------------------- -iter = 10000 - -## ----------------------------------------------------------------------------- -applySettingsDefault(sampler = "Metropolis") - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = F, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, adapt = F, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, adapt = T, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = c(1,0.5,0), temperingFunction = NULL, optimize = T, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# temperingFunction <- function(x) 5 * exp(-0.01*x) + 1 -# settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = c(1,1,0), temperingFunction = temperingFunction, optimize = T, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DE", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(iterations = iter, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAM", settings = settings) -# plot(out) - -## ----results = 'hide', eval = FALSE------------------------------------------- -# settings <- list(iterations = iter, message = FALSE) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAMzs", settings = settings) -# plot(out) - -## ----eval = F----------------------------------------------------------------- -# settings = list(iterations = iter, message = FALSE) -# -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Twalk", settings = settings) - -## ----eval = T----------------------------------------------------------------- -settings <- list(iterations = iter, nrChains = 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) - -#chain = getSample(out, coda = T) -gelmanDiagnostics(out, plot = F) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(initialParticles = iter, iterations= 1) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) -# plot(out) - -## ----results = 'hide', eval = F----------------------------------------------- -# settings <- list(initialParticles = iter, iterations= 10) -# out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) -# plot(out) - -## ----------------------------------------------------------------------------- -sampleSize = 30 -x <- (-(sampleSize-1)/2):((sampleSize-1)/2) -y <- 1 * x + 1*x^2 + rnorm(n=sampleSize,mean=0,sd=10) -plot(x,y, main="Test Data") - -## ----------------------------------------------------------------------------- -likelihood1 <- function(param){ - pred = param[1] + param[2]*x + param[3] * x^2 - singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) - return(sum(singlelikelihoods)) -} - -likelihood2 <- function(param){ - pred = param[1] + param[2]*x - singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[3]^2), log = T) - return(sum(singlelikelihoods)) -} - -## ----------------------------------------------------------------------------- -setUp1 <- createBayesianSetup(likelihood1, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) - -setUp2 <- createBayesianSetup(likelihood2, lower = c(-5,-5,0.01), upper = c(5,5,30)) - -## ----results = 'hide'--------------------------------------------------------- -settings = list(iterations = 15000, message = FALSE) -out1 <- runMCMC(bayesianSetup = setUp1, sampler = "Metropolis", settings = settings) -#tracePlot(out1, start = 5000) -M1 = marginalLikelihood(out1) -M1 - -settings = list(iterations = 15000, message = FALSE) -out2 <- runMCMC(bayesianSetup = setUp2, sampler = "Metropolis", settings = settings) -#tracePlot(out2, start = 5000) -M2 = marginalLikelihood(out2) -M2 - -## ----------------------------------------------------------------------------- -exp(M1$ln.ML - M2$ln.ML) - -## ----------------------------------------------------------------------------- -exp(M1$ln.ML) / ( exp(M1$ln.ML) + exp(M2$ln.ML)) - -## ----------------------------------------------------------------------------- -DIC(out1)$DIC -DIC(out2)$DIC - -## ----------------------------------------------------------------------------- -# This will not work, since likelihood1 has no sum argument -# WAIC(out1) - -# likelihood with sum argument -likelihood3 <- function(param, sum = TRUE){ - pred <- param[1] + param[2]*x + param[3] * x^2 - singlelikelihoods <- dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) - return(if (sum == TRUE) sum(singlelikelihoods) else singlelikelihoods) -} -setUp3 <- createBayesianSetup(likelihood3, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) -out3 <- runMCMC(bayesianSetup = setUp3, sampler = "Metropolis", settings = settings) - -WAIC(out3) - diff --git a/BayesianTools/doc/BayesianTools.Rmd b/BayesianTools/doc/BayesianTools.Rmd deleted file mode 100644 index e76bea3..0000000 --- a/BayesianTools/doc/BayesianTools.Rmd +++ /dev/null @@ -1,714 +0,0 @@ ---- -title: "Bayesian Tools - General-Purpose MCMC and SMC Samplers and Tools for Bayesian Statistics" -output: - rmarkdown::html_vignette: - toc: true -vignette: > - %\VignetteIndexEntry{Manual for the BayesianTools R package} - %\VignetteEngine{knitr::rmarkdown} - \usepackage[utf8]{inputenc} -abstract: "The BayesianTools (BT) package supports model analysis (including sensitivity analysis and uncertainty analysis), Bayesian model calibration, as well as model selection and multi-model inference techniques for system models." ---- - -```{r global_options, include=FALSE} -knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) -``` - -```{r, echo = F, message = F} -set.seed(123) -``` - -# Quick start - -The purpose of this first section is to give you a quick overview of the most important functions of the BayesianTools (BT) package. For a more detailed description, see the later sections - -## Installing, loading and citing the package - -If you haven't installed the package yet, either run - -```{r, eval = F} -install.packages("BayesianTools") -``` - -Or follow the instructions on to install a development or an older version. - -Loading and citation - -```{r} -library(BayesianTools) -citation("BayesianTools") -``` - -Note: BayesianTools calls a number of secondary packages. Particular important is coda, which is used on a number of plots and summary statistics. If you make heavy use of the summary statistics and diagnostics plots, it would be nice to cite coda as well! - -Pro-tip: if you are running a stochastic algorithms such as an MCMC, you should always set or record your random seed to make your results reproducible (otherwise, results will change slightly every time you run the code) - -```{r} -set.seed(123) -``` - -In a real application, to ensure reproducibility, it would also be useful to record the session info, - -```{r, eval = F} -sessionInfo() -``` - -which lists the version number of R and all loaded packages. - -## The Bayesian Setup - -The central object in the BT package is the BayesianSetup. This class contains the information about the model to be fit (likelihood), and the priors for the model parameters. - -A BayesianSetup is created by the createBayesianSetup function. The function expects a log-likelihood and (optional) a log-prior. It then automatically creates the posterior and various convenience functions for the samplers. - -Advantages of the BayesianSetup include 1. support for automatic parallelization 2. functions are wrapped in try-catch statements to avoid crashes during long MCMC evaluations 3. and the posterior checks if the parameter is outside the prior first, in which case the likelihood is not evaluated (makes the algorithms faster for slow likelihoods). - -If no prior information is provided, an unbounded flat prior is created. If no explicit prior, but lower and upper values are provided, a standard uniform prior with the respective bounds is created, including the option to sample from this prior, which is useful for SMC and also for getting starting values. This option is used in the following example, which creates a multivariate normal likelihood density and a uniform prior for 3 parameters. - -```{r} -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) -``` - -See later more detailed description about the BayesianSetup. - -**Hint:** for an example how to run this steps for dynamic ecological model, see ?VSEM - -## Running MCMC and SMC functions - -Once you have your setup, you may want to run a calibration. The runMCMC function is the main wrapper for all other implemented MCMC/SMC functions. It always takes the following arguments - -- A bayesianSetup (alternatively, the log target function) -- The sampler name -- A list with settings - if a parameter is not provided, the default will be used - -As an example, choosing the sampler name "Metropolis" calls a versatile Metropolis-type MCMC with options for covariance adaptation, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the the later reference on MCMC samplers. This is how we would call this sampler with default settings - -```{r} -iter = 10000 -settings = list(iterations = iter, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -``` - -#### Summarizing outputs - -All samplers can be plotted and summarized via the console with the standard print, and summary commands - -```{r} -print(out) -summary(out) -``` - -and plottted with several plot functions. The marginalPlot can either be plotted as histograms with density overlay, which is also the default, or as a violin plot (see "?marginalPlot"). - -```{r} -plot(out) # plot internally calls tracePlot(out) -correlationPlot(out) -marginalPlot(out, prior = TRUE) -``` - -Other Functions that can be applied to all samplers include model selection scores such as the DIC and the marginal Likelihood (for the calculation of the Bayes factor, see later section for more details), and the Maximum Aposteriori Value (MAP). For the marginal likelihood calculation it is possible to chose from a set of methods (see "?marginalLikelihood"). - -```{r} -marginalLikelihood(out) -DIC(out) -MAP(out) -``` - -You can extract (a part of) the sampled parameter values by - -```{r, eval = F} -getSample(out, start = 100, end = NULL, thin = 5, whichParameters = 1:2) -``` - -For all samplers, you can conveniently perform multiple runs via the nrChains argument - -```{r, echo = T} -iter = 1000 -settings = list(iterations = iter, nrChains = 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -``` - -The result is an object of mcmcSamplerList, which should allow to do everything one can do with an mcmcSampler object (with slightly different output sometimes). - -```{r} -print(out) -summary(out) -``` - -For example, in the plot you now see 3 chains. - -```{r} -plot(out) -``` - -There are a few additional functions that may only be available for lists, for example convergence checks - -```{r} -#getSample(out, coda = F) -gelmanDiagnostics(out, plot = T) -``` - -#### Which sampler to choose? - -The BT package provides a large class of different MCMC samplers, and it depends on the particular application which is most suitable. - -In the absence of further information, we currently recommend the DEzs sampler. This is also the default in the runMCMC function. - -# BayesianSetup Reference - -## Reference on creating likelihoods - -The likelihood should be provided as a log density function. - -```{r, eval = F} -ll = logDensity(x) -``` - -See options for parallelization below. We will use a simple 3-d multivariate normal density for this demonstration. - -```{r} -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) -``` - -#### Parallelization of the likelihood evaluations - -Likelihoods are often costly to compute. If that is the case for you, you should think about parallelization possibilities. The 'createBayesianSetup' function has the input variable 'parallel', with the following options - -- F / FALSE means no parallelization should be used -- T / TRUE means that automatic parallelization options from R are used (careful: this will not work if your likelihood writes to file, or uses global variables or functions - see general R help on parallelization) -- "external", assumed that the likelihood is already parallelized. In this case, the function needs to accept a matrix with parameters as columns, and rows as the different model runs you want to evaluate. This is the most likely option to use if you have a complicated setup (file I/O, HPC cluster) that cannot be treated with the standard R parallelization. - -Algorithms in the BayesianTools package can make use of parallel computing if this option is specified in the BayesianSetup. Note that currently, parallelization is used by the following algorithms: SMC, DEzs and DREAMzs sampler. It can also be used through the BayesianSetup with the functions of the sensitivity package. - -Here some more details on the parallelization - -#### 1. In-build parallelization: - -The in-build parallelization is the easiest way to make use of parallel computing. In the "parallel" argument you can choose the number of cores used for parallelization. Alternatively for TRUE or "auto" all available cores except for one will be used. Now the proposals are evaluated in parallel. Technically, the in-build parallelization uses an R cluster to evaluate the posterior density function. The input for the parallel function is a matrix, where each column represents a parameter and each row a proposal. In this way, the proposals can be evaluated in parallel. For sampler, where only one proposal is evaluated at a time (namely the Metropolis based algorithms as well as DE/DREAM without the zs extension), no parallelization can be used. - -#### 2. External parallelization - -The second option is to use an external parallelization. Here, a parallelization is attempted in the user defined likelihood function. To make use of external parallelization, the likelihood function needs to take a matrix of proposals and return a vector of likelihood values. In the proposal matrix each row represents one proposal, each column a parameter. Further, you need to specify the "external" parallelization in the "parallel" argument. In simplified terms the use of external parallelization uses the following steps: - -```{r, eval = FALSE} -## Definition of likelihood function -likelihood <- function(matrix){ - # Calculate likelihood in parallel - # Return vector of likelihood valus -} - -## Create Bayesian Setup -BS <- createBayesianSetup(likelihood, parallel = "external", ...) - -## Run MCMC -runMCMC(BS, sampler = "SMC", ...) -``` - -#### 3. Multi-core and cluster calculations - -If you want to run your calculations on a cluster there are several ways to achieve it. - -In the first case you want to parallize n internal (not overall chains) on n cores. The argument "parallel = T" in "createBayesianSetup" allows only at most parallelization on 3 cores for the SMC, DEzs and DreamsSamplers. But by setting "parallel = n" to n cores in the "createBayesianSetup", the internal chains of DEzs and DREAMzs will be parallelized on n cores. This works only for the DEzs and DREAMzs samplers. - -```{r, eval = FALSE} -## n = Number of cores -n=2 -x <- c(1:10) -likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) -bayesianSetup <- createBayesianSetup(likelihood, parallel = n, lower = -5, upper = 5) - -## give runMCMC a matrix with n rows of proposals as startValues or sample n times from the previous created sampler -out <- runMCMC(bayesianSetup, settings = list(iterations = 1000)) -``` - -In the second case you want to parallize n internal chains on n cores with a external parallilzed likelihood function. Unlike the previous case, that way DEzs, DREAMzs, and SMC samplers can be parallelized. - -```{r, eval = FALSE} -### Create cluster with n cores -cl <- parallel::makeCluster(n) - -## Definition of the likelihood -likelihood <- function(X) sum(dnorm(c(1:10), mean = X, log = T)) - -## Definition of the likelihood which will be calculated in parallel. Instead of the parApply function, we could also define a costly parallelized likelihood -pLikelihood <- function(param) parallel::parApply(cl = cl, X = param, MARGIN = 1, FUN = likelihood) - -## export functions, dlls, libraries -# parallel::clusterEvalQ(cl, library(BayesianTools)) -parallel::clusterExport(cl, varlist = list(likelihood)) - -## create BayesianSetup -bayesianSetup <- createBayesianSetup(pLikelihood, lower = -10, upper = 10, parallel = 'external') - -## For this case we want to parallelize the internal chains, therefore we create a n row matrix with startValues, if you parallelize a model in the likelihood, do not set a n*row Matrix for startValue -settings = list(iterations = 100, nrChains = 1, startValue = bayesianSetup$prior$sampler(n)) - -## runMCMC -out <- runMCMC(bayesianSetup, settings, sampler = "DEzs") -``` - -In a another case your likelihood requires a parallized model. Start your cluster and export your model, the required libraries, and dlls. Now you can start your calculations with the argument "parallel = external" in createBayesianSetup. - -```{r, eval = FALSE} -### Create cluster with n cores -cl <- parallel::makeCluster(n) - -## export your model -# parallel::clusterExport(cl, varlist = list(complexModel)) - -## Definition of the likelihood -likelihood <- function(param) { - # ll <- complexModel(param) - # return(ll) -} - -## create BayesianSetup and settings -bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = 'external') -settings = list(iterations = 100, nrChains = 1) - -## runMCMC -out <- runMCMC(bayesianSetup, settings) - -``` - -In the last case you can parallize over whole chain calculations. However, here the likelihood itself will not be parallelized. Each chain will be run on one core and the likelihood will be calculated on that core. - -```{r, eval = FALSE} -### Definition of likelihood function -x <- c(1:10) -likelihood <- function(param) return(sum(dnorm(x, mean = param, log = T))) - -## Create BayesianSetup and settings -bayesianSetup <- createBayesianSetup(likelihood, lower = -10, upper = 10, parallel = F) -settings = list(iterations = 100000) - -## Start cluster with n cores for n chains and export BayesianTools library -cl <- parallel::makeCluster(n) -parallel::clusterEvalQ(cl, library(BayesianTools)) - -## calculate parallel n chains, for each chain the likelihood will be calculated on one core -out <- parallel::parLapply(cl, 1:n, fun = function(X, bayesianSetup, settings) runMCMC(bayesianSetup, settings, sampler = "DEzs"), bayesianSetup, settings) - -## Combine the chains -out <- createMcmcSamplerList(out) -``` - -\*\* Remark: even though parallelization can significantly reduce the computation time, it is not always useful because of the so-called communication overhead (computational time for distributing and retrieving infos from the parallel cores). For models with low computational cost, this procedure can take more time than the actual evaluation of the likelihood. If in doubt, make a small comparison of the runtime before starting your large sampling. \*\* - -## Reference on creating priors - -The prior in the BayesianSetup consists of four parts - -- A log density function -- An (optional) sampling function (must be a function without parameters, that returns a draw from the prior) -- lower / upper boundaries -- Additional info - best values, names of the parameters, ... - -These information can be passed by first creating an a extra object, via createPrior, or through the the createBayesianSetup function. - -#### Creating priors - -You have 5 options to create a prior - -- Do not set a prior - in this case, an infinite prior will be created -- Set min/max values - a bounded flat prior and the corresponding sampling function will be created -- Use one of the pre-definded priors, see ?createPrior for a list. One of the options here is to use a previous MCMC output as new prior. Pre-defined priors will usually come with a sampling function -- Use a user-define prior, see ?createPrior -- Create a prior from a previous MCMC sample - -The prior we choose depends on the prior information we have. For example, if we have no prior information, we can choose a uniform prior. The normal distribution is often used to model a wide range of phenomena in statistics, such as the distribution of heights or weights in a population. Beta distribution, on the other hand, is defined on the interval 0, 1. It is often used to model random variables that represent proportions, probabilities or other values that are constrained to lie within this interval. - -| | | | | -|:----------------:|:----------------:|:----------------:|:----------------:| -| createPrior | createBetaPrior | createUniformPrior | createTruncatedNormalPrior | -| Any density provided by the user | Beta density | Uniform density | Normal density | -| | ![](betaDensity.png "Density plot for Beta distribution") | ![](normalDensity.png "Density plot for Normal distribution") | ![](uniformDensity.png "Density plot for Uniform distribution") | -| createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | - -#### Creating user-defined priors - -If creating a user-defined prior, the following information can/should be provided to createPrior: - -- A log density function, as a function of a parameter vector x, same syntax as the likelihood -- Additionally, you should consider providing a function that samples from the prior, because many samplers (SMC, DE, DREAM) can make use of this function for initial conditions. If you use one of the pre-defined priors, the sampling function is already implemented -- lower / upper boundaries (can be set on top of any prior, to create truncation) -- Additional info - best values, names of the parameters, ... - -#### Creating a prior from a previous MCMC sample - -The following example from the help shows how this works - -```{r} -# Create a BayesianSetup -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 2500, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) - - -newPrior = createPriorDensity(out, method = "multivariate", eps = 1e-10, lower = rep(-10, 3), upper = rep(10, 3), best = NULL) -bayesianSetup <- createBayesianSetup(likelihood = ll, prior = newPrior) - -settings = list(iterations = 1000, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) -``` - -# MCMC sampler reference - -## The runMCMC() function - -The runMCMC function is the central function for starting MCMC algorithms in the BayesianTools package. It requires a bayesianSetup, a choice of sampler (standard is DEzs), and optionally changes to the standard settings of the chosen sampler. - -runMCMC(bayesianSetup, sampler = "DEzs", settings = NULL) - -One optional argument that you can always use is nrChains - the default is 1. If you choose more, the runMCMC will perform several runs. - -```{r, message = F} - -ll <- generateTestDensityMultiNormal(sigma = "no correlation") - -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 10000, nrChains= 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -plot(out) -marginalPlot(out, prior = T) -correlationPlot(out) -gelmanDiagnostics(out, plot=T) - -# option to restart the sampler - -settings = list(iterations = 1000, nrChains= 1, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -out2 <- runMCMC(bayesianSetup = out) - -out3 <- runMCMC(bayesianSetup = out2) - -#plot(out) -#plot(out3) - -# create new prior from posterior sample - -newPriorFromPosterior <- createPriorDensity(out2) - -``` - -## The different MCMC samplers - -For convenience we define a number of iterations - -```{r} -iter = 10000 -``` - -### The Metropolis MCMC class - -The BayesianTools package is able to run a large number of Metropolis-Hastings (MH) based algorithms All of these samplers can be accessed by the "Metropolis" sampler in the runMCMC function by specifying the sampler's settings. - -The following code gives an overview about the default settings of the MH sampler. - -```{r} -applySettingsDefault(sampler = "Metropolis") -``` - -The following examples show how the different settings can be used. As you will see different options can be activated singly or in combination. - -#### Standard MH MCMC - -The following settings will run the standard Metropolis Hastings MCMC. - -Refernences: Hastings, W. K. (1970). Monte carlo sampling methods using markov chains and their applications. Biometrika 57 (1), 97-109. - -Metropolis, N., A. W. Rosenbluth, M. N. Rosenbluth, A. H. Teller, and E. Teller (1953). Equation of state calculations by fast computing machines. The journal of chemical physics 21 (6), 1087 - 1092. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = F, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -#### Standard MH MCMC, prior optimization - -This sampler uses an optimization step prior to the sampling process. The optimization aims at improving the starting values and the covariance of the proposal distribution. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -#### Adaptive MCMC, prior optimization - -In the adaptive Metropolis sampler (AM) the information already acquired in the sampling process is used to improve (or adapt) the proposal function. In the BayesianTools package the history of the chain is used to adapt the covariance of the propoasal distribution. - -References: Haario, H., E. Saksman, and J. Tamminen (2001). An adaptive metropolis algorithm. Bernoulli , 223-242. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -#### Standard MCMC, prior optimization, delayed rejection - -Even though rejection is an essential step of a MCMC algorithm it can also mean that the proposal distribution is (locally) badly tuned to the target distribution. In a delayed rejection (DR) sampler a second (or third, etc.) proposal is made before rejection. This proposal is usually drawn from a different distribution, allowing for a greater flexibility of the sampler. In the BayesianTools package the number of delayed rejection steps as well as the scaling of the proposals can be determined. \*\* Note that the current version only supports two delayed rejection steps. \*\* - -References: Green, Peter J., and Antonietta Mira. "Delayed rejection in reversible jump Metropolis-Hastings." Biometrika (2001): 1035-1053. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, adapt = F, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -#### Adaptive MCMC, prior optimization, delayed rejection - -The delayed rejection adaptive Metropolis (DRAM) sampler is merely a combination of the two previous sampler (DR and AM). - -References: Haario, Heikki, et al. "DRAM: efficient adaptive MCMC." Statistics and Computing 16.4 (2006): 339-354. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, adapt = T, DRlevels = 2, gibbsProbabilities = NULL, temperingFunction = NULL, optimize = T, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -#### Standard MCMC, prior optimization, Gibbs updating - -To reduce the dimensions of the target function a Metropolis-within-Gibbs sampler can be run with the BayesianTools package. This means in each iteration only a subset of the parameter vector is updated. In the example below at most two (of the three) parameters are updated each step, and it is double as likely to vary one than varying two. - -\*\* Note that currently adaptive cannot be mixed with Gibbs updating! \*\* - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, adapt = T, DRlevels = 1, gibbsProbabilities = c(1,0.5,0), temperingFunction = NULL, optimize = T, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -#### Standard MCMC, prior optimization, gibbs updating, tempering - -Simulated tempering is closely related to simulated annealing (e.g. Bélisle, 1992) in optimization algorithms. The idea of tempering is to increase the acceptance rate during burn-in. This should result in a faster initial scanning of the target function. To include this a tempering function needs to be supplied by the user. The function describes how the acceptance rate is influenced during burn-in. In the example below an exponential decline approaching 1 (= no influece on the acceptance rate)is used. - -References: Bélisle, C. J. (1992). Convergence theorems for a class of simulated annealing algorithms on rd. Journal of Applied Probability, 885--895. - -C. J. Geyer (2011) Importance sampling, simulated tempering, and umbrella sampling, in the Handbook of Markov Chain Monte Carlo, S. P. Brooks, et al (eds), Chapman & Hall/CRC. - -```{r, results = 'hide', eval = F} -temperingFunction <- function(x) 5 * exp(-0.01*x) + 1 -settings <- list(iterations = iter, adapt = F, DRlevels = 1, gibbsProbabilities = c(1,1,0), temperingFunction = temperingFunction, optimize = T, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) -``` - -### Differential Evolution MCMC - -The BT package implements two versions of the differential evolution MCMC. In doubt, you should use the DEzs option. - -The first is the normal DE MCMC, corresponding to Ter Braak, Cajo JF. "A Markov Chain Monte Carlo version of the genetic algorithm Differential Evolution: easy Bayesian computing for real parameter spaces." Statistics and Computing 16.3 (2006): 239-249. In this sampler multiple chains are run in parallel (but not in the sense of parallel computing). The main difference to the Metropolis based algorithms is the creation of the proposal. Generally all samplers use the current positin of the chain and add a step in the parameter space to generate a new proposal. Whereas in the Metropolis based sampler this step is usually drawn from a multivariate normal distribution (yet every distribution is possible), the DE sampler uses the current position of two other chains to generate the step for each chain. For sucessful sampling at least 2\*d chains, with d being the number of parameters, need to be run in parallel. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DE", settings = settings) -plot(out) -``` - -The second is the Differential Evolution MCMC with snooker update and sampling from past states, corresponding to ter Braak, Cajo JF, and Jasper A. Vrugt. "Differential evolution Markov chain with snooker updater and fewer chains." Statistics and Computing 18.4 (2008): 435-446. This extension covers two differences to the normal DE MCMC. First a snooker update is used based on a user defined probability. Second also past states of other chains are respected in the creation of the proposal. These extensions allow for fewer chains (i.e. 3 chains are usually enough for up to 200 parameters) and parallel computing as the current position of each chain is only dependent on the past states of the other chains. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) -plot(out) -``` - -### DREAM sampler - -Also for the DREAM sampler, there are two versions included. First of all, the standard DREAM sampler, see Vrugt, Jasper A., et al. "Accelerating Markov chain Monte Carlo simulation by differential evolution with self-adaptive randomized subspace sampling." International Journal of Nonlinear Sciences and Numerical Simulation 10.3 (2009): 273-290. - -This sampler is largely build on the DE sampler with some significant differences: 1) More than two chains can be used to generate a proposal. 2) A randomized subspace sampling can be used to enhance the efficiency for high dimensional posteriors. Each dimension is updated with a crossover probalitity CR. To speed up the exploration of the posterior DREAM adapts the distribution of CR values during burn-in to favor large jumps over small ones. 3) Outlier chains can be removed during burn-in. - -```{r, results = 'hide', eval = F} -settings <- list(iterations = iter, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAM", settings = settings) -plot(out) -``` - -The second implementation uses the same extension as the DEzs sampler. Namely sampling from past states and a snooker update. Also here this extension allows for the use of fewer chains and parallel computing. - -Again, in doubt you should prefer "DREAMzs". - -```{r, results = 'hide', eval = FALSE} -settings <- list(iterations = iter, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAMzs", settings = settings) -plot(out) -``` - -### T-walk - -The T-walk is a MCMC algorithm developed by Christen, J. Andrés, and Colin Fox. "A general purpose sampling algorithm for continuous distributions (the t-walk)." Bayesian Analysis 5.2 (2010): 263-281. In the sampler two independent points are used to explore the posterior space. Based on probabilities four different moves are used to generate proposals for the two points. As for the DE sampler this procedure requires no tuning of the proposal distribution for efficient sampling in complex posterior distributions. - -```{r, eval = F} -settings = list(iterations = iter, message = FALSE) - -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Twalk", settings = settings) -``` - -### Convergence checks for MCMCs - -All MCMCs should be checked for convergence. We recommend the standard procedure of Gelmal-Rubin. This procedure requires running several MCMCs (we recommend 3). This can be achieved either directly in the runMCMC (nrChains = 3), or, for runtime reasons, by combining the results of three independent runMCMC evaluations with nrChains = 1. - -```{r, eval = T} -settings <- list(iterations = iter, nrChains = 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) -plot(out) - -#chain = getSample(out, coda = T) -gelmanDiagnostics(out, plot = F) -``` - -## Non-MCMC sampling algorithms - -MCMCs sample the posterior space by creating a chain in parameter space. While this allows "learning" from past steps, it does not permit the parallel execution of a large number of posterior values at the same time. - -An alternative to MCMCs are particle filters, aka Sequential Monte-Carlo (SMC) algorithms. See Hartig, F.; Calabrese, J. M.; Reineking, B.; Wiegand, T. & Huth, A. Statistical inference for stochastic simulation models - theory and application Ecol. Lett., 2011, 14, 816-827 - -### Rejection samling - -The easiest option is to simply sample a large number of parameters and accept them according to their posterior value. This option can be emulated with the implemented SMC, setting iterations to 1. - -```{r, results = 'hide', eval = F} -settings <- list(initialParticles = iter, iterations= 1) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) -plot(out) -``` - -### Sequential Monte Carlo (SMC) - -The more sophisticated option is using the implemented SMC, which is basically a particle filter that applies several filter steps. - -```{r, results = 'hide', eval = F} -settings <- list(initialParticles = iter, iterations= 10) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "SMC", settings = settings) -plot(out) -``` - -Note that the use of a number for initialParticles requires that the bayesianSetup includes the possibility to sample from the prior. - -# Bayesian model comparison and averaging - -There are a number of Bayesian model selection and model comparison methods. The BT implements three of the most common of them, the DIC, the WAIC, and the Bayes factor. - -- On the Bayes factor, see Kass, R. E. & Raftery, A. E. Bayes Factors J. Am. Stat. Assoc., Amer Statist Assn, 1995, 90, 773-795 - -- An overview on DIC and WAIC is given in Gelman, A.; Hwang, J. & Vehtari, A. (2014) Understanding predictive information criteria for Bayesian models. Statistics and Computing, 24, 997-1016-. On DIC, see also the original reference by Spiegelhalter, D. J.; Best, N. G.; Carlin, B. P. & van der Linde, A. (2002) Bayesian measures of model complexity and fit. J. Roy. Stat. Soc. B, 64, 583-639. - -The Bayes factor relies on the calculation of marginal likelihoods, which is numerically not without problems. The BT package currently implements three methods - -- The recommended way is the method "Chib" (Chib and Jeliazkov, 2001). which is based on MCMC samples, but performs additional calculations. Despite being the current recommendation, note there are some numeric issues with this algorithm that may limit reliability for larger dimensions. - -- The harmonic mean approximation, is implemented only for comparison. Note that the method is numerically unrealiable and usually should not be used. - -- The third method is simply sampling from the prior. While in principle unbiased, it will only converge for a large number of samples, and is therefore numerically inefficient. - -## Example - -Data linear Regression with quadratic and linear effect - -```{r} -sampleSize = 30 -x <- (-(sampleSize-1)/2):((sampleSize-1)/2) -y <- 1 * x + 1*x^2 + rnorm(n=sampleSize,mean=0,sd=10) -plot(x,y, main="Test Data") -``` - -Likelihoods for both - -```{r} -likelihood1 <- function(param){ - pred = param[1] + param[2]*x + param[3] * x^2 - singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) - return(sum(singlelikelihoods)) -} - -likelihood2 <- function(param){ - pred = param[1] + param[2]*x - singlelikelihoods = dnorm(y, mean = pred, sd = 1/(param[3]^2), log = T) - return(sum(singlelikelihoods)) -} -``` - -Posterior definitions - -```{r} -setUp1 <- createBayesianSetup(likelihood1, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) - -setUp2 <- createBayesianSetup(likelihood2, lower = c(-5,-5,0.01), upper = c(5,5,30)) -``` - -MCMC and marginal likelihood calculation - -```{r, results = 'hide'} -settings = list(iterations = 15000, message = FALSE) -out1 <- runMCMC(bayesianSetup = setUp1, sampler = "Metropolis", settings = settings) -#tracePlot(out1, start = 5000) -M1 = marginalLikelihood(out1) -M1 - -settings = list(iterations = 15000, message = FALSE) -out2 <- runMCMC(bayesianSetup = setUp2, sampler = "Metropolis", settings = settings) -#tracePlot(out2, start = 5000) -M2 = marginalLikelihood(out2) -M2 -``` - -### Model comparison via Bayes factor - -Bayes factor (need to reverse the log) - -```{r} -exp(M1$ln.ML - M2$ln.ML) -``` - -BF \> 1 means the evidence is in favor of M1. See Kass, R. E. & Raftery, A. E. (1995) Bayes Factors. J. Am. Stat. Assoc., Amer Statist Assn, 90, 773-795. - -Assuming equal prior weights on all models, we can calculate the posterior weight of M1 as - -```{r} -exp(M1$ln.ML) / ( exp(M1$ln.ML) + exp(M2$ln.ML)) -``` - -If models have different model priors, multiply with the prior probabilities of each model. - -### Model comparison via DIC - -The Deviance information criterion is a commonly applied method to summarize the fit of an MCMC chain. It can be obtained via - -```{r} -DIC(out1)$DIC -DIC(out2)$DIC -``` - -### Model comparison via WAIC - -The Watanabe--Akaike information criterion is another criterion for model comparison. To be able to calculate the WAIC, the model must implement a log-likelihood that density that allows to calculate the log-likelihood point-wise (the likelihood functions requires a "sum" argument that determines whether the summed log-likelihood should be returned). It can be obtained via - -```{r} -# This will not work, since likelihood1 has no sum argument -# WAIC(out1) - -# likelihood with sum argument -likelihood3 <- function(param, sum = TRUE){ - pred <- param[1] + param[2]*x + param[3] * x^2 - singlelikelihoods <- dnorm(y, mean = pred, sd = 1/(param[4]^2), log = T) - return(if (sum == TRUE) sum(singlelikelihoods) else singlelikelihoods) -} -setUp3 <- createBayesianSetup(likelihood3, lower = c(-5,-5,-5,0.01), upper = c(5,5,5,30)) -out3 <- runMCMC(bayesianSetup = setUp3, sampler = "Metropolis", settings = settings) - -WAIC(out3) -``` diff --git a/BayesianTools/doc/InterfacingAModel.R b/BayesianTools/doc/InterfacingAModel.R deleted file mode 100644 index 0ea45a8..0000000 --- a/BayesianTools/doc/InterfacingAModel.R +++ /dev/null @@ -1,113 +0,0 @@ -## ----global_options, include=FALSE-------------------------------------------- -knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) - -## ----echo = F, message = F---------------------------------------------------- -set.seed(123) - -## ----eval = F----------------------------------------------------------------- -# runMyModel(par) - -## ----eval = F----------------------------------------------------------------- -# dyn.load(model) -# -# runMyModel(par){ -# out = # model call here -# # process out -# return(out) -# } - -## ----eval = F----------------------------------------------------------------- -# runMyModel(par){ -# -# # Create here a string with what you would write to call the model from the command line -# systemCall <- paste("model.exe", par[1], par[2]) -# -# out = system(systemCall, intern = TRUE) # intern indicates whether to capture the output of the command as an R character vector -# -# # write here to convert out in the apprpriate R classes -# -# } - -## ----eval = F----------------------------------------------------------------- -# runMyModel(par, returnData = NULL){ -# -# writeParameters(par) -# -# system("Model.exe") -# -# if(! is.null(returnData)) return(readData(returnData)) # The readData function will be defined later -# -# } -# -# writeParameters(par){ -# -# # e.g. -# # read template parameter fil -# # replace strings in template file -# # write parameter file -# } - -## ----eval = F----------------------------------------------------------------- -# setUpModel <- function(parameterTemplate, site, localConditions){ -# -# # create the runModel, readData functions (see later) here -# -# return(list(runModel, readData)) -# -# } - -## ----eval = F----------------------------------------------------------------- -# getData(type = X){ -# -# read.csv(xxx) -# -# # do some transformation -# -# # return data in desidered format -# } - -## ----eval = F----------------------------------------------------------------- -# par = c(1,2,3,4 ..) -# -# runMyModel(par) -# -# output <- getData(type = DesiredType) -# -# plot(output) - -## ----------------------------------------------------------------------------- -mymodel<-function(x){ - output<-0.2*x+0.1^x - return(output) -} - -## ----eval = F----------------------------------------------------------------- -# -# library(parallel) -# cl <- makeCluster(2) -# -# runParallel<- function(parList){ -# parSapply(cl, parList, mymodel) -# } -# -# runParallel(c(1,2)) - -## ----eval = F----------------------------------------------------------------- -# library(BayesianTools) -# parModel <- generateParallelExecuter(mymodel) - -## ----------------------------------------------------------------------------- -library(BayesianTools) - -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup <- createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 200) - -# run the several MCMCs chains either in seperate R sessions, or via R parallel packages -out1 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) -out2 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) - -res <- createMcmcSamplerList(list(out1, out2)) -plot(res) - diff --git a/BayesianTools/doc/InterfacingAModel.Rmd b/BayesianTools/doc/InterfacingAModel.Rmd deleted file mode 100644 index 636490d..0000000 --- a/BayesianTools/doc/InterfacingAModel.Rmd +++ /dev/null @@ -1,300 +0,0 @@ ---- -title: "Interfacing your model with R" -output: - rmarkdown::html_vignette: - toc: true -vignette: > - %\VignetteIndexEntry{Interfacing your model with R} - \usepackage[utf8]{inputenc} - %\VignetteEngine{knitr::rmarkdown} -abstract: "This tutorial discusses how to interface models written in other programming languages with R, so that they can be fit with BayesianTools" -author: Florian Hartig -editor_options: - chunk_output_type: console ---- - -```{r global_options, include=FALSE} -knitr::opts_chunk$set(fig.width=5, fig.height=5, warning=FALSE, cache = F) -``` - -```{r, echo = F, message = F} -set.seed(123) -``` - -# Interfacing a model with BT - step-by-step guide - -## Step 1: Create a runModel(par) function - -A basic requirement to allow calibration in BT is that we need to be able to execute the model with a given set of parameters. Strictly speaking, BT will not see the model as such, but requires a likelihood function with interface likelihood(par), where par is a vector, but in this function, you will then probably run the model with parameters par, where par could stay a vector, or be transformed to another format, e.g. data.frame, matrix or list. - -What happens now depends on how your model is programmed - I have listed the steps in order of convenience / speed. If your model has never been interfaced with R you will likely have to move down to the last option. - -\begin{enumerate} -\item Model in R, or R interface existing -\item Model can be compiled and linked as a dll -\item Model is in C/C++ and can be interfaced with RCPP -\item Model can be compiled as executable and accepts parameters via the command line -\item Model can be compiled as executable reads parameters via parameter file -\item Model parameters are hard-coded in the executable -\end{enumerate} - -### Case 1 - model programmed in R - -Usually, you will have to do nothing. Just make sure you can call your model a in - -```{r, eval = F} -runMyModel(par) -``` - -Typically this function will directly return the model outputs, so step 2 can be skipped. - -### Case 2 - compiled dll, parameters are set via dll interface - -If you have your model prepared as a dll, or you can prepare it that way, you can use the \ref{https://stat.ethz.ch/R-manual/R-devel/library/base/html/dynload.html}{dyn.load()} function to link R to your model - -```{r, eval = F} -dyn.load(model) - -runMyModel(par){ - out = # model call here - # process out - return(out) -} -``` - -Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. - -The tricky thing in this approach is that you have to code the interface to your dll, which technically means in most programming languages to set your variables as external or something similar, so that they can be accessed from the outside. How this works will depend on the programming language. - - -### Case 3 - model programmed in C / C++, interfaced with RCPP - -RCPP is a highly flexible environment to interface between R and C/C++. If your model is coded in C / C++, RCPP offers the most save and powerful way to connect with R (much more flexible than with command line or dll). - -However, doing the interface may need some adjustments to the code, and there can be technical problems that are difficult to solve for beginners. I do not recommend to attempt interfacing an existing C/C++ model unless you have RCPP experience, or at least very food C/C++ experience. - -Again, if you implement this, you will also typically return the output directly via the dll and not write to file, which means that step 2 can be skipped. - -### Case 4 - compiled executable, parameters set via command line (std I/O) - -If your model is written in a compiled or interpreted language, and accepts parameters via std I/O, wrapping is usually nothing more than writing the system call in an R function. An example would be - -```{r, eval = F} -runMyModel(par){ - - # Create here a string with what you would write to call the model from the command line - systemCall <- paste("model.exe", par[1], par[2]) - - out = system(systemCall, intern = TRUE) # intern indicates whether to capture the output of the command as an R character vector - - # write here to convert out in the apprpriate R classes - -} -``` - -Note: If you have problems with the system command, try system2. If the model returns the output via std.out, you can catch this and convert it and skip step 2. If your model writes to file, go to step 2. - -### Case 5 - compiled model, parameters set via parameter file or in any other method - -Many models read parameters with a parameter file. In this case you want to do something like this - -```{r, eval = F} -runMyModel(par, returnData = NULL){ - - writeParameters(par) - - system("Model.exe") - - if(! is.null(returnData)) return(readData(returnData)) # The readData function will be defined later - -} - -writeParameters(par){ - - # e.g. - # read template parameter fil - # replace strings in template file - # write parameter file -} -``` - -Depending on your problem, it can also make sense to define a setup function such as - -```{r, eval = F} -setUpModel <- function(parameterTemplate, site, localConditions){ - - # create the runModel, readData functions (see later) here - - return(list(runModel, readData)) - -} -``` - -How you do the write parameter function depends on the file format you use for the parameters. In general, you probably want to create a template parameter file that you use as a base and from which you change parameters - -* If your parameter file is in an *.xml format*, check out the xml functions in R -* If your parameter file is in a *general text format*, the best option may be to create a template parameter file, place a unique string at the locations of the parameters that you want to replace, and then use string replace functions in R, e.g. [grep](https://stat.ethz.ch/R-manual/R-devel/library/base/html/grep.html) to replace this string. - -### Case 6 - compiled model, parameters cannot be changed - -You have to change your model code to achieve one of the former options. If the model is in C/C++, going directly to RCPP seems the best alternative. - -## Step 2: Reading back data - -If your model returns the output directly (which is highly preferable, ), you can skip this step. - -For simple models, you might consider returning the model output directly with the runMyModel function. This is probably so for cases a) and b) above, i.e. model is already in R, or accepts parameters via command line. - -More complicated models, however, produce a large number of outputs and you typically don't need all of them. It is therefore more useful to make on or several separate readData or getDate function. The only two different cases I will consider here is - -* via dll / RCPP -* via file ouputs - -*Model is a dll* If the model is a dll file, the best thing would probably be to implement appropriate getData functions in the source code that can then be called from R. If your model is in C and in a dll, interfacing this via RCPP would probably be easier, because you can directly return R dataframes and other data structures. - - -*Model writes file output* If the model writes file output, write a getData function that reads in the model outputs and returns the data in the desired format, typically the same that you would use to represent your field data. - - -```{r, eval = F} -getData(type = X){ - - read.csv(xxx) - - # do some transformation - - # return data in desidered format -} -``` - - -\subsection{Testing the approach} - - -From R, you should now be able to do something like that - - -```{r, eval = F} -par = c(1,2,3,4 ..) - -runMyModel(par) - -output <- getData(type = DesiredType) - -plot(output) -``` - - - - -## Step 3 (optional) - creating an R package from your code - -The last step is optional, but we recommend that you take it from the start, because there is really no downside to it. You work with R code in several files that you run by hand, or diretly put all code into an R package. Creating and managing R packages is very easy, and it's easier to pass on your code because everything, including help, is in on package. To create an R package, follow the tutorial \href{http://biometry.github.io/APES/R/R70-PackageDevelopment.html}{here}. Remember to create a good documentation using Roxygen. - - -# Speed optimization and parallelization - -For running sensitivity analyses or calibrations, runtime is often an issue. Before you parallelize, make sure your model is as fast as possible. - -## Easy things - -* Are you compiling with maximum optimization (e.g. -o3 in cpp) -* If you have a spin-up phase, could you increase the time-step during this phase? -* Could you increase the time step generally -* Do you write unnecessary outputs that you could turn off (harddisk I/O is often slow)? - -## Difficult things - -* Make the model directly callable (RCPPor dll) to avoid harddisk I/O -* Is it possible to reduce initialization time (not only spin-up, but also for reading in the forcings / drivers) by avoid ending the model executable after each run, but rather keep it "waiting" for a new run. -* Code optimization: did you use a profiler? Read up on code optimization -* Check for unnecessary calculations in your code / introduce compiler flags where appropriate - -## Parallelization - -A possibility to speed up the run time of your model is to run it on multiple cores (CPU's). To do so, you have two choices: - -1. Parallelize the model itself -2. Parallelize the model call, so that BT can do several model evaluations in parallel - -Which of the two makes more sense depends a lot on your problem. To parallelize the model itself will be interesting in particular for very large models, which could otherwise not be calibrated with MCMCs. However, this approach will typically require to write parallel C/C++ code and require advanced programming skills, which is the reason why we will not further discuss it here. - -The usual advice in parallel computing is anyway to parallelize the outer loops first, to minimize communication overhead, which would suggest to start with parallelizing model evaluations. This is also much easier to program. Even within this, there are two levels of parallelization possible: - -1. Parallelize the call of several MCMC / SMC samplers -2. Parallelize within the MCMC / SMC samplers - -Currently, BT only supports parallelization within MCMCs / SMCs, but it easy to also implement between sampler parallelization by hand. Both approaches are describe below. - -### Within sampler parallelization - -Within-sampler parallelization is particular useful for algorithms that can use a large number of cores in parallel, e.g. sensitivity analyses or SMC sampling. For the MCMCs, it depends on the settings and the algorithm how much parallelization they can make use of. In general, MCMCs are Markovian, as the name says, i.e. the set up a chain of sequential model evaluations, and those calls can therefore not be fully parallelized. However, a number of MCMCs in the BT package uses MCMC algorithms that can be partly parallelized, in particular the population MCMC algorithms DE/DEzs/DREAM/DREAMzs. For all these cases, BT will automatically use parallelization of the BT setup indicates that this is implemented. - -How to do this? A first requirement to do so is to to have your model wrapped into an R function (see PREVIOUS SECTION). If that is the case, R offers a number of options to run functions in parallel. The easiest is to use the parallel package that comes with the R core. For other packages, see the internet and the CRAN task view on [High Performance Computing](https://CRAN.R-project.org/view=HighPerformanceComputing) - -As an example, assume we have the following, very simple model: - -```{r} -mymodel<-function(x){ - output<-0.2*x+0.1^x - return(output) -} -``` - -To start a parallel computation, we will first need to create a cluster object. Here we will initiate a cluster with 2 CPU's. - -```{r, eval = F} - -library(parallel) -cl <- makeCluster(2) - -runParallel<- function(parList){ - parSapply(cl, parList, mymodel) -} - -runParallel(c(1,2)) -``` - -You could use this principle to build your own parallelized likelihood. However, something very similar to the previous loop is automatized in BayesianTools. You can directly create a parallel model evaluation function with the function generateParallelExecuter, or alternatively directly in the createBayesianSetup - -```{r, eval = F} -library(BayesianTools) -parModel <- generateParallelExecuter(mymodel) -``` - -If your model is tread-safe, you should be able to run this out of the box. I therefore recommend using the hand-coded paraellelization only of the model is not thread-safe. - -### Running several MCMCs in parallel - -Additionally to the within-chain parallelization, you can also run several MCMCs in parallel, and combine them later to a single McmcSamplerList - -```{r} -library(BayesianTools) - -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup <- createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 200) - -# run the several MCMCs chains either in seperate R sessions, or via R parallel packages -out1 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) -out2 <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = settings) - -res <- createMcmcSamplerList(list(out1, out2)) -plot(res) -``` - - - -### Thread safety - -Thread safety quite generally means that you can execute multiple instances of your code on your hardware. There are various things that can limit Thread safety, for example - -* writing outputs to file (several threads might write to the same file at the same time) - - - - - - - From 5658f650ed5fa7bf03830c3fe778ddc28b6e14f8 Mon Sep 17 00:00:00 2001 From: rajoma-02 <70383336+rajoma-02@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:07:26 +0100 Subject: [PATCH 06/10] Corrected some typos and eraesed duplicated code Shouldn't we set plot = T in line 126: gelmanDiagnostics(out, plot = F, start = 100) And should the s after `sampler` be erased? (looks kind of weird after kniting) and the iterations were set to 1000 instead of 10000. Should we keep it that way? (it still converges) --- BayesianTools/vignettes/BayesianTools.Rmd | 25 ++++++----------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/BayesianTools/vignettes/BayesianTools.Rmd b/BayesianTools/vignettes/BayesianTools.Rmd index 3956905..037b06f 100644 --- a/BayesianTools/vignettes/BayesianTools.Rmd +++ b/BayesianTools/vignettes/BayesianTools.Rmd @@ -63,7 +63,7 @@ This session information includes the version number of R and all loaded package The central object in the `BT` package is the `BayesianSetup`. This class contains the information about the model to be fit (likelihood), and the priors for the model parameters. -The `createBayesianSetup` function generates a `BayesianSetup` object. The function requires a log-likelihood and a log-prior (optional) as arguments. It then automatically creates the posterior and variousn convenience functions for the samplers. +The `createBayesianSetup` function generates a `BayesianSetup` object. The function requires a log-likelihood and a log-prior (optional) as arguments. It then automatically creates the posterior and various convenience functions for the samplers. Advantages of the `BayesianSetup` include @@ -84,8 +84,7 @@ A more detailed description of the `BayesianSetup` will follow below. ## Run MCMC and SMC functions -After setup, you may need to run a calibration. The `runMCMC` function serves as the main wrapper for all other implemented `MCMC`/`SMC` -functions. It always requires the following arguments: +After setup, you may need to run a calibration. The `runMCMC` function serves as the main wrapper for all other implemented `MCMC`/`SMC` functions. It always requires the following arguments: - `bayesianSetup` (alternatively, the log target function) - `sampler` name @@ -401,7 +400,7 @@ out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) The `runMCMC` function is the central function for starting MCMC algorithms in the `BayesianTools` package. It takes a `bayesianSetup`, a choice of `sampler` (default is `DEzs`), and optionally changes to the default settings of the chosen `sampler`. ```{r, message = F} -runMCMC(bayesianSetup, sampler = "DEzs", settings = NULL) +runMCMC(bayesianSetup, sampler = "DEzs", settings = list("message" = F)) ``` You may use an optional argument `nrChains`, which is set to the default value of 1 but can be modified if needed. Increasing its value will lead `runMCMC` to execute multiple runs. @@ -448,8 +447,7 @@ iter = 10000 ### The Metropolis MCMC class -The `BayesianTools` package is able to run a large number of Metropolis-Hastings (MH) based algorithms. All of these `sampler`s can be accessed by the "Metropolis" `sampler` in the `runMCMC` function by -specifying the `sampler`'s settings. +The `BayesianTools` package is able to run a large number of Metropolis-Hastings (MH) based algorithms. All of these `sampler`s can be accessed by the "Metropolis" `sampler` in the `runMCMC` function by specifying the `sampler`'s settings. The subsequent code provides an overview of the default settings of the MH `sampler`. @@ -577,7 +575,8 @@ There are two versions of the DREAM `sampler`. First, the standard DREAM sampler This sampler is largely based on the DE sampler with some significant changes: 1) More than two chains can be used to generate a proposal. - 2) Randomized subspace sampling can be used to improve efficiency for high-dimensional posteriors. Each dimension is updated with a crossover probability CR. To speed up the exploration of the posterior, DREAM adjusts the distribution of CR values during burn-in to favor large jumps over small ones. 3) Outlier chains can be removed during burn-in. + 2) Randomized subspace sampling can be used to improve efficiency for high-dimensional posteriors. Each dimension is updated with a crossover probability CR. To speed up the exploration of the posterior, DREAM adjusts the distribution of CR values during burn-in to favor large jumps over small ones. + 3) Outlier chains can be removed during burn-in. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, message = FALSE) @@ -611,18 +610,6 @@ MCMCs sample the posterior space by creating a chain in parameter space. While t An alternative to MCMCs are particle filters, also known as Sequential Monte-Carlo (SMC) algorithms. See Hartig, F.; Calabrese, J. M.; Reineking, B.; Wiegand, T. & Huth, A. Statistical inference for stochastic simulation models - theory and application Ecol. Lett., 2011, 14, 816-827 -### Rejection sampling - -#chain = getSample(out, coda = T) -gelmanDiagnostics(out, plot = F) -``` - -## Non-MCMC sampling algorithms - -MCMCs sample the posterior space by creating a chain in parameter space. While this allows "learning" from past steps, it does not permit the parallel execution of a large number of posterior values at the same time. - -An alternative to MCMCs are particle filters, aka Sequential Monte-Carlo (SMC) algorithms. See Hartig, F.; Calabrese, J. M.; Reineking, B.; Wiegand, T. & Huth, A. Statistical inference for stochastic simulation models - theory and application Ecol. Lett., 2011, 14, 816-827 - ### Rejection samling The simplest option is to sample a large number of parameters and accept them according to their posterior value. This option can be emulated with the implemented SMC by setting iterations to 1. From 0bf002565e6cc33a7f061b4a9736acd1c150a402 Mon Sep 17 00:00:00 2001 From: rajoma-02 <70383336+rajoma-02@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:24:23 +0100 Subject: [PATCH 07/10] Some more small corrections and eraseed section "Which sampler to choose" eraseed section "Which sampler to choose", since that is basically the same as previous code and it did not provide any informations about which sampler to choose except for one sentence which I put above into the section Run MCMC and SMC functions --- BayesianTools/vignettes/BayesianTools.Rmd | 46 ++++------------------- 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/BayesianTools/vignettes/BayesianTools.Rmd b/BayesianTools/vignettes/BayesianTools.Rmd index 037b06f..ea3b8f7 100644 --- a/BayesianTools/vignettes/BayesianTools.Rmd +++ b/BayesianTools/vignettes/BayesianTools.Rmd @@ -90,7 +90,7 @@ After setup, you may need to run a calibration. The `runMCMC` function serves as - `sampler` name - list with `settings` for each sampler - if `settings` is not specified, the default value will be applied -For example, choosing the `sampler` name "Metropolis" calls a versatile Metropolis-type MCMC with options for covariance adjustment, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the later reference on MCMC samplers. When in doubt about the choice of MCMC sampler, we recommend using the default "DEzs". +The BT package provides a large class of different MCMC samplers, and it depends on the particular application which one is most suitable. For example, choosing the `sampler` name "Metropolis" calls a versatile Metropolis-type MCMC with options for covariance adjustment, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the later reference on MCMC samplers. When in doubt about the choice of MCMC sampler, we recommend using the default "DEzs". This is also the default in the `runMCMC` function. ```{r} iter = 1000 @@ -123,12 +123,12 @@ The trace plot is examined for major problems (chains look different, systematic If the trace plots look good, we can look at the Gelman-Rubin convergence diagnostics. Note that you have to discard the burn-in. ```{r} -gelmanDiagnostics(out, plot = F, start = 100) +gelmanDiagnostics(out, plot = T, start = 100) ``` Usually, a value \< 1.05 for each parameter and a msrf \< 1.1 of 1.2 are considered sufficient for convergence. -### Summarize the outputs +## Summarize the outputs If we are happy with the convergence, we can plot and summarize all `sampler`s from the console with the standard `print` and `summary` commands. @@ -158,38 +158,6 @@ To extract part of the sampled parameter values, you can use the following proce getSample(out, start = 100, end = NULL, thin = 5, whichParameters = 1:2) ``` -### Which sampler to choose? - -```{r, echo = T} -iter = 1000 -settings = list(iterations = iter, nrChains = 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -``` - -The result is an object of mcmcSamplerList, which should allow to do everything one can do with an mcmcSampler object (with slightly different output sometimes). - -```{r} -print(out) -summary(out) -``` - -For example, in the plot you now see 3 chains. - -```{r} -plot(out) -``` - -There are a few additional functions that may only be available for lists, for example convergence checks - -```{r} -#getSample(out, coda = F) -gelmanDiagnostics(out, plot = T) -``` -The BT package provides a large class of different MCMC samplers, and it depends on the particular application which one is most suitable. - -In the absence of further information, we currently recommend the `DEz`s sampler. This is also the default in the `runMCMC` function. - # BayesianSetup Reference ## Reference on creating likelihoods @@ -345,7 +313,7 @@ The prior in the `BayesianSetup` consists of four parts This information can be passed by first creating an extra object, via `createPrior`, or via the `createBayesianSetup` function. -#### Creating priors +### Creating priors You have 5 options to create a prior @@ -364,7 +332,7 @@ The prior we choose depends on the prior information we have. For example, if we | | ![](betaDensity.png "Density plot for Beta distribution") | ![](normalDensity.png "Density plot for Normal distribution") | ![](uniformDensity.png "Density plot for Uniform distribution") | | createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | -#### Creating user-defined priors +### Creating user-defined priors When creating a user-defined prior, the following information can/should be passed to `createPrior` @@ -373,7 +341,7 @@ When creating a user-defined prior, the following information can/should be pass - lower / upper boundaries (can be set on top of any prior, to create truncation) - Additional info - best values, names of the parameters, ... -#### Creating a prior from a previous MCMC sample +### Creating a prior from a previous MCMC sample The following example from the help file illustrates the process @@ -400,6 +368,8 @@ out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) The `runMCMC` function is the central function for starting MCMC algorithms in the `BayesianTools` package. It takes a `bayesianSetup`, a choice of `sampler` (default is `DEzs`), and optionally changes to the default settings of the chosen `sampler`. ```{r, message = F} +ll <- generateTestDensityMultiNormal(sigma = "no correlation") +bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) runMCMC(bayesianSetup, sampler = "DEzs", settings = list("message" = F)) ``` From a484028192e1a3ebcd37864e32dbe33c562d4672 Mon Sep 17 00:00:00 2001 From: rajoma-02 <70383336+rajoma-02@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:54:52 +0100 Subject: [PATCH 08/10] Eraesed the section The runMCMC function Eraesed the section The runMCMC function, since the is just the same code, which got executed in the introduction section. --- BayesianTools/vignettes/BayesianTools.Rmd | 81 +++++++++-------------- 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/BayesianTools/vignettes/BayesianTools.Rmd b/BayesianTools/vignettes/BayesianTools.Rmd index ea3b8f7..199ac90 100644 --- a/BayesianTools/vignettes/BayesianTools.Rmd +++ b/BayesianTools/vignettes/BayesianTools.Rmd @@ -26,7 +26,7 @@ set.seed(123) The purpose of this first section is to give you a quick overview of the most important functions of the BayesianTools (BT) package. For a more detailed description, see the following sections. -### Install, load and cite the package +## Install, load and cite the package If you haven't installed the package yet, either run @@ -84,7 +84,7 @@ A more detailed description of the `BayesianSetup` will follow below. ## Run MCMC and SMC functions -After setup, you may need to run a calibration. The `runMCMC` function serves as the main wrapper for all other implemented `MCMC`/`SMC` functions. It always requires the following arguments: +After setup, you may want to run a calibration. The `runMCMC` function serves as the main wrapper for all other implemented `MCMC`/`SMC` functions. It always requires the following arguments: - `bayesianSetup` (alternatively, the log target function) - `sampler` name @@ -98,6 +98,32 @@ settings = list(iterations = iter, message = FALSE) out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) ``` +You can also continue the sampling (multiple times) based on a previous run: + +```{r} +# sampling twice another 1000 iterations with the same settings +out2 <- runMCMC(bayesianSetup = out) +out3 <- runMCMC(bayesianSetup = out2) + + +# just a helper function to plot the trace of only the first parameter +plotTracePar1<-function(output, outputName){ + codaChain = getSample(output, coda = T, whichParameters = 1) + class(codaChain)<-"numeric" + plot(codaChain, type = "l", xlab = "Iterations", ylab = "", main = paste0("Trace of par 1 of ", outputName)) +} + +# as you can see, the length of the chain increases by 1000 steps every plot +par(mfrow=c(3,1)) +plotTracePar1(out, "run 1") +plotTracePar1(out2, "run 2") +plotTracePar1(out3, "run 3") +``` + +```{r, include=FALSE} +par(mfrow=c(1,1)) +``` + ## Convergence checks for MCMCs Before interpreting the results, MCMCs should be checked for convergence. We recommend the Gelman-Rubin convergence diagnostics,which are the standard used in most publications. The Gelman-Rubin diagnostics requires running multiple MCMCs (we recommend 3-5). @@ -332,7 +358,7 @@ The prior we choose depends on the prior information we have. For example, if we | | ![](betaDensity.png "Density plot for Beta distribution") | ![](normalDensity.png "Density plot for Normal distribution") | ![](uniformDensity.png "Density plot for Uniform distribution") | | createPrior(density, sampler, lower, upper, best) | createBetaPrior(a, b, lower, upper) | createUniformPrior(lower, upper, best) | createTruncatedNormalPrior(mean, sd, lower, upper). | -### Creating user-defined priors +#### Creating user-defined priors When creating a user-defined prior, the following information can/should be passed to `createPrior` @@ -341,7 +367,7 @@ When creating a user-defined prior, the following information can/should be pass - lower / upper boundaries (can be set on top of any prior, to create truncation) - Additional info - best values, names of the parameters, ... -### Creating a prior from a previous MCMC sample +#### Creating a prior from a previous MCMC sample The following example from the help file illustrates the process @@ -363,58 +389,15 @@ out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) # MCMC sampler reference -## The runMCMC() function - -The `runMCMC` function is the central function for starting MCMC algorithms in the `BayesianTools` package. It takes a `bayesianSetup`, a choice of `sampler` (default is `DEzs`), and optionally changes to the default settings of the chosen `sampler`. - -```{r, message = F} -ll <- generateTestDensityMultiNormal(sigma = "no correlation") -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) -runMCMC(bayesianSetup, sampler = "DEzs", settings = list("message" = F)) -``` - -You may use an optional argument `nrChains`, which is set to the default value of 1 but can be modified if needed. Increasing its value will lead `runMCMC` to execute multiple runs. - -```{r, message = F} - -ll <- generateTestDensityMultiNormal(sigma = "no correlation") - -bayesianSetup = createBayesianSetup(likelihood = ll, lower = rep(-10, 3), upper = rep(10, 3)) - -settings = list(iterations = 10000, nrChains= 3, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -plot(out) -marginalPlot(out, prior = T) -correlationPlot(out) -gelmanDiagnostics(out, plot=T) - -# option to restart the sampler - -settings = list(iterations = 1000, nrChains= 1, message = FALSE) -out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) - -out2 <- runMCMC(bayesianSetup = out) - -out3 <- runMCMC(bayesianSetup = out2) - -#plot(out) -#plot(out3) - -# create new prior from posterior sample - -newPriorFromPosterior <- createPriorDensity(out2) - -``` - ## The different MCMC samplers +Note: Please recall, that every `sampler` can be accessed through the `runMCMC` function. For a general introduction of how to run a MCMC sampling and how to generate the `BayesianSetup`-object, we refer to [The Bayesian Setup] and [Run MCMC and SMC functions]. Also please note, that every result should be checked for convergence before interpretation (see [Convergence checks for MCMCs]). + For simplicity, we will define a fixed number of iterations. ```{r} iter = 10000 ``` - ### The Metropolis MCMC class The `BayesianTools` package is able to run a large number of Metropolis-Hastings (MH) based algorithms. All of these `sampler`s can be accessed by the "Metropolis" `sampler` in the `runMCMC` function by specifying the `sampler`'s settings. From 633da194bafb8828a6369fc13fc0caf24d60fafe Mon Sep 17 00:00:00 2001 From: rajoma-02 <70383336+rajoma-02@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:49:12 +0100 Subject: [PATCH 09/10] ereased many `...` and updated the part about continuing sampling from a previously started chain --- BayesianTools/vignettes/BayesianTools.Rmd | 69 +++++++++++------------ 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/BayesianTools/vignettes/BayesianTools.Rmd b/BayesianTools/vignettes/BayesianTools.Rmd index 199ac90..db3e47e 100644 --- a/BayesianTools/vignettes/BayesianTools.Rmd +++ b/BayesianTools/vignettes/BayesianTools.Rmd @@ -98,37 +98,33 @@ settings = list(iterations = iter, message = FALSE) out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "Metropolis", settings = settings) ``` -You can also continue the sampling (multiple times) based on a previous run: +The returned object is of class `mcmcSampler`, superclass `bayesianOutput` and contains the BayesianSetup, the sampler and the MCMC chain. We can continue sampling from the posterior via ```{r} -# sampling twice another 1000 iterations with the same settings out2 <- runMCMC(bayesianSetup = out) -out3 <- runMCMC(bayesianSetup = out2) +``` +In this case, the sampling continues with the same parameters as before, which means that we will sample for another 1000 iterations. However, you can change all parameters in settings at this point. -# just a helper function to plot the trace of only the first parameter -plotTracePar1<-function(output, outputName){ - codaChain = getSample(output, coda = T, whichParameters = 1) - class(codaChain)<-"numeric" - plot(codaChain, type = "l", xlab = "Iterations", ylab = "", main = paste0("Trace of par 1 of ", outputName)) -} +If you want to extract the MCMC chain from such an output, you can use the `getSample()` function. The `getSample()` function allows to specify which parameters to extract, start and end points (e.g. to discard burn-in), thinning, and can return the chain either as a matrix or as a coda object. Note that the `getSample()` function is also used by most downstream function and its parameters can thus be provided in `...` in those downstream functions. -# as you can see, the length of the chain increases by 1000 steps every plot -par(mfrow=c(3,1)) -plotTracePar1(out, "run 1") -plotTracePar1(out2, "run 2") -plotTracePar1(out3, "run 3") -``` +As an example how to use getSample, we'll extract the first parameter of both the shorter and the longer MCMC chain and plot them -```{r, include=FALSE} -par(mfrow=c(1,1)) +```{r} +opar = par(mfrow=c(2,1)) + +plot(getSample(out, whichParameters = 1), type = "l", ylab = "par1", xlab = "iteration") +plot(getSample(out2, whichParameters = 1) , type = "l", ylab = "par1", xlab = "iteration") + +par(opar) ``` + ## Convergence checks for MCMCs Before interpreting the results, MCMCs should be checked for convergence. We recommend the Gelman-Rubin convergence diagnostics,which are the standard used in most publications. The Gelman-Rubin diagnostics requires running multiple MCMCs (we recommend 3-5). -For all samplers, you can conveniently perform multiple runs using the `nrChains` argument. Alternatively, for runtime reasons, you can combine the results of three independent `runMCMC` runs with `nrChains = 1` using `combineChains` +For all samplers, you can conveniently perform multiple runs using the `nrChains` argument. Alternatively, for runtime reasons, you can combine the results of three independent `runMCMC()` runs with `nrChains = 1` using `combineChains()` ```{r, echo = T} settings = list(iterations = iter, nrChains = 3, message = FALSE) @@ -141,7 +137,7 @@ The result is an object of `mcmcSamplerList`, which should allow you to do every Basic convergence is checked via so-called trace plots, which show the 3 MCMC chains in different colors. ```{r} -plot(out) +tracePlot(out) # identical to plot(out) ``` The trace plot is examined for major problems (chains look different, systematic trends) and to decide on the burn-in, i.e. the point at which the MCMC has reached the sampling range (i.e. the chains no longer systematically go in one direction). Here, they have basically reached this point immediately, so we could set the burn-in to 0, but I choose 100, i.e. discard the first 100 samples in all further plots. @@ -156,21 +152,21 @@ Usually, a value \< 1.05 for each parameter and a msrf \< 1.1 of 1.2 are conside ## Summarize the outputs -If we are happy with the convergence, we can plot and summarize all `sampler`s from the console with the standard `print` and `summary` commands. +If we are happy with the convergence, we can plot and summarize all sampler from the console with the standard `print()` and `summary()` functions. ```{r} print(out, start = 100) summary(out, start = 100) ``` -You can also use built-in plot functions from the package for visualization. The `marginalPlot` can be either plotted as histograms with density overlay (default setting) or as a violin plot (see "?marginalPlot"). +You can also use built-in `plot())` functions from the package for visualization. The `marginalPlot()` can be either plotted as histograms with density overlay (default setting) or as a violin plot (see "?marginalPlot"). ```{r} correlationPlot(out) marginalPlot(out, prior = TRUE) ``` -Additional functions that may be used on all `sampler`s are model selection scores, including the Deviance Information Criterion (DIC) and the marginal likelihood (see later section for details on calculating the Bayes factor), alongside the Maximum A Posteriori (MAP) value. A set of methods are available for calculation of marginal likelihood (refer to "?marginalLikelihood"). +Additional functions that may be used on all samplers are model selection scores, including the Deviance Information Criterion (DIC) and the marginal likelihood (see later section for details on calculating the Bayes factor), alongside the Maximum A Posteriori (MAP) value. A set of methods are available for calculation of marginal likelihood (refer to `?marginalLikelihood`). ```{r} marginalLikelihood(out) @@ -215,7 +211,7 @@ Here are some more details about the parallelization. #### 1. In-build parallelization: -In-built parallelizing is the easiest way to use parallel computing. The "parallel" argument allows you to select the number of cores to use for parallelization. Alternatively, TRUE or "auto" will use all available cores except one. Now the proposals are evaluated in parallel. Technically, the built-in parallelization uses an R cluster to evaluate the posterior density function. The input to the parallel function is a matrix where each column represents a parameter and each row represents a proposal. This allows the proposals to be evaluated in parallel. For `sampler`s that evaluate only one proposal at a time (namely the Metropolis-based algorithms and DE/DREAM without the `zs` extension), parallelization cannot be used. +In-built parallelizing is the easiest way to use parallel computing. The "parallel" argument allows you to select the number of cores to use for parallelization. Alternatively, TRUE or "auto" will use all available cores except one. Now the proposals are evaluated in parallel. Technically, the built-in parallelization uses an R cluster to evaluate the posterior density function. The input to the parallel function is a matrix where each column represents a parameter and each row represents a proposal. This allows the proposals to be evaluated in parallel. For samplers that evaluate only one proposal at a time (namely the Metropolis-based algorithms and DE/DREAM without the 'zs' extension), parallelization cannot be used. #### 2. External parallelization @@ -239,7 +235,7 @@ runMCMC(BS, sampler = "SMC", ...) If you want to run your calculations on a cluster there are several ways to do it. -In the first case, you want to parallelize n internal (not total chains) on n cores. The argument "parallel = T" in "createBayesianSetup" only allows parallelization on a maximum of 3 cores for the `SMC`, `DEzs` and `DreamsSamplers`. But by setting "parallel = n" in "createBayesianSetup" to `n` cores, the internal chains of `DEzs` and `DREAMzs` will be parallelized on `n` cores. This only works for `DEzs` and `DREAMzs` samplers. +In the first case, you want to parallelize n internal (not total chains) on n cores. The argument `parallel = T` in `createBayesianSetup()` only allows parallelization on a maximum of 3 cores for the SMC, DEzs and DreamsSamplers. But by setting `parallel = n` in `createBayesianSetup()` to `n` cores, the internal chains of DEzs and DREAMzs will be parallelized on n cores. This only works for DEzs and DREAMzs samplers. ```{r, eval = FALSE} ## n = Number of cores @@ -252,7 +248,7 @@ bayesianSetup <- createBayesianSetup(likelihood, parallel = n, lower = -5, upper out <- runMCMC(bayesianSetup, settings = list(iterations = 1000)) ``` -In the second case, you want to parallelize n internal chains on `n` cores with an external parallelized likelihood function. Unlike the previous case, `DEzs`, `DREAMzs`, and `SMC` samplers can be parallelized this way. +In the second case, you want to parallelize n internal chains on n cores with an external parallelized likelihood function. Unlike the previous case, DEzs, DREAMzs, and SMC samplers can be parallelized this way. ```{r, eval = FALSE} ### Create cluster with n cores @@ -278,8 +274,7 @@ settings = list(iterations = 100, nrChains = 1, startValue = bayesianSetup$prior out <- runMCMC(bayesianSetup, settings, sampler = "DEzs") ``` -In another case, your likelihood requires a parallelized model. Start your cluster and export your model, the required libraries, and `dll`s. Now you can start your calculations with the argument "parallel = -external" in `createBayesianSetup`. +In another case, your likelihood requires a parallelized model. Start your cluster and export your model, the required libraries, and dlls. Now you can start your calculations with the argument `parallel = external` in `createBayesianSetup()`. ```{r, eval = FALSE} ### Create cluster with n cores @@ -391,7 +386,7 @@ out <- runMCMC(bayesianSetup = bayesianSetup, settings = settings) ## The different MCMC samplers -Note: Please recall, that every `sampler` can be accessed through the `runMCMC` function. For a general introduction of how to run a MCMC sampling and how to generate the `BayesianSetup`-object, we refer to [The Bayesian Setup] and [Run MCMC and SMC functions]. Also please note, that every result should be checked for convergence before interpretation (see [Convergence checks for MCMCs]). +Note: Please recall, that every sampler can be accessed through the `runMCMC()` function. For a general introduction of how to run a MCMC sampling and how to generate the `BayesianSetup`-object, we refer to [The Bayesian Setup] and [Run MCMC and SMC functions]. Also please note, that every result should be checked for convergence before interpretation (see [Convergence checks for MCMCs]). For simplicity, we will define a fixed number of iterations. @@ -400,9 +395,9 @@ iter = 10000 ``` ### The Metropolis MCMC class -The `BayesianTools` package is able to run a large number of Metropolis-Hastings (MH) based algorithms. All of these `sampler`s can be accessed by the "Metropolis" `sampler` in the `runMCMC` function by specifying the `sampler`'s settings. +The `BayesianTools` package is able to run a large number of Metropolis-Hastings (MH) based algorithms. All of these samplers can be accessed by specifying `sampler = "Metropolis"` in the `runMCMC()`. -The subsequent code provides an overview of the default settings of the MH `sampler`. +The subsequent code provides an overview of the default settings of the MH sampler. The following code gives an overview about the default settings of the MH sampler. @@ -463,7 +458,7 @@ plot(out) #### Adaptive MCMC, prior optimization, delayed rejection -The Delayed Rejection Adaptive Metropolis (DRAM) `sampler` is simply a combination of the two previous `sampler`s (DR and AM). +The Delayed Rejection Adaptive Metropolis (DRAM) sampler is simply a combination of the two previous samplers (DR and AM). References: Haario, Heikki, et al. "DRAM: efficient adaptive MCMC." Statistics and Computing 16.4 (2006): 339-354. @@ -475,7 +470,7 @@ plot(out) #### Standard MCMC, prior optimization, Gibbs updating -To reduce the dimensions of the target function, a Metropolis-within-Gibbs `sampler` can be run with the `BayesianTools` package. This means that only a subset of the parameter vector is updated in each iteration. In the example below, at most two (of the three) parameters are updated at each step, and it is twice as likely to vary one as to vary two. +To reduce the dimensions of the target function, a Metropolis-within-Gibbs sampler can be run with the `BayesianTools` package. This means that only a subset of the parameter vector is updated in each iteration. In the example below, at most two (of the three) parameters are updated at each step, and it is twice as likely to vary one as to vary two. \*\* Note that currently adaptive cannot be mixed with Gibbs updating! \*\* @@ -505,7 +500,7 @@ plot(out) The BT package implements two differential evolution MCMCs. When in doubt, use the DEzs option. -The first is the normal DE MCMC, according to Ter Braak, Cajo JF. "A Markov Chain Monte Carlo version of the genetic algorithm Differential Evolution: easy Bayesian computing for real parameter spaces". Statistics and Computing 16.3 (2006): 239-249. This sampler runs multiple chains in parallel (but not in the sense of parallel computing). The main difference to the Metropolis based algorithms is the generation of the proposal. In general, all `sampler`s use the current position of the chain and add a step in the parameter space to generate a new proposal. While in the Metropolis based `sampler` this step is usually drawn from a multivariate normal distribution (but any distribution is possible), the `DE` `sampler` uses the current position of two other chains to generate the step for each chain. For successful sampling, at least `2*d` chains, where `d` is the number of parameters, must be run in parallel. +The first is the normal DE MCMC, according to Ter Braak, Cajo JF. "A Markov Chain Monte Carlo version of the genetic algorithm Differential Evolution: easy Bayesian computing for real parameter spaces". Statistics and Computing 16.3 (2006): 239-249. This sampler runs multiple chains in parallel (but not in the sense of parallel computing). The main difference to the Metropolis based algorithms is the generation of the proposal. In general, all samplers use the current position of the chain and add a step in the parameter space to generate a new proposal. While in the Metropolis based sampler this step is usually drawn from a multivariate normal distribution (but any distribution is possible), the DE sampler uses the current position of two other chains to generate the step for each chain. For successful sampling, at least `2*d` chains, where `d` is the number of parameters, must be run in parallel. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, message = FALSE) @@ -513,7 +508,7 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DE", settings = setting plot(out) ``` -The second is the Differential Evolution MCMC with snooker update and sampling from past states, according to ter Braak, Cajo JF, and Jasper A. Vrugt. "Differential Evolution Markov Chain with Snooker Updater and Fewer Chains". Statistics and Computing 18.4 (2008): 435-446. This extension covers two differences from the normal `DE` MCMC. First, it uses a snooker update based on a user-defined probability. Second, past states of other chains are taken into account when generating the proposal. These extensions allow fewer chains (i.e., 3 chains are usually sufficient for up to 200 parameters) and parallel computing, since the current position of each chain depends only on the past states of the other chains. +The second is the Differential Evolution MCMC with snooker update and sampling from past states, according to ter Braak, Cajo JF, and Jasper A. Vrugt. "Differential Evolution Markov Chain with Snooker Updater and Fewer Chains". Statistics and Computing 18.4 (2008): 435-446. This extension covers two differences from the normal DE MCMC. First, it uses a snooker update based on a user-defined probability. Second, past states of other chains are taken into account when generating the proposal. These extensions allow fewer chains (i.e., 3 chains are usually sufficient for up to 200 parameters) and parallel computing, since the current position of each chain depends only on the past states of the other chains. ```{r, results = 'hide', eval = F} settings <- list(iterations = iter, message = FALSE) @@ -521,9 +516,9 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DEzs", settings = setti plot(out) ``` -## DREAM sampler +### DREAM sampler -There are two versions of the DREAM `sampler`. First, the standard DREAM sampler, see Vrugt, Jasper A., et al. "Accelerating Markov chain Monte Carlo simulation by differential evolution with self-adaptive randomized subspace sampling". International Journal of Nonlinear Sciences and Numerical Simulation 10.3 (2009): 273-290. +There are two versions of the DREAM sampler. First, the standard DREAM sampler, see Vrugt, Jasper A., et al. "Accelerating Markov chain Monte Carlo simulation by differential evolution with self-adaptive randomized subspace sampling". International Journal of Nonlinear Sciences and Numerical Simulation 10.3 (2009): 273-290. This sampler is largely based on the DE sampler with some significant changes: @@ -547,7 +542,7 @@ out <- runMCMC(bayesianSetup = bayesianSetup, sampler = "DREAMzs", settings = se plot(out) ``` -## T-walk +### T-walk The t-walk is an MCMC algorithm developed by Christen, J. Andrés, and Colin Fox. "A general purpose sampling algorithm for continuous distributions (the t-walk)". Bayesian Analysis 5.2 (2010): 263-281. The sampler uses two independent points to explore the posterior space. Based on probabilities, four different moves are used to generate proposals for the two points. As with the DE sampler, this procedure does not require tuning of the proposal distribution for efficient sampling in complex posterior distributions. From 56ea69544a137f0f00bfffb3f56c98af756eb8bb Mon Sep 17 00:00:00 2001 From: rajoma-02 <70383336+rajoma-02@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:53:36 +0100 Subject: [PATCH 10/10] forgot some `` --- BayesianTools/vignettes/BayesianTools.Rmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BayesianTools/vignettes/BayesianTools.Rmd b/BayesianTools/vignettes/BayesianTools.Rmd index db3e47e..4da582d 100644 --- a/BayesianTools/vignettes/BayesianTools.Rmd +++ b/BayesianTools/vignettes/BayesianTools.Rmd @@ -86,11 +86,11 @@ A more detailed description of the `BayesianSetup` will follow below. After setup, you may want to run a calibration. The `runMCMC` function serves as the main wrapper for all other implemented `MCMC`/`SMC` functions. It always requires the following arguments: -- `bayesianSetup` (alternatively, the log target function) -- `sampler` name -- list with `settings` for each sampler - if `settings` is not specified, the default value will be applied +- bayesianSetup (alternatively, the log target function) +- sampler name +- list with settings for each sampler - if settings is not specified, the default value will be applied -The BT package provides a large class of different MCMC samplers, and it depends on the particular application which one is most suitable. For example, choosing the `sampler` name "Metropolis" calls a versatile Metropolis-type MCMC with options for covariance adjustment, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the later reference on MCMC samplers. When in doubt about the choice of MCMC sampler, we recommend using the default "DEzs". This is also the default in the `runMCMC` function. +The BT package provides a large class of different MCMC samplers, and it depends on the particular application which one is most suitable. For example, choosing `sampler = "Metropolis"` calls a versatile Metropolis-type MCMC with options for covariance adjustment, delayed rejection, tempering and Metropolis-within-Gibbs sampling. For details, see the later reference on MCMC samplers. When in doubt about the choice of MCMC sampler, we recommend using the default "DEzs". This is also the default in the `runMCMC()` function. ```{r} iter = 1000