我是zoro
分类: LINUX
2013-02-06 14:17:07
转自:
本文介绍如何使用GNU科学计算库GSL(GNU Scientific Library)产生正态分布(高斯分布)、柯西分布和Levy分布的随机数。本文程序都在Linux下用GCC4.5编译通过。编译时请使用命令: gcc -Wall test.c -o -lgsl -lgslcblas test。并将你的/usr/local/lib/目录设置到库搜索路径中。
GNU Scientific Library (GSL) 是以GNU-GPL 协议发布的基于linux的C/C++数值和科学运算库。在linux下,GSL+Gnuplot 基本上就可以替代Matlab的数值计算功能了。GSL的官网是,下载并安装好后,就可以在C程序中调用了。介绍稳定分布(stable distribution)的时候,提到了三种稳定分布的特例,分别是正态分布、柯西分布和Levy分布,这里就用GSL产生满足这三种分布的随机数。
计算机只能利用均匀分布随机数来产生各种非均匀分布(non-uniform distribution)随机数,所以这里先介绍如何产生均匀随机数。我们要用到下面几个函数:
Function 1.1 : gsl_rng *gsl_rng_alloc (const gsl_rng_type *T)
gsl_rng 是gsl 自定义的类型名,它表示”random number generator”。
函数返回一个指针,这个指针指向一个随机数发生器类型T的实例。这里要提到的是,GSL 中有很多随机数发生器,默认的是 “gsl_rng_mt19937″,还有随机效果比较好的 “gsl_rng_ranlxs0″、”gsl_rng_ranlxs1″、”gsl_rng_ranlxs2″用于产生单精度随机数(24bits),”gsl_rng_ranlxd1″、”gsl_rng_ranlxd2″用于产生双精度随机数(32bits)。这里的参数T就是其中的一种类型。
Function 1.2:void gsl_rng_free(gsl_rng *r)
就像是C程序中用malloc分配的内存一样,在程序结束前,我们同样要释放上面为随机数发生器分配的内存。
Function 1.3:double gsl_rng_uniform (const gsl_rng *r)
产生一个在[0, 1)区间上的双精度随机数,这也是科学计算最常用。它产生的随机数包括0,但不包括1。
Function 1.4:double gsl_rng_uniform_pos (const gsl_rng *r)
产生一个在(0, 1)区间上的双精度随机数。0和1都不包括。
例子程序1:
GSL 支持通过设置环境变量来改变随机数发生器的类型T和产生随机数的种子(seed),这样可以避免重新编译程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include |
运行结果:
generator type: mt19937
seed = 0
first value = 0.99974
默认的seed=0。generator type和seed分别由环境变量 GSL_RNG_TYPE和GSL_RNG_SEED控制。修改后,重新运行程序。
$export GSL_RNG_TYPE=”ranlxs0″
$export GSL_RNG_SEED=”123″
运行结果:
generator type: ranlxs0
seed = 123
first value = 0.28774
例子程序2:
由计算机产生的随机数取决于它的生成算法(generator)和种子(seed),所以例子程序1 运行n次的结果都是一样的,产生同样的随机数。例子程序2 把生成器类型和种子大小放在程序中定义,使得程序每次运行产生不同的随机序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include |
第一次运行结果:
generator type: ranlxs0
seed = 1290757286
0.28880
0.46950
0.77044
0.75054
0.25988
第二次运行结果:
generator type: ranlxs0
seed = 1290757289
0.72488
0.89850
0.54173
0.18530
0.99199
只要两次运行间隔超过1秒,seed的值就会变化,导致随机数序列的改变。对我来说,一般情况下,这个方法都适用。
声明:文章未经说明都是原创,转载请注明: 转载自
本文链接地址: