stdtrl.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* stdtrl.c
  2. *
  3. * Student's t distribution
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double p, t, stdtrl();
  10. * int k;
  11. *
  12. * p = stdtrl( k, t );
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Computes the integral from minus infinity to t of the Student
  18. * t distribution with integer k > 0 degrees of freedom:
  19. *
  20. * t
  21. * -
  22. * | |
  23. * - | 2 -(k+1)/2
  24. * | ( (k+1)/2 ) | ( x )
  25. * ---------------------- | ( 1 + --- ) dx
  26. * - | ( k )
  27. * sqrt( k pi ) | ( k/2 ) |
  28. * | |
  29. * -
  30. * -inf.
  31. *
  32. * Relation to incomplete beta integral:
  33. *
  34. * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z )
  35. * where
  36. * z = k/(k + t**2).
  37. *
  38. * For t < -1.6, this is the method of computation. For higher t,
  39. * a direct method is derived from integration by parts.
  40. * Since the function is symmetric about t=0, the area under the
  41. * right tail of the density is found by calling the function
  42. * with -t instead of t.
  43. *
  44. * ACCURACY:
  45. *
  46. * Tested at random 1 <= k <= 100. The "domain" refers to t.
  47. * Relative error:
  48. * arithmetic domain # trials peak rms
  49. * IEEE -100,-1.6 10000 5.7e-18 9.8e-19
  50. * IEEE -1.6,100 10000 3.8e-18 1.0e-19
  51. */
  52. /* stdtril.c
  53. *
  54. * Functional inverse of Student's t distribution
  55. *
  56. *
  57. *
  58. * SYNOPSIS:
  59. *
  60. * long double p, t, stdtril();
  61. * int k;
  62. *
  63. * t = stdtril( k, p );
  64. *
  65. *
  66. * DESCRIPTION:
  67. *
  68. * Given probability p, finds the argument t such that stdtrl(k,t)
  69. * is equal to p.
  70. *
  71. * ACCURACY:
  72. *
  73. * Tested at random 1 <= k <= 100. The "domain" refers to p:
  74. * Relative error:
  75. * arithmetic domain # trials peak rms
  76. * IEEE 0,1 3500 4.2e-17 4.1e-18
  77. */
  78. /*
  79. Cephes Math Library Release 2.3: January, 1995
  80. Copyright 1984, 1995 by Stephen L. Moshier
  81. */
  82. #include <math.h>
  83. extern long double PIL, MACHEPL, MAXNUML;
  84. #ifdef ANSIPROT
  85. extern long double sqrtl ( long double );
  86. extern long double atanl ( long double );
  87. extern long double incbetl ( long double, long double, long double );
  88. extern long double incbil ( long double, long double, long double );
  89. extern long double fabsl ( long double );
  90. #else
  91. long double sqrtl(), atanl(), incbetl(), incbil(), fabsl();
  92. #endif
  93. long double stdtrl( k, t )
  94. int k;
  95. long double t;
  96. {
  97. long double x, rk, z, f, tz, p, xsqk;
  98. int j;
  99. if( k <= 0 )
  100. {
  101. mtherr( "stdtrl", DOMAIN );
  102. return(0.0L);
  103. }
  104. if( t == 0.0L )
  105. return( 0.5L );
  106. if( t < -1.6L )
  107. {
  108. rk = k;
  109. z = rk / (rk + t * t);
  110. p = 0.5L * incbetl( 0.5L*rk, 0.5L, z );
  111. return( p );
  112. }
  113. /* compute integral from -t to + t */
  114. if( t < 0.0L )
  115. x = -t;
  116. else
  117. x = t;
  118. rk = k; /* degrees of freedom */
  119. z = 1.0L + ( x * x )/rk;
  120. /* test if k is odd or even */
  121. if( (k & 1) != 0)
  122. {
  123. /* computation for odd k */
  124. xsqk = x/sqrtl(rk);
  125. p = atanl( xsqk );
  126. if( k > 1 )
  127. {
  128. f = 1.0L;
  129. tz = 1.0L;
  130. j = 3;
  131. while( (j<=(k-2)) && ( (tz/f) > MACHEPL ) )
  132. {
  133. tz *= (j-1)/( z * j );
  134. f += tz;
  135. j += 2;
  136. }
  137. p += f * xsqk/z;
  138. }
  139. p *= 2.0L/PIL;
  140. }
  141. else
  142. {
  143. /* computation for even k */
  144. f = 1.0L;
  145. tz = 1.0L;
  146. j = 2;
  147. while( ( j <= (k-2) ) && ( (tz/f) > MACHEPL ) )
  148. {
  149. tz *= (j - 1)/( z * j );
  150. f += tz;
  151. j += 2;
  152. }
  153. p = f * x/sqrtl(z*rk);
  154. }
  155. /* common exit */
  156. if( t < 0.0L )
  157. p = -p; /* note destruction of relative accuracy */
  158. p = 0.5L + 0.5L * p;
  159. return(p);
  160. }
  161. long double stdtril( k, p )
  162. int k;
  163. long double p;
  164. {
  165. long double t, rk, z;
  166. int rflg;
  167. if( k <= 0 || p <= 0.0L || p >= 1.0L )
  168. {
  169. mtherr( "stdtril", DOMAIN );
  170. return(0.0L);
  171. }
  172. rk = k;
  173. if( p > 0.25L && p < 0.75L )
  174. {
  175. if( p == 0.5L )
  176. return( 0.0L );
  177. z = 1.0L - 2.0L * p;
  178. z = incbil( 0.5L, 0.5L*rk, fabsl(z) );
  179. t = sqrtl( rk*z/(1.0L-z) );
  180. if( p < 0.5L )
  181. t = -t;
  182. return( t );
  183. }
  184. rflg = -1;
  185. if( p >= 0.5L)
  186. {
  187. p = 1.0L - p;
  188. rflg = 1;
  189. }
  190. z = incbil( 0.5L*rk, 0.5L, 2.0L*p );
  191. if( MAXNUML * z < rk )
  192. return(rflg* MAXNUML);
  193. t = sqrtl( rk/z - rk );
  194. return( rflg * t );
  195. }