Dain

写出一个可以工作的程序并不够

统计

留言簿(3)

积分与排名

良师益友

阅读排行榜

评论排行榜

统计函数NormSDist和NormSInv函数实现

先说下今天写VBA学到的,那就是Excel的统计工作表函数。
Excel的统计工作表函数用于对数据区域进行统计分析。例如,统计工作表函数可以用来统计样本的方差、数据区间的频率分布等。是不是觉得好像是很专业范畴的东西?是的,统计工作表函数中提供了很多属于统计学范畴的函数,但也有些函数其实在你我的日常生活中是很常用的,比如求班级平均成绩,排名等。
但是我的程序是要cpp实现上面俩个函数,可是cpp没有这样的统计函数。查了好多资料,找到了多项式近似的方法:
/***************************************************************/
/* 返回标准正态分布的累积函数,该分布的平均值为 0,标准偏差为 1。                           */
/***************************************************************/
double NormSDist(const double z)
{
 // this guards against overflow
 if(z > 6) return 1;
 if(z < -6) return 0;

 static const double gamma =  0.231641900,
      a1  =  0.319381530,
      a2  = -0.356563782,
      a3  =  1.781477973,
      a4  = -1.821255978,
      a5  =  1.330274429;

 double k = 1.0 / (1 + fabs(z) * gamma);
 double n = k * (a1 + k * (a2 + k * (a3 + k * (a4 + k * a5))));
 n = 1 - Normal(z) * n;
 if(z < 0)
  return 1.0 - n;

 return n;
}


/***************************************************************/
/* 返回标准正态分布累积函数的逆函数。该分布的平均值为 0,标准偏差为 1。
 
 
                  */
/***************************************************************/
double normsinv(const double p)
{
 static const double LOW  = 0.02425;
 static const double HIGH = 0.97575;

 /* Coefficients in rational approximations. */
 static const double a[] =
 {
  -3.969683028665376e+01,
   2.209460984245205e+02,
  -2.759285104469687e+02,
   1.383577518672690e+02,
  -3.066479806614716e+01,
   2.506628277459239e+00
 };

 static const double b[] =
 {
  -5.447609879822406e+01,
   1.615858368580409e+02,
  -1.556989798598866e+02,
   6.680131188771972e+01,
  -1.328068155288572e+01
 };

 static const double c[] =
 {
  -7.784894002430293e-03,
  -3.223964580411365e-01,
  -2.400758277161838e+00,
  -2.549732539343734e+00,
   4.374664141464968e+00,
   2.938163982698783e+00
 };

 static const double d[] =
 {
  7.784695709041462e-03,
  3.224671290700398e-01,
  2.445134137142996e+00,
  3.754408661907416e+00
 };

 double q, r;

 errno = 0;

 if (p < 0 || p > 1)
 {
  errno = EDOM;
  return 0.0;
 }
 else if (p == 0)
 {
  errno = ERANGE;
  return -HUGE_VAL /* minus "infinity" */;
 }
 else if (p == 1)
 {
  errno = ERANGE;
  return HUGE_VAL /* "infinity" */;
 }
 else if (p < LOW)
 {
  /* Rational approximation for lower region */
  q = sqrt(-2*log(p));
  return (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
   ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
 }
 else if (p > HIGH)
 {
  /* Rational approximation for upper region */
  q  = sqrt(-2*log(1-p));
  return -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
   ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
 }
 else
 {
  /* Rational approximation for central region */
      q = p - 0.5;
      r = q*q;
  return (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /
   (((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1);
 }
}

posted on 2007-03-13 20:52 Dain 阅读(4059) 评论(4)  编辑 收藏 引用 所属分类: Computational Finance程序

评论

# re: 统计函数NormSDist和NormSInv函数实现 2007-04-17 14:50 yn

请问这句话中的Normal是个什么函数?
n = 1 - Normal(z) * n;  回复  更多评论   

# re: 统计函数NormSDist和NormSInv函数实现 2007-04-17 18:18 Dain

标准正态分布@yn
  回复  更多评论   

# re: 统计函数NormSDist和NormSInv函数实现 2008-10-12 04:21 YL

请问你这个Normal函数从哪里可以得到? 我就是想要一个算标准正太分布的函数
谢谢  回复  更多评论   

# re: 统计函数NormSDist和NormSInv函数实现 2010-05-14 18:06 WPXU

多谢分享~~~  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理