I am a first-time rstan/Stan user trying to set up a custom likelihood and integrate it using integrate_1d
. Based on the documentation, I set up my integrand function as follows:
// internal function to integrate over z
// integrate_1d is super picky: the argument types need to be real, real,
real[], real[], int[]
// e.g., cannot use vectors in place of real[] or int[]
real integrand( real x, // the observed Z-stat; value at which to evaluate integral
real xc,
real[] theta,
real[] x_r,
int[] x_i ){
// separate the parameters
real zeta = theta[1];
real eta = theta[2];
real vi = theta[3];
// significance indicator
int signif;
signif = fabs(x) > 1.96;
return( (1/eta) * (1 - signif) + signif ) * exp( normal_lpdf( x | zeta, sqrt(vi) ) );
}
I am trying to test and debug this function because it ultimately causes errors in evaluating the log-likelihood when I run my model. To this end, I want to be able to run the function interactively, passing arguments of my own choosing. I am trying to use rstan's expose_stan_functions
to do this:
code = "functions{
real integrand( real x, // the observed Z-stat
real xc,
real[] theta,
real[] x_r,
int[] x_i ){
// separate the parameters
real zeta = theta[1];
real eta = theta[2];
real vi = theta[3];
// significance indicator
int signif;
signif = fabs(x) > 1.96;
return( (1/eta) * (1 - signif) + signif ) * exp( normal_lpdf( x | zeta, sqrt(vi) ) );
}
}"
expose_stan_functions(stanc(model_code = code))
integrand(1, {1,1,1}, real[], int[], 1e-8)
integrate_1d( integrand, negative_infinity(), positive_infinity(), {1, 1, 1}, real[], int[], 1e-8 )
but the calls to integrand
and integrate_1d
each throw error
Error: unexpected ','
as if I am calling the functions with fundamentally incorrect syntax. (In the call to integrate_1d
, I wasn't quite sure what to do about xc
. I omitted it because the documentation (Section 9.3.2.4) seems to suggest it should be NaN
for an indefinite integral.)
I also welcome completely different suggestions for interactively debugging integrand
if expose_stan_functions
is not the ideal way to go.
The integrate_1d
function is a Stan / C++ function, so if you want to call it from R, you need to specify another function that calls it. In your case, you could do
code = "functions{
real integrand( real x, // the observed Z-stat
real xc,
real[] theta,
real[] x_r,
int[] x_i ){
// separate the parameters
real zeta = theta[1];
real eta = theta[2];
real vi = theta[3];
// significance indicator
int signif;
signif = fabs(x) > 1.96;
return( (1/eta) * (1 - signif) + signif ) * exp( normal_lpdf( x | zeta, sqrt(vi) ) );
}
real area(real[] theta, data real[] x_r) {
int x_i[0];
return integrate_1d(integrand, negative_infinity(), positive_infinity(),
theta, x_r, x_i, 1e-8);
}
}"
library(rstan)
expose_stan_functions(stanc(model_code = code))
area(theta = rep(1, 3), x_r = double()) # yields 1