dawsnf.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* dawsnf.c
  2. *
  3. * Dawson's Integral
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float x, y, dawsnf();
  10. *
  11. * y = dawsnf( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Approximates the integral
  18. *
  19. * x
  20. * -
  21. * 2 | | 2
  22. * dawsn(x) = exp( -x ) | exp( t ) dt
  23. * | |
  24. * -
  25. * 0
  26. *
  27. * Three different rational approximations are employed, for
  28. * the intervals 0 to 3.25; 3.25 to 6.25; and 6.25 up.
  29. *
  30. *
  31. * ACCURACY:
  32. *
  33. * Relative error:
  34. * arithmetic domain # trials peak rms
  35. * IEEE 0,10 50000 4.4e-7 6.3e-8
  36. *
  37. *
  38. */
  39. /* dawsn.c */
  40. /*
  41. Cephes Math Library Release 2.1: January, 1989
  42. Copyright 1984, 1987, 1989 by Stephen L. Moshier
  43. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  44. */
  45. #include <math.h>
  46. /* Dawson's integral, interval 0 to 3.25 */
  47. static float AN[10] = {
  48. 1.13681498971755972054E-11,
  49. 8.49262267667473811108E-10,
  50. 1.94434204175553054283E-8,
  51. 9.53151741254484363489E-7,
  52. 3.07828309874913200438E-6,
  53. 3.52513368520288738649E-4,
  54. -8.50149846724410912031E-4,
  55. 4.22618223005546594270E-2,
  56. -9.17480371773452345351E-2,
  57. 9.99999999999999994612E-1,
  58. };
  59. static float AD[11] = {
  60. 2.40372073066762605484E-11,
  61. 1.48864681368493396752E-9,
  62. 5.21265281010541664570E-8,
  63. 1.27258478273186970203E-6,
  64. 2.32490249820789513991E-5,
  65. 3.25524741826057911661E-4,
  66. 3.48805814657162590916E-3,
  67. 2.79448531198828973716E-2,
  68. 1.58874241960120565368E-1,
  69. 5.74918629489320327824E-1,
  70. 1.00000000000000000539E0,
  71. };
  72. /* interval 3.25 to 6.25 */
  73. static float BN[11] = {
  74. 5.08955156417900903354E-1,
  75. -2.44754418142697847934E-1,
  76. 9.41512335303534411857E-2,
  77. -2.18711255142039025206E-2,
  78. 3.66207612329569181322E-3,
  79. -4.23209114460388756528E-4,
  80. 3.59641304793896631888E-5,
  81. -2.14640351719968974225E-6,
  82. 9.10010780076391431042E-8,
  83. -2.40274520828250956942E-9,
  84. 3.59233385440928410398E-11,
  85. };
  86. static float BD[10] = {
  87. /* 1.00000000000000000000E0,*/
  88. -6.31839869873368190192E-1,
  89. 2.36706788228248691528E-1,
  90. -5.31806367003223277662E-2,
  91. 8.48041718586295374409E-3,
  92. -9.47996768486665330168E-4,
  93. 7.81025592944552338085E-5,
  94. -4.55875153252442634831E-6,
  95. 1.89100358111421846170E-7,
  96. -4.91324691331920606875E-9,
  97. 7.18466403235734541950E-11,
  98. };
  99. /* 6.25 to infinity */
  100. static float CN[5] = {
  101. -5.90592860534773254987E-1,
  102. 6.29235242724368800674E-1,
  103. -1.72858975380388136411E-1,
  104. 1.64837047825189632310E-2,
  105. -4.86827613020462700845E-4,
  106. };
  107. static float CD[5] = {
  108. /* 1.00000000000000000000E0,*/
  109. -2.69820057197544900361E0,
  110. 1.73270799045947845857E0,
  111. -3.93708582281939493482E-1,
  112. 3.44278924041233391079E-2,
  113. -9.73655226040941223894E-4,
  114. };
  115. extern float PIF, MACHEPF;
  116. #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
  117. #ifdef ANSIC
  118. float polevlf(float, float *, int);
  119. float p1evlf(float, float *, int);
  120. #else
  121. float polevlf(), p1evlf();
  122. #endif
  123. float dawsnf( float xxx )
  124. {
  125. float xx, x, y;
  126. int sign;
  127. xx = xxx;
  128. sign = 1;
  129. if( xx < 0.0 )
  130. {
  131. sign = -1;
  132. xx = -xx;
  133. }
  134. if( xx < 3.25 )
  135. {
  136. x = xx*xx;
  137. y = xx * polevlf( x, AN, 9 )/polevlf( x, AD, 10 );
  138. return( sign * y );
  139. }
  140. x = 1.0/(xx*xx);
  141. if( xx < 6.25 )
  142. {
  143. y = 1.0/xx + x * polevlf( x, BN, 10) / (p1evlf( x, BD, 10) * xx);
  144. return( sign * 0.5 * y );
  145. }
  146. if( xx > 1.0e9 )
  147. return( (sign * 0.5)/xx );
  148. /* 6.25 to infinity */
  149. y = 1.0/xx + x * polevlf( x, CN, 4) / (p1evlf( x, CD, 5) * xx);
  150. return( sign * 0.5 * y );
  151. }