Update Copyright years for files modified in 2011 and/or 2012.
[official-gcc.git] / libstdc++-v3 / include / tr1 / hypergeometric.tcc
blob27713b82c7f9a9a595fafb3397866aa5fb2dda61
1 // Special functions -*- C++ -*-
3 // Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
26 /** @file tr1/hypergeometric.tcc
27  *  This is an internal header file, included by other library headers.
28  *  Do not attempt to use it directly. @headername{tr1/cmath}
29  */
32 // ISO C++ 14882 TR1: 5.2  Special functions
35 // Written by Edward Smith-Rowland based:
36 //   (1) Handbook of Mathematical Functions,
37 //       ed. Milton Abramowitz and Irene A. Stegun,
38 //       Dover Publications,
39 //       Section 6, pp. 555-566
40 //   (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
42 #ifndef _GLIBCXX_TR1_HYPERGEOMETRIC_TCC
43 #define _GLIBCXX_TR1_HYPERGEOMETRIC_TCC 1
45 namespace std _GLIBCXX_VISIBILITY(default)
47 namespace tr1
49   // [5.2] Special functions
51   // Implementation-space details.
52   namespace __detail
53   {
54   _GLIBCXX_BEGIN_NAMESPACE_VERSION
56     /**
57      *   @brief This routine returns the confluent hypergeometric function
58      *          by series expansion.
59      * 
60      *   @f[
61      *     _1F_1(a;c;x) = \frac{\Gamma(c)}{\Gamma(a)}
62      *                      \sum_{n=0}^{\infty}
63      *                      \frac{\Gamma(a+n)}{\Gamma(c+n)}
64      *                      \frac{x^n}{n!}
65      *   @f]
66      * 
67      *   If a and b are integers and a < 0 and either b > 0 or b < a
68      *   then the series is a polynomial with a finite number of
69      *   terms.  If b is an integer and b <= 0 the confluent
70      *   hypergeometric function is undefined.
71      *
72      *   @param  __a  The "numerator" parameter.
73      *   @param  __c  The "denominator" parameter.
74      *   @param  __x  The argument of the confluent hypergeometric function.
75      *   @return  The confluent hypergeometric function.
76      */
77     template<typename _Tp>
78     _Tp
79     __conf_hyperg_series(const _Tp __a, const _Tp __c, const _Tp __x)
80     {
81       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
83       _Tp __term = _Tp(1);
84       _Tp __Fac = _Tp(1);
85       const unsigned int __max_iter = 100000;
86       unsigned int __i;
87       for (__i = 0; __i < __max_iter; ++__i)
88         {
89           __term *= (__a + _Tp(__i)) * __x
90                   / ((__c + _Tp(__i)) * _Tp(1 + __i));
91           if (std::abs(__term) < __eps)
92             {
93               break;
94             }
95           __Fac += __term;
96         }
97       if (__i == __max_iter)
98         std::__throw_runtime_error(__N("Series failed to converge "
99                                        "in __conf_hyperg_series."));
101       return __Fac;
102     }
105     /**
106      *  @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
107      *          by an iterative procedure described in
108      *          Luke, Algorithms for the Computation of Mathematical Functions.
109      *
110      *  Like the case of the 2F1 rational approximations, these are 
111      *  probably guaranteed to converge for x < 0, barring gross    
112      *  numerical instability in the pre-asymptotic regime.         
113      */
114     template<typename _Tp>
115     _Tp
116     __conf_hyperg_luke(const _Tp __a, const _Tp __c, const _Tp __xin)
117     {
118       const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L));
119       const int __nmax = 20000;
120       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
121       const _Tp __x  = -__xin;
122       const _Tp __x3 = __x * __x * __x;
123       const _Tp __t0 = __a / __c;
124       const _Tp __t1 = (__a + _Tp(1)) / (_Tp(2) * __c);
125       const _Tp __t2 = (__a + _Tp(2)) / (_Tp(2) * (__c + _Tp(1)));
126       _Tp __F = _Tp(1);
127       _Tp __prec;
129       _Tp __Bnm3 = _Tp(1);
130       _Tp __Bnm2 = _Tp(1) + __t1 * __x;
131       _Tp __Bnm1 = _Tp(1) + __t2 * __x * (_Tp(1) + __t1 / _Tp(3) * __x);
133       _Tp __Anm3 = _Tp(1);
134       _Tp __Anm2 = __Bnm2 - __t0 * __x;
135       _Tp __Anm1 = __Bnm1 - __t0 * (_Tp(1) + __t2 * __x) * __x
136                  + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x;
138       int __n = 3;
139       while(1)
140         {
141           _Tp __npam1 = _Tp(__n - 1) + __a;
142           _Tp __npcm1 = _Tp(__n - 1) + __c;
143           _Tp __npam2 = _Tp(__n - 2) + __a;
144           _Tp __npcm2 = _Tp(__n - 2) + __c;
145           _Tp __tnm1  = _Tp(2 * __n - 1);
146           _Tp __tnm3  = _Tp(2 * __n - 3);
147           _Tp __tnm5  = _Tp(2 * __n - 5);
148           _Tp __F1 =  (_Tp(__n - 2) - __a) / (_Tp(2) * __tnm3 * __npcm1);
149           _Tp __F2 =  (_Tp(__n) + __a) * __npam1
150                    / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1);
151           _Tp __F3 = -__npam2 * __npam1 * (_Tp(__n - 2) - __a)
152                    / (_Tp(8) * __tnm3 * __tnm3 * __tnm5
153                    * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1);
154           _Tp __E  = -__npam1 * (_Tp(__n - 1) - __c)
155                    / (_Tp(2) * __tnm3 * __npcm2 * __npcm1);
157           _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1
158                    + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3;
159           _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1
160                    + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3;
161           _Tp __r = __An / __Bn;
163           __prec = std::abs((__F - __r) / __F);
164           __F = __r;
166           if (__prec < __eps || __n > __nmax)
167             break;
169           if (std::abs(__An) > __big || std::abs(__Bn) > __big)
170             {
171               __An   /= __big;
172               __Bn   /= __big;
173               __Anm1 /= __big;
174               __Bnm1 /= __big;
175               __Anm2 /= __big;
176               __Bnm2 /= __big;
177               __Anm3 /= __big;
178               __Bnm3 /= __big;
179             }
180           else if (std::abs(__An) < _Tp(1) / __big
181                 || std::abs(__Bn) < _Tp(1) / __big)
182             {
183               __An   *= __big;
184               __Bn   *= __big;
185               __Anm1 *= __big;
186               __Bnm1 *= __big;
187               __Anm2 *= __big;
188               __Bnm2 *= __big;
189               __Anm3 *= __big;
190               __Bnm3 *= __big;
191             }
193           ++__n;
194           __Bnm3 = __Bnm2;
195           __Bnm2 = __Bnm1;
196           __Bnm1 = __Bn;
197           __Anm3 = __Anm2;
198           __Anm2 = __Anm1;
199           __Anm1 = __An;
200         }
202       if (__n >= __nmax)
203         std::__throw_runtime_error(__N("Iteration failed to converge "
204                                        "in __conf_hyperg_luke."));
206       return __F;
207     }
210     /**
211      *   @brief  Return the confluent hypogeometric function
212      *           @f$ _1F_1(a;c;x) @f$.
213      * 
214      *   @todo  Handle b == nonpositive integer blowup - return NaN.
215      *
216      *   @param  __a  The @a numerator parameter.
217      *   @param  __c  The @a denominator parameter.
218      *   @param  __x  The argument of the confluent hypergeometric function.
219      *   @return  The confluent hypergeometric function.
220      */
221     template<typename _Tp>
222     inline _Tp
223     __conf_hyperg(const _Tp __a, const _Tp __c, const _Tp __x)
224     {
225 #if _GLIBCXX_USE_C99_MATH_TR1
226       const _Tp __c_nint = std::tr1::nearbyint(__c);
227 #else
228       const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L));
229 #endif
230       if (__isnan(__a) || __isnan(__c) || __isnan(__x))
231         return std::numeric_limits<_Tp>::quiet_NaN();
232       else if (__c_nint == __c && __c_nint <= 0)
233         return std::numeric_limits<_Tp>::infinity();
234       else if (__a == _Tp(0))
235         return _Tp(1);
236       else if (__c == __a)
237         return std::exp(__x);
238       else if (__x < _Tp(0))
239         return __conf_hyperg_luke(__a, __c, __x);
240       else
241         return __conf_hyperg_series(__a, __c, __x);
242     }
245     /**
246      *   @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
247      *   by series expansion.
248      * 
249      *   The hypogeometric function is defined by
250      *   @f[
251      *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
252      *                      \sum_{n=0}^{\infty}
253      *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
254      *                      \frac{x^n}{n!}
255      *   @f]
256      * 
257      *   This works and it's pretty fast.
258      *
259      *   @param  __a  The first @a numerator parameter.
260      *   @param  __a  The second @a numerator parameter.
261      *   @param  __c  The @a denominator parameter.
262      *   @param  __x  The argument of the confluent hypergeometric function.
263      *   @return  The confluent hypergeometric function.
264      */
265     template<typename _Tp>
266     _Tp
267     __hyperg_series(const _Tp __a, const _Tp __b,
268                     const _Tp __c, const _Tp __x)
269     {
270       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
272       _Tp __term = _Tp(1);
273       _Tp __Fabc = _Tp(1);
274       const unsigned int __max_iter = 100000;
275       unsigned int __i;
276       for (__i = 0; __i < __max_iter; ++__i)
277         {
278           __term *= (__a + _Tp(__i)) * (__b + _Tp(__i)) * __x
279                   / ((__c + _Tp(__i)) * _Tp(1 + __i));
280           if (std::abs(__term) < __eps)
281             {
282               break;
283             }
284           __Fabc += __term;
285         }
286       if (__i == __max_iter)
287         std::__throw_runtime_error(__N("Series failed to converge "
288                                        "in __hyperg_series."));
290       return __Fabc;
291     }
294     /**
295      *   @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
296      *           by an iterative procedure described in
297      *           Luke, Algorithms for the Computation of Mathematical Functions.
298      */
299     template<typename _Tp>
300     _Tp
301     __hyperg_luke(const _Tp __a, const _Tp __b, const _Tp __c,
302                   const _Tp __xin)
303     {
304       const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L));
305       const int __nmax = 20000;
306       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
307       const _Tp __x  = -__xin;
308       const _Tp __x3 = __x * __x * __x;
309       const _Tp __t0 = __a * __b / __c;
310       const _Tp __t1 = (__a + _Tp(1)) * (__b + _Tp(1)) / (_Tp(2) * __c);
311       const _Tp __t2 = (__a + _Tp(2)) * (__b + _Tp(2))
312                      / (_Tp(2) * (__c + _Tp(1)));
314       _Tp __F = _Tp(1);
316       _Tp __Bnm3 = _Tp(1);
317       _Tp __Bnm2 = _Tp(1) + __t1 * __x;
318       _Tp __Bnm1 = _Tp(1) + __t2 * __x * (_Tp(1) + __t1 / _Tp(3) * __x);
320       _Tp __Anm3 = _Tp(1);
321       _Tp __Anm2 = __Bnm2 - __t0 * __x;
322       _Tp __Anm1 = __Bnm1 - __t0 * (_Tp(1) + __t2 * __x) * __x
323                  + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x;
325       int __n = 3;
326       while (1)
327         {
328           const _Tp __npam1 = _Tp(__n - 1) + __a;
329           const _Tp __npbm1 = _Tp(__n - 1) + __b;
330           const _Tp __npcm1 = _Tp(__n - 1) + __c;
331           const _Tp __npam2 = _Tp(__n - 2) + __a;
332           const _Tp __npbm2 = _Tp(__n - 2) + __b;
333           const _Tp __npcm2 = _Tp(__n - 2) + __c;
334           const _Tp __tnm1  = _Tp(2 * __n - 1);
335           const _Tp __tnm3  = _Tp(2 * __n - 3);
336           const _Tp __tnm5  = _Tp(2 * __n - 5);
337           const _Tp __n2 = __n * __n;
338           const _Tp __F1 = (_Tp(3) * __n2 + (__a + __b - _Tp(6)) * __n
339                          + _Tp(2) - __a * __b - _Tp(2) * (__a + __b))
340                          / (_Tp(2) * __tnm3 * __npcm1);
341           const _Tp __F2 = -(_Tp(3) * __n2 - (__a + __b + _Tp(6)) * __n
342                          + _Tp(2) - __a * __b) * __npam1 * __npbm1
343                          / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1);
344           const _Tp __F3 = (__npam2 * __npam1 * __npbm2 * __npbm1
345                          * (_Tp(__n - 2) - __a) * (_Tp(__n - 2) - __b))
346                          / (_Tp(8) * __tnm3 * __tnm3 * __tnm5
347                          * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1);
348           const _Tp __E  = -__npam1 * __npbm1 * (_Tp(__n - 1) - __c)
349                          / (_Tp(2) * __tnm3 * __npcm2 * __npcm1);
351           _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1
352                    + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3;
353           _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1
354                    + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3;
355           const _Tp __r = __An / __Bn;
357           const _Tp __prec = std::abs((__F - __r) / __F);
358           __F = __r;
360           if (__prec < __eps || __n > __nmax)
361             break;
363           if (std::abs(__An) > __big || std::abs(__Bn) > __big)
364             {
365               __An   /= __big;
366               __Bn   /= __big;
367               __Anm1 /= __big;
368               __Bnm1 /= __big;
369               __Anm2 /= __big;
370               __Bnm2 /= __big;
371               __Anm3 /= __big;
372               __Bnm3 /= __big;
373             }
374           else if (std::abs(__An) < _Tp(1) / __big
375                 || std::abs(__Bn) < _Tp(1) / __big)
376             {
377               __An   *= __big;
378               __Bn   *= __big;
379               __Anm1 *= __big;
380               __Bnm1 *= __big;
381               __Anm2 *= __big;
382               __Bnm2 *= __big;
383               __Anm3 *= __big;
384               __Bnm3 *= __big;
385             }
387           ++__n;
388           __Bnm3 = __Bnm2;
389           __Bnm2 = __Bnm1;
390           __Bnm1 = __Bn;
391           __Anm3 = __Anm2;
392           __Anm2 = __Anm1;
393           __Anm1 = __An;
394         }
396       if (__n >= __nmax)
397         std::__throw_runtime_error(__N("Iteration failed to converge "
398                                        "in __hyperg_luke."));
400       return __F;
401     }
404     /**
405      *  @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$ 
406      *  by the reflection formulae in Abramowitz & Stegun formula
407      *  15.3.6 for d = c - a - b not integral and formula 15.3.11 for
408      *  d = c - a - b integral.  This assumes a, b, c != negative
409      *  integer.
410      *
411      *   The hypogeometric function is defined by
412      *   @f[
413      *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
414      *                      \sum_{n=0}^{\infty}
415      *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
416      *                      \frac{x^n}{n!}
417      *   @f]
418      *
419      *   The reflection formula for nonintegral @f$ d = c - a - b @f$ is:
420      *   @f[
421      *     _2F_1(a,b;c;x) = \frac{\Gamma(c)\Gamma(d)}{\Gamma(c-a)\Gamma(c-b)}
422      *                            _2F_1(a,b;1-d;1-x)
423      *                    + \frac{\Gamma(c)\Gamma(-d)}{\Gamma(a)\Gamma(b)}
424      *                            _2F_1(c-a,c-b;1+d;1-x)
425      *   @f]
426      *
427      *   The reflection formula for integral @f$ m = c - a - b @f$ is:
428      *   @f[
429      *     _2F_1(a,b;a+b+m;x) = \frac{\Gamma(m)\Gamma(a+b+m)}{\Gamma(a+m)\Gamma(b+m)}
430      *                        \sum_{k=0}^{m-1} \frac{(m+a)_k(m+b)_k}{k!(1-m)_k}
431      *                      - 
432      *   @f]
433      */
434     template<typename _Tp>
435     _Tp
436     __hyperg_reflect(const _Tp __a, const _Tp __b, const _Tp __c,
437                      const _Tp __x)
438     {
439       const _Tp __d = __c - __a - __b;
440       const int __intd  = std::floor(__d + _Tp(0.5L));
441       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
442       const _Tp __toler = _Tp(1000) * __eps;
443       const _Tp __log_max = std::log(std::numeric_limits<_Tp>::max());
444       const bool __d_integer = (std::abs(__d - __intd) < __toler);
446       if (__d_integer)
447         {
448           const _Tp __ln_omx = std::log(_Tp(1) - __x);
449           const _Tp __ad = std::abs(__d);
450           _Tp __F1, __F2;
452           _Tp __d1, __d2;
453           if (__d >= _Tp(0))
454             {
455               __d1 = __d;
456               __d2 = _Tp(0);
457             }
458           else
459             {
460               __d1 = _Tp(0);
461               __d2 = __d;
462             }
464           const _Tp __lng_c = __log_gamma(__c);
466           //  Evaluate F1.
467           if (__ad < __eps)
468             {
469               //  d = c - a - b = 0.
470               __F1 = _Tp(0);
471             }
472           else
473             {
475               bool __ok_d1 = true;
476               _Tp __lng_ad, __lng_ad1, __lng_bd1;
477               __try
478                 {
479                   __lng_ad = __log_gamma(__ad);
480                   __lng_ad1 = __log_gamma(__a + __d1);
481                   __lng_bd1 = __log_gamma(__b + __d1);
482                 }
483               __catch(...)
484                 {
485                   __ok_d1 = false;
486                 }
488               if (__ok_d1)
489                 {
490                   /* Gamma functions in the denominator are ok.
491                    * Proceed with evaluation.
492                    */
493                   _Tp __sum1 = _Tp(1);
494                   _Tp __term = _Tp(1);
495                   _Tp __ln_pre1 = __lng_ad + __lng_c + __d2 * __ln_omx
496                                 - __lng_ad1 - __lng_bd1;
498                   /* Do F1 sum.
499                    */
500                   for (int __i = 1; __i < __ad; ++__i)
501                     {
502                       const int __j = __i - 1;
503                       __term *= (__a + __d2 + __j) * (__b + __d2 + __j)
504                               / (_Tp(1) + __d2 + __j) / __i * (_Tp(1) - __x);
505                       __sum1 += __term;
506                     }
508                   if (__ln_pre1 > __log_max)
509                     std::__throw_runtime_error(__N("Overflow of gamma functions"
510                                                    " in __hyperg_luke."));
511                   else
512                     __F1 = std::exp(__ln_pre1) * __sum1;
513                 }
514               else
515                 {
516                   //  Gamma functions in the denominator were not ok.
517                   //  So the F1 term is zero.
518                   __F1 = _Tp(0);
519                 }
520             } // end F1 evaluation
522           // Evaluate F2.
523           bool __ok_d2 = true;
524           _Tp __lng_ad2, __lng_bd2;
525           __try
526             {
527               __lng_ad2 = __log_gamma(__a + __d2);
528               __lng_bd2 = __log_gamma(__b + __d2);
529             }
530           __catch(...)
531             {
532               __ok_d2 = false;
533             }
535           if (__ok_d2)
536             {
537               //  Gamma functions in the denominator are ok.
538               //  Proceed with evaluation.
539               const int __maxiter = 2000;
540               const _Tp __psi_1 = -__numeric_constants<_Tp>::__gamma_e();
541               const _Tp __psi_1pd = __psi(_Tp(1) + __ad);
542               const _Tp __psi_apd1 = __psi(__a + __d1);
543               const _Tp __psi_bpd1 = __psi(__b + __d1);
545               _Tp __psi_term = __psi_1 + __psi_1pd - __psi_apd1
546                              - __psi_bpd1 - __ln_omx;
547               _Tp __fact = _Tp(1);
548               _Tp __sum2 = __psi_term;
549               _Tp __ln_pre2 = __lng_c + __d1 * __ln_omx
550                             - __lng_ad2 - __lng_bd2;
552               // Do F2 sum.
553               int __j;
554               for (__j = 1; __j < __maxiter; ++__j)
555                 {
556                   //  Values for psi functions use recurrence;
557                   //  Abramowitz & Stegun 6.3.5
558                   const _Tp __term1 = _Tp(1) / _Tp(__j)
559                                     + _Tp(1) / (__ad + __j);
560                   const _Tp __term2 = _Tp(1) / (__a + __d1 + _Tp(__j - 1))
561                                     + _Tp(1) / (__b + __d1 + _Tp(__j - 1));
562                   __psi_term += __term1 - __term2;
563                   __fact *= (__a + __d1 + _Tp(__j - 1))
564                           * (__b + __d1 + _Tp(__j - 1))
565                           / ((__ad + __j) * __j) * (_Tp(1) - __x);
566                   const _Tp __delta = __fact * __psi_term;
567                   __sum2 += __delta;
568                   if (std::abs(__delta) < __eps * std::abs(__sum2))
569                     break;
570                 }
571               if (__j == __maxiter)
572                 std::__throw_runtime_error(__N("Sum F2 failed to converge "
573                                                "in __hyperg_reflect"));
575               if (__sum2 == _Tp(0))
576                 __F2 = _Tp(0);
577               else
578                 __F2 = std::exp(__ln_pre2) * __sum2;
579             }
580           else
581             {
582               // Gamma functions in the denominator not ok.
583               // So the F2 term is zero.
584               __F2 = _Tp(0);
585             } // end F2 evaluation
587           const _Tp __sgn_2 = (__intd % 2 == 1 ? -_Tp(1) : _Tp(1));
588           const _Tp __F = __F1 + __sgn_2 * __F2;
590           return __F;
591         }
592       else
593         {
594           //  d = c - a - b not an integer.
596           //  These gamma functions appear in the denominator, so we
597           //  catch their harmless domain errors and set the terms to zero.
598           bool __ok1 = true;
599           _Tp __sgn_g1ca = _Tp(0), __ln_g1ca = _Tp(0);
600           _Tp __sgn_g1cb = _Tp(0), __ln_g1cb = _Tp(0);
601           __try
602             {
603               __sgn_g1ca = __log_gamma_sign(__c - __a);
604               __ln_g1ca = __log_gamma(__c - __a);
605               __sgn_g1cb = __log_gamma_sign(__c - __b);
606               __ln_g1cb = __log_gamma(__c - __b);
607             }
608           __catch(...)
609             {
610               __ok1 = false;
611             }
613           bool __ok2 = true;
614           _Tp __sgn_g2a = _Tp(0), __ln_g2a = _Tp(0);
615           _Tp __sgn_g2b = _Tp(0), __ln_g2b = _Tp(0);
616           __try
617             {
618               __sgn_g2a = __log_gamma_sign(__a);
619               __ln_g2a = __log_gamma(__a);
620               __sgn_g2b = __log_gamma_sign(__b);
621               __ln_g2b = __log_gamma(__b);
622             }
623           __catch(...)
624             {
625               __ok2 = false;
626             }
628           const _Tp __sgn_gc = __log_gamma_sign(__c);
629           const _Tp __ln_gc = __log_gamma(__c);
630           const _Tp __sgn_gd = __log_gamma_sign(__d);
631           const _Tp __ln_gd = __log_gamma(__d);
632           const _Tp __sgn_gmd = __log_gamma_sign(-__d);
633           const _Tp __ln_gmd = __log_gamma(-__d);
635           const _Tp __sgn1 = __sgn_gc * __sgn_gd  * __sgn_g1ca * __sgn_g1cb;
636           const _Tp __sgn2 = __sgn_gc * __sgn_gmd * __sgn_g2a  * __sgn_g2b;
638           _Tp __pre1, __pre2;
639           if (__ok1 && __ok2)
640             {
641               _Tp __ln_pre1 = __ln_gc + __ln_gd  - __ln_g1ca - __ln_g1cb;
642               _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a  - __ln_g2b
643                             + __d * std::log(_Tp(1) - __x);
644               if (__ln_pre1 < __log_max && __ln_pre2 < __log_max)
645                 {
646                   __pre1 = std::exp(__ln_pre1);
647                   __pre2 = std::exp(__ln_pre2);
648                   __pre1 *= __sgn1;
649                   __pre2 *= __sgn2;
650                 }
651               else
652                 {
653                   std::__throw_runtime_error(__N("Overflow of gamma functions "
654                                                  "in __hyperg_reflect"));
655                 }
656             }
657           else if (__ok1 && !__ok2)
658             {
659               _Tp __ln_pre1 = __ln_gc + __ln_gd - __ln_g1ca - __ln_g1cb;
660               if (__ln_pre1 < __log_max)
661                 {
662                   __pre1 = std::exp(__ln_pre1);
663                   __pre1 *= __sgn1;
664                   __pre2 = _Tp(0);
665                 }
666               else
667                 {
668                   std::__throw_runtime_error(__N("Overflow of gamma functions "
669                                                  "in __hyperg_reflect"));
670                 }
671             }
672           else if (!__ok1 && __ok2)
673             {
674               _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a - __ln_g2b
675                             + __d * std::log(_Tp(1) - __x);
676               if (__ln_pre2 < __log_max)
677                 {
678                   __pre1 = _Tp(0);
679                   __pre2 = std::exp(__ln_pre2);
680                   __pre2 *= __sgn2;
681                 }
682               else
683                 {
684                   std::__throw_runtime_error(__N("Overflow of gamma functions "
685                                                  "in __hyperg_reflect"));
686                 }
687             }
688           else
689             {
690               __pre1 = _Tp(0);
691               __pre2 = _Tp(0);
692               std::__throw_runtime_error(__N("Underflow of gamma functions "
693                                              "in __hyperg_reflect"));
694             }
696           const _Tp __F1 = __hyperg_series(__a, __b, _Tp(1) - __d,
697                                            _Tp(1) - __x);
698           const _Tp __F2 = __hyperg_series(__c - __a, __c - __b, _Tp(1) + __d,
699                                            _Tp(1) - __x);
701           const _Tp __F = __pre1 * __F1 + __pre2 * __F2;
703           return __F;
704         }
705     }
708     /**
709      *   @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$.
710      *
711      *   The hypogeometric function is defined by
712      *   @f[
713      *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
714      *                      \sum_{n=0}^{\infty}
715      *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
716      *                      \frac{x^n}{n!}
717      *   @f]
718      *
719      *   @param  __a  The first @a numerator parameter.
720      *   @param  __a  The second @a numerator parameter.
721      *   @param  __c  The @a denominator parameter.
722      *   @param  __x  The argument of the confluent hypergeometric function.
723      *   @return  The confluent hypergeometric function.
724      */
725     template<typename _Tp>
726     inline _Tp
727     __hyperg(const _Tp __a, const _Tp __b, const _Tp __c, const _Tp __x)
728     {
729 #if _GLIBCXX_USE_C99_MATH_TR1
730       const _Tp __a_nint = std::tr1::nearbyint(__a);
731       const _Tp __b_nint = std::tr1::nearbyint(__b);
732       const _Tp __c_nint = std::tr1::nearbyint(__c);
733 #else
734       const _Tp __a_nint = static_cast<int>(__a + _Tp(0.5L));
735       const _Tp __b_nint = static_cast<int>(__b + _Tp(0.5L));
736       const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L));
737 #endif
738       const _Tp __toler = _Tp(1000) * std::numeric_limits<_Tp>::epsilon();
739       if (std::abs(__x) >= _Tp(1))
740         std::__throw_domain_error(__N("Argument outside unit circle "
741                                       "in __hyperg."));
742       else if (__isnan(__a) || __isnan(__b)
743             || __isnan(__c) || __isnan(__x))
744         return std::numeric_limits<_Tp>::quiet_NaN();
745       else if (__c_nint == __c && __c_nint <= _Tp(0))
746         return std::numeric_limits<_Tp>::infinity();
747       else if (std::abs(__c - __b) < __toler || std::abs(__c - __a) < __toler)
748         return std::pow(_Tp(1) - __x, __c - __a - __b);
749       else if (__a >= _Tp(0) && __b >= _Tp(0) && __c >= _Tp(0)
750             && __x >= _Tp(0) && __x < _Tp(0.995L))
751         return __hyperg_series(__a, __b, __c, __x);
752       else if (std::abs(__a) < _Tp(10) && std::abs(__b) < _Tp(10))
753         {
754           //  For integer a and b the hypergeometric function is a
755           //  finite polynomial.
756           if (__a < _Tp(0)  &&  std::abs(__a - __a_nint) < __toler)
757             return __hyperg_series(__a_nint, __b, __c, __x);
758           else if (__b < _Tp(0)  &&  std::abs(__b - __b_nint) < __toler)
759             return __hyperg_series(__a, __b_nint, __c, __x);
760           else if (__x < -_Tp(0.25L))
761             return __hyperg_luke(__a, __b, __c, __x);
762           else if (__x < _Tp(0.5L))
763             return __hyperg_series(__a, __b, __c, __x);
764           else
765             if (std::abs(__c) > _Tp(10))
766               return __hyperg_series(__a, __b, __c, __x);
767             else
768               return __hyperg_reflect(__a, __b, __c, __x);
769         }
770       else
771         return __hyperg_luke(__a, __b, __c, __x);
772     }
774   _GLIBCXX_END_NAMESPACE_VERSION
775   } // namespace std::tr1::__detail
779 #endif // _GLIBCXX_TR1_HYPERGEOMETRIC_TCC