xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/tr1/beta_function.tcc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
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