14fee23f9Smrg // Special functions -*- C++ -*- 24fee23f9Smrg 3*b1e83836Smrg // Copyright (C) 2006-2022 Free Software Foundation, Inc. 44fee23f9Smrg // 54fee23f9Smrg // This file is part of the GNU ISO C++ Library. This library is free 64fee23f9Smrg // software; you can redistribute it and/or modify it under the 74fee23f9Smrg // terms of the GNU General Public License as published by the 84fee23f9Smrg // Free Software Foundation; either version 3, or (at your option) 94fee23f9Smrg // any later version. 104fee23f9Smrg // 114fee23f9Smrg // This library is distributed in the hope that it will be useful, 124fee23f9Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 134fee23f9Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144fee23f9Smrg // GNU General Public License for more details. 154fee23f9Smrg // 164fee23f9Smrg // Under Section 7 of GPL version 3, you are granted additional 174fee23f9Smrg // permissions described in the GCC Runtime Library Exception, version 184fee23f9Smrg // 3.1, as published by the Free Software Foundation. 194fee23f9Smrg 204fee23f9Smrg // You should have received a copy of the GNU General Public License and 214fee23f9Smrg // a copy of the GCC Runtime Library Exception along with this program; 224fee23f9Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234fee23f9Smrg // <http://www.gnu.org/licenses/>. 244fee23f9Smrg 254fee23f9Smrg /** @file tr1/beta_function.tcc 264fee23f9Smrg * This is an internal header file, included by other library headers. 2748fb7bfaSmrg * Do not attempt to use it directly. @headername{tr1/cmath} 284fee23f9Smrg */ 294fee23f9Smrg 304fee23f9Smrg // 314fee23f9Smrg // ISO C++ 14882 TR1: 5.2 Special functions 324fee23f9Smrg // 334fee23f9Smrg 344fee23f9Smrg // Written by Edward Smith-Rowland based on: 354fee23f9Smrg // (1) Handbook of Mathematical Functions, 364fee23f9Smrg // ed. Milton Abramowitz and Irene A. Stegun, 374fee23f9Smrg // Dover Publications, 384fee23f9Smrg // Section 6, pp. 253-266 394fee23f9Smrg // (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl 404fee23f9Smrg // (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, 414fee23f9Smrg // W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), 424fee23f9Smrg // 2nd ed, pp. 213-216 434fee23f9Smrg // (4) Gamma, Exploring Euler's Constant, Julian Havil, 444fee23f9Smrg // Princeton, 2003. 454fee23f9Smrg 464fee23f9Smrg #ifndef _GLIBCXX_TR1_BETA_FUNCTION_TCC 474fee23f9Smrg #define _GLIBCXX_TR1_BETA_FUNCTION_TCC 1 484fee23f9Smrg 4948fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default) 504fee23f9Smrg { 51a3e9eb18Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 52a3e9eb18Smrg 53b17d1066Smrg #if _GLIBCXX_USE_STD_SPEC_FUNCS 54f9a78e0eSmrg # define _GLIBCXX_MATH_NS ::std 55f9a78e0eSmrg #elif defined(_GLIBCXX_TR1_CMATH) 564fee23f9Smrg namespace tr1 574fee23f9Smrg { 58f9a78e0eSmrg # define _GLIBCXX_MATH_NS ::std::tr1 59f9a78e0eSmrg #else 60f9a78e0eSmrg # error do not include this header directly, use <cmath> or <tr1/cmath> 61f9a78e0eSmrg #endif 624fee23f9Smrg // [5.2] Special functions 634fee23f9Smrg 644fee23f9Smrg // Implementation-space details. 654fee23f9Smrg namespace __detail 664fee23f9Smrg { 674fee23f9Smrg /** 684fee23f9Smrg * @brief Return the beta function: \f$B(x,y)\f$. 694fee23f9Smrg * 704fee23f9Smrg * The beta function is defined by 714fee23f9Smrg * @f[ 724fee23f9Smrg * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} 734fee23f9Smrg * @f] 744fee23f9Smrg * 754fee23f9Smrg * @param __x The first argument of the beta function. 764fee23f9Smrg * @param __y The second argument of the beta function. 774fee23f9Smrg * @return The beta function. 784fee23f9Smrg */ 794fee23f9Smrg template<typename _Tp> 804fee23f9Smrg _Tp __beta_gamma(_Tp __x,_Tp __y)814fee23f9Smrg __beta_gamma(_Tp __x, _Tp __y) 824fee23f9Smrg { 834fee23f9Smrg 844fee23f9Smrg _Tp __bet; 854fee23f9Smrg #if _GLIBCXX_USE_C99_MATH_TR1 864fee23f9Smrg if (__x > __y) 874fee23f9Smrg { 88f9a78e0eSmrg __bet = _GLIBCXX_MATH_NS::tgamma(__x) 89f9a78e0eSmrg / _GLIBCXX_MATH_NS::tgamma(__x + __y); 90f9a78e0eSmrg __bet *= _GLIBCXX_MATH_NS::tgamma(__y); 914fee23f9Smrg } 924fee23f9Smrg else 934fee23f9Smrg { 94f9a78e0eSmrg __bet = _GLIBCXX_MATH_NS::tgamma(__y) 95f9a78e0eSmrg / _GLIBCXX_MATH_NS::tgamma(__x + __y); 96f9a78e0eSmrg __bet *= _GLIBCXX_MATH_NS::tgamma(__x); 974fee23f9Smrg } 984fee23f9Smrg #else 994fee23f9Smrg if (__x > __y) 1004fee23f9Smrg { 1014fee23f9Smrg __bet = __gamma(__x) / __gamma(__x + __y); 1024fee23f9Smrg __bet *= __gamma(__y); 1034fee23f9Smrg } 1044fee23f9Smrg else 1054fee23f9Smrg { 1064fee23f9Smrg __bet = __gamma(__y) / __gamma(__x + __y); 1074fee23f9Smrg __bet *= __gamma(__x); 1084fee23f9Smrg } 1094fee23f9Smrg #endif 1104fee23f9Smrg 1114fee23f9Smrg return __bet; 1124fee23f9Smrg } 1134fee23f9Smrg 1144fee23f9Smrg /** 1154fee23f9Smrg * @brief Return the beta function \f$B(x,y)\f$ using 1164fee23f9Smrg * the log gamma functions. 1174fee23f9Smrg * 1184fee23f9Smrg * The beta function is defined by 1194fee23f9Smrg * @f[ 1204fee23f9Smrg * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} 1214fee23f9Smrg * @f] 1224fee23f9Smrg * 1234fee23f9Smrg * @param __x The first argument of the beta function. 1244fee23f9Smrg * @param __y The second argument of the beta function. 1254fee23f9Smrg * @return The beta function. 1264fee23f9Smrg */ 1274fee23f9Smrg template<typename _Tp> 1284fee23f9Smrg _Tp __beta_lgamma(_Tp __x,_Tp __y)1294fee23f9Smrg __beta_lgamma(_Tp __x, _Tp __y) 1304fee23f9Smrg { 1314fee23f9Smrg #if _GLIBCXX_USE_C99_MATH_TR1 132f9a78e0eSmrg _Tp __bet = _GLIBCXX_MATH_NS::lgamma(__x) 133f9a78e0eSmrg + _GLIBCXX_MATH_NS::lgamma(__y) 134f9a78e0eSmrg - _GLIBCXX_MATH_NS::lgamma(__x + __y); 1354fee23f9Smrg #else 1364fee23f9Smrg _Tp __bet = __log_gamma(__x) 1374fee23f9Smrg + __log_gamma(__y) 1384fee23f9Smrg - __log_gamma(__x + __y); 1394fee23f9Smrg #endif 1404fee23f9Smrg __bet = std::exp(__bet); 1414fee23f9Smrg return __bet; 1424fee23f9Smrg } 1434fee23f9Smrg 1444fee23f9Smrg 1454fee23f9Smrg /** 1464fee23f9Smrg * @brief Return the beta function \f$B(x,y)\f$ using 1474fee23f9Smrg * the product form. 1484fee23f9Smrg * 1494fee23f9Smrg * The beta function is defined by 1504fee23f9Smrg * @f[ 1514fee23f9Smrg * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} 1524fee23f9Smrg * @f] 1534fee23f9Smrg * 1544fee23f9Smrg * @param __x The first argument of the beta function. 1554fee23f9Smrg * @param __y The second argument of the beta function. 1564fee23f9Smrg * @return The beta function. 1574fee23f9Smrg */ 1584fee23f9Smrg template<typename _Tp> 1594fee23f9Smrg _Tp __beta_product(_Tp __x,_Tp __y)1604fee23f9Smrg __beta_product(_Tp __x, _Tp __y) 1614fee23f9Smrg { 1624fee23f9Smrg 1634fee23f9Smrg _Tp __bet = (__x + __y) / (__x * __y); 1644fee23f9Smrg 1654fee23f9Smrg unsigned int __max_iter = 1000000; 1664fee23f9Smrg for (unsigned int __k = 1; __k < __max_iter; ++__k) 1674fee23f9Smrg { 1684fee23f9Smrg _Tp __term = (_Tp(1) + (__x + __y) / __k) 1694fee23f9Smrg / ((_Tp(1) + __x / __k) * (_Tp(1) + __y / __k)); 1704fee23f9Smrg __bet *= __term; 1714fee23f9Smrg } 1724fee23f9Smrg 1734fee23f9Smrg return __bet; 1744fee23f9Smrg } 1754fee23f9Smrg 1764fee23f9Smrg 1774fee23f9Smrg /** 1784fee23f9Smrg * @brief Return the beta function \f$ B(x,y) \f$. 1794fee23f9Smrg * 1804fee23f9Smrg * The beta function is defined by 1814fee23f9Smrg * @f[ 1824fee23f9Smrg * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} 1834fee23f9Smrg * @f] 1844fee23f9Smrg * 1854fee23f9Smrg * @param __x The first argument of the beta function. 1864fee23f9Smrg * @param __y The second argument of the beta function. 1874fee23f9Smrg * @return The beta function. 1884fee23f9Smrg */ 1894fee23f9Smrg template<typename _Tp> 1904fee23f9Smrg inline _Tp __beta(_Tp __x,_Tp __y)1914fee23f9Smrg __beta(_Tp __x, _Tp __y) 1924fee23f9Smrg { 1934fee23f9Smrg if (__isnan(__x) || __isnan(__y)) 1944fee23f9Smrg return std::numeric_limits<_Tp>::quiet_NaN(); 1954fee23f9Smrg else 1964fee23f9Smrg return __beta_lgamma(__x, __y); 1974fee23f9Smrg } 198f9a78e0eSmrg } // namespace __detail 199f9a78e0eSmrg #undef _GLIBCXX_MATH_NS 200b17d1066Smrg #if ! _GLIBCXX_USE_STD_SPEC_FUNCS && defined(_GLIBCXX_TR1_CMATH) 201f9a78e0eSmrg } // namespace tr1 202f9a78e0eSmrg #endif 203a3e9eb18Smrg 204a3e9eb18Smrg _GLIBCXX_END_NAMESPACE_VERSION 2054fee23f9Smrg } 2064fee23f9Smrg 2074d5abbe8Smrg #endif // _GLIBCXX_TR1_BETA_FUNCTION_TCC 208