逃离北上广好吗:转:SAS和蒙特卡罗模拟(3 ) - 模型编程 - 风险视界-风险管理与金融工程专业交流平...

来源:百度文库 编辑:九乡新闻网 时间:2024/04/27 21:53:43
转:SAS和蒙特卡罗模拟(3 )
http://blog.csdn.net/JiangtangHu/archive/2008/05/17/2455117.aspx
SAS和蒙特卡罗模拟(3):SAS随机数函数及CALL子程序收藏************************************************************************************************************************** 《SAS和蒙特卡罗模拟(1):开篇》——简介,通过例子建立起蒙卡的直观概念;参考软件包及书目
《SAS和蒙特卡罗模拟(2):随机数基础》——随机数入门;参考书目
**************************************************************************************************************************************************
一、SAS随机数函数和CALL子程序
SAS系统产生随机数,两种方式,利用SAS函数(Functions)或者CALL子程序(CALL Routines),它们的语法格式是(具体的区别容后讨论):
方式          代码                        说明
函数var=name(seed,)var为存储随机数列的变量,name为特定的分布函数形式,seed为随机数种子,为特定分布要求的参数(可选)
CALL子程序call name(seed,,var)同上,记得seed=0, ±1,±2, , ± (2**31-2)
SAS可用的随机数函数列表如下(可以参见SAS Help and Documentation-SAS Products-Base SAS-SAS Language Dictionary-Functions and CALL Routines-Functions and CALL Routines by Category):
分布    SAS函数        说明
二项分布(Binomial)ranBin(seed,n,p)n为独立实验的次数,p为成功概率
指数分布(Exponential)ranExp(seed)
正态分布(Normal)ranNor(seed),or normal(seed)ranNor和normal是同质的,但normal没有相对应的CALL子程序
泊松分布(Poisson)ranPoi(seed,m)m为均值
均匀分布(Uniform)ranUni(seed),or uniform(seed)ranUni和uniform是同质的,但uniform没有相对应的CALL子程序
柯西分布(Cauchy)ranCau(seed)
伽玛分布(Gamma)ranGam(seed,a)a>0为形状参数
由分布律表格决定的离散分布(tabled probability distribution)ranTbl(seed,p1,p2,...pn) ∑p=1
三角分布(Triangular)ranTri(seed,h) h为斜边(最可能值)
上面的随机函数,除了normal和uniform,都可以由直接相应的CALL子程序调用。
二、SAS随机数函数和CALL子程序:比较
用SAS随机数函数同时创建的多个随机数变量其实都属于同一个随机数列。这话费解,一个例子先,创建两个随机数变量,各包含3个记录,其中x1的种子为123,x2的种子为456:
data ranuni(drop=i);
retain seed1 123 seed2 456;
do i=1 to 3;
x1=ranuni(seed1);
x2=ranuni(seed2);
output;
end;
run;
proc print data=ranuni;run;
结果为:
Obs    seed1    seed2       x1         x2
1      123      456     0.75040    0.32091
2      123      456     0.17839    0.90603
3      123      456     0.35712    0.22111
好像没什么异样。我们把上面的x1增加为6个记录:
data ranuni2(drop=i);
retain seed1 123;
do i=1 to 6;
x1=ranuni(seed1);
output;
end;
run;
proc print data=ranuni2;run;
结果如下,把上下用红色标出的数字对照看一看:
Obs    seed1       x1
1      123     0.75040
2      123     0.32091
3      123     0.17839
4      123     0.90603
5      123     0.35712
6      123    0.22111
什么意思?在第一段代码中,x2的种子根本不起作用,把x2的记录安插到x1里,看起来就是用种子123产生的随机数列加长了而已。x2的第一个值并不是由种子456产生的,而是产生第一个x1后的下一个值,x1、x2其实属于同一个随机数列,尽管x2的种子被指定为456,而x1的被指定为123。现在就可以重复上面的一句话:用SAS随机数函数同时创建的多个随机数变量其实都属于同一个随机数列。
用CALL子程序就能够同时产生独立的随机数列。
data ranuni3(drop=i);
retain seed3 123 seed4 456;
do i=1 to 3;
call ranuni(seed3,x3);
call ranuni(seed4,x4);
output;
end;
run;
proc print data=ranuni3;run;
结果如下:
Obs       seed3        seed4         x3         x4
1     1611463328    736440516   0.75040    0.34293
2      689153326    774069794    0.32091    0.36045
3      383088854    686944750    0.17839    0.31988
以上x3就是x1。x1和x3的初始种子都是123,但x3那个结果显示的种子是当前种子值。要在SAS随机数函数语句中显示随机种子的当前值,可以由以下代码给出:
data ranuni4(drop=i);
retain seed1 123;
do i=1 to 3;
x1=ranuni(seed1);
seed=x1*(2**31-1);
output;
end;
run;
proc print data=ranuni4;
var seed1 seed x1;
run;
结果如下,可以跟上面由CALL子程序得出的结果对照:
Obs    seed1       seed          x1
1      123     1611463328   0.75040
2      123      689153326    0.32091
3      123      383088854    0.17839
---------参考资料---------
Xitao Fan, etc..Monte Carlo Studies: A Guide for Quantitative Researchers. SAS Institute Inc.,2002 朱世武《SAS编程技术与金融数据处理》,北京:清华大学出版社,2003