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