hypergeometric.tcc 27 KB

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