We aren’t planning to add a multivariate CDF any time soon—nobody knows how to calculate it. But we may be adding a bivariate case. Until then, you can just implement it as a Stan function. The issue to track it is here:
opened 03:41PM - 14 Jul 17 UTC
feature
new function
good first issue
#### Summary:
Add a function to compute the bivariate normal cdf.
#### D… escription:
For size 2 vectors `y` and `mu` and 2 x 2 covariance matrix `Sigma`, compute
```
bivar_normal_cdf(y, mu, Sigma)
= INT_{u < y} multinormal_pdf(u, mu, Sigma) d.u
```
where `u` is also a 2-vector and `u < y` is defined componentwise as `u[1] < y[1] && u[2] < y[2]`.
There could also be a parameterization where covariance is given in terms of two scale parameters and a correlation parameter.
### Additional Info:
This paper is often cited for an algorithm:
* Boys, R.J., 1989. Algorithm AS R80: A remark on Algorithm AS 76: An integral useful in calculating noncentral t and bivariate normal probabilities. Journal of the Royal Statistical Society. Series C (Applied Statistics), 38(3), pp.580-582. https://www.jstor.org/stable/2347755
#### Current Version:
v2.16.0
and here’s @bgoodri ’s comment with Stan code:
opened 03:41PM - 14 Jul 17 UTC
feature
new function
good first issue
#### Summary:
Add a function to compute the bivariate normal cdf.
#### D… escription:
For size 2 vectors `y` and `mu` and 2 x 2 covariance matrix `Sigma`, compute
```
bivar_normal_cdf(y, mu, Sigma)
= INT_{u < y} multinormal_pdf(u, mu, Sigma) d.u
```
where `u` is also a 2-vector and `u < y` is defined componentwise as `u[1] < y[1] && u[2] < y[2]`.
There could also be a parameterization where covariance is given in terms of two scale parameters and a correlation parameter.
### Additional Info:
This paper is often cited for an algorithm:
* Boys, R.J., 1989. Algorithm AS R80: A remark on Algorithm AS 76: An integral useful in calculating noncentral t and bivariate normal probabilities. Journal of the Royal Statistical Society. Series C (Applied Statistics), 38(3), pp.580-582. https://www.jstor.org/stable/2347755
#### Current Version:
v2.16.0
Those links are super-confusing given that they just summarize the issue, not what’s being linked, so I’ll add the actual code from @bgoodri :
real binormal_cdf(real z1, real z2, real rho) {
if (z1 != 0 || z2 != 0) {
real denom = fabs(rho) < 1.0 ? sqrt((1 + rho) * (1 - rho)) : not_a_number();
real a1 = (z2 / z1 - rho) / denom;
real a2 = (z1 / z2 - rho) / denom;
real product = z1 * z2;
real delta = product < 0 || (product == 0 && (z1 + z2) < 0);
return 0.5 * (Phi(z1) + Phi(z2) - delta) - owens_t(z1, a1) - owens_t(z2, a2);
}
return 0.25 + asin(rho) / (2 * pi());
}