Re: [S] Inverse Wishart distrib

John Castelloe (
Thu, 11 Jun 1998 17:40:27 -0500

Bill Venables provided an S-Plus function to generate random Wishart
variates in response to one of my previous questions. I will include the
function at the end of this message.

Suppose V is a covariance matrix on which you want an inverse Wishart
distribution. Suppose also you want V to have _mean_ R and degrees of
freedom d. Then the _inverse_ of V has a Wishart distribution with the
following parameters: degrees of freedom = d, covariance matrix = inverse
of (d*R). So, just generate V-inverse and invert to obtain samples from an
inverse Wishart distribution. In the code below, you would set "df" to d
and "SqrtSigma" to chol(solve(d*R)), the Cholesky decomposition of the
inverse of d*R, and invert the result.

Now, here is Bill Venables code, along with his commentary:

"The following code should generate a single p x p Wishart matrix
realisation with df degrees of freedom. If SqrtSigma is not
specified the parent variance matrix is assumed to be the
identity matrix; if it is specified it must be some matrix
"square root" of the variance matrix, Sigma, e.g. chol(Sigma).
In other words crossprod(SqrtSigma) must be equal to Sigma. (As
this is a big-ticket computation I figured it was better to do it
once outside the function than inside every time.)
Limited testing suggests it is not completely stupid, at any
rate, but that's all. Caveat emptor."

--(cut here)--
rwishart <- function(df, p = nrow(SqrtSigma), SqrtSigma = diag(p)) {
if((Ident <- missing(SqrtSigma)) && missing(p))
stop("either p or SqrtSigma must be specified")
Z <- matrix(0, p, p)
diag(Z) <- sqrt(rchisq(p, df:(df-p+1)))
if(p > 1) {
pseq <- 1:(p-1)
Z[rep(p*pseq, pseq) + unlist(lapply(pseq, seq))] <- rnorm(p*(p-1)/2)
crossprod(Z %*% SqrtSigma)
--(cut here)--

Hope this helps.

| John Castelloe phone: (319)335-2009 |
| Computer RA fax: (319)335-3017 |
| Dept. of Statistics web: |
| University of Iowa office: 269 SH |
This message was distributed by To unsubscribe
send e-mail to with the BODY of the
message: unsubscribe s-news