data {
int<lower=1> N;
int<lower=1> J;
int<lower=1> Q;
matrix[N, J] data_matrix[Q];
vector[N] data_vector[Q];
}
--
I think in terms of reading data, matrix[N, J] data_matrix[Q] is equivalent to data_matrix[Q, N, J]. We can see this using print statement in Stan.
list_of_matrices <- lapply(1:Q, FUN = function(...) matrix(rnorm(N * J), nrow = N, ncol = J))
data_matrix <- array(NA_real_, dim = c(Q,N,J))
for(q in 1:Q) data_matrix[q,,] <- list_of_matrices[[q]]
vector[N] data_vector[Q];
data { int<lower=1> N; // number of observations per quarter int<lower=1> Q; // number of quarters int<lower=1> J; // number of variables int<lower=1> D; // number of district-seasons // injuries vector[N] traum_injuries[Q]; // log total hours worked vector[N] log_total_hours_worked[Q]; // main covariates: Q quarters of NxJ matrices
matrix[N, J] data_matrix[Q];
// district-season indicators: Q quarters of a Nx(D-1) matrix matrix[N, D-1] district_season[Q];}
parameters { vector[J] beta[Q + 1]; real<lower=-40,upper=20> intercept; vector[D-1] district_season_eff; real<lower=.01, upper=1.4142> sig[J];}
transformed parameters { vector[N] intercept_vector; for (i in 1:N) intercept_vector[i] <- intercept;}
model { // implicit: sig ~ uniform(.01,1.4142); // implicit: intercept ~ uniform(-40,20); beta[1] ~ normal(0,100); district_season_eff ~ normal(0, 1); for(q in 2:(Q + 1)) beta[q] ~ normal(beta[q-1],sig); for (q in 1:Q) { traum_injuries[q] ~ poisson(exp(log_total_hours_worked[q] + intercept_vector + data_matrix[q] * beta[q] + district_season[q] * district_season_eff)); }}
Thanks for all the help. The reason I use vector[N] data_vector[Q] instead of real data_vector[Q,N] or matrix[Q,N] data_vector is because I want to loop through Q column vectors for ease of matrix multiplication later. That is also why I use matrix[N, J] data_matrix[Q] rather than data_matrix[Q,N,J].
for(q in 1:Q) col(matrix,q) ~ something;
But it appears from page 205 of the 1.0.3 reference manual that the poisson distribution is not vectorized yet. Does anyone know if this is on the to-do list, and if so, when it might be done? Are there any work-arounds I should consider?
model {
vector[Q] log_lambda;
...
log_lambda <- intercept + log_total_hours_worked + data_matrix * beta + district_season *
district_season_eff;
lp__ <- lp__ + dot_product(traum_injuries, log_lambda) - sum(exp(log_lambda));
# ignore factorial thing
}
Are there any work-arounds I should consider? Thanks.
model {
beta[1] ~ normal(0,100);district_season_eff ~ normal(0, 1);for(q in 2:(Q + 1))beta[q] ~ normal(beta[q-1],sig);
parameters {
real beta_init;
vector[Q-1] beta_noise;
...
}
transformed parameters {
vector[Q] beta;
beta[1] <- beta_init;
for (q in 2:Q)
beta[q] <- beta[q-1] + beta_noise[q];
}
model {
beta_init ~ normal(0.0, 100.0);
beta_noise ~ normal(0.0, sig);
...
}
On 11/2/12 2:59 PM, Ben Goodrich wrote:
> This is unnecessarily slow, and I believe it will also yield the wrong answer in Stan because you have specified a bunch
> of conditional distributions for the betas whose product is not equal to the joint distribution of the betas.
Why not? Isn't this the usual way to do a time series?
Isn't the joint just as follows:
p(beta[1]) * PROD_{q in 2:(Q+1)} p(beta[q]|beta[q-1])
beta[q] <- beta[q - 1] + sig * beta_noise[q];
data { int<lower=1> N; // number of observations (mines) per quarter
int<lower=1> Q; // number of quarters int<lower=1> J; // number of variables int<lower=1> D; // number of district-seasons // injuries
int<lower=0> traum_injuries[Q,N];
// log total hours worked vector[N] log_total_hours_worked[Q]; // main covariates: Q quarters of NxJ matrices matrix[N, J] data_matrix[Q]; // district-season indicators: Q quarters of a Nx(D-1) matrix matrix[N, D-1] district_season[Q];}
transformed data { vector[N] traum_injuries_vec[Q];
for (i in 1:N)
for (q in 1:Q)
traum_injuries_vec[q,i] <- traum_injuries[q,i];}
parameters { vector[J] beta_init; vector[J] beta_noise[Q];
real<lower=-40,upper=20> intercept; vector[D-1] district_season_eff;
real<lower=.01,upper=1.4142> sig[J];}
transformed parameters { vector[J] sig_vec; vector[J] beta[Q+1]; for (j in 1:J) sig_vec[j] <- sig[j]; beta[1] <- beta_init; for (q in 2:(Q+1)) beta[q] <- beta[q-1] + sig_vec .* beta_noise[q-1];}
model { vector[N] log_lambda;
// implicit: sig ~ uniform(.01,1.4142);
// implicit: intercept ~ uniform(-40.0,20.0); beta_init ~ normal(0.0, 100.0); district_season_eff ~ normal(0.0, 1.0);
for (q in 1:Q) {
beta_noise[q] ~ normal(0.0,1.0); log_lambda <- intercept + log_total_hours_worked[q] + data_matrix[q] * beta[q] + district_season[q] * district_season_eff; lp__ <- lp__ + sum(traum_injuries_vec[q] .* log_lambda) - sum(exp(log_lambda)); }}
The code posted below compiled and is running with one chain at 1000 iterations now. However, I don't understand the lp__ stuff conceptually so I'm not sure if the code that I adapted from Ben's reply is correct. Would you mind checking it out for me?
lp__ <- lp__ + whatever;
Ben--