ndtr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /* ndtr.c
  2. *
  3. * Normal distribution function
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, ndtr();
  10. *
  11. * y = ndtr( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns the area under the Gaussian probability density
  18. * function, integrated from minus infinity to x:
  19. *
  20. * x
  21. * -
  22. * 1 | | 2
  23. * ndtr(x) = --------- | exp( - t /2 ) dt
  24. * sqrt(2pi) | |
  25. * -
  26. * -inf.
  27. *
  28. * = ( 1 + erf(z) ) / 2
  29. * = erfc(z) / 2
  30. *
  31. * where z = x/sqrt(2). Computation is via the functions
  32. * erf and erfc with care to avoid error amplification in computing exp(-x^2).
  33. *
  34. *
  35. * ACCURACY:
  36. *
  37. * Relative error:
  38. * arithmetic domain # trials peak rms
  39. * IEEE -13,0 30000 1.3e-15 2.2e-16
  40. *
  41. *
  42. * ERROR MESSAGES:
  43. *
  44. * message condition value returned
  45. * erfc underflow x > 37.519379347 0.0
  46. *
  47. */
  48. /* erf.c
  49. *
  50. * Error function
  51. *
  52. *
  53. *
  54. * SYNOPSIS:
  55. *
  56. * double x, y, erf();
  57. *
  58. * y = erf( x );
  59. *
  60. *
  61. *
  62. * DESCRIPTION:
  63. *
  64. * The integral is
  65. *
  66. * x
  67. * -
  68. * 2 | | 2
  69. * erf(x) = -------- | exp( - t ) dt.
  70. * sqrt(pi) | |
  71. * -
  72. * 0
  73. *
  74. * The magnitude of x is limited to 9.231948545 for DEC
  75. * arithmetic; 1 or -1 is returned outside this range.
  76. *
  77. * For 0 <= |x| < 1, erf(x) = x * P4(x**2)/Q5(x**2); otherwise
  78. * erf(x) = 1 - erfc(x).
  79. *
  80. *
  81. *
  82. * ACCURACY:
  83. *
  84. * Relative error:
  85. * arithmetic domain # trials peak rms
  86. * DEC 0,1 14000 4.7e-17 1.5e-17
  87. * IEEE 0,1 30000 3.7e-16 1.0e-16
  88. *
  89. */
  90. /* erfc.c
  91. *
  92. * Complementary error function
  93. *
  94. *
  95. *
  96. * SYNOPSIS:
  97. *
  98. * double x, y, erfc();
  99. *
  100. * y = erfc( x );
  101. *
  102. *
  103. *
  104. * DESCRIPTION:
  105. *
  106. *
  107. * 1 - erf(x) =
  108. *
  109. * inf.
  110. * -
  111. * 2 | | 2
  112. * erfc(x) = -------- | exp( - t ) dt
  113. * sqrt(pi) | |
  114. * -
  115. * x
  116. *
  117. *
  118. * For small x, erfc(x) = 1 - erf(x); otherwise rational
  119. * approximations are computed.
  120. *
  121. * A special function expx2.c is used to suppress error amplification
  122. * in computing exp(-x^2).
  123. *
  124. *
  125. * ACCURACY:
  126. *
  127. * Relative error:
  128. * arithmetic domain # trials peak rms
  129. * IEEE 0,26.6417 30000 1.3e-15 2.2e-16
  130. *
  131. *
  132. * ERROR MESSAGES:
  133. *
  134. * message condition value returned
  135. * erfc underflow x > 9.231948545 (DEC) 0.0
  136. *
  137. *
  138. */
  139. /*
  140. Cephes Math Library Release 2.9: November, 2000
  141. Copyright 1984, 1987, 1988, 1992, 2000 by Stephen L. Moshier
  142. */
  143. #include "mconf.h"
  144. extern double SQRTH;
  145. extern double MAXLOG;
  146. /* Define this macro to suppress error propagation in exp(x^2)
  147. by using the expx2 function. The tradeoff is that doing so
  148. generates two calls to the exponential function instead of one. */
  149. #define USE_EXPXSQ 1
  150. #ifdef UNK
  151. static double P[] = {2.46196981473530512524E-10, 5.64189564831068821977E-1,
  152. 7.46321056442269912687E0, 4.86371970985681366614E1,
  153. 1.96520832956077098242E2, 5.26445194995477358631E2,
  154. 9.34528527171957607540E2, 1.02755188689515710272E3,
  155. 5.57535335369399327526E2};
  156. static double Q[] = {
  157. /* 1.00000000000000000000E0,*/
  158. 1.32281951154744992508E1, 8.67072140885989742329E1,
  159. 3.54937778887819891062E2, 9.75708501743205489753E2,
  160. 1.82390916687909736289E3, 2.24633760818710981792E3,
  161. 1.65666309194161350182E3, 5.57535340817727675546E2};
  162. static double R[] = {5.64189583547755073984E-1, 1.27536670759978104416E0,
  163. 5.01905042251180477414E0, 6.16021097993053585195E0,
  164. 7.40974269950448939160E0, 2.97886665372100240670E0};
  165. static double S[] = {
  166. /* 1.00000000000000000000E0,*/
  167. 2.26052863220117276590E0, 9.39603524938001434673E0,
  168. 1.20489539808096656605E1, 1.70814450747565897222E1,
  169. 9.60896809063285878198E0, 3.36907645100081516050E0};
  170. static double T[] = {9.60497373987051638749E0, 9.00260197203842689217E1,
  171. 2.23200534594684319226E3, 7.00332514112805075473E3,
  172. 5.55923013010394962768E4};
  173. static double U[] = {
  174. /* 1.00000000000000000000E0,*/
  175. 3.35617141647503099647E1, 5.21357949780152679795E2,
  176. 4.59432382970980127987E3, 2.26290000613890934246E4,
  177. 4.92673942608635921086E4};
  178. #define UTHRESH 37.519379347
  179. #endif
  180. #ifdef DEC
  181. static unsigned short P[] = {
  182. 0030207, 0054445, 0011173, 0021706, 0040020, 0067272, 0030661, 0122075,
  183. 0040756, 0151236, 0173053, 0067042, 0041502, 0106175, 0062555, 0151457,
  184. 0042104, 0102525, 0047401, 0003667, 0042403, 0116176, 0011446, 0075303,
  185. 0042551, 0120723, 0061641, 0123275, 0042600, 0070651, 0007264, 0134516,
  186. 0042413, 0061102, 0167507, 0176625};
  187. static unsigned short Q[] = {
  188. /*0040200,0000000,0000000,0000000,*/
  189. 0041123, 0123257, 0165741, 0017142, 0041655, 0065027, 0173413, 0115450,
  190. 0042261, 0074011, 0021573, 0004150, 0042563, 0166530, 0013662, 0007200,
  191. 0042743, 0176427, 0162443, 0105214, 0043014, 0062546, 0153727, 0123772,
  192. 0042717, 0012470, 0006227, 0067424, 0042413, 0061103, 0003042, 0013254};
  193. static unsigned short R[] = {
  194. 0040020, 0067272, 0101024, 0155421, 0040243, 0037467, 0056706, 0026462,
  195. 0040640, 0116017, 0120665, 0034315, 0040705, 0020162, 0143350, 0060137,
  196. 0040755, 0016234, 0134304, 0130157, 0040476, 0122700, 0051070, 0015473};
  197. static unsigned short S[] = {
  198. /*0040200,0000000,0000000,0000000,*/
  199. 0040420, 0126200, 0044276, 0070413, 0041026, 0053051, 0007302, 0063746,
  200. 0041100, 0144203, 0174051, 0061151, 0041210, 0123314, 0126343, 0177646,
  201. 0041031, 0137125, 0051431, 0033011, 0040527, 0117362, 0152661, 0066201};
  202. static unsigned short T[] = {0041031, 0126770, 0170672, 0166101, 0041664,
  203. 0006522, 0072360, 0031770, 0043013, 0100025,
  204. 0162641, 0126671, 0043332, 0155231, 0161627,
  205. 0076200, 0044131, 0024115, 0021020, 0117343};
  206. static unsigned short U[] = {
  207. /*0040200,0000000,0000000,0000000,*/
  208. 0041406, 0037461, 0177575, 0032714, 0042402, 0053350, 0123061,
  209. 0153557, 0043217, 0111227, 0032007, 0164217, 0043660, 0145000,
  210. 0004013, 0160114, 0044100, 0071544, 0167107, 0125471};
  211. #define UTHRESH 14.0
  212. #endif
  213. #ifdef IBMPC
  214. static unsigned short P[] = {
  215. 0x6479, 0xa24f, 0xeb24, 0x3df0, 0x3488, 0x4636, 0x0dd7, 0x3fe2, 0x6dc4,
  216. 0xdec5, 0xda53, 0x401d, 0xba66, 0xacad, 0x518f, 0x4048, 0x20f7, 0xa9e0,
  217. 0x90aa, 0x4068, 0xcf58, 0xc264, 0x738f, 0x4080, 0x34d8, 0x6c74, 0x343a,
  218. 0x408d, 0x972a, 0x21d6, 0x0e35, 0x4090, 0xffb3, 0x5de8, 0x6c48, 0x4081};
  219. static unsigned short Q[] = {
  220. /*0x0000,0x0000,0x0000,0x3ff0,*/
  221. 0x23cc, 0xfd7c, 0x74d5, 0x402a, 0x7365, 0xfee1, 0xad42, 0x4055,
  222. 0x610d, 0x246f, 0x2f01, 0x4076, 0x41d0, 0x02f6, 0x7dab, 0x408e,
  223. 0x7151, 0xfca4, 0x7fa2, 0x409c, 0xf4ff, 0xdafa, 0x8cac, 0x40a1,
  224. 0xede2, 0x0192, 0xe2a7, 0x4099, 0x42d6, 0x60c4, 0x6c48, 0x4081};
  225. static unsigned short R[] = {0x9b62, 0x5042, 0x0dd7, 0x3fe2, 0xc5a6, 0xebb8,
  226. 0x67e6, 0x3ff4, 0xa71a, 0xf436, 0x1381, 0x4014,
  227. 0x0c0c, 0x58dd, 0xa40e, 0x4018, 0x960e, 0x9718,
  228. 0xa393, 0x401d, 0x0367, 0x0a47, 0xd4b8, 0x4007};
  229. static unsigned short S[] = {
  230. /*0x0000,0x0000,0x0000,0x3ff0,*/
  231. 0xce21, 0x0917, 0x1590, 0x4002, 0x4cfd, 0x21d8, 0xcac5, 0x4022,
  232. 0x2c4d, 0x7f05, 0x1910, 0x4028, 0x7ff5, 0x959c, 0x14d9, 0x4031,
  233. 0x26c1, 0xaa63, 0x37ca, 0x4023, 0x2d90, 0x5ab6, 0xf3de, 0x400a};
  234. static unsigned short T[] = {0x5d88, 0x1e37, 0x35bf, 0x4023, 0x067f,
  235. 0x4e9e, 0x81aa, 0x4056, 0x35b7, 0xbcb4,
  236. 0x7002, 0x40a1, 0xef90, 0x3c72, 0x5b53,
  237. 0x40bb, 0x13dc, 0xa442, 0x2509, 0x40eb};
  238. static unsigned short U[] = {
  239. /*0x0000,0x0000,0x0000,0x3ff0,*/
  240. 0xa6ba, 0x3fef, 0xc7e6, 0x4040, 0x3aee, 0x14c6, 0x4add,
  241. 0x4080, 0xfd12, 0xe680, 0xf252, 0x40b1, 0x7c0a, 0x0101,
  242. 0x1940, 0x40d6, 0xf567, 0x9dc8, 0x0e6c, 0x40e8};
  243. #define UTHRESH 37.519379347
  244. #endif
  245. #ifdef MIEEE
  246. static unsigned short P[] = {
  247. 0x3df0, 0xeb24, 0xa24f, 0x6479, 0x3fe2, 0x0dd7, 0x4636, 0x3488, 0x401d,
  248. 0xda53, 0xdec5, 0x6dc4, 0x4048, 0x518f, 0xacad, 0xba66, 0x4068, 0x90aa,
  249. 0xa9e0, 0x20f7, 0x4080, 0x738f, 0xc264, 0xcf58, 0x408d, 0x343a, 0x6c74,
  250. 0x34d8, 0x4090, 0x0e35, 0x21d6, 0x972a, 0x4081, 0x6c48, 0x5de8, 0xffb3};
  251. static unsigned short Q[] = {
  252. 0x402a, 0x74d5, 0xfd7c, 0x23cc, 0x4055, 0xad42, 0xfee1, 0x7365,
  253. 0x4076, 0x2f01, 0x246f, 0x610d, 0x408e, 0x7dab, 0x02f6, 0x41d0,
  254. 0x409c, 0x7fa2, 0xfca4, 0x7151, 0x40a1, 0x8cac, 0xdafa, 0xf4ff,
  255. 0x4099, 0xe2a7, 0x0192, 0xede2, 0x4081, 0x6c48, 0x60c4, 0x42d6};
  256. static unsigned short R[] = {0x3fe2, 0x0dd7, 0x5042, 0x9b62, 0x3ff4, 0x67e6,
  257. 0xebb8, 0xc5a6, 0x4014, 0x1381, 0xf436, 0xa71a,
  258. 0x4018, 0xa40e, 0x58dd, 0x0c0c, 0x401d, 0xa393,
  259. 0x9718, 0x960e, 0x4007, 0xd4b8, 0x0a47, 0x0367};
  260. static unsigned short S[] = {0x4002, 0x1590, 0x0917, 0xce21, 0x4022, 0xcac5,
  261. 0x21d8, 0x4cfd, 0x4028, 0x1910, 0x7f05, 0x2c4d,
  262. 0x4031, 0x14d9, 0x959c, 0x7ff5, 0x4023, 0x37ca,
  263. 0xaa63, 0x26c1, 0x400a, 0xf3de, 0x5ab6, 0x2d90};
  264. static unsigned short T[] = {0x4023, 0x35bf, 0x1e37, 0x5d88, 0x4056,
  265. 0x81aa, 0x4e9e, 0x067f, 0x40a1, 0x7002,
  266. 0xbcb4, 0x35b7, 0x40bb, 0x5b53, 0x3c72,
  267. 0xef90, 0x40eb, 0x2509, 0xa442, 0x13dc};
  268. static unsigned short U[] = {0x4040, 0xc7e6, 0x3fef, 0xa6ba, 0x4080,
  269. 0x4add, 0x14c6, 0x3aee, 0x40b1, 0xf252,
  270. 0xe680, 0xfd12, 0x40d6, 0x1940, 0x0101,
  271. 0x7c0a, 0x40e8, 0x0e6c, 0x9dc8, 0xf567};
  272. #define UTHRESH 37.519379347
  273. #endif
  274. #ifdef ANSIPROT
  275. extern double polevl(double, void *, int);
  276. extern double p1evl(double, void *, int);
  277. extern double exp(double);
  278. extern double log(double);
  279. extern double fabs(double);
  280. extern double sqrt(double);
  281. extern double expx2(double, int);
  282. double erf(double);
  283. double erfc(double);
  284. static double erfce(double);
  285. #else
  286. double polevl(), p1evl(), exp(), log(), fabs();
  287. double erf(), erfc(), expx2(), sqrt();
  288. static double erfce();
  289. #endif
  290. double ndtr(a) double a;
  291. {
  292. double x, y, z;
  293. x = a * SQRTH;
  294. z = fabs(x);
  295. /* if( z < SQRTH ) */
  296. if (z < 1.0)
  297. y = 0.5 + 0.5 * erf(x);
  298. else {
  299. #ifdef USE_EXPXSQ
  300. /* See below for erfce. */
  301. y = 0.5 * erfce(z);
  302. /* Multiply by exp(-x^2 / 2) */
  303. z = expx2(a, -1);
  304. y = y * sqrt(z);
  305. #else
  306. y = 0.5 * erfc(z);
  307. #endif
  308. if (x > 0)
  309. y = 1.0 - y;
  310. }
  311. return (y);
  312. }
  313. double erfc(a) double a;
  314. {
  315. double p, q, x, y, z;
  316. if (a < 0.0)
  317. x = -a;
  318. else
  319. x = a;
  320. if (x < 1.0)
  321. return (1.0 - erf(a));
  322. z = -a * a;
  323. if (z < -MAXLOG) {
  324. under:
  325. mtherr("erfc", UNDERFLOW);
  326. if (a < 0)
  327. return (2.0);
  328. else
  329. return (0.0);
  330. }
  331. #ifdef USE_EXPXSQ
  332. /* Compute z = exp(z). */
  333. z = expx2(a, -1);
  334. #else
  335. z = exp(z);
  336. #endif
  337. if (x < 8.0) {
  338. p = polevl(x, P, 8);
  339. q = p1evl(x, Q, 8);
  340. } else {
  341. p = polevl(x, R, 5);
  342. q = p1evl(x, S, 6);
  343. }
  344. y = (z * p) / q;
  345. if (a < 0)
  346. y = 2.0 - y;
  347. if (y == 0.0)
  348. goto under;
  349. return (y);
  350. }
  351. /* Exponentially scaled erfc function
  352. exp(x^2) erfc(x)
  353. valid for x > 1.
  354. Use with ndtr and expx2. */
  355. static double erfce(x) double x;
  356. {
  357. double p, q;
  358. if (x < 8.0) {
  359. p = polevl(x, P, 8);
  360. q = p1evl(x, Q, 8);
  361. } else {
  362. p = polevl(x, R, 5);
  363. q = p1evl(x, S, 6);
  364. }
  365. return (p / q);
  366. }
  367. double erf(x) double x;
  368. {
  369. double y, z;
  370. if (fabs(x) > 1.0)
  371. return (1.0 - erfc(x));
  372. z = x * x;
  373. y = x * polevl(z, T, 4) / p1evl(z, U, 5);
  374. return (y);
  375. }