SPECFUNC.CPP
上传用户:zengbais
上传日期:2022-08-08
资源大小:49k
文件大小:6k
开发平台:

C++ Builder

  1. #include "func.h"
  2. DOUBLE gamma(DOUBLE x)
  3. {
  4. size_t i;
  5. DOUBLE y,t,s,u;
  6. static DOUBLE a[11]={ 0.0000677106,-0.0003442342,
  7.   0.0015397681,-0.0024467480,0.0109736958,
  8.   -0.0002109075,0.0742379071,0.0815782188,
  9.   0.4118402518,0.4227843370,1.0};
  10. if (x<=0.0)
  11. throw "err**x<=0!n";
  12. y=x;
  13. if (y<=1.0)
  14. { t=1.0/(y*(y+1.0)); y+=2.0;}
  15. else if (y<=2.0)
  16. { t=1.0/y; y+=1.0;}
  17. else if (y<=3.0) t=1.0;
  18. else
  19. { t=1.0;
  20.   while (y>3.0)
  21.  { y-=1.0; t=t*y;}
  22. }
  23.  s=a[0]; u=y-2.0;
  24.  for (i=1; i<=10; i++)
  25. s=s*u+a[i];
  26.  s*=t;
  27.  return(s);
  28. }
  29. DOUBLE gamma2(DOUBLE a, DOUBLE x)
  30. { size_t n;
  31. DOUBLE p,q,d,s,s1,p0,q0,p1,q1,qq;
  32. if ((a<=0.0)||(x<0.0))
  33. { if (a<=0.0) throw "err**a<=0!n";
  34.   if (x<0.0) throw "err**x<0!n";
  35.   return(-1.0);
  36. }
  37. if (x+1.0==1.0) return(0.0);
  38. if (x>1.0e+35) return(1.0);
  39. q=log(x); q=a*q; qq=exp(q);
  40. if (x<1.0+a)
  41. { p=a; d=1.0/a; s=d;
  42.   for (n=1; n<=100; n++)
  43.  { p=1.0+p; d=d*x/p; s=s+d;
  44.  if (fabs(d)<fabs(s)*defaulterr)
  45.   { s=s*exp(-x)*qq/gamma(a);
  46.  return(s);
  47.   }
  48.  }
  49. }
  50.  else
  51. { s=1.0/x; p0=0.0; p1=1.0; q0=1.0; q1=x;
  52.   for (n=1; n<=100; n++)
  53.  { p0=p1+(n-a)*p0; q0=q1+(n-a)*q0;
  54. p=x*p0+n*p1; q=x*q0+n*q1;
  55. if (fabs(q)+1.0!=1.0)
  56.   { s1=p/q; p1=p; q1=q;
  57.  if (fabs((s1-s)/s1)<defaulterr)
  58. { s=s1*exp(-x)*qq/gamma(a);
  59.   return(1.0-s);
  60. }
  61.  s=s1;
  62.   }
  63. p1=p; q1=q;
  64.  }
  65. }
  66. //  printf("a too large !n");
  67.  s=1.0-s*exp(-x)*qq/gamma(a);
  68.  return(s);
  69. }
  70. DOUBLE erf(DOUBLE x)
  71. { double y;
  72. if (x>=0.0)
  73. y=gamma2(0.5,x*x);
  74. else
  75. y=-gamma2(0.5,x*x);
  76. return(y);
  77. }
  78. static DOUBLE bet(DOUBLE a,DOUBLE b,DOUBLE x);
  79. DOUBLE beta(DOUBLE a,DOUBLE b,DOUBLE x) // 计算不完全贝塔分布函数
  80.   { DOUBLE y;
  81.  if (a<=0.0) throw "err**a<=0!";
  82.  if (b<=0.0) throw "err**b<=0!";
  83.  if ((x<0.0)||(x>1.0)) throw "err**x<0 or x>1 !";
  84.  if ((x==0.0)||(x==1.0)) y=0.0;
  85.  else
  86. { y=a*log(x)+b*log(1.0-x);
  87.   y=exp(y);
  88.   y*=gamma(a+b)/(gamma(a)*gamma(b));
  89. }
  90.  if (x<(a+1.0)/(a+b+2.0))
  91. y*=bet(a,b,x)/a;
  92.  else
  93. y=1.0-y*bet(b,a,1.0-x)/b;
  94.  return(y);
  95.   }
  96. static DOUBLE bet(DOUBLE a,DOUBLE b,DOUBLE x)
  97. { size_t k;
  98.  DOUBLE d,p0,q0,p1,q1,s0,s1;
  99.  p0=0.0; q0=1.0; p1=1.0; q1=1.0;
  100.  for (k=1; k<=100; k++)
  101. { d=(a+k)*(a+b+k)*x;
  102.   d=-d/((a+k+k)*(a+k+k+1.0));
  103.   p0=p1+d*p0; q0=q1+d*q0; s0=p0/q0;
  104.   d=k*(b-k)*x;
  105.   d=d/((a+k+k-1.0)*(a+k+k));
  106.   p1=p0+d*p1; q1=q0+d*q1; s1=p1/q1;
  107.   if (fabs(s1-s0)<fabs(s1)*defaulterr)
  108.  return(s1);
  109. }
  110. //  printf("a or b too big !");
  111.  return(s1);
  112. }
  113. DOUBLE gass(DOUBLE a,DOUBLE d,DOUBLE x)
  114. { DOUBLE y;
  115. if (d<=0.0) d=1.0e-10;
  116. y=0.5+0.5*erf((x-a)/(sqrt(2.0)*d));
  117. return(y);
  118. }
  119. DOUBLE student(DOUBLE t, size_t n)
  120.   { DOUBLE y;
  121.  if (t<0.0) t=-t;
  122.  y=1.0-beta(n/2.0,0.5,n/(n+t*t));
  123.  return(y);
  124.   }
  125. DOUBLE chii(DOUBLE x,size_t n)
  126. {   DOUBLE y;
  127.  if (x<0.0) x=-x;
  128.  y=gamma2(n/2.0,x/2.0);
  129.  return(y);
  130. }
  131. DOUBLE fdisp(DOUBLE f,size_t n1,size_t n2)
  132. { DOUBLE y;
  133. if (f<0.0) f=-f;
  134. y=beta(n2/2.0,n1/2.0,n2/(n2+n1*f));
  135. return(y);
  136. }
  137. DOUBLE integral(DOUBLE (*f)(DOUBLE),DOUBLE a, DOUBLE b, DOUBLE eps)
  138.  // 函数f,在(a,b)区间积分,采用勒让德高斯求积法
  139. {
  140.  size_t m,i,j;
  141.  DOUBLE s,p,ep,h,aa,bb,w,x,g;
  142.  static DOUBLE t[5]={-0.9061798459,-0.5384693101,0.0,
  143.  0.5384693101,0.9061798459};
  144.  static DOUBLE c[5]={0.2369268851,0.4786286705,0.5688888889,
  145. 0.4786286705,0.2369268851};
  146.  m=1;
  147.  h=b-a; s=fabs(0.001*h);
  148.  p=1.0e+35; ep=eps+1.0;
  149.  while ((ep>=eps)&&(fabs(h)>s))
  150. { g=0.0;
  151.   for (i=1;i<=m;i++)
  152.  { aa=a+(i-1.0)*h; bb=a+i*h;
  153. w=0.0;
  154. for (j=0;j<=4;j++)
  155.   { x=((bb-aa)*t[j]+(bb+aa))/2.0;
  156.  w=w+f(x)*c[j];  //flrgsf(x)*c[j];
  157.   }
  158. g=g+w;
  159.  }
  160.   g *= h/2.0;
  161.   ep=fabs(g-p)/(1.0+fabs(g));
  162.   p=g; m=m+1; h=(b-a)/m;
  163. }
  164.  return g;
  165. }
  166. static DOUBLE sinc(DOUBLE x)
  167. {
  168. return sin(x)/x;
  169. }
  170. DOUBLE sinn(DOUBLE x)
  171. {
  172. if(x==0.0)return 0;
  173. if(x<0.0) throw "x less than 0n";
  174. return integral(sinc,0,x);
  175. }
  176. static DOUBLE cosc(DOUBLE x)
  177. {
  178. return (1-cos(x))/x;
  179. }
  180. #define EULER 0.57721566490153286060651
  181. DOUBLE coss(DOUBLE x)
  182. {
  183. DOUBLE r=EULER;
  184. if (x<0) throw "x less than 0n";
  185. if (x==0) x=1.0e-35;
  186. return r+log(x)-integral(cosc,0,x);
  187. }
  188. static DOUBLE ex(DOUBLE x)
  189. {
  190. return (exp(-x)-1)/x;
  191. }
  192. DOUBLE expp(DOUBLE x)
  193. {
  194. if(x<0) throw "x less than 0n";
  195. if(x==0) x=1.0e-10;
  196. DOUBLE r=EULER;
  197. return r+log(x)+integral(ex,0,x);
  198. }
  199. DOUBLE getroot(DOUBLE (*f)(DOUBLE), DOUBLE x0, DOUBLE eps)
  200. { int i,j,m,l;// it
  201. double a[10],y[10],z,h,q;
  202. l=10; q=1.0e+35; h=0.0;
  203. while (l!=0)
  204. { l=l-1; j=0; // it=l;
  205.   while (j<=7)
  206.   { if (j<=2) z=x0+0.1*j;
  207.  else z=h;
  208.  y[j]=f(z);
  209.  h=z;
  210.  if (j==0) a[0]=z;
  211.  else
  212. { m=0; i=0;
  213.   while ((m==0)&&(i<=j-1))
  214.  { if (fabs(h-a[i])==0.0) m=1;
  215. else h=(y[j]-y[i])/(h-a[i]);
  216. i=i+1;
  217.  }
  218.   a[j]=h;
  219.   if (m!=0) a[j]=q;
  220.   h=0.0;
  221.   for (i=j-1; i>=0; i--)
  222.  { if (fabs(a[i+1]+h)==0.0) h=q;
  223. else h=-y[i]/(a[i+1]+h);
  224.  }
  225.   h=h+a[0];
  226. }
  227.  if (fabs(y[j])>=eps) j=j+1;
  228.  else { j=10; l=0;}
  229.   }
  230. x0=h;
  231.  }
  232. if(fabs(f(x0)) > eps) throw "no root!";
  233. return x0;
  234. }
  235. DOUBLE getroot(algo & alg, DOUBLE x0, DOUBLE eps)
  236. { int i,j,m,l;
  237. double a[10],y[10],z,h,q;
  238. l=10; q=1.0e+35; h=0.0;
  239. while (l!=0)
  240. { l--; j=0;
  241.   while (j<=7)
  242.   { if (j<=2) z=x0+0.1*j;
  243.  else z=h;
  244.  y[j]=alg.cal(z);
  245.  h=z;
  246.  if (j==0) a[0]=z;
  247.  else
  248. { m=0; i=0;
  249.   while ((m==0)&&(i<=j-1))
  250.  { if (fabs(h-a[i])==0.0) m=1;
  251. else h=(y[j]-y[i])/(h-a[i]);
  252. i=i+1;
  253.  }
  254.   a[j]=h;
  255.   if (m!=0) a[j]=q;
  256.   h=0.0;
  257.   for (i=j-1; i>=0; i--)
  258.  { if (fabs(a[i+1]+h)==0.0) h=q;
  259. else h=-y[i]/(a[i+1]+h);
  260.  }
  261.   h=h+a[0];
  262. }
  263.  if (fabs(y[j])>=eps) j=j+1;
  264.  else { j=10; l=0;}
  265.   }
  266. x0=h;
  267.  }
  268. if(fabs(alg.cal(x0)) > eps) throw "no root!";
  269. return x0;
  270. }