I’m working on a multilevel logistic regression model with missing binary response data. Everything works fine with a single random intercept, but when I try to add a random slope, I get the below compilation error. I’m having a lot of difficulty debugging as it’s unclear to me whether it’s a compiler issue or an error in my Stan code.
The error message
In file included from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/BH/include/boost/config.hpp:39:0,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/BH/include/boost/math/tools/config.hpp:13,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/core/var.hpp:7,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/core/gevv_vvv_vari.hpp:5,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/core.hpp:12,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/mat.hpp:4,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math.hpp:4,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/src/stan/model/model_header.hpp:4,
from file602c70c0cf.cpp:8:
/home/rsb/R/x86_64-pc-linux-gnu-library/3.4/BH/include/boost/config/compiler/gcc.hpp:186:0: warning: "BOOST_NO_CXX11_RVALUE_REFERENCES" redefined
# define BOOST_NO_CXX11_RVALUE_REFERENCES
^
<command-line>:0:0: note: this is the location of the previous definition
In file included from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/arr/fun/promote_elements.hpp:4:0,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/mat/fun/promote_elements.hpp:4,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/mat/fun/promote_common.hpp:5,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/mat/fun/mdivide_left.hpp:6,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/mat.hpp:149,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/mat.hpp:12,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math.hpp:4,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/src/stan/model/model_header.hpp:4,
from file602c70c0cf.cpp:8:
/home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/scal/fun/promote_elements.hpp: In instantiation of ‘static T stan::math::promote_elements<T, S>::promote(const S&) [with T = double; S = stan::math::var]’:
/home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/arr/fun/array_builder.hpp:37:53: required from ‘stan::math::array_builder<T>& stan::math::array_builder<T>::add(const S&) [with S = stan::math::var; T = double]’
file602c70c0cf.cpp:473:94: required from ‘T__ model602c410cb45f_dichotomousMissing_namespace::model602c410cb45f_dichotomousMissing::log_prob(std::vector<T2>&, std::vector<int>&, std::ostream*) const [with bool propto__ = true; bool jacobian__ = true; T__ = stan::math::var; std::ostream = std::basic_ostream<char>]’
/home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/src/stan/model/log_prob_grad.hpp:45:39: required from ‘double stan::model::log_prob_grad(const M&, std::vector<double>&, std::vector<int>&, std::vector<double>&, std::ostream*) [with bool propto = true; bool jacobian_adjust_transform = true; M = model602c410cb45f_dichotomousMissing_namespace::model602c410cb45f_dichotomousMissing; std::ostream = std::basic_ostream<char>]’
/home/rsb/R/x86_64-pc-linux-gnu-library/3.4/rstan/include/rstan/stan_fit.hpp:1164:49: required from ‘SEXPREC* rstan::stan_fit<Model, RNG_t>::grad_log_prob(SEXP, SEXP) [with Model = model602c410cb45f_dichotomousMissing_namespace::model602c410cb45f_dichotomousMissing; RNG_t = boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014u, 0u, 2147483563u>, boost::random::linear_congruential_engine<unsigned int, 40692u, 0u, 2147483399u> >; SEXP = SEXPREC*]’
file602c70c0cf.cpp:848:0: required from here
/home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/prim/scal/fun/promote_elements.hpp:24:16: error: cannot convert ‘const stan::math::var’ to ‘double’ in return
return u;
^
cc1plus: warning: unrecognized command line option ‘-Wno-ignored-attributes’
cc1plus: warning: unrecognized command line option ‘-Wno-macro-redefined’
make: *** [file602c70c0cf.o] Error 1
ERROR(s) during compilation: source code errors or compiler configuration errors!
.... lots of cpp ....
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created! In file included from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/BH/include/boost/config.hpp:39:0,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/BH/include/boost/math/tools/config.hpp:13,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/core/var.hpp:7,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/core/gevv_vvv_vari.hpp:5,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/core.hpp:12,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math/rev/mat.hpp:4,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/stan/math.hpp:4,
from /home/rsb/R/x86_64-pc-linux-gnu-library/3.4/StanHeaders/include/src/stan/model/model_header.hpp:4,
from file602c7309332
In addition: Warning message:
running command '/usr/lib/R/bin/R CMD SHLIB file602c73093324.cpp 2> file602c73093324.cpp.err.txt' had status 1
The Stan code that doesn’t work (with random intercept and random slope):
data {
int<lower=1> N; // # of total observations of predictors
int<lower=0> P; // # of covariates with fixed effects
int<lower=1> D; // # of levels of sample
int sample[N]; // sample indicator
int<lower=0,upper=1> y[N]; // outcome
row_vector[P] x[N]; // covariates
real z[N]; // covariate with random slope
int<lower=0,upper=1> attrited[N];// indictor of missingness of response
}
parameters {
real a; // fixed intercept
vector[P] bCov; // fixed effect slopes
vector[D] alpha; // random intercept
vector[D] bRandom; // random slope
cov_matrix[2] Sigma; // random effect vcov mat
// real<lower=0> varAlpha; // random intercept variance
// real<lower=0> varBRandom; // random slope variance
// real<lower=0> covAB; // random slope / random intercept covariance
// vector[2] mu;
}
transformed parameters {
// matrix[2,2] Sigma = [[varAlpha,covAB],[covAB,varBRandom]];
vector<lower=0, upper=1>[N] pi; // probability of outcome
for (j in 1:N) { // logistic function:
pi[j] = 1/(1+exp(-(a + alpha[sample[j]] + x[j]*bCov + z[j]*bRandom[sample[j]])));
}
}
model {
/////// PRIORS ///////
a ~ normal(0,5);
// varAlpha ~ normal(0,5);
// covAB ~ normal(0,5);
// varBRandom ~ normal(0,5);
// mu[1] ~ normal(0,5);
// mu[2] ~ normal(0,5);
for (d in 1:D) { // joint distribution of random effects:
[alpha[d], bRandom[d]]' ~ multi_normal([0,0]',Sigma);
}
for (p in 1:P) {
bCov[p] ~ normal(0,10);
}
////// LIKELIHOOD //////
for (j in 1:N) {
real lp;
if (attrited[j] == 0) {
lp = bernoulli_lpmf( y[j] | pi[j]);
}
else {
real tmp[2];
tmp[1] = bernoulli_lpmf(1 | pi[j]);
tmp[2] = bernoulli_lpmf(0 | pi[j]);
lp = log_mix(pi[j], tmp[1], tmp[2]);
}
target += lp;
}
}
The Stan code that does work (with random intercept only):
data {
int<lower=1> N; // # total observations of predictors
int<lower=0> P; // # covariates
int<lower=1> D; // # levels of sample
int sample[N]; // sample indicator
int<lower=0,upper=1> y[N]; // outcome
row_vector[P] x[N]; // covariates
int<lower=0,upper=1> attrited[N];// indictor of missingness
}
parameters {
real a; // fixed intercept
vector[P] bCov; // fixed effect slopes
real alpha[D]; // random intercept
real<lower=0> sigma; // random intercept variance
}
transformed parameters {
vector<lower=0, upper=1>[N] pi; // probability of arrest
for (j in 1:N) { // logistic function
pi[j] = 1/(1+exp(-(a + alpha[sample[j]] + x[j]*bCov)));
}
}
model {
////// PRIORS
a ~ normal(0,5);
sigma ~ normal(0,5);
for (d in 1:D) {
alpha[d] ~ normal(0,sigma);
}
for (p in 1:P) {
bCov[p] ~ normal(0,10);
}
////// Likelihood
for (j in 1:N) {
real lp;
if (attrited[j] == 0) {
lp = bernoulli_lpmf( y[j] | pi[j]);
}
else {
real tmp[2];
tmp[1] = bernoulli_lpmf(1 | pi[j]);
tmp[2] = bernoulli_lpmf(0 | pi[j]);
lp = log_mix(pi[j], tmp[1], tmp[2]);
}
target += lp;
}
}
And, for ease of readability, here are
The differences between the working code and the broken code by block:
Data - added new variable:
real z[N]; // covariate with random slope
Parameters - replaced:
real a; // fixed intercept
vector[P] bCov; // fixed effect slopes
real alpha[D]; // random intercept
real<lower=0> sigma; // random intercept variance
with
real a; // fixed intercept
vector[P] bCov; // fixed effect slopes
vector[D] alpha; // random intercept
vector[D] bRandom; // random slope
cov_matrix[2] Sigma; // random effect vcov mat
Transformed parameters - add random slope term to linear predictor.
From:
vector<lower=0, upper=1>[N] pi; // probability of outcome
for (j in 1:N) { // logistic function
pi[j] = 1/(1+exp(-(a + alpha[sample[j]] + x[j]*bCov)));
}
To:
vector<lower=0, upper=1>[N] pi; // probability of outcome
for (j in 1:N) { // logistic function:
pi[j] = 1/(1+exp(-(a + alpha[sample[j]] + x[j]*bCov + z[j]*bRandom[sample[j]])));
}
Model - model joint distribution of random intercept and random slope term as multivariate normal:
From:
a ~ normal(0,5);
sigma ~ normal(0,5);
for (d in 1:D) {
alpha[d] ~ normal(0,sigma);
}
To:
for (d in 1:D) { // joint distribution of random effects:
[alpha[d], bRandom[d]]' ~ multi_normal([0,0]',Sigma);
}
Any advice you have would be greatly appreciated! Thank you!