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; }