Here’s a minimal exmple that illustrates my problem (I'm on the rstan development branch):
library(rstan)
m <- stan_model(model_code ='
data {
int<lower = 0, upper = 1> flag;
}
parameters {
real y;
vector[flag ? 1 : 0] phi;
}
model {
if ( flag == 1 ) {
phi ~ normal(10, 0.1);
y ~ normal(phi, 1);
} else if (flag == 0) {
y ~ normal(0, 1);
}
}')
f <- sampling(m, data = list( flag = 1 ))
f
## Inference for Stan model: c8cae5506057d06542f71d41e99c8846.
## 4 chains, each with iter=2000; warmup=1000; thin=1;
## post-warmup draws per chain=1000, total post-warmup draws=4000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
## y 10.01 0.02 0.99 8.12 9.34 9.99 10.65 11.99 3757 1
## phi[1] 10.00 0.00 0.10 9.81 9.94 10.00 10.07 10.20 3024 1
## lp__ -0.96 0.02 0.96 -3.54 -1.33 -0.65 -0.27 -0.02 1578 1
##
## Samples were drawn using NUTS(diag_e) at Tue Oct 22 10:11:13 2019.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
And with flag = 0
f <- sampling(m, data = list( flag = 0 ))
f
## Inference for Stan model: c8cae5506057d06542f71d41e99c8846.
## 4 chains, each with iter=2000; warmup=1000; thin=1;
## post-warmup draws per chain=1000, total post-warmup draws=4000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
## y 0.02 0.03 1.03 -1.99 -0.68 0.02 0.72 1.98 1175 1
## lp__ -0.53 0.02 0.75 -2.58 -0.68 -0.24 -0.06 0.00 1445 1
##
## Samples were drawn using NUTS(diag_e) at Tue Oct 22 10:11:18 2019.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
So far, so good: When flag = 0, phi
is a null-dimensional vector and not included in the output – nor in the as.matrix(f)
GQS part:
First, model is compiled with vector[flag ? 1 : 0] phi;
commented out. Flag will be always 0:
mc <-'
data {
int<lower = 0, upper = 1> flag;
}
parameters {
real y;
// vector[flag ? 1 : 0] phi;
}
generated quantities {
real y_rep;
y_rep = normal_rng(y, 1);
}'
m2 <- stan_model(model_code = mc)
f2 <- rstan::gqs(m2, draws = as.matrix(f), data = list( flag = 0))
f2
## Inference for Stan model: 17e2d78e13de006222877a7663a21f94.
## 1 chains, each with iter=4000; warmup=0; thin=1;
## post-warmup draws per chain=4000, total post-warmup draws=4000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
## y_rep 0.02 0.04 1.46 -2.83 -0.96 0.02 1.03 2.87 1641 1
##
## Samples were drawn using at Tue Oct 22 10:11:25 2019.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
This works because phi
was commented out by hand.
Now, vector[flag ? 1 : 0] phi;
is left in model, flag is still flag = 0
mc <-'
data {
int<lower = 0, upper = 1> flag;
}
parameters {
real y;
vector[flag ? 1 : 0] phi;
}
generated quantities {
real y_rep;
y_rep = normal_rng(y, 1);
}'
m2 <- stan_model(model_code = mc)
## recompiling to avoid crashing R session
Problem:
Now let’s call gqs()
, with flag = 0
f2 <- rstan::gqs(m2, draws = as.matrix(f), data = list( flag = 0))
This returns Exception: Variable phi missing (in 'model49802b31ca9a_ea9a19bd60c8bdb46970b36a506c1c97' at line 7)
The summary indicates that nothing gets evaluated.