xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/tr1/beta_function.tcc (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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