[dfe06d]: / src / priors.cpp

Download this file

159 lines (97 with data), 4.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <Rcpp.h>
#include <Rmath.h>
#include "internals.h"
// ON WHEN THESE ARE USED
// These functions implement various default priors. The alternative to these
// defaults is using user-specified closures, which only take one parameter
// 'param', and have prior parameters enclosed or hard-coded. If user-specified
// functions are using C/C++ code, we strongly recommend using the native R API
// to distribution functions. For a list of available distributions, see:
// https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Distribution-functions
// ON THE USE OF CLOSURES
// User-specified prior functions are R closures which contain the prior
// parameters, so that the evaluation of the prior is simple and takes a single
// argument 'param'. On the C++ side, using closures would add unwanted
// complexity to the code. Besides, closures would have to be created within the
// movement functions, i.e. every time they are called. Therefore, the C++
// priors used by default are not closures, and take three arguments:
// - param: a Rcpp:List containing parameters
// - config: a Rcpp:List containing parameters for the priors in
// config["prior_xxx"] where 'xxx' is the name of the relevant parameter
// - custom_function: an optional custom prior function (closure); if NULL
// (i.e. R_NilValue in C++) then the basic functions are used
// The prior for the mutation rate 'mu' is an exponential distribution
// [[Rcpp::export(rng = false)]]
double cpp_prior_mu(Rcpp::List param, Rcpp::List config,
Rcpp::RObject custom_function = R_NilValue) {
if (custom_function == R_NilValue) {
// note: R::dexp is parametrised by scale, not rate
double scale = 1.0 / Rcpp::as<double>(config["prior_mu"]);
return R::dexp(Rcpp::as<double>(param["mu"]), scale, true);
} else {
Rcpp::Function f = Rcpp::as<Rcpp::Function>(custom_function);
return Rcpp::as<double>(f(param));
}
}
// The prior for the reporting probability 'pi' is a beta distribution
// [[Rcpp::export(rng = false)]]
double cpp_prior_pi(Rcpp::List param, Rcpp::List config,
Rcpp::RObject custom_function = R_NilValue) {
if (custom_function == R_NilValue) {
Rcpp::NumericVector shape = config["prior_pi"];
return R::dbeta(Rcpp::as<double>(param["pi"]),
(double) shape[0],
(double) shape[1],
true);
} else {
Rcpp::Function f = Rcpp::as<Rcpp::Function>(custom_function);
return Rcpp::as<double>(f(param));
}
}
// The prior for the contact reporting coverage 'eps' is a beta distribution
// [[Rcpp::export(rng = false)]]
double cpp_prior_eps(Rcpp::List param, Rcpp::List config,
Rcpp::RObject custom_function = R_NilValue) {
if (custom_function == R_NilValue) {
Rcpp::NumericVector shape = config["prior_eps"];
return R::dbeta(Rcpp::as<double>(param["eps"]),
(double) shape[0],
(double) shape[1],
true);
} else {
Rcpp::Function f = Rcpp::as<Rcpp::Function>(custom_function);
return Rcpp::as<double>(f(param));
}
}
// The prior for the non-transmision contact rate 'lambda' is a beta distribution
// [[Rcpp::export(rng = false)]]
double cpp_prior_lambda(Rcpp::List param, Rcpp::List config,
Rcpp::RObject custom_function = R_NilValue) {
if (custom_function == R_NilValue) {
Rcpp::NumericVector shape = config["prior_lambda"];
return R::dbeta(Rcpp::as<double>(param["lambda"]),
(double) shape[0],
(double) shape[1],
true);
} else {
Rcpp::Function f = Rcpp::as<Rcpp::Function>(custom_function);
return Rcpp::as<double>(f(param));
}
}
// [[Rcpp::export(rng = false)]]
double cpp_prior_all(Rcpp::List param, Rcpp::List config,
Rcpp::RObject custom_functions = R_NilValue
) {
if (custom_functions == R_NilValue) {
return cpp_prior_mu(param, config) +
cpp_prior_pi(param, config) +
cpp_prior_eps(param, config) +
cpp_prior_lambda(param, config);
} else {
Rcpp::List list_functions = Rcpp::as<Rcpp::List>(custom_functions);
return cpp_prior_mu(param, config, list_functions["mu"]) +
cpp_prior_pi(param, config, list_functions["pi"]) +
cpp_prior_eps(param, config, list_functions["eps"]) +
cpp_prior_lambda(param, config, list_functions["lambda"]);
}
}