---
title: "Frequently Asked Questions"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Frequently Asked Questions}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(mcmcensemble)
```

## Can estimations go beyond outside the range of the `inits`?

Yes, the `inits` and `inits` control the range of the *initial*
values, but the chain is still allowed to move freely after this initial step,
as shown in the following example.

Please report to the next question to learn how you can specify hard limits for
the chains.

```{r, eval = require("coda")}
## a log-pdf to sample from
p.log <- function(x) {
  B <- 0.03 # controls 'bananacity'
  -x[1]^2 / 200 - 1 / 2 * (x[2] + B * x[1]^2 - 100 * B)^2
}

unif_inits <- data.frame(
  a = runif(10, min = -10, max = -5),
  b = runif(10, min = -10, max = -5)
)

set.seed(20201209)

res1 <- MCMCEnsemble(
  p.log,
  inits = unif_inits,
  max.iter = 3000, n.walkers = 10,
  method = "stretch",
  coda = TRUE
)

summary(res1$samples)
```

```{r, eval = identical(Sys.getenv("IN_PKGDOWN"), "true")}
plot(res1$samples)
```

```{r}
res2 <- MCMCEnsemble(
  p.log,
  inits = unif_inits,
  max.iter = 3000, n.walkers = 10,
  method = "differential.evolution",
  coda = TRUE
)

summary(res2$samples)
```

```{r, eval = identical(Sys.getenv("IN_PKGDOWN"), "true")}
plot(res2$samples)
```

## How to restrict the possible parameter range?

There is no built-in way to define hard limits for the parameter and make sure
they never go outside of this range.

The recommended way to address this issue is to handle these cases in the
function `f` you provide.

For example, to keep parameters in the 0-1 range:

```{r}
p.log.restricted <- function(x) {

  if (any(x < 0, x > 1)) {
    return(-Inf)
  }

  B <- 0.03 # controls 'bananacity'
  -x[1]^2 / 200 - 1 / 2 * (x[2] + B * x[1]^2 - 100 * B)^2
}

unif_inits <- data.frame(
  a = runif(10, min = 0, max = 1),
  b = runif(10, min = 0, max = 1)
)

res <- MCMCEnsemble(
  p.log.restricted,
  inits = unif_inits,
  max.iter = 3000, n.walkers = 10,
  method = "stretch",
  coda = TRUE
)
summary(res$samples)
```

```{r, eval = identical(Sys.getenv("IN_PKGDOWN"), "true")}
plot(res$samples)
```

This might seem inconvenient but in most cases, users will define their posterior probability as the product of a prior probability
and the likelihood. In this situation, values that are not contained in the log-prior density automatically return `-Inf` in the log-posterior and it is not necessary to define it explicitly:

```{r}
prior.log <- function(x) {
 dunif(x, log = TRUE)
}

lkl.log <- function(x) {
  B <- 0.03 # controls 'bananacity'
  -x[1]^2 / 200 - 1 / 2 * (x[2] + B * x[1]^2 - 100 * B)^2
}

posterior.log <- function(x) {
  sum(prior.log(x)) + lkl.log(x)
}

res <- MCMCEnsemble(
  posterior.log,
  inits = unif_inits,
  max.iter = 5000, n.walkers = 10,
  method = "stretch",
  coda = TRUE
)
summary(res$samples)
```

```{r, eval = identical(Sys.getenv("IN_PKGDOWN"), "true")}
plot(res$samples)
```
