如何在SAS中使用给定的均值和SD从对数正态分布生成随机数?

时间:2014-05-13 14:42:07

标签: function macros sas distribution random-sample

Wenping(Wendy)Zhang points out SAS RAND function“基本上给出了”标准“分发”。

作者描述了一个有趣的SAS %rndnmb宏来从“非标准”发行版生成数据。不幸的是,代码不可用。所以,我敢于自己做。

如果我理解正确的维基百科says y 来自对数正态分布,如果
y = exp ^(mu + sigma * Z)
以下公式连接非对数样本值的 mean variance
mu = ln((平均^ 2)/(sqrt(方差+平均值^ 2))

sigma = sqrt(ln(1 +(variance)/(mean ^ 2)))

如果这是正确的,我的 y 将在日期时从对数正态分布中提取 Z来自标准正态分布Z,mu'= 0,sigma'= 1。

最后, y 来自对数正态分布 mean variance 是否正确 y = exp ^(ln((平均^ 2)/(sqrt(方差+平均^ 2))+ sqrt(ln(1 +(方差)/(平均^ 2)))* Z)

我的SAS代码是:
/*I use StdDev^2 notation instead of variance here. */
DATA nonStLogNorm;
nonStLN = exp(1)**(log((mean**2)/(sqrt(StdDev^2 + mean**2)) + sqrt(log(1 + (StdDev^2)/(mean**2))) * rand('UNIFORM'));
RUN;

参考文献:
Rick Wicklin的RAND函数: http://blogs.sas.com/content/iml/2013/07/10/stop-using-ranuni/ http://blogs.sas.com/content/iml/2011/08/24/how-to-generate-random-numbers-in-sas/

2 个答案:

答案 0 :(得分:2)

您需要的是逆累积分布函数。这是与整个域上的分布的归一化积分相反的函数。因此,0%是您最负面的可能值,100%是您最积极的。实际上,虽然你会吝啬0.01%和99.99%之类的东西,或者类似的东西,否则你会在很多发行版中达到无限。

然后从那里你只需要随机输入一个范围(0,1)中的数字并将其插入到函数中。记得夹住它!

double CDF = 0.5 + 0.5*erf((ln(x) - center)/(sqrt(2)*sigma))

所以

double x = exp(inverf((CDF - 0.5)*2.0)*sqrt(2)*sigma + center);

应该为您提供所需的分发。 inverf是erf函数的反函数。这是一个常见的函数,但通常不在math.h中。

基于SIMD的随机数生成器是否需要进行分发。这样工作正常,假设我在输入时没有注意到某些东西,上面的工作就可以了。

根据要求如何钳制:

   //This is how I do it with my Random class where the first argument
   //is the min value and the second is the max 
   double CDF = Random::Range(0.0001,0.9999); //Depends on what you are using to random

   //How you get there from Random Ints
   unsigned int RandomNumber = rand();
    //Conver number to range [0,1]
   double CDF = (double)RandomNumber/(double)RAND_MAX; 
   //now clamp it to a min, max of your choosing
   CDF = CDF*(max - min) + min; 

答案 1 :(得分:1)

如果您希望从标准正态分布中提取Z,是否应该通过调用RAND('NORMAL')而不是RAND('UNIFORM')来获取它?