erfc_scaled_inc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* Implementation of the ERFC_SCALED intrinsic, to be included by erfc_scaled.c
  2. Copyright (C) 2008-2022 Free Software Foundation, Inc.
  3. This file is part of the GNU Fortran runtime library (libgfortran).
  4. Libgfortran is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public
  6. License as published by the Free Software Foundation; either
  7. version 3 of the License, or (at your option) any later version.
  8. Libgfortran is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR a PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. Under Section 7 of GPL version 3, you are granted additional
  13. permissions described in the GCC Runtime Library Exception, version
  14. 3.1, as published by the Free Software Foundation.
  15. You should have received a copy of the GNU General Public License and
  16. a copy of the GCC Runtime Library Exception along with this program;
  17. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  18. <http://www.gnu.org/licenses/>. */
  19. /* This implementation of ERFC_SCALED is based on the netlib algorithm
  20. available at http://www.netlib.org/specfun/erf */
  21. #define TYPE KIND_SUFFIX(GFC_REAL_,KIND)
  22. #define CONCAT(x,y) x ## y
  23. #define KIND_SUFFIX(x,y) CONCAT(x,y)
  24. #if (KIND == 4)
  25. # define EXP(x) expf(x)
  26. # define TRUNC(x) truncf(x)
  27. #elif (KIND == 8)
  28. # define EXP(x) exp(x)
  29. # define TRUNC(x) trunc(x)
  30. #elif (KIND == 10)
  31. # ifdef HAVE_EXPL
  32. # define EXP(x) expl(x)
  33. # endif
  34. # ifdef HAVE_TRUNCL
  35. # define TRUNC(x) truncl(x)
  36. # endif
  37. #else
  38. # error "What exactly is it that you want me to do?"
  39. #endif
  40. #if defined(EXP) && defined(TRUNC)
  41. extern TYPE KIND_SUFFIX(erfc_scaled_r,KIND) (TYPE);
  42. export_proto(KIND_SUFFIX(erfc_scaled_r,KIND));
  43. TYPE
  44. KIND_SUFFIX(erfc_scaled_r,KIND) (TYPE x)
  45. {
  46. /* The main computation evaluates near-minimax approximations
  47. from "Rational Chebyshev approximations for the error function"
  48. by W. J. Cody, Math. Comp., 1969, PP. 631-638. This
  49. transportable program uses rational functions that theoretically
  50. approximate erf(x) and erfc(x) to at least 18 significant
  51. decimal digits. The accuracy achieved depends on the arithmetic
  52. system, the compiler, the intrinsic functions, and proper
  53. selection of the machine-dependent constants. */
  54. int i;
  55. TYPE del, res, xden, xnum, y, ysq;
  56. #if (KIND == 4)
  57. static TYPE xneg = -9.382, xsmall = 5.96e-8,
  58. xbig = 9.194, xhuge = 2.90e+3, xmax = 4.79e+37;
  59. #else
  60. static TYPE xneg = -26.628, xsmall = 1.11e-16,
  61. xbig = 26.543, xhuge = 6.71e+7, xmax = 2.53e+307;
  62. #endif
  63. #define SQRPI ((TYPE) 0.56418958354775628695L)
  64. #define THRESH ((TYPE) 0.46875L)
  65. static TYPE a[5] = { 3.16112374387056560l, 113.864154151050156l,
  66. 377.485237685302021l, 3209.37758913846947l, 0.185777706184603153l };
  67. static TYPE b[4] = { 23.6012909523441209l, 244.024637934444173l,
  68. 1282.61652607737228l, 2844.23683343917062l };
  69. static TYPE c[9] = { 0.564188496988670089l, 8.88314979438837594l,
  70. 66.1191906371416295l, 298.635138197400131l, 881.952221241769090l,
  71. 1712.04761263407058l, 2051.07837782607147l, 1230.33935479799725l,
  72. 2.15311535474403846e-8l };
  73. static TYPE d[8] = { 15.7449261107098347l, 117.693950891312499l,
  74. 537.181101862009858l, 1621.38957456669019l, 3290.79923573345963l,
  75. 4362.61909014324716l, 3439.36767414372164l, 1230.33935480374942l };
  76. static TYPE p[6] = { 0.305326634961232344l, 0.360344899949804439l,
  77. 0.125781726111229246l, 0.0160837851487422766l,
  78. 0.000658749161529837803l, 0.0163153871373020978l };
  79. static TYPE q[5] = { 2.56852019228982242l, 1.87295284992346047l,
  80. 0.527905102951428412l, 0.0605183413124413191l,
  81. 0.00233520497626869185l };
  82. y = (x > 0 ? x : -x);
  83. if (y <= THRESH)
  84. {
  85. ysq = 0;
  86. if (y > xsmall)
  87. ysq = y * y;
  88. xnum = a[4]*ysq;
  89. xden = ysq;
  90. for (i = 0; i <= 2; i++)
  91. {
  92. xnum = (xnum + a[i]) * ysq;
  93. xden = (xden + b[i]) * ysq;
  94. }
  95. res = x * (xnum + a[3]) / (xden + b[3]);
  96. res = 1 - res;
  97. res = EXP(ysq) * res;
  98. return res;
  99. }
  100. else if (y <= 4)
  101. {
  102. xnum = c[8]*y;
  103. xden = y;
  104. for (i = 0; i <= 6; i++)
  105. {
  106. xnum = (xnum + c[i]) * y;
  107. xden = (xden + d[i]) * y;
  108. }
  109. res = (xnum + c[7]) / (xden + d[7]);
  110. }
  111. else
  112. {
  113. res = 0;
  114. if (y >= xbig)
  115. {
  116. if (y >= xmax)
  117. goto finish;
  118. if (y >= xhuge)
  119. {
  120. res = SQRPI / y;
  121. goto finish;
  122. }
  123. }
  124. ysq = ((TYPE) 1) / (y * y);
  125. xnum = p[5]*ysq;
  126. xden = ysq;
  127. for (i = 0; i <= 3; i++)
  128. {
  129. xnum = (xnum + p[i]) * ysq;
  130. xden = (xden + q[i]) * ysq;
  131. }
  132. res = ysq *(xnum + p[4]) / (xden + q[4]);
  133. res = (SQRPI - res) / y;
  134. }
  135. finish:
  136. if (x < 0)
  137. {
  138. if (x < xneg)
  139. res = __builtin_inf ();
  140. else
  141. {
  142. ysq = TRUNC (x*((TYPE) 16))/((TYPE) 16);
  143. del = (x-ysq)*(x+ysq);
  144. y = EXP(ysq*ysq) * EXP(del);
  145. res = (y+y) - res;
  146. }
  147. }
  148. return res;
  149. }
  150. #endif
  151. #undef EXP
  152. #undef TRUNC
  153. #undef CONCAT
  154. #undef TYPE
  155. #undef KIND_SUFFIX