I got a more informative error when compiling under Linux:
Error in compileCode(f, code, language = language, verbose = verbose) :
| ^~~~~~~~~~~~/home/andrew/R/x86_64-pc-linux-gnu-library/4.0/StanHeaders/include/stan/math/rev/arr/functor/integrate_1d.hpp:119:41: note: template argument deduction/substitution failed:file13a16cf9dbb7.cpp:110:51: note: cannot convert ‘stan::math::array_builder<T>::array() [with T = stan::math::var]()’ (type ‘std::vector<stan::math::var>’) to type ‘const std::vector<double>&’ 110 | stan::math::assign(delta_part,integrate_1d(expected_delta_part_functor__(), stan::math::negative_infinity(), stan::math::positive_infinity(), static_cast<std::vector<local_scalar_t__> >(stan::math::array_builder<local_scalar_t__ >().add(w).add(u_sd).array()), static_cast<std::vector<local_scalar_t__> >(stan::math::array_builder<local_scalar_t__ >().add(0.0).array()), static_cast<std::vector<int> >(stan::math::array_builder<int >().add(0).array()), *pstream__, 0.01)); |
After a bit of digging, it turns out this wasn’t due to a bug in the Math library, it’s the Stanc transpiler. RStan still uses the Stanc2 transpiler, which is the original (and now deprecated) method for translating Stan code to c++ to be compiled. cmdstanr
uses Stanc3, which is the new method (that RStan will use in the next update, I believe).
For some reason Stanc2 has some errors with it how it handles typing with integrate_1d
. For those interested you can replicate this error using cmdstan 2.25 with the STANC2=TRUE
flag, and the model:
functions {
real expected_delta_part(real v, real xc, real[] theta, data real[] x_r, data int[] x_i) {
real w = theta[1];
real u_sd = theta[2];
return v * exp(normal_lcdf(w - v | 0, u_sd) + normal_lpdf(v | 0, 1));
}
real expected_delta(real w, real u_sd) {
real delta_part = integrate_1d(expected_delta_part, negative_infinity(), positive_infinity(), { w, u_sd }, { 0.0 }, { 0 }, 0.01);
real F_w = Phi_approx(w / u_sd);
return - delta_part / (F_w * (1 - F_w));
}
}
data {
real y_mean;
}
parameters {
real y;
}
transformed parameters {
real test_comp = expected_delta(y, y);
}
model {
y ~ normal(y_mean, 1);
}