RNMVGC

Given a Cholesky factorization of a correlation matrix, generates pseudorandom numbers from a Gaussian Copula distribution.

Required Arguments

CHOL — Array of size n by n containing the upper‑triangular Cholesky factorization of the correlation matrix of order n where n = size(CHOL,1). (Input)

R — Array of length n containing the pseudorandom numbers from a multivariate Gaussian Copula distribution. (Output)

FORTRAN 90 Interface

Generic: RNMVGC (CHOL, R)

Specific: The specific interface names are S_RNMVGC and D_RNMVGC.

Description

RNMVGC generates pseudorandom numbers from a multivariate Gaussian Copula distribution which are uniformly distributed on the interval (0,1) representing the probabilities associated with standard normal N(0,1) deviates imprinted with correlation information from input upper‑triangular Cholesky matrix CHOL. Cholesky matrix CHOL is defined as the “square root” of a user‑defined correlation matrix, that is CHOL is an upper triangular matrix such that the transpose of CHOL times CHOL is the correlation matrix. First, a length n array of independent random normal deviates with mean 0 and variance 1 is generated, and then this deviate array is post‑multiplied by Cholesky matrix CHOL. Finally, the Cholesky‑imprinted random N(0,1) deviates are mapped to output probabilities using the N(0,1) cumulative distribution function (CDF).

Random deviates from arbitrary marginal distributions which are imprinted with the correlation information contained in Cholesky matrix CHOL can then be generated by inverting the output probabilities using user‑specified inverse CDF functions.

Example: Using Copulas to Imprint and Extract Correlation Information

This example uses subroutine RNMVGC to generate a multivariate sequence gcdevt whose marginal distributions are user‑defined and imprinted with a user‑specified input correlation matrix corrin and then uses subroutine CANCOR to extract an output canonical correlation matrix corrout from this multivariate random sequence.

This example illustrates two useful copula related procedures. The first procedure generates a random multivariate sequence with arbitrary user‑defined marginal deviates whose dependence is specified by a user‑defined correlation matrix. The second procedure is the inverse of the first: an arbitrary multivariate deviate input sequence is first mapped to a corresponding sequence of empirically derived variates, i.e. cumulative distribution function values representing the probability that each random variable has a value less than or equal to the input deviate. The variates are then inverted, using the inverse standard normal CDF function, to N(0,1) deviates; and finally, a canonical covariance matrix is extracted from the multivariate N(0,1) sequence using the standard sum of products.

This example demonstrates that subroutine RNMVGC correctly imbeds the user‑defined correlation information into an arbitrary marginal distribution sequence by extracting the canonical correlation from these sequences and showing that they differ from the original correlation matrix by a small relative error, which generally decreases as the number of multivariate sequence vectors increases.

 

use rnmvgc_int

use cancor_int

use anorin_int

use chiin_int

use fin_int

use amach_int

use rnopt_int

use rnset_int

use umach_int

use chfac_int

implicit none

 

integer, parameter :: lmax=15000, nvar=3

real corrin(nvar,nvar), tol, chol(nvar,nvar), gcvart(nvar), &

gcdevt(lmax,nvar), corrout(nvar,nvar), relerr

integer irank, k, kmax, kk, i, j, nout

 

data corrin /&

1.0, -0.9486832, 0.8164965, &

-0.9486832, 1.0, -0.6454972, &

0.8164965, -0.6454972, 1.0/

 

call umach (2, nout)

 

write(nout,*)

write(nout,*) "Off-diagonal Elements of Input " // &

"Correlation Matrix: "

write(nout,*)

 

do i = 2, nvar

do j = 1, i-1

write(nout,'(" CorrIn(",i2,",",i2,") = ", f10.6)') &

i, j, corrin(i,j)

end do

end do

 

write(nout,*)

write(nout,*) "Off-diagonal Elements of Output Correlation " // &

"Matrices calculated from"

write(nout,*) "Gaussian Copula imprinted multivariate sequence:"

 

! Compute the Cholesky factorization of CORRIN.

tol=amach(4)

tol=100.0*tol

call chfac (corrin, irank, chol, tol=tol)

 

kmax = lmax/100

do kk = 1, 3

write (*, '(/" # vectors in multivariate sequence: ", &

i7/)') kmax

 

call rnopt(1)

call rnset (123457)

 

do k = 1, kmax

 

! Generate an array of Gaussian Copula random numbers.

call rnmvgc (chol, gcvart)

do j = 1, nvar

! Invert Gaussian Copula probabilities to deviates.

if (j .eq. 1) then

! ChiSquare(df=10) deviates:

gcdevt(k, j) = chiin(gcvart(j), 10.e0)

else if (j .eq. 2) then

! F(dfn=15,dfd=10) deviates:

gcdevt(k, j) = fin(gcvart(j), 15.e0, 10.e0)

else

! Normal(mean=0,variance=1) deviates:

gcdevt(k, j) = anorin(gcvart(j))

end if

end do

end do

 

! Extract Canonical Correlation matrix.

call cancor (gcdevt(:kmax,:), corrout)

 

do i = 2, nvar

do j = 1, i-1

relerr = abs(1.0 - (corrout(i,j) / corrin(i,j)))

write(nout,'(" CorrOut(",i2,",",i2,") = ", '// &

'f10.6, "; relerr = ", f10.6)') &

i, j, corrout(i,j), relerr

end do

end do

kmax = kmax*10

end do

end

Output

 

Off-diagonal Elements of Input Correlation Matrix:

 

CorrIn( 2, 1) = -0.948683

CorrIn( 3, 1) = 0.816496

CorrIn( 3, 2) = -0.645497

 

Off-diagonal Elements of Output Correlation Matrices calculated from

Gaussian Copula imprinted multivariate sequence:

 

# vectors in multivariate sequence: 150

 

CorrOut( 2, 1) = -0.940215; relerr = 0.008926

CorrOut( 3, 1) = 0.794511; relerr = 0.026927

CorrOut( 3, 2) = -0.616082; relerr = 0.045569

 

# vectors in multivariate sequence: 1500

 

CorrOut( 2, 1) = -0.947443; relerr = 0.001308

CorrOut( 3, 1) = 0.808307; relerr = 0.010031

CorrOut( 3, 2) = -0.635650; relerr = 0.015256

 

# vectors in multivariate sequence: 15000

 

CorrOut( 2, 1) = -0.948267; relerr = 0.000439

CorrOut( 3, 1) = 0.817261; relerr = 0.000936

CorrOut( 3, 2) = -0.646208; relerr = 0.001101