normp.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include <math.h>
  2. /*-
  3. * SUBROUTINE Cdhc_normp(Z, P, Q, PDF)
  4. *
  5. * Normal distribution probabilities accurate to 1.e-15.
  6. * Z = no. of standard deviations from the mean.
  7. * P, Q = probabilities to the left & right of Z. P + Q = 1.
  8. * PDF = the probability density.
  9. *
  10. * Based upon algorithm 5666 for the error function, from:
  11. * Hart, J.F. et al, 'Computer Approximations', Wiley 1968
  12. *
  13. * Programmer: Alan Miller
  14. *
  15. * Latest revision - 30 March 1986
  16. *
  17. */
  18. /* Conversion to C by James Darrell McCauley, 24 September 1994 */
  19. double Cdhc_normp(double z)
  20. {
  21. static double p[7] = { 220.2068679123761, 221.2135961699311,
  22. 112.079291497870, 33.91286607838300, 6.37396220353165,
  23. 0.7003830644436881, 0.352624965998910e-1
  24. };
  25. static double q[8] = { 440.4137358247522, 793.8265125199484,
  26. 637.3336333788311, 296.5642487796737, 86.78073220294608,
  27. 16.06417757920695, 1.755667163182642, 0.8838834764831844e-1
  28. };
  29. static double cutoff = 7.071, root2pi = 2.506628274631001;
  30. double zabs, expntl;
  31. double pee, queue, pdf;
  32. zabs = fabs(z);
  33. if (zabs > 37.0) {
  34. pdf = 0.0;
  35. if (z > 0.0) {
  36. pee = 1.0;
  37. queue = 0.0;
  38. }
  39. else {
  40. pee = 0.0;
  41. queue = 1.0;
  42. }
  43. return pee;
  44. }
  45. expntl = exp(-0.5 * zabs * zabs);
  46. pdf = expntl / root2pi;
  47. if (zabs < cutoff)
  48. pee = expntl * ((((((p[6] * zabs + p[5]) * zabs + p[4])
  49. * zabs + p[3]) * zabs + p[2]) * zabs +
  50. p[1]) * zabs + p[0])
  51. / (((((((q[7] * zabs + q[6]) * zabs + q[5]) * zabs + q[4])
  52. * zabs + q[3]) * zabs + q[2]) * zabs + q[1]) * zabs + q[0]);
  53. else
  54. pee = pdf / (zabs + 1.0 / (zabs + 2.0 / (zabs + 3.0 / (zabs + 4.0 /
  55. (zabs +
  56. 0.65)))));
  57. if (z < 0.0)
  58. queue = 1.0 - pee;
  59. else {
  60. queue = pee;
  61. pee = 1.0 - queue;
  62. }
  63. return pee;
  64. }