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