You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.9KB

  1. // Special functions -*- C++ -*-
  2. // Copyright (C) 2006-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // Under Section 7 of GPL version 3, you are granted additional
  16. // permissions described in the GCC Runtime Library Exception, version
  17. // 3.1, as published by the Free Software Foundation.
  18. // You should have received a copy of the GNU General Public License and
  19. // a copy of the GCC Runtime Library Exception along with this program;
  20. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  21. // <http://www.gnu.org/licenses/>.
  22. /** @file tr1/beta_function.tcc
  23. * This is an internal header file, included by other library headers.
  24. * Do not attempt to use it directly. @headername{tr1/cmath}
  25. */
  26. //
  27. // ISO C++ 14882 TR1: 5.2 Special functions
  28. //
  29. // Written by Edward Smith-Rowland based on:
  30. // (1) Handbook of Mathematical Functions,
  31. // ed. Milton Abramowitz and Irene A. Stegun,
  32. // Dover Publications,
  33. // Section 6, pp. 253-266
  34. // (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
  35. // (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
  36. // W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
  37. // 2nd ed, pp. 213-216
  38. // (4) Gamma, Exploring Euler's Constant, Julian Havil,
  39. // Princeton, 2003.
  40. #ifndef _GLIBCXX_TR1_BETA_FUNCTION_TCC
  41. #define _GLIBCXX_TR1_BETA_FUNCTION_TCC 1
  42. namespace std _GLIBCXX_VISIBILITY(default)
  43. {
  44. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  45. #if _GLIBCXX_USE_STD_SPEC_FUNCS
  46. # define _GLIBCXX_MATH_NS ::std
  47. #elif defined(_GLIBCXX_TR1_CMATH)
  48. namespace tr1
  49. {
  50. # define _GLIBCXX_MATH_NS ::std::tr1
  51. #else
  52. # error do not include this header directly, use <cmath> or <tr1/cmath>
  53. #endif
  54. // [5.2] Special functions
  55. // Implementation-space details.
  56. namespace __detail
  57. {
  58. /**
  59. * @brief Return the beta function: \f$B(x,y)\f$.
  60. *
  61. * The beta function is defined by
  62. * @f[
  63. * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
  64. * @f]
  65. *
  66. * @param __x The first argument of the beta function.
  67. * @param __y The second argument of the beta function.
  68. * @return The beta function.
  69. */
  70. template<typename _Tp>
  71. _Tp
  72. __beta_gamma(_Tp __x, _Tp __y)
  73. {
  74. _Tp __bet;
  75. #if _GLIBCXX_USE_C99_MATH_TR1
  76. if (__x > __y)
  77. {
  78. __bet = _GLIBCXX_MATH_NS::tgamma(__x)
  79. / _GLIBCXX_MATH_NS::tgamma(__x + __y);
  80. __bet *= _GLIBCXX_MATH_NS::tgamma(__y);
  81. }
  82. else
  83. {
  84. __bet = _GLIBCXX_MATH_NS::tgamma(__y)
  85. / _GLIBCXX_MATH_NS::tgamma(__x + __y);
  86. __bet *= _GLIBCXX_MATH_NS::tgamma(__x);
  87. }
  88. #else
  89. if (__x > __y)
  90. {
  91. __bet = __gamma(__x) / __gamma(__x + __y);
  92. __bet *= __gamma(__y);
  93. }
  94. else
  95. {
  96. __bet = __gamma(__y) / __gamma(__x + __y);
  97. __bet *= __gamma(__x);
  98. }
  99. #endif
  100. return __bet;
  101. }
  102. /**
  103. * @brief Return the beta function \f$B(x,y)\f$ using
  104. * the log gamma functions.
  105. *
  106. * The beta function is defined by
  107. * @f[
  108. * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
  109. * @f]
  110. *
  111. * @param __x The first argument of the beta function.
  112. * @param __y The second argument of the beta function.
  113. * @return The beta function.
  114. */
  115. template<typename _Tp>
  116. _Tp
  117. __beta_lgamma(_Tp __x, _Tp __y)
  118. {
  119. #if _GLIBCXX_USE_C99_MATH_TR1
  120. _Tp __bet = _GLIBCXX_MATH_NS::lgamma(__x)
  121. + _GLIBCXX_MATH_NS::lgamma(__y)
  122. - _GLIBCXX_MATH_NS::lgamma(__x + __y);
  123. #else
  124. _Tp __bet = __log_gamma(__x)
  125. + __log_gamma(__y)
  126. - __log_gamma(__x + __y);
  127. #endif
  128. __bet = std::exp(__bet);
  129. return __bet;
  130. }
  131. /**
  132. * @brief Return the beta function \f$B(x,y)\f$ using
  133. * the product form.
  134. *
  135. * The beta function is defined by
  136. * @f[
  137. * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
  138. * @f]
  139. *
  140. * @param __x The first argument of the beta function.
  141. * @param __y The second argument of the beta function.
  142. * @return The beta function.
  143. */
  144. template<typename _Tp>
  145. _Tp
  146. __beta_product(_Tp __x, _Tp __y)
  147. {
  148. _Tp __bet = (__x + __y) / (__x * __y);
  149. unsigned int __max_iter = 1000000;
  150. for (unsigned int __k = 1; __k < __max_iter; ++__k)
  151. {
  152. _Tp __term = (_Tp(1) + (__x + __y) / __k)
  153. / ((_Tp(1) + __x / __k) * (_Tp(1) + __y / __k));
  154. __bet *= __term;
  155. }
  156. return __bet;
  157. }
  158. /**
  159. * @brief Return the beta function \f$ B(x,y) \f$.
  160. *
  161. * The beta function is defined by
  162. * @f[
  163. * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
  164. * @f]
  165. *
  166. * @param __x The first argument of the beta function.
  167. * @param __y The second argument of the beta function.
  168. * @return The beta function.
  169. */
  170. template<typename _Tp>
  171. inline _Tp
  172. __beta(_Tp __x, _Tp __y)
  173. {
  174. if (__isnan(__x) || __isnan(__y))
  175. return std::numeric_limits<_Tp>::quiet_NaN();
  176. else
  177. return __beta_lgamma(__x, __y);
  178. }
  179. } // namespace __detail
  180. #undef _GLIBCXX_MATH_NS
  181. #if ! _GLIBCXX_USE_STD_SPEC_FUNCS && defined(_GLIBCXX_TR1_CMATH)
  182. } // namespace tr1
  183. #endif
  184. _GLIBCXX_END_NAMESPACE_VERSION
  185. }
  186. #endif // _GLIBCXX_TR1_BETA_FUNCTION_TCC