gsl_cdf__gaussinv.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* cdf/inverse_normal.c
  2. *
  3. * Copyright (C) 2002 Przemyslaw Sliwa and Jason H. Stover.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. /*
  20. * Computes the inverse normal cumulative distribution function
  21. * according to the algorithm shown in
  22. *
  23. * Wichura, M.J. (1988).
  24. * Algorithm AS 241: The Percentage Points of the Normal Distribution.
  25. * Applied Statistics, 37, 477-484.
  26. */
  27. #include "gsl__config.h"
  28. #include "gsl_errno.h"
  29. #include "gsl_math.h"
  30. #include "gsl_cdf.h"
  31. #include "gsl_cdf__rat_eval.h"
  32. static double
  33. small (double q)
  34. {
  35. const double a[8] = { 3.387132872796366608, 133.14166789178437745,
  36. 1971.5909503065514427, 13731.693765509461125,
  37. 45921.953931549871457, 67265.770927008700853,
  38. 33430.575583588128105, 2509.0809287301226727
  39. };
  40. const double b[8] = { 1.0, 42.313330701600911252,
  41. 687.1870074920579083, 5394.1960214247511077,
  42. 21213.794301586595867, 39307.89580009271061,
  43. 28729.085735721942674, 5226.495278852854561
  44. };
  45. double r = 0.180625 - q * q;
  46. double x = q * rat_eval (a, 8, b, 8, r);
  47. return x;
  48. }
  49. static double
  50. intermediate (double r)
  51. {
  52. const double a[] = { 1.42343711074968357734, 4.6303378461565452959,
  53. 5.7694972214606914055, 3.64784832476320460504,
  54. 1.27045825245236838258, 0.24178072517745061177,
  55. 0.0227238449892691845833, 7.7454501427834140764e-4
  56. };
  57. const double b[] = { 1.0, 2.05319162663775882187,
  58. 1.6763848301838038494, 0.68976733498510000455,
  59. 0.14810397642748007459, 0.0151986665636164571966,
  60. 5.475938084995344946e-4, 1.05075007164441684324e-9
  61. };
  62. double x = rat_eval (a, 8, b, 8, (r - 1.6));
  63. return x;
  64. }
  65. static double
  66. tail (double r)
  67. {
  68. const double a[] = { 6.6579046435011037772, 5.4637849111641143699,
  69. 1.7848265399172913358, 0.29656057182850489123,
  70. 0.026532189526576123093, 0.0012426609473880784386,
  71. 2.71155556874348757815e-5, 2.01033439929228813265e-7
  72. };
  73. const double b[] = { 1.0, 0.59983220655588793769,
  74. 0.13692988092273580531, 0.0148753612908506148525,
  75. 7.868691311456132591e-4, 1.8463183175100546818e-5,
  76. 1.4215117583164458887e-7, 2.04426310338993978564e-15
  77. };
  78. double x = rat_eval (a, 8, b, 8, (r - 5.0));
  79. return x;
  80. }
  81. double
  82. gsl_cdf_ugaussian_Pinv (const double P)
  83. {
  84. double r, x, pp;
  85. double dP = P - 0.5;
  86. if (P == 1.0)
  87. {
  88. return GSL_POSINF;
  89. }
  90. else if (P == 0.0)
  91. {
  92. return GSL_NEGINF;
  93. }
  94. if (fabs (dP) <= 0.425)
  95. {
  96. x = small (dP);
  97. return x;
  98. }
  99. pp = (P < 0.5) ? P : 1.0 - P;
  100. r = sqrt (-log (pp));
  101. if (r <= 5.0)
  102. {
  103. x = intermediate (r);
  104. }
  105. else
  106. {
  107. x = tail (r);
  108. }
  109. if (P < 0.5)
  110. {
  111. return -x;
  112. }
  113. else
  114. {
  115. return x;
  116. }
  117. }
  118. double
  119. gsl_cdf_ugaussian_Qinv (const double Q)
  120. {
  121. double r, x, pp;
  122. double dQ = Q - 0.5;
  123. if (Q == 1.0)
  124. {
  125. return GSL_NEGINF;
  126. }
  127. else if (Q == 0.0)
  128. {
  129. return GSL_POSINF;
  130. }
  131. if (fabs (dQ) <= 0.425)
  132. {
  133. x = small (dQ);
  134. return -x;
  135. }
  136. pp = (Q < 0.5) ? Q : 1.0 - Q;
  137. r = sqrt (-log (pp));
  138. if (r <= 5.0)
  139. {
  140. x = intermediate (r);
  141. }
  142. else
  143. {
  144. x = tail (r);
  145. }
  146. if (Q < 0.5)
  147. {
  148. return x;
  149. }
  150. else
  151. {
  152. return -x;
  153. }
  154. }
  155. double
  156. gsl_cdf_gaussian_Pinv (const double P, const double sigma)
  157. {
  158. return sigma * gsl_cdf_ugaussian_Pinv (P);
  159. }
  160. double
  161. gsl_cdf_gaussian_Qinv (const double Q, const double sigma)
  162. {
  163. return sigma * gsl_cdf_ugaussian_Qinv (Q);
  164. }