1// Special functions -*- C++ -*-
2
3// Copyright (C) 2006, 2007, 2008, 2009, 2010
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.
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// 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.
20
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/>.
25
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 */
30
31//
32// ISO C++ 14882 TR1: 5.2  Special functions
33//
34
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
41
42#ifndef _GLIBCXX_TR1_HYPERGEOMETRIC_TCC
43#define _GLIBCXX_TR1_HYPERGEOMETRIC_TCC 1
44
45namespace std _GLIBCXX_VISIBILITY(default)
46{
47namespace tr1
48{
49  // [5.2] Special functions
50
51  // Implementation-space details.
52  namespace __detail
53  {
54  _GLIBCXX_BEGIN_NAMESPACE_VERSION
55
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();
82
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."));
100
101      return __Fac;
102    }
103
104
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;
128
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);
132
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;
137
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);
156
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;
162
163          __prec = std::abs((__F - __r) / __F);
164          __F = __r;
165
166          if (__prec < __eps || __n > __nmax)
167            break;
168
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            }
192
193          ++__n;
194          __Bnm3 = __Bnm2;
195          __Bnm2 = __Bnm1;
196          __Bnm1 = __Bn;
197          __Anm3 = __Anm2;
198          __Anm2 = __Anm1;
199          __Anm1 = __An;
200        }
201
202      if (__n >= __nmax)
203        std::__throw_runtime_error(__N("Iteration failed to converge "
204                                       "in __conf_hyperg_luke."));
205
206      return __F;
207    }
208
209
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    }
243
244
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();
271
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."));
289
290      return __Fabc;
291    }
292
293
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)));
313
314      _Tp __F = _Tp(1);
315
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);
319
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;
324
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);
350
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;
356
357          const _Tp __prec = std::abs((__F - __r) / __F);
358          __F = __r;
359
360          if (__prec < __eps || __n > __nmax)
361            break;
362
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            }
386
387          ++__n;
388          __Bnm3 = __Bnm2;
389          __Bnm2 = __Bnm1;
390          __Bnm1 = __Bn;
391          __Anm3 = __Anm2;
392          __Anm2 = __Anm1;
393          __Anm1 = __An;
394        }
395
396      if (__n >= __nmax)
397        std::__throw_runtime_error(__N("Iteration failed to converge "
398                                       "in __hyperg_luke."));
399
400      return __F;
401    }
402
403
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);
445
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;
451
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            }
463
464          const _Tp __lng_c = __log_gamma(__c);
465
466          //  Evaluate F1.
467          if (__ad < __eps)
468            {
469              //  d = c - a - b = 0.
470              __F1 = _Tp(0);
471            }
472          else
473            {
474
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                }
487
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;
497
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                    }
507
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
521
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            }
534
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);
544
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;
551
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"));
574
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
586
587          const _Tp __sgn_2 = (__intd % 2 == 1 ? -_Tp(1) : _Tp(1));
588          const _Tp __F = __F1 + __sgn_2 * __F2;
589
590          return __F;
591        }
592      else
593        {
594          //  d = c - a - b not an integer.
595
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            }
612
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            }
627
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);
634
635          const _Tp __sgn1 = __sgn_gc * __sgn_gd  * __sgn_g1ca * __sgn_g1cb;
636          const _Tp __sgn2 = __sgn_gc * __sgn_gmd * __sgn_g2a  * __sgn_g2b;
637
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            }
695
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);
700
701          const _Tp __F = __pre1 * __F1 + __pre2 * __F2;
702
703          return __F;
704        }
705    }
706
707
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    }
773
774  _GLIBCXX_END_NAMESPACE_VERSION
775  } // namespace std::tr1::__detail
776}
777}
778
779#endif // _GLIBCXX_TR1_HYPERGEOMETRIC_TCC
780