Hi!
I want to generate random numbers from a multivariate normal distribution with parameters mu = [3.0 5.0 2.0] and sigma = [ 16.0 8.0 4.0; 8.0 13.0 17.0; 4.0 17.0 62.0].
I wrote a mex-code using the the function vdRngGaussianMV and the results of the simulation are
>> mean(out)
ans =
3.4558 2.9934 3.3013
>> cov(out)
ans =
146.5081 -1.9068 -2.1787
-1.9068 144.7461 -0.7771
-2.1787 -0.7771 142.3955
Could you please tell me what I am doing wrong.
Thank you very much.
The code is the following:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <mkl.h>
#include "mkl_vml.h"
#include "mex.h"
#include "matrix.h"
#include "mkl_vsl.h"
#include <time.h>
#define SEED time(NULL)
#define BRNG VSL_BRNG_MCG31 // VSL basic generator to be used
double normalMVN(int npars, int N, double *cov, double *mean, double *out);
/* main fucntion */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int npars, N;
double *cov, *mean, *out;
/* make pointers to input data */
npars = (int)mxGetScalar(prhs[0]);
N = (int)mxGetScalar(prhs[1]);
cov = mxGetPr(prhs[2]);
mean = mxGetPr(prhs[3]);
/* make pointers to output data */
plhs[0] = mxCreateDoubleMatrix( N, npars, mxREAL);
out = mxGetPr(plhs[0]);
/* call */
normalMVN(npars, N, cov, mean, out);
return 0;
}
double normalMVN(int npars, int N, double *cov, double *mean, double *out)
{
/* This we need it for distributions */
VSLSSTaskPtr task;
VSLStreamStatePtr stream;
char uplo;
int i, j, n, lda, info;
double *T, fiori[3];
T = (double *)mxMalloc( npars*npars*sizeof( double* ) );
uplo = 'L';
n = npars;
lda = npars;
cblas_dcopy(npars*npars, cov, 1, T, 1);
dpotrf( &uplo, &n, T, &lda, &info );
if(info != 0){mexPrintf("c++ error: Cholesky failed\n\n");}
vslNewStream( &stream, BRNG, SEED );
vdRngGaussianMV( VSL_METHOD_DGAUSSIANMV_BOXMULLER2, stream, N, out, npars, VSL_MATRIX_STORAGE_FULL, mean, T );
vslDeleteStream( &stream );
/* Free memory */
mxFree(T);
return 0;
}