-
-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FR: Matrix inputs to multi_normal_* #937
Comments
Yes I agree! I have an issue in Stan math about this as well and @adamhaber is currently working on this |
@mike-lawrence: I totally feel your pain here. Part of this (array of vector vs. matrix) is due to an original bad design decision I made to give those different memory representations. Given that, I think the easiest thing to do now is write transform functions then the use of them won't get in the way of reading the program as much as new variable decls and loops. Here's a version I refactored to use functions (and also remove the comments and reformat so I could more easily read). I didn't test, so use with caution! functions {
matrix to_mat(array[] row_vector x) {
matrix[x.size(), rows(x[1])] y;
for (i in 1:x.size())
y[i, ] = x[i];
return y;
}
array[] row_vector to_arr_rowvec(matrix x) {
array[x.rows()] row_vector[x.cols()] y;
for (i in 1:y.size())
y[i] = x.row(i);
return y;
}
}
data {
int<lower=2> nXg;
int<lower=nXg> rXg;
matrix[rXg, nXg] Xg;
int<lower=nXg> nI;
array[nI] int<lower=1, upper=rXg> iXg;
int<lower=2> nXq;
int<lower=nXq> rXq;
matrix[rXq,nXq] Xq;
array[rXq] int<lower=1, upper=nI> iXq;
int<lower=nXg * nXq * nI> nY;
vector[nY] Y;
array[nY] int<lower=1, upper=rXq> yXq;
}
parameters {
real<lower=0> Y_sd;
matrix[nXg, nXq] Z;
vector<lower=0>[nXq] iZq_sd;
cholesky_factor_corr[nXq] iZq_cholcorr;
array[nI] row_vector[nXq] iZq;
}
model {
to_vector(Z) ~ std_normal();
matrix[rXg,nXq] gZq;
for (this_nXq in 1:nXq)
gZq[ , this_nXq]
= rows_dot_product(rep_matrix(to_row_vector(Z[ , this_nXq]),
rXg),
Xg);
iZq_sd ~ std_normal();
iZq_cholcorr ~ lkj_corr_cholesky(1);
iZq ~ multi_normal_cholesky(to_arr_rowvec(gZq)[iXg],
diag_pre_multiply(iZq_sd, iZq_cholcorr));
Y_sd ~ weibull(2,1);
Y ~ normal(rows_dot_product(to_mat(iZq)[iXq], Xq)[yXq], Y_sd);
} The most efficient way to do this is going to depend a lot on what all those indexing arrays of integers look like ( A quick improvement would be to make I'm tempted to define |
It would be really nice to have signatures for the multi_normal_* family that accept matrix inputs for at least the data and means arguments, possibly with a new argument that designates whether they should be treated as row-wise or column-wise manner. For example, see below for a centered-parameterized hierarchical model (of the same core structure as SUG1.13), where I currently have to do two format conversions, one to convert a matrix to an array of row-vectors for input to multi_normal_cholesky, then another conversion of the first argument to a matrix for use with rows_dot_product. The latter is made easier by #931, but it would be nice to skip it altogether.
The text was updated successfully, but these errors were encountered: