---
title: "User-defined kernels"
author: "George G. Vega Yon"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{User-defined kernels}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse  = TRUE,
  comment   = "#>",
  out.width = "80%",
  warning = FALSE,
  fig.width = 7, fig.height = 5
)
```

## Introduction

One of the most significant benefits of the `fcmc` package is that it
allows creating personalized kernel functions. `fmcmc_kernel` objects are built
with the `kernel_new` function (a function factory) and require (at least) one
parameter, the `proposal` function. In what follows, we show an example where
the user specifies a transition kernel used to estimate an integer parameter,
the `n` parameter of a binomial distribution.

## Size parameter in a binomial distribution

Imagine that we are interested in learning the size of
a population given an observed proportion. In this case, we already
know about the prevalence of a disease. Furthermore, assume that 20\% of the
individuals acquire this disease, and we have a random sample from the population
$y \sim \mbox{Binomial}(0.2, N)$. We don't know $N$.

Such a scenario, while perhaps a bit uncommon, needs special treatment in a
Bayesian/MCMC framework. The parameter to estimate is not continuous, so we would
like to draw samples from a discrete distribution. Using the "normal" (pun
intended) transition kernel may still be able to estimate something but does
not provide us with the correct posterior distribution. In this case, a
transition kernel that makes discrete proposals would be desired.

Let's simulate some data, say, 300 observations from this Binomial random
variable with parameters $p = .2$ and $N = 500$:

```{r dgp}
library(fmcmc)
set.seed(1) # Always set the seed!!!!

# Population parameters
p <- .2
N <- 500

y <- rbinom(300, size = N, prob = p)
```

Our goal is to be able to estimate the parameter $N$. As in any MCMC function,
we need to define the log-likelihood function:

```{r ll}
ll <- function(n., p.) {
  sum(dbinom(y, n., prob = p., log = TRUE))
}
```


Now comes the kernel object. In order to create an `fmcmc_kernel`, we can use
the helper function `kernel_new` as follows:

```{r creating-kernel}
kernel_unif_int <- kernel_new(
    proposal = function(env) env$theta0 + sample(-3:3, 1),
    logratio = function(env) env$f1 - env$f0 # We could have skipped this
    )
```

Here, the kernel is in the form of
$\theta_1 = \theta_0 + R, R\sim \mbox{U}\{-3, ..., 3\}$, this is, proposals are
done by adding a number $R$ drawn from a discrete uniform distribution with
values between -3 and 3. While in this example, we could have skipped the
`logratio` function (as this transition kernel is symmetric), but we defined it
so that the user can see an example of it.[^kernel_new] Let's take a look at the
object:

[^kernel_new]: For more details on what the `env` object contains, see the
manual page of `kernel_new`.


```{r print-kernel}
kernel_unif_int
```

The object itself is an R environment. If we added more parameters to
`kernel_new`, we would have seen those as well. Now that we have our transition
kernel, let's give it a first try with the `MCMC` function.

```{r first-run}
ans <- MCMC(
  ll,                        # The log-likleihood function
  initial = max(y),          # A fair initial guess
  kernel  = kernel_unif_int, # Our new kernel function
  nsteps  = 1000,            # 1,000 MCMC draws
  thin    = 10,              # We will sample every 10
  p.      = p                # Passing extra parameters to be used by `ll`.
  )
```

Notice that for the initial guess, we are using the max of `y', which is a
reasonable starting point (the $N$ parameter MUST be at least the max of `y').
Since the returning object is an object of class `mcmc` from the `coda` R
package, we can use any available method. Let's start by plotting the
chain:

```{r plot1}
plot(ans)
```

As you can see, the trace of the parameter started to go up right away, and then
stayed around 500, the actual population parameter $N$. As the first part of the
chain is useless (we are essentially moving away from the starting point); it is
wise (if not necessary) to start the MCMC chain from the last point of `ans`.
We can easily do so by just passing `ans` as a starting point, since `MCMC`
will automatically take the last value of the chain as the starting point of this
new one. This time, let's increase the sample size as well:

```{r second-run}
ans <- MCMC(
  ll,
  initial = ans,             # MCMC will use tail(ans, 0) automatically
  kernel  = kernel_unif_int, # same as before
  nsteps  = 10000,           # More steps this time
  thin    = 10,              # same as before
  p.      = p                # same as before
)
```

Let's take a look at the posterior distribution:

```{r plot2}
plot(ans)
summary(ans)
table(ans)
```

A very lovely mixing (at least visually) and a posterior distribution from which
we can safely sample parameters.
