Diff of /src/priors.cpp [000000] .. [dfe06d]

Switch to unified view

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