ndtril.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /* ndtril.c
  2. *
  3. * Inverse of Normal distribution function
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, ndtril();
  10. *
  11. * x = ndtril( y );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns the argument, x, for which the area under the
  18. * Gaussian probability density function (integrated from
  19. * minus infinity to x) is equal to y.
  20. *
  21. *
  22. * For small arguments 0 < y < exp(-2), the program computes
  23. * z = sqrt( -2 log(y) ); then the approximation is
  24. * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z) .
  25. * For larger arguments, x/sqrt(2 pi) = w + w^3 R(w^2)/S(w^2)) ,
  26. * where w = y - 0.5 .
  27. *
  28. * ACCURACY:
  29. *
  30. * Relative error:
  31. * arithmetic domain # trials peak rms
  32. * Arguments uniformly distributed:
  33. * IEEE 0, 1 5000 7.8e-19 9.9e-20
  34. * Arguments exponentially distributed:
  35. * IEEE exp(-11355),-1 30000 1.7e-19 4.3e-20
  36. *
  37. *
  38. * ERROR MESSAGES:
  39. *
  40. * message condition value returned
  41. * ndtril domain x <= 0 -MAXNUML
  42. * ndtril domain x >= 1 MAXNUML
  43. *
  44. */
  45. /*
  46. Cephes Math Library Release 2.3: January, 1995
  47. Copyright 1984, 1995 by Stephen L. Moshier
  48. */
  49. #include <math.h>
  50. extern long double MAXNUML;
  51. /* ndtri(y+0.5)/sqrt(2 pi) = y + y^3 R(y^2)
  52. 0 <= y <= 3/8
  53. Peak relative error 6.8e-21. */
  54. #if UNK
  55. /* sqrt(2pi) */
  56. static long double s2pi = 2.506628274631000502416E0L;
  57. static long double P0[8] = {
  58. 8.779679420055069160496E-3L,
  59. -7.649544967784380691785E-1L,
  60. 2.971493676711545292135E0L,
  61. -4.144980036933753828858E0L,
  62. 2.765359913000830285937E0L,
  63. -9.570456817794268907847E-1L,
  64. 1.659219375097958322098E-1L,
  65. -1.140013969885358273307E-2L,
  66. };
  67. static long double Q0[7] = {
  68. /* 1.000000000000000000000E0L, */
  69. -5.303846964603721860329E0L,
  70. 9.908875375256718220854E0L,
  71. -9.031318655459381388888E0L,
  72. 4.496118508523213950686E0L,
  73. -1.250016921424819972516E0L,
  74. 1.823840725000038842075E-1L,
  75. -1.088633151006419263153E-2L,
  76. };
  77. #endif
  78. #if IBMPC
  79. static unsigned short s2p[] = {
  80. 0x2cb3,0xb138,0x98ff,0xa06c,0x4000, XPD
  81. };
  82. #define s2pi *(long double *)s2p
  83. static short P0[] = {
  84. 0xb006,0x9fc1,0xa4fe,0x8fd8,0x3ff8, XPD
  85. 0x6f8a,0x976e,0x0ed2,0xc3d4,0xbffe, XPD
  86. 0xf1f1,0x6fcc,0xf3d0,0xbe2c,0x4000, XPD
  87. 0xccfb,0xa681,0xad2c,0x84a3,0xc001, XPD
  88. 0x9a0d,0x0082,0xa825,0xb0fb,0x4000, XPD
  89. 0x13d1,0x054a,0xf220,0xf500,0xbffe, XPD
  90. 0xcee9,0x2c92,0x70bd,0xa9e7,0x3ffc, XPD
  91. 0x5fee,0x4a42,0xa6cb,0xbac7,0xbff8, XPD
  92. };
  93. static short Q0[] = {
  94. /* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
  95. 0x841e,0xfec7,0x1d44,0xa9b9,0xc001, XPD
  96. 0x97e6,0xcde0,0xc0e7,0x9e8a,0x4002, XPD
  97. 0x66f9,0x8f3e,0x47fd,0x9080,0xc002, XPD
  98. 0x212f,0x2185,0x33ec,0x8fe0,0x4001, XPD
  99. 0x8e73,0x7bac,0x8df2,0xa000,0xbfff, XPD
  100. 0xc143,0xcb94,0xe3ea,0xbac2,0x3ffc, XPD
  101. 0x25d9,0xc8f3,0x9573,0xb25c,0xbff8, XPD
  102. };
  103. #endif
  104. #if MIEEE
  105. static unsigned long s2p[] = {
  106. 0x40000000,0xa06c98ff,0xb1382cb3,
  107. };
  108. #define s2pi *(long double *)s2p
  109. static long P0[24] = {
  110. 0x3ff80000,0x8fd8a4fe,0x9fc1b006,
  111. 0xbffe0000,0xc3d40ed2,0x976e6f8a,
  112. 0x40000000,0xbe2cf3d0,0x6fccf1f1,
  113. 0xc0010000,0x84a3ad2c,0xa681ccfb,
  114. 0x40000000,0xb0fba825,0x00829a0d,
  115. 0xbffe0000,0xf500f220,0x054a13d1,
  116. 0x3ffc0000,0xa9e770bd,0x2c92cee9,
  117. 0xbff80000,0xbac7a6cb,0x4a425fee,
  118. };
  119. static long Q0[21] = {
  120. /* 0x3fff0000,0x80000000,0x00000000, */
  121. 0xc0010000,0xa9b91d44,0xfec7841e,
  122. 0x40020000,0x9e8ac0e7,0xcde097e6,
  123. 0xc0020000,0x908047fd,0x8f3e66f9,
  124. 0x40010000,0x8fe033ec,0x2185212f,
  125. 0xbfff0000,0xa0008df2,0x7bac8e73,
  126. 0x3ffc0000,0xbac2e3ea,0xcb94c143,
  127. 0xbff80000,0xb25c9573,0xc8f325d9,
  128. };
  129. #endif
  130. /* Approximation for interval z = sqrt(-2 log y ) between 2 and 8
  131. */
  132. /* ndtri(p) = z - ln(z)/z - 1/z P1(1/z)/Q1(1/z)
  133. z = sqrt(-2 ln(p))
  134. 2 <= z <= 8, i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14.
  135. Peak relative error 5.3e-21 */
  136. #if UNK
  137. static long double P1[10] = {
  138. 4.302849750435552180717E0L,
  139. 4.360209451837096682600E1L,
  140. 9.454613328844768318162E1L,
  141. 9.336735653151873871756E1L,
  142. 5.305046472191852391737E1L,
  143. 1.775851836288460008093E1L,
  144. 3.640308340137013109859E0L,
  145. 3.691354900171224122390E-1L,
  146. 1.403530274998072987187E-2L,
  147. 1.377145111380960566197E-4L,
  148. };
  149. static long double Q1[9] = {
  150. /* 1.000000000000000000000E0L, */
  151. 2.001425109170530136741E1L,
  152. 7.079893963891488254284E1L,
  153. 8.033277265194672063478E1L,
  154. 5.034715121553662712917E1L,
  155. 1.779820137342627204153E1L,
  156. 3.845554944954699547539E0L,
  157. 3.993627390181238962857E-1L,
  158. 1.526870689522191191380E-2L,
  159. 1.498700676286675466900E-4L,
  160. };
  161. #endif
  162. #if IBMPC
  163. static short P1[] = {
  164. 0x6105,0xb71e,0xf1f5,0x89b0,0x4001, XPD
  165. 0x461d,0x2604,0x8b77,0xae68,0x4004, XPD
  166. 0x8b33,0x4a47,0x9ec8,0xbd17,0x4005, XPD
  167. 0xa0b2,0xc1b0,0x1627,0xbabc,0x4005, XPD
  168. 0x9901,0x28f7,0xad06,0xd433,0x4004, XPD
  169. 0xddcb,0x5009,0x7213,0x8e11,0x4003, XPD
  170. 0x2432,0x0fa6,0xcfd5,0xe8fa,0x4000, XPD
  171. 0x3e24,0xd53c,0x53b2,0xbcff,0x3ffd, XPD
  172. 0x4058,0x3d75,0x5393,0xe5f4,0x3ff8, XPD
  173. 0x1789,0xf50a,0x7524,0x9067,0x3ff2, XPD
  174. };
  175. static short Q1[] = {
  176. /* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
  177. 0xd901,0x2673,0x2fad,0xa01d,0x4003, XPD
  178. 0x24f5,0xc93c,0x0e9d,0x8d99,0x4005, XPD
  179. 0x8cda,0x523a,0x612d,0xa0aa,0x4005, XPD
  180. 0x602c,0xb5fc,0x7b9b,0xc963,0x4004, XPD
  181. 0xac72,0xd3e7,0xb766,0x8e62,0x4003, XPD
  182. 0x048e,0xe34c,0x927c,0xf61d,0x4000, XPD
  183. 0x6d88,0xa5cc,0x45de,0xcc79,0x3ffd, XPD
  184. 0xe6d1,0x199a,0x9931,0xfa29,0x3ff8, XPD
  185. 0x4c7d,0x3675,0x70a0,0x9d26,0x3ff2, XPD
  186. };
  187. #endif
  188. #if MIEEE
  189. static long P1[30] = {
  190. 0x40010000,0x89b0f1f5,0xb71e6105,
  191. 0x40040000,0xae688b77,0x2604461d,
  192. 0x40050000,0xbd179ec8,0x4a478b33,
  193. 0x40050000,0xbabc1627,0xc1b0a0b2,
  194. 0x40040000,0xd433ad06,0x28f79901,
  195. 0x40030000,0x8e117213,0x5009ddcb,
  196. 0x40000000,0xe8facfd5,0x0fa62432,
  197. 0x3ffd0000,0xbcff53b2,0xd53c3e24,
  198. 0x3ff80000,0xe5f45393,0x3d754058,
  199. 0x3ff20000,0x90677524,0xf50a1789,
  200. };
  201. static long Q1[27] = {
  202. /* 0x3fff0000,0x80000000,0x00000000, */
  203. 0x40030000,0xa01d2fad,0x2673d901,
  204. 0x40050000,0x8d990e9d,0xc93c24f5,
  205. 0x40050000,0xa0aa612d,0x523a8cda,
  206. 0x40040000,0xc9637b9b,0xb5fc602c,
  207. 0x40030000,0x8e62b766,0xd3e7ac72,
  208. 0x40000000,0xf61d927c,0xe34c048e,
  209. 0x3ffd0000,0xcc7945de,0xa5cc6d88,
  210. 0x3ff80000,0xfa299931,0x199ae6d1,
  211. 0x3ff20000,0x9d2670a0,0x36754c7d,
  212. };
  213. #endif
  214. /* ndtri(x) = z - ln(z)/z - 1/z P2(1/z)/Q2(1/z)
  215. z = sqrt(-2 ln(y))
  216. 8 <= z <= 32
  217. i.e., y between exp(-32) = 1.27e-14 and exp(-512) = 4.38e-223
  218. Peak relative error 1.0e-21 */
  219. #if UNK
  220. static long double P2[8] = {
  221. 3.244525725312906932464E0L,
  222. 6.856256488128415760904E0L,
  223. 3.765479340423144482796E0L,
  224. 1.240893301734538935324E0L,
  225. 1.740282292791367834724E-1L,
  226. 9.082834200993107441750E-3L,
  227. 1.617870121822776093899E-4L,
  228. 7.377405643054504178605E-7L,
  229. };
  230. static long double Q2[7] = {
  231. /* 1.000000000000000000000E0L, */
  232. 6.021509481727510630722E0L,
  233. 3.528463857156936773982E0L,
  234. 1.289185315656302878699E0L,
  235. 1.874290142615703609510E-1L,
  236. 9.867655920899636109122E-3L,
  237. 1.760452434084258930442E-4L,
  238. 8.028288500688538331773E-7L,
  239. };
  240. #endif
  241. #if IBMPC
  242. static short P2[] = {
  243. 0xafb1,0x4ff9,0x4f3a,0xcfa6,0x4000, XPD
  244. 0xbd81,0xaffa,0x7401,0xdb66,0x4001, XPD
  245. 0x3a32,0x3863,0x9d0f,0xf0fd,0x4000, XPD
  246. 0x300e,0x633d,0x977a,0x9ed5,0x3fff, XPD
  247. 0xea3a,0x56b6,0x74c5,0xb234,0x3ffc, XPD
  248. 0x38c6,0x49d2,0x2af6,0x94d0,0x3ff8, XPD
  249. 0xc85d,0xe17d,0x5ed1,0xa9a5,0x3ff2, XPD
  250. 0x536c,0x808b,0x2542,0xc609,0x3fea, XPD
  251. };
  252. static short Q2[] = {
  253. /* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
  254. 0xaabd,0x125a,0x34a7,0xc0b0,0x4001, XPD
  255. 0x0ded,0xe6da,0x5a11,0xe1d2,0x4000, XPD
  256. 0xc742,0x9d16,0x0640,0xa504,0x3fff, XPD
  257. 0xea1e,0x4cc2,0x643a,0xbfed,0x3ffc, XPD
  258. 0x7a9b,0xfaff,0xf2dd,0xa1ab,0x3ff8, XPD
  259. 0xfd90,0x4688,0xc902,0xb898,0x3ff2, XPD
  260. 0xf003,0x032a,0xfa7e,0xd781,0x3fea, XPD
  261. };
  262. #endif
  263. #if MIEEE
  264. static long P2[24] = {
  265. 0x40000000,0xcfa64f3a,0x4ff9afb1,
  266. 0x40010000,0xdb667401,0xaffabd81,
  267. 0x40000000,0xf0fd9d0f,0x38633a32,
  268. 0x3fff0000,0x9ed5977a,0x633d300e,
  269. 0x3ffc0000,0xb23474c5,0x56b6ea3a,
  270. 0x3ff80000,0x94d02af6,0x49d238c6,
  271. 0x3ff20000,0xa9a55ed1,0xe17dc85d,
  272. 0x3fea0000,0xc6092542,0x808b536c,
  273. };
  274. static long Q2[21] = {
  275. /* 0x3fff0000,0x80000000,0x00000000, */
  276. 0x40010000,0xc0b034a7,0x125aaabd,
  277. 0x40000000,0xe1d25a11,0xe6da0ded,
  278. 0x3fff0000,0xa5040640,0x9d16c742,
  279. 0x3ffc0000,0xbfed643a,0x4cc2ea1e,
  280. 0x3ff80000,0xa1abf2dd,0xfaff7a9b,
  281. 0x3ff20000,0xb898c902,0x4688fd90,
  282. 0x3fea0000,0xd781fa7e,0x032af003,
  283. };
  284. #endif
  285. /* ndtri(x) = z - ln(z)/z - 1/z P3(1/z)/Q3(1/z)
  286. 32 < z < 2048/13
  287. Peak relative error 1.4e-20 */
  288. #if UNK
  289. static long double P3[8] = {
  290. 2.020331091302772535752E0L,
  291. 2.133020661587413053144E0L,
  292. 2.114822217898707063183E-1L,
  293. -6.500909615246067985872E-3L,
  294. -7.279315200737344309241E-4L,
  295. -1.275404675610280787619E-5L,
  296. -6.433966387613344714022E-8L,
  297. -7.772828380948163386917E-11L,
  298. };
  299. static long double Q3[7] = {
  300. /* 1.000000000000000000000E0L, */
  301. 2.278210997153449199574E0L,
  302. 2.345321838870438196534E-1L,
  303. -6.916708899719964982855E-3L,
  304. -7.908542088737858288849E-4L,
  305. -1.387652389480217178984E-5L,
  306. -7.001476867559193780666E-8L,
  307. -8.458494263787680376729E-11L,
  308. };
  309. #endif
  310. #if IBMPC
  311. static short P3[] = {
  312. 0x87b2,0x0f31,0x1ac7,0x814d,0x4000, XPD
  313. 0x491c,0xcd74,0x6917,0x8883,0x4000, XPD
  314. 0x935e,0x1776,0xcba9,0xd88e,0x3ffc, XPD
  315. 0xbafd,0x8abb,0x9518,0xd505,0xbff7, XPD
  316. 0xc87e,0x2ed3,0xa84a,0xbed2,0xbff4, XPD
  317. 0x0094,0xa402,0x36b5,0xd5fa,0xbfee, XPD
  318. 0xbc53,0x0fc3,0x1ab2,0x8a2b,0xbfe7, XPD
  319. 0x30b4,0x71c0,0x223d,0xaaed,0xbfdd, XPD
  320. };
  321. static short Q3[] = {
  322. /* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */
  323. 0xdfc1,0x8a57,0x357f,0x91ce,0x4000, XPD
  324. 0xcc4f,0x9e03,0x346e,0xf029,0x3ffc, XPD
  325. 0x38b1,0x9788,0x8f42,0xe2a5,0xbff7, XPD
  326. 0xb281,0x2117,0x53da,0xcf51,0xbff4, XPD
  327. 0xf2ab,0x1d42,0x3760,0xe8cf,0xbfee, XPD
  328. 0x741b,0xf14f,0x06b0,0x965b,0xbfe7, XPD
  329. 0x37c2,0xa91f,0x16ea,0xba01,0xbfdd, XPD
  330. };
  331. #endif
  332. #if MIEEE
  333. static long P3[24] = {
  334. 0x40000000,0x814d1ac7,0x0f3187b2,
  335. 0x40000000,0x88836917,0xcd74491c,
  336. 0x3ffc0000,0xd88ecba9,0x1776935e,
  337. 0xbff70000,0xd5059518,0x8abbbafd,
  338. 0xbff40000,0xbed2a84a,0x2ed3c87e,
  339. 0xbfee0000,0xd5fa36b5,0xa4020094,
  340. 0xbfe70000,0x8a2b1ab2,0x0fc3bc53,
  341. 0xbfdd0000,0xaaed223d,0x71c030b4,
  342. };
  343. static long Q3[21] = {
  344. /* 0x3fff0000,0x80000000,0x00000000, */
  345. 0x40000000,0x91ce357f,0x8a57dfc1,
  346. 0x3ffc0000,0xf029346e,0x9e03cc4f,
  347. 0xbff70000,0xe2a58f42,0x978838b1,
  348. 0xbff40000,0xcf5153da,0x2117b281,
  349. 0xbfee0000,0xe8cf3760,0x1d42f2ab,
  350. 0xbfe70000,0x965b06b0,0xf14f741b,
  351. 0xbfdd0000,0xba0116ea,0xa91f37c2,
  352. };
  353. #endif
  354. #ifdef ANSIPROT
  355. extern long double polevll ( long double, void *, int );
  356. extern long double p1evll ( long double, void *, int );
  357. extern long double logl ( long double );
  358. extern long double sqrtl ( long double );
  359. #else
  360. long double polevll(), p1evll(), logl(), sqrtl();
  361. #endif
  362. long double ndtril(y0)
  363. long double y0;
  364. {
  365. long double x, y, z, y2, x0, x1;
  366. int code;
  367. if( y0 <= 0.0L )
  368. {
  369. mtherr( "ndtril", DOMAIN );
  370. return( -MAXNUML );
  371. }
  372. if( y0 >= 1.0L )
  373. {
  374. mtherr( "ndtri", DOMAIN );
  375. return( MAXNUML );
  376. }
  377. code = 1;
  378. y = y0;
  379. if( y > (1.0L - 0.13533528323661269189L) ) /* 0.135... = exp(-2) */
  380. {
  381. y = 1.0L - y;
  382. code = 0;
  383. }
  384. if( y > 0.13533528323661269189L )
  385. {
  386. y = y - 0.5L;
  387. y2 = y * y;
  388. x = y + y * (y2 * polevll( y2, P0, 7 )/p1evll( y2, Q0, 7 ));
  389. x = x * s2pi;
  390. return(x);
  391. }
  392. x = sqrtl( -2.0L * logl(y) );
  393. x0 = x - logl(x)/x;
  394. z = 1.0L/x;
  395. if( x < 8.0L )
  396. x1 = z * polevll( z, P1, 9 )/p1evll( z, Q1, 9 );
  397. else if( x < 32.0L )
  398. x1 = z * polevll( z, P2, 7 )/p1evll( z, Q2, 7 );
  399. else
  400. x1 = z * polevll( z, P3, 7 )/p1evll( z, Q3, 7 );
  401. x = x0 - x1;
  402. if( code != 0 )
  403. x = -x;
  404. return( x );
  405. }