使用gsl库产生高斯分布随机数

什么是GSL?

The GNU Scientific Library (GSL) is a numerical library for C and C++ programmers.

The library provides a wide range of mathematical routines such as random number generators, special functions and least-squares fitting. There are over 1000 functions in total with an extensive test suite.

The complete range of subject areas covered by the library includes,

Complex NumbersRoots of Polynomials
Special FunctionsVectors and Matrices
PermutationsSorting
BLAS SupportLinear Algebra
EigensystemsFast Fourier Transforms
QuadratureRandom Numbers
Quasi-Random SequencesRandom Distributions
StatisticsHistograms
N-TuplesMonte Carlo Integration
Simulated AnnealingDifferential Equations
InterpolationNumerical Differentiation
Chebyshev ApproximationSeries Acceleration
Discrete Hankel TransformsRoot-Finding
MinimizationLeast-Squares Fitting
Physical ConstantsIEEE Floating-Point
Discrete Wavelet TransformsBasis splines
Running StatisticsSparse Matrices and Linear Algebra

以上摘自http://www.gnu.org/software/gsl/

可见里面还是有不少干货的。

我们知道计算机产生的随机数都是伪随机数,需要一个种子,种子不同,产生的随机数序列才不同,这个种子可以是时间,因为系统的时间一直都在变。通常,我们用c标准库里的函数rand产生的随机数是均匀分布的,那么要产生高斯分布的(钟形)随机数就需要一个算法,在GSL库中实现了两个这样的算法。

这里解读其随机数产生的实现,我使用的源码是gsl-2.4.tar.gz,gsl_ran_gaussian函数就是产生高斯分布随机数。

其代码在gsl-2.4/randist/gauss.c中

double
gsl_ran_gaussian (const gsl_rng * r, const double sigma)
{
  double x, y, r2;

  do
    {
      /* choose x,y in uniform square (-1,-1) to (+1,+1) */
      x = -1 + 2 * gsl_rng_uniform_pos (r);
      y = -1 + 2 * gsl_rng_uniform_pos (r);

      /* see if it is in the unit circle */
      r2 = x * x + y * y;
    }
  while (r2 > 1.0 || r2 == 0);

  /* Box-Muller transform */
  return sigma * y * sqrt (-2.0 * log (r2) / r2);
}

这是Box-Muller方法实现的,在Knuth的The Art Of Computer Programming Vol.2, 3rd edition里有讲到。

另一个方法是Kinderman-Monahan方法,有相关论文,这里不讲。

上面那个函数中的gsl_rng_uniform_pos就是产生均匀分布的随机数,范围是(0, 1)

其实现在gsl-2.4/rng/gsl_rng.h中,

INLINE_FUN double
gsl_rng_uniform_pos (const gsl_rng * r)
{
  double x ;
  do
    {
      x = (r->type->get_double) (r->state) ;
    }
  while (x == 0) ;

  return x ;
}
如果要在深挖下去,就到了gsl_rng_type *gsl_rng_mt19937

get_double就是gsl_rng_mt19937的成员函数,具体实现在gsl-2.4/rng/mt.c中。

它也可以用rand() / (RAND_MAX + 1.0)代替,那样就要在产生随机数之前用srand设置一个随机数种子。

附:

#define RAND_MAX 0x7fff

static double
mt_get_double (void * vstate)
{
  return mt_get (vstate) / 4294967296.0 ;
}
可以看出还是有点不同,后者除以(0xFFFFFFFF+1)

% This folder contains a collection of "fitting" functions. % (Some has demo options - the third section) % The GENERAL input to the functions should be samples of the distribution. % % for example, if we are to fit a normal distribution ('gaussian') with a mean "u" and varaince "sig"^2 % then the samples will distribute like: % samples = randn(1,10000)*sig + u % %fitting with Least-Squares is done on the histogram of the samples. % fitting with Maximum likelihood is done directly on the samples. % % % Contents of this folder % ======================= % 1) Maximum likelihood estimators % 2) Least squares estimators % 3) EM algorithm for estimation of multivariant gaussian distribution (mixed gaussians) % 4) added folders: Create - which create samples for the EM algorithm test % Plot - used to plot each of the distributions (parametric plot) % % % % % % Maximum likelihood estimators % ============================= % fit_ML_maxwell - fit maxwellian distribution % fit_ML_rayleigh - fit rayleigh distribution % (which is for example: sqrt(abs(randn)^2+abs(randn)^2)) % fit_ML_laplace - fit laplace distribution % fit_ML_log_normal- fit log-normal distribution % fit_ML_normal - fit normal (gaussian) distribution % % NOTE: all estimators are efficient estimators. for this reason, the distribution % might be written in a different way, for example, the "Rayleigh" distribution % is given with a parameter "s" and not "s^2". % % % least squares estimators % ========================= % fit_maxwell_pdf - fits a given curve of a maxwellian distribution % fit_rayleigh_pdf - fits a given curve of a rayleigh distribution % % NOTE: these fit function are used on a histogram output which is like a sampled % distribution function. the given curve MUST be normalized, since the estimator % is trying to fit a normalized distribution function. % % % % % Multivariant Gaussian distribution % ================================== % for demo of 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值