Helpful Stan Functions
Normal Copula Functions

Functions

real normal_copula_lpdf (real u, real v, real rho)
 
real normal_copula_vector_lpdf (vector u, vector v, real rho)
 
real bivariate_normal_copula_cdf (real u, real v, real rho)
 
real multi_normal_cholesky_copula_lpdf (matrix U, matrix L)
 

Detailed Description

The normal copula is an elliptical copula over the unit cube \([0,\,1]^d \).

real normal_copula_lpdf(real u, real v, real rho) {
real rho_sq = square(rho);
return (0.5 * rho * (-2. * u * v + square(u) * rho + square(v) * rho)) / (-1. + rho_sq)
- 0.5 * log1m(rho_sq);
}
real normal_copula_vector_lpdf(vector u, vector v, real rho) {
int N = num_elements(u);
real rho_sq = square(rho);
real a1 = 0.5 * rho;
real a2 = rho_sq - 1;
real a3 = 0.5 * log1m(rho_sq);
real x = -2 * u' * v + rho * (dot_self(u) + dot_self(v));
return a1 * x / a2 - N * a3;
}
real bivariate_normal_copula_cdf(real u, real v, real rho) {
real a = 1 / sqrt(1 - square(rho));
real avg_uv = mean([u, v]);
real pu = inv_Phi(u);
real pv = inv_Phi(v);
real alpha_u = a * (pv / pu - rho);
real alpha_v = a * (pu / pv - rho);
real d = 0;
if (v == 0.5 || u == 0.5 && v != u) {
real x = u == 0.5 ? v : u;
if (rho < 0)
return 0.5 * bivariate_normal_copula_cdf(x | x, 1 - 2 * rho ^ 2);
else
return u - 0.5 * bivariate_normal_copula_cdf(x | x, 1 - 2 * rho ^ 2);
}
if (v == u)
return u - 2 * owens_t(inv_Phi(u), sqrt((1 - rho) / (1 + rho)));
if (u < 0.5 && v >= 0.5 || u >= 0.5 && v < 0.5)
d = 0.5;
return avg_uv - owens_t(pu, alpha_u) - owens_t(pv, alpha_v) - d;
}
real multi_normal_cholesky_copula_lpdf(matrix U, matrix L) {
int N = rows(U);
int J = cols(U);
matrix[J, J] Gammainv = chol2inv(L);
return -N * sum(log(diagonal(L))) - 0.5 * sum(add_diag(Gammainv, -1.0) .* crossprod(U));
}
real normal_copula_vector_lpdf(vector u, vector v, real rho)
Definition: normal_copula.stanfunctions:52
real normal_copula_lpdf(real u, real v, real rho)
Definition: normal_copula.stanfunctions:31

Function Documentation

◆ bivariate_normal_copula_cdf()

real bivariate_normal_copula_cdf ( real  u,
real  v,
real  rho 
)

Bivariate Normal Copula cdf

Meyer, Christian. "The Bivariate Normal Copula."
arXiv preprint arXiv:0912.2816 (2009). Eqn 3.11.
accessed Feb. 6, 2021.

Parameters
uVector size 2
rhoReal on (-1, 1)
Returns
cumulative density

◆ multi_normal_cholesky_copula_lpdf()

real multi_normal_cholesky_copula_lpdf ( matrix  U,
matrix  L 
)

Multivariate Normal Copula log density (Cholesky parameterisation)

\begin{aligned} c(\mathbf{u}) &= \frac{\partial^d C}{\partial \mathbf{\Phi_1}\cdots \partial \mathbf{\Phi_d}} \\ &= \prod_{i=1}^{n} \lvert \Sigma \rvert^{-1/2} \exp \left\{-\frac{1}{2} \begin{pmatrix} \mathbf{\Phi}^{-1}(u_1) \\ \vdots \\ \mathbf{\Phi}^{-1}(u_d) \end{pmatrix}^T (\Sigma^{-1} - I) \begin{pmatrix} \mathbf{\Phi}^{-1}(u_1) \\ \vdots \\ \mathbf{\Phi}^{-1}(u_d) \end{pmatrix} \right\} \\ &= \lvert \Sigma \rvert^{-n/2} \exp\left\{ -\frac{1}{2} \text{tr}\left( \left[ \Sigma^{-1} - I \right] \sum_{i=1}^n \Phi^{-1}(u_i) \Phi^{-1}(u_i)' \right) \right\} \hspace{0.5cm} \\ &= \lvert L \rvert^{-n} \exp\left\{ -\frac{1}{2} \text{tr}\left( \left[ L^{-T}L^{-1}- I \right] Q'Q \right) \right\} \\ &= \lvert L \rvert^{-n} \exp\left\{ -\frac{1}{2} \sum_{j=1}^{d}\sum_{i=1}^{n} \left( \left[ L^{-T}L^{-1}- I \right] \odot Q'Q \right) \right\} \\ \end{aligned}

where

\[ Q_{n \times d} = \begin{pmatrix} \mathbf{\Phi}^{-1}(u_1) \\ \vdots \\ \mathbf{\Phi}^{-1}(u_d) \end{pmatrix} \]

and \( \odot \) is the elementwise multiplication operator.
Note that \(\det \Sigma = |LL^T| = |L |^2 = \big(\prod_{i=1}^d L_{i,i}\big)^2\) so \(\sqrt{\det \Sigma} = \prod_{i=1}^d L_{i,i}\).

Parameters
UMatrix of outcomes from marginal calculations
LCholesky factor of the correlation/covariance matrix
Returns
log density of distribution

◆ normal_copula_lpdf()

real normal_copula_lpdf ( real  u,
real  v,
real  rho 
)

Normal copula log density

\[ c(u,\,v;\, \rho) = \frac{1}{\sqrt{1 - \rho^2}} \exp \bigg( \frac{2\rho \Phi^{-1}(u) \Phi^{-1}(v) - \rho^2 (\Phi^{-1}(u)^2 + \Phi^{-1}(v)^2)}{2 (1 - \rho^2)}\bigg) \]

Meyer, Christian. "The Bivariate Normal Copula."
arXiv preprint arXiv:0912.2816 (2009). Eqn 3.3.
accessed Feb. 6, 2021.

Parameters
uReal number on (0,1], not checked but function will return NaN
vReal number on (0,1], not checked but function will return NaN
rhoReal number (-1, 1)
Returns
log density

◆ normal_copula_vector_lpdf()

real normal_copula_vector_lpdf ( vector  u,
vector  v,
real  rho 
)

Normal copula log density vectorized

Meyer, Christian. "The Bivariate Normal Copula."
arXiv preprint arXiv:0912.2816 (2009). Eqn 3.3.
accessed Feb. 6, 2021.

Parameters
uReal number on (0,1], not checked but function will return NaN
vReal number on (0,1], not checked but function will return NaN
rhoReal number (-1, 1)
Returns
log density