/* Generates gaussian random deviates from uniform random deviates.
**
** Pseudo code of the algorithm is given at http://home.online.no/~pjacklam/notes/invnorm
**
** Copyright (C) 2010-2011 Dynare Team
**
** This file is part of Dynare.
**
** Dynare is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Dynare is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Dynare. If not, see .
**
** AUTHOR(S): stephane DOT adjemian AT univ DASH lemans DOT fr
*/
#include
#include
#include
#include
#include
#include
using namespace std;
#define lb .02425
#define ub .97575
#ifdef USE_OMP
# include
#endif
#define DEBUG_OMP 0
template T icdf( const T uniform )
/*
** This function invert the gaussian cumulative distribution function.
**
*/
{
static T A[6] =
{
-3.969683028665376e+01,
2.209460984245205e+02,
-2.759285104469687e+02,
1.383577518672690e+02,
-3.066479806614716e+01,
2.506628277459239e+00
};
static T B[5] =
{
-5.447609879822406e+01,
1.615858368580409e+02,
-1.556989798598866e+02,
6.680131188771972e+01,
-1.328068155288572e+01
};
static T C[6] =
{
-7.784894002430293e-03,
-3.223964580411365e-01,
-2.400758277161838e+00,
-2.549732539343734e+00,
4.374664141464968e+00,
2.938163982698783e+00
};
static T D[4] =
{
7.784695709041462e-03,
3.224671290700398e-01,
2.445134137142996e+00,
3.754408661907416e+00
};
T gaussian = (T)0.0;
if ( (0 void icdfm( const int n, T *U)
{
#if USE_OMP
#pragma omp parallel for num_threads(omp_get_num_threads())
#endif
for(int i=0; i void icdfmSigma( const int d, const int n, T *U, const double *LowerCholSigma)
{
double one = 1.0;
double zero = 0.0;
blas_int dd(d);
blas_int nn(n);
icdfm(n*d, U);
double tmp[n*d];
dgemm("N","N",&dd,&nn,&dd,&one,LowerCholSigma,&dd,U,&dd,&zero,tmp,&dd);
memcpy(U,tmp,d*n*sizeof(double));
return;
}
template void usphere( const int d, const int n, T *U)
{
icdfm(n*d, U);
#if USE_OMP
#pragma omp parallel for num_threads(omp_get_num_threads())
#endif
for (int j=0; j void usphereRadius( const int d, const int n, double radius, T *U)
{
icdfm(n*d, U);
#if USE_OMP
#pragma omp parallel for num_threads(omp_get_num_threads())
#endif
for (int j=0; j