# GaussianMV

Generates random numbers from multivariate normal distribution.

## Syntax

Fortran:

status = vsrnggaussianmv( method, stream, n, r, dimen, mstorage, a, t )

status = vdrnggaussianmv( method, stream, n, r, dimen, mstorage, a, t )

C:

status = vsRngGaussianMV( method, stream, n, r, dimen, mstorage, a, t );

status = vdRngGaussianMV( method, stream, n, r, dimen, mstorage, a, t );

## Description

This function generates random numbers with d-variate normal (Gaussian) distribution with mean value a and variance-covariance matrix C, where `a∈Rd; C` is a `d×d` symmetric positive-definite matrix.

The probability density function is given by:

where `x∈Rd` .

Matrix C can be represented as `C = TTT`, where T is a lower triangular matrix - Cholesky factor of C.

Instead of variance-covariance matrix C the generation routines require Cholesky factor of C in input. To compute Cholesky factor of matrix C, the user may call MKL LAPACK routines for matrix factorization: ?potrf or ?pptrf for v?RngGaussianMV/v?rnggaussianmv routines (? means either s or d for single and double precision respectively). See Application Notes for more details.

## Input Parameters

Name | Type | Description
--- | --- | ---
method | FORTRAN: INTEGER, INTENT(IN) C: int | Generation method. The specific values are as follows: `VSL_METHOD_SGAUSSIANMV_BOXMULLER` `VSL_METHOD_SGAUSSIANMV_BOXMULLER2` `VSL_METHOD_SGAUSSIANMV_ICDF` `VSL_METHOD_DGAUSSIANMV_BOXMULLER` `VSL_METHOD_DGAUSSIANMV_BOXMULLER2` `VSL_METHOD_DGAUSSIANMV_ICDF` See brief description of the methods BOXMULLER, BOXMULLER2, and ICDF in Table“Values of `<method>` in method parameter”
stream | FORTRAN: TYPE (VSL_STREAM_STATE), INTENT(IN) C: VSLStreamStatePtr | FORTRAN: Descriptor of the stream state structure. C: Pointer to the stream state structure
n | FORTRAN: INTEGER, INTENT(IN) C: int | Number of random values to be generated
dimen | FORTRAN: INTEGER, INTENT(IN) C: int | Dimension `d ( d ≥ 1)` of output random vectors
mstorage | FORTRAN: INTEGER, INTENT(IN) C: int | FORTRAN: Matrix storage scheme for upper triangular matrix `TT`. The routine supports three matrix storage schemes: VSL_MATRIX_STORAGE_FULL— all `d x d` elements of the matrix `TT` are passed, however, only the upper triangle part is actually used in the routine. VSL_MATRIX_STORAGE_PACKED— upper triangle elements of `TT` are packed by rows into a one-dimensional array. VSL_MATRIX_STORAGE_DIAGONAL— only diagonal elements of `TT` are passed. C: Matrix storage scheme for lower triangular matrix T. The routine supports three matrix storage schemes: VSL_MATRIX_STORAGE_FULL— all `d x d` elements of the matrix T are passed, however, only the lower triangle part is actually used in the routine. VSL_MATRIX_STORAGE_PACKED— lower triangle elements of T are packed by rows into a one-dimensional array. VSL_MATRIX_STORAGE_DIAGONAL— only diagonal elements of T are passed.
a | FORTRAN: REAL, INTENT(IN) for vsrnggaussianmv DOUBLE PRECISION, INTENT(IN) for vdrnggaussianmv C: float* for vsRngGaussianMV double* for vdRngGaussianMV | Mean vector a of dimension d
t | FORTRAN: REAL, INTENT(IN) for vsrnggaussianmv DOUBLE PRECISION, INTENT(IN) for vdrnggaussianmv C: float* for vsRngGaussianMV double* for vdRngGaussianMV | FORTRAN: Elements of the upper triangular matrix passed according to the matrix `TT` storage scheme mstorage. C: Elements of the lower triangular matrix passed according to the matrix T storage scheme mstorage.

## Output Parameters

Name | Type | Description
--- | --- | ---
r | FORTRAN: REAL, INTENT(OUT) for vsrnggaussianmv DOUBLE PRECISION, INTENT(OUT) for vdrnggaussianmv C: float* for vsRngGaussianMV double* for vdRngGaussianMV | Array of n random vectors of dimension dimen

## Application Notes

Since matrices are stored in Fortran by columns, while in C they are stored by rows, the usage of MKL factorization routines (assuming Fortran matrices storage) in combination with multivariate normal RNG (assuming C matrix storage) is slightly different in C and Fortran. The following tables help in using these routines in C and Fortran. For further information please refer to the appropriate VSL example file.

Using Cholesky Factorization Routines in Fortran
Matrix Storage Scheme | Variance-Covariance Matrix Argument | Factorization Routine | UPLO Parameter in Factorization Routine | Result of Factorization as Input Argument for RNG
--- | --- | --- | --- | ---
VSL_MATRIX_STORAGE_FULL | C in Fortran two-dimensional array | spotrf for vsrnggaussianmv dpotrf for vdrnggaussianmv | ‘U’ | Upper triangle of `TT`. Lower triangle is not used.
VSL_MATRIX_STORAGE_PACKED | Lower triangle of C packed by columns into one-dimensional array | spptrf for vsrnggaussianmv dpptrf for vdrnggaussianmv | ‘L’ | Upper triangle of `TT` packed by rows into one-dimensional array.

Using Cholesky Factorization Routines in C
Matrix Storage Scheme | Variance-Covariance Matrix Argument | Factorization Routine | UPLO Parameter in Factorization Routine | Result of Factorization as Input Argument for RNG
--- | --- | --- | --- | ---
VSL_MATRIX_STORAGE_FULL | C in C two-dimensional array | spotrf for vsRngGaussianMV dpotrf for vdRngGaussianMV | ‘U’ | Upper triangle of `TT`. Lower triangle is not used.
VSL_MATRIX_STORAGE_PACKED | Lower triangle of C packed by columns into one-dimensional array | spptrf for vsRngGaussianMV dpptrf for vdRngGaussianMV | ‘L’ | Upper triangle of `TT` packed by rows into one-dimensional array.

## Return Values

VSL_ERROR_OK, VSL_STATUS_OK
  Indicates no error, execution is successful.
VSL_ERROR_NULL_PTR
  stream is a NULL pointer.
VSL_ERROR_BAD_STREAM

  stream is not a valid random stream.

VSL_ERROR_BAD_UPDATE

  Callback function for an abstract BRNG returns an invalid number of updated entries in a buffer, that is, `< 0` or `> nmax`.

VSL_ERROR_NO_NUMBERS

  Callback function for an abstract BRNG returns 0 as the number of updated entries in a buffer.

Parent topic: Continuous Distributions