OSDN Git Service

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