hypergeometric.tcc 27 KB

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