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