Just allocate a dense N x 2 matrix and ignore
the entries you don't need. You can encode
the indexes to ignore, or even create an N x 2
matrix of 1 and 0 values to indicate which ones
are included.
If the bivariate distribution is easily marginalized
into univariate distributions, like say a normal,
you'd use those on the observed components. So
that'd be:
vector[2] y[N];
int<lower=0, upper=1> y_observed[N, 2];
for (n in 1:N) {
if (y_observed[n, 1] && y_observed[n, 2])
y[n] ~ multi_normal(mu, Sigma);
else if (y_observed[n, 1])
y[n, 1] ~ normal(mu[1], sqrt(Sigma[1, 1]));
else if (y_observed[n, 2])
y[n, 2] ~ normal(mu[2], sqrt(Sigma[2, 2]));
}
But... that's not very efficient. It's much better
to vectorize all of this. So, in transformed data,
build up three vectors of indices, for the three cases
above:
transformed data {
int ns12[observed_12(y_observed)];
int ns1[observed_1(y_observed)];
int ns2[observed_2(y_observed)];
you need to do this with functions to count because you need to declare
sizes. Then the rest of transformed data just fills (I'm going to
use the syntax about to release in 2.13):
int n12 = 1;
int n1 = 1;
int n2 = 1;
for (n in 1:N) {
if (y_observed[n, 1] && y_observed[n, 2]) {
ns12[n12] = n;
n12 = n12 + 1;
} else if (y_observed[n, 1]) {
ns1[n1] = n;
n1 = n1 + 1;
} else if (y_observed[n, 2]) {
ns2[n2] = n;
n2 = n2 + 1;
}
}
and then, in the model block, everything's nice and vectorizable
using those indexes constructed once in transformed data:
y[ns12] ~ multi_normal(mu, Sigma);
y[ns1] ~ normal(mu[1], sqrt(Sigma[1, 1]));
y[ns2] ~ normal(mu[2], sqrt(Sigma[2, 2]));
This is much more efficient than using latent variables for the
missing data, but requires the multivariate distribution to be marginalized
analytically.
I'll add this discussion to the missing data chapter:
https://github.com/stan-dev/stan/issues/2122#issuecomment-263031536
- Bob