digamma.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. // (C) Copyright John Maddock 2006.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_SF_DIGAMMA_HPP
  6. #define BOOST_MATH_SF_DIGAMMA_HPP
  7. #ifdef _MSC_VER
  8. #pragma once
  9. #pragma warning(push)
  10. #pragma warning(disable:4702) // Unreachable code (release mode only warning)
  11. #endif
  12. #include <boost/math/special_functions/math_fwd.hpp>
  13. #include <boost/math/tools/rational.hpp>
  14. #include <boost/math/tools/series.hpp>
  15. #include <boost/math/tools/promotion.hpp>
  16. #include <boost/math/policies/error_handling.hpp>
  17. #include <boost/math/constants/constants.hpp>
  18. #include <boost/math/tools/big_constant.hpp>
  19. #if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
  20. //
  21. // This is the only way we can avoid
  22. // warning: non-standard suffix on floating constant [-Wpedantic]
  23. // when building with -Wall -pedantic. Neither __extension__
  24. // nor #pragma diagnostic ignored work :(
  25. //
  26. #pragma GCC system_header
  27. #endif
  28. namespace boost{
  29. namespace math{
  30. namespace detail{
  31. //
  32. // Begin by defining the smallest value for which it is safe to
  33. // use the asymptotic expansion for digamma:
  34. //
  35. inline unsigned digamma_large_lim(const std::integral_constant<int, 0>*)
  36. { return 20; }
  37. inline unsigned digamma_large_lim(const std::integral_constant<int, 113>*)
  38. { return 20; }
  39. inline unsigned digamma_large_lim(const void*)
  40. { return 10; }
  41. //
  42. // Implementations of the asymptotic expansion come next,
  43. // the coefficients of the series have been evaluated
  44. // in advance at high precision, and the series truncated
  45. // at the first term that's too small to effect the result.
  46. // Note that the series becomes divergent after a while
  47. // so truncation is very important.
  48. //
  49. // This first one gives 34-digit precision for x >= 20:
  50. //
  51. template <class T>
  52. inline T digamma_imp_large(T x, const std::integral_constant<int, 113>*)
  53. {
  54. BOOST_MATH_STD_USING // ADL of std functions.
  55. static const T P[] = {
  56. BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333),
  57. BOOST_MATH_BIG_CONSTANT(T, 113, -0.0083333333333333333333333333333333333333333333333333),
  58. BOOST_MATH_BIG_CONSTANT(T, 113, 0.003968253968253968253968253968253968253968253968254),
  59. BOOST_MATH_BIG_CONSTANT(T, 113, -0.0041666666666666666666666666666666666666666666666667),
  60. BOOST_MATH_BIG_CONSTANT(T, 113, 0.0075757575757575757575757575757575757575757575757576),
  61. BOOST_MATH_BIG_CONSTANT(T, 113, -0.021092796092796092796092796092796092796092796092796),
  62. BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333),
  63. BOOST_MATH_BIG_CONSTANT(T, 113, -0.44325980392156862745098039215686274509803921568627),
  64. BOOST_MATH_BIG_CONSTANT(T, 113, 3.0539543302701197438039543302701197438039543302701),
  65. BOOST_MATH_BIG_CONSTANT(T, 113, -26.456212121212121212121212121212121212121212121212),
  66. BOOST_MATH_BIG_CONSTANT(T, 113, 281.4601449275362318840579710144927536231884057971),
  67. BOOST_MATH_BIG_CONSTANT(T, 113, -3607.510546398046398046398046398046398046398046398),
  68. BOOST_MATH_BIG_CONSTANT(T, 113, 54827.583333333333333333333333333333333333333333333),
  69. BOOST_MATH_BIG_CONSTANT(T, 113, -974936.82385057471264367816091954022988505747126437),
  70. BOOST_MATH_BIG_CONSTANT(T, 113, 20052695.796688078946143462272494530559046688078946),
  71. BOOST_MATH_BIG_CONSTANT(T, 113, -472384867.72162990196078431372549019607843137254902),
  72. BOOST_MATH_BIG_CONSTANT(T, 113, 12635724795.916666666666666666666666666666666666667)
  73. };
  74. x -= 1;
  75. T result = log(x);
  76. result += 1 / (2 * x);
  77. T z = 1 / (x*x);
  78. result -= z * tools::evaluate_polynomial(P, z);
  79. return result;
  80. }
  81. //
  82. // 19-digit precision for x >= 10:
  83. //
  84. template <class T>
  85. inline T digamma_imp_large(T x, const std::integral_constant<int, 64>*)
  86. {
  87. BOOST_MATH_STD_USING // ADL of std functions.
  88. static const T P[] = {
  89. BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333),
  90. BOOST_MATH_BIG_CONSTANT(T, 64, -0.0083333333333333333333333333333333333333333333333333),
  91. BOOST_MATH_BIG_CONSTANT(T, 64, 0.003968253968253968253968253968253968253968253968254),
  92. BOOST_MATH_BIG_CONSTANT(T, 64, -0.0041666666666666666666666666666666666666666666666667),
  93. BOOST_MATH_BIG_CONSTANT(T, 64, 0.0075757575757575757575757575757575757575757575757576),
  94. BOOST_MATH_BIG_CONSTANT(T, 64, -0.021092796092796092796092796092796092796092796092796),
  95. BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333),
  96. BOOST_MATH_BIG_CONSTANT(T, 64, -0.44325980392156862745098039215686274509803921568627),
  97. BOOST_MATH_BIG_CONSTANT(T, 64, 3.0539543302701197438039543302701197438039543302701),
  98. BOOST_MATH_BIG_CONSTANT(T, 64, -26.456212121212121212121212121212121212121212121212),
  99. BOOST_MATH_BIG_CONSTANT(T, 64, 281.4601449275362318840579710144927536231884057971),
  100. };
  101. x -= 1;
  102. T result = log(x);
  103. result += 1 / (2 * x);
  104. T z = 1 / (x*x);
  105. result -= z * tools::evaluate_polynomial(P, z);
  106. return result;
  107. }
  108. //
  109. // 17-digit precision for x >= 10:
  110. //
  111. template <class T>
  112. inline T digamma_imp_large(T x, const std::integral_constant<int, 53>*)
  113. {
  114. BOOST_MATH_STD_USING // ADL of std functions.
  115. static const T P[] = {
  116. BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333),
  117. BOOST_MATH_BIG_CONSTANT(T, 53, -0.0083333333333333333333333333333333333333333333333333),
  118. BOOST_MATH_BIG_CONSTANT(T, 53, 0.003968253968253968253968253968253968253968253968254),
  119. BOOST_MATH_BIG_CONSTANT(T, 53, -0.0041666666666666666666666666666666666666666666666667),
  120. BOOST_MATH_BIG_CONSTANT(T, 53, 0.0075757575757575757575757575757575757575757575757576),
  121. BOOST_MATH_BIG_CONSTANT(T, 53, -0.021092796092796092796092796092796092796092796092796),
  122. BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333),
  123. BOOST_MATH_BIG_CONSTANT(T, 53, -0.44325980392156862745098039215686274509803921568627)
  124. };
  125. x -= 1;
  126. T result = log(x);
  127. result += 1 / (2 * x);
  128. T z = 1 / (x*x);
  129. result -= z * tools::evaluate_polynomial(P, z);
  130. return result;
  131. }
  132. //
  133. // 9-digit precision for x >= 10:
  134. //
  135. template <class T>
  136. inline T digamma_imp_large(T x, const std::integral_constant<int, 24>*)
  137. {
  138. BOOST_MATH_STD_USING // ADL of std functions.
  139. static const T P[] = {
  140. BOOST_MATH_BIG_CONSTANT(T, 24, 0.083333333333333333333333333333333333333333333333333),
  141. BOOST_MATH_BIG_CONSTANT(T, 24, -0.0083333333333333333333333333333333333333333333333333),
  142. BOOST_MATH_BIG_CONSTANT(T, 24, 0.003968253968253968253968253968253968253968253968254)
  143. };
  144. x -= 1;
  145. T result = log(x);
  146. result += 1 / (2 * x);
  147. T z = 1 / (x*x);
  148. result -= z * tools::evaluate_polynomial(P, z);
  149. return result;
  150. }
  151. //
  152. // Fully generic asymptotic expansion in terms of Bernoulli numbers, see:
  153. // http://functions.wolfram.com/06.14.06.0012.01
  154. //
  155. template <class T>
  156. struct digamma_series_func
  157. {
  158. private:
  159. int k;
  160. T xx;
  161. T term;
  162. public:
  163. digamma_series_func(T x) : k(1), xx(x * x), term(1 / (x * x)) {}
  164. T operator()()
  165. {
  166. T result = term * boost::math::bernoulli_b2n<T>(k) / (2 * k);
  167. term /= xx;
  168. ++k;
  169. return result;
  170. }
  171. typedef T result_type;
  172. };
  173. template <class T, class Policy>
  174. inline T digamma_imp_large(T x, const Policy& pol, const std::integral_constant<int, 0>*)
  175. {
  176. BOOST_MATH_STD_USING
  177. digamma_series_func<T> s(x);
  178. T result = log(x) - 1 / (2 * x);
  179. boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
  180. result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, -result);
  181. result = -result;
  182. policies::check_series_iterations<T>("boost::math::digamma<%1%>(%1%)", max_iter, pol);
  183. return result;
  184. }
  185. //
  186. // Now follow rational approximations over the range [1,2].
  187. //
  188. // 35-digit precision:
  189. //
  190. template <class T>
  191. T digamma_imp_1_2(T x, const std::integral_constant<int, 113>*)
  192. {
  193. //
  194. // Now the approximation, we use the form:
  195. //
  196. // digamma(x) = (x - root) * (Y + R(x-1))
  197. //
  198. // Where root is the location of the positive root of digamma,
  199. // Y is a constant, and R is optimised for low absolute error
  200. // compared to Y.
  201. //
  202. // Max error found at 128-bit long double precision: 5.541e-35
  203. // Maximum Deviation Found (approximation error): 1.965e-35
  204. //
  205. static const float Y = 0.99558162689208984375F;
  206. static const T root1 = T(1569415565) / 1073741824uL;
  207. static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
  208. static const T root3 = ((T(111616537) / 1073741824uL) / 1073741824uL) / 1073741824uL;
  209. static const T root4 = (((T(503992070) / 1073741824uL) / 1073741824uL) / 1073741824uL) / 1073741824uL;
  210. static const T root5 = BOOST_MATH_BIG_CONSTANT(T, 113, 0.52112228569249997894452490385577338504019838794544e-36);
  211. static const T P[] = {
  212. BOOST_MATH_BIG_CONSTANT(T, 113, 0.25479851061131551526977464225335883769),
  213. BOOST_MATH_BIG_CONSTANT(T, 113, -0.18684290534374944114622235683619897417),
  214. BOOST_MATH_BIG_CONSTANT(T, 113, -0.80360876047931768958995775910991929922),
  215. BOOST_MATH_BIG_CONSTANT(T, 113, -0.67227342794829064330498117008564270136),
  216. BOOST_MATH_BIG_CONSTANT(T, 113, -0.26569010991230617151285010695543858005),
  217. BOOST_MATH_BIG_CONSTANT(T, 113, -0.05775672694575986971640757748003553385),
  218. BOOST_MATH_BIG_CONSTANT(T, 113, -0.0071432147823164975485922555833274240665),
  219. BOOST_MATH_BIG_CONSTANT(T, 113, -0.00048740753910766168912364555706064993274),
  220. BOOST_MATH_BIG_CONSTANT(T, 113, -0.16454996865214115723416538844975174761e-4),
  221. BOOST_MATH_BIG_CONSTANT(T, 113, -0.20327832297631728077731148515093164955e-6)
  222. };
  223. static const T Q[] = {
  224. BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
  225. BOOST_MATH_BIG_CONSTANT(T, 113, 2.6210924610812025425088411043163287646),
  226. BOOST_MATH_BIG_CONSTANT(T, 113, 2.6850757078559596612621337395886392594),
  227. BOOST_MATH_BIG_CONSTANT(T, 113, 1.4320913706209965531250495490639289418),
  228. BOOST_MATH_BIG_CONSTANT(T, 113, 0.4410872083455009362557012239501953402),
  229. BOOST_MATH_BIG_CONSTANT(T, 113, 0.081385727399251729505165509278152487225),
  230. BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089478633066857163432104815183858149496),
  231. BOOST_MATH_BIG_CONSTANT(T, 113, 0.00055861622855066424871506755481997374154),
  232. BOOST_MATH_BIG_CONSTANT(T, 113, 0.1760168552357342401304462967950178554e-4),
  233. BOOST_MATH_BIG_CONSTANT(T, 113, 0.20585454493572473724556649516040874384e-6),
  234. BOOST_MATH_BIG_CONSTANT(T, 113, -0.90745971844439990284514121823069162795e-11),
  235. BOOST_MATH_BIG_CONSTANT(T, 113, 0.48857673606545846774761343500033283272e-13),
  236. };
  237. T g = x - root1;
  238. g -= root2;
  239. g -= root3;
  240. g -= root4;
  241. g -= root5;
  242. T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
  243. T result = g * Y + g * r;
  244. return result;
  245. }
  246. //
  247. // 19-digit precision:
  248. //
  249. template <class T>
  250. T digamma_imp_1_2(T x, const std::integral_constant<int, 64>*)
  251. {
  252. //
  253. // Now the approximation, we use the form:
  254. //
  255. // digamma(x) = (x - root) * (Y + R(x-1))
  256. //
  257. // Where root is the location of the positive root of digamma,
  258. // Y is a constant, and R is optimised for low absolute error
  259. // compared to Y.
  260. //
  261. // Max error found at 80-bit long double precision: 5.016e-20
  262. // Maximum Deviation Found (approximation error): 3.575e-20
  263. //
  264. static const float Y = 0.99558162689208984375F;
  265. static const T root1 = T(1569415565) / 1073741824uL;
  266. static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
  267. static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.9016312093258695918615325266959189453125e-19);
  268. static const T P[] = {
  269. BOOST_MATH_BIG_CONSTANT(T, 64, 0.254798510611315515235),
  270. BOOST_MATH_BIG_CONSTANT(T, 64, -0.314628554532916496608),
  271. BOOST_MATH_BIG_CONSTANT(T, 64, -0.665836341559876230295),
  272. BOOST_MATH_BIG_CONSTANT(T, 64, -0.314767657147375752913),
  273. BOOST_MATH_BIG_CONSTANT(T, 64, -0.0541156266153505273939),
  274. BOOST_MATH_BIG_CONSTANT(T, 64, -0.00289268368333918761452)
  275. };
  276. static const T Q[] = {
  277. BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
  278. BOOST_MATH_BIG_CONSTANT(T, 64, 2.1195759927055347547),
  279. BOOST_MATH_BIG_CONSTANT(T, 64, 1.54350554664961128724),
  280. BOOST_MATH_BIG_CONSTANT(T, 64, 0.486986018231042975162),
  281. BOOST_MATH_BIG_CONSTANT(T, 64, 0.0660481487173569812846),
  282. BOOST_MATH_BIG_CONSTANT(T, 64, 0.00298999662592323990972),
  283. BOOST_MATH_BIG_CONSTANT(T, 64, -0.165079794012604905639e-5),
  284. BOOST_MATH_BIG_CONSTANT(T, 64, 0.317940243105952177571e-7)
  285. };
  286. T g = x - root1;
  287. g -= root2;
  288. g -= root3;
  289. T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
  290. T result = g * Y + g * r;
  291. return result;
  292. }
  293. //
  294. // 18-digit precision:
  295. //
  296. template <class T>
  297. T digamma_imp_1_2(T x, const std::integral_constant<int, 53>*)
  298. {
  299. //
  300. // Now the approximation, we use the form:
  301. //
  302. // digamma(x) = (x - root) * (Y + R(x-1))
  303. //
  304. // Where root is the location of the positive root of digamma,
  305. // Y is a constant, and R is optimised for low absolute error
  306. // compared to Y.
  307. //
  308. // Maximum Deviation Found: 1.466e-18
  309. // At double precision, max error found: 2.452e-17
  310. //
  311. static const float Y = 0.99558162689208984F;
  312. static const T root1 = T(1569415565) / 1073741824uL;
  313. static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
  314. static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.9016312093258695918615325266959189453125e-19);
  315. static const T P[] = {
  316. BOOST_MATH_BIG_CONSTANT(T, 53, 0.25479851061131551),
  317. BOOST_MATH_BIG_CONSTANT(T, 53, -0.32555031186804491),
  318. BOOST_MATH_BIG_CONSTANT(T, 53, -0.65031853770896507),
  319. BOOST_MATH_BIG_CONSTANT(T, 53, -0.28919126444774784),
  320. BOOST_MATH_BIG_CONSTANT(T, 53, -0.045251321448739056),
  321. BOOST_MATH_BIG_CONSTANT(T, 53, -0.0020713321167745952)
  322. };
  323. static const T Q[] = {
  324. BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
  325. BOOST_MATH_BIG_CONSTANT(T, 53, 2.0767117023730469),
  326. BOOST_MATH_BIG_CONSTANT(T, 53, 1.4606242909763515),
  327. BOOST_MATH_BIG_CONSTANT(T, 53, 0.43593529692665969),
  328. BOOST_MATH_BIG_CONSTANT(T, 53, 0.054151797245674225),
  329. BOOST_MATH_BIG_CONSTANT(T, 53, 0.0021284987017821144),
  330. BOOST_MATH_BIG_CONSTANT(T, 53, -0.55789841321675513e-6)
  331. };
  332. T g = x - root1;
  333. g -= root2;
  334. g -= root3;
  335. T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
  336. T result = g * Y + g * r;
  337. return result;
  338. }
  339. //
  340. // 9-digit precision:
  341. //
  342. template <class T>
  343. inline T digamma_imp_1_2(T x, const std::integral_constant<int, 24>*)
  344. {
  345. //
  346. // Now the approximation, we use the form:
  347. //
  348. // digamma(x) = (x - root) * (Y + R(x-1))
  349. //
  350. // Where root is the location of the positive root of digamma,
  351. // Y is a constant, and R is optimised for low absolute error
  352. // compared to Y.
  353. //
  354. // Maximum Deviation Found: 3.388e-010
  355. // At float precision, max error found: 2.008725e-008
  356. //
  357. static const float Y = 0.99558162689208984f;
  358. static const T root = 1532632.0f / 1048576;
  359. static const T root_minor = static_cast<T>(0.3700660185912626595423257213284682051735604e-6L);
  360. static const T P[] = {
  361. 0.25479851023250261e0f,
  362. -0.44981331915268368e0f,
  363. -0.43916936919946835e0f,
  364. -0.61041765350579073e-1f
  365. };
  366. static const T Q[] = {
  367. 0.1e1,
  368. 0.15890202430554952e1f,
  369. 0.65341249856146947e0f,
  370. 0.63851690523355715e-1f
  371. };
  372. T g = x - root;
  373. g -= root_minor;
  374. T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
  375. T result = g * Y + g * r;
  376. return result;
  377. }
  378. template <class T, class Tag, class Policy>
  379. T digamma_imp(T x, const Tag* t, const Policy& pol)
  380. {
  381. //
  382. // This handles reflection of negative arguments, and all our
  383. // error handling, then forwards to the T-specific approximation.
  384. //
  385. BOOST_MATH_STD_USING // ADL of std functions.
  386. T result = 0;
  387. //
  388. // Check for negative arguments and use reflection:
  389. //
  390. if(x <= -1)
  391. {
  392. // Reflect:
  393. x = 1 - x;
  394. // Argument reduction for tan:
  395. T remainder = x - floor(x);
  396. // Shift to negative if > 0.5:
  397. if(remainder > 0.5)
  398. {
  399. remainder -= 1;
  400. }
  401. //
  402. // check for evaluation at a negative pole:
  403. //
  404. if(remainder == 0)
  405. {
  406. return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, (1-x), pol);
  407. }
  408. result = constants::pi<T>() / tan(constants::pi<T>() * remainder);
  409. }
  410. if(x == 0)
  411. return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, x, pol);
  412. //
  413. // If we're above the lower-limit for the
  414. // asymptotic expansion then use it:
  415. //
  416. if(x >= digamma_large_lim(t))
  417. {
  418. result += digamma_imp_large(x, t);
  419. }
  420. else
  421. {
  422. //
  423. // If x > 2 reduce to the interval [1,2]:
  424. //
  425. while(x > 2)
  426. {
  427. x -= 1;
  428. result += 1/x;
  429. }
  430. //
  431. // If x < 1 use recurrence to shift to > 1:
  432. //
  433. while(x < 1)
  434. {
  435. result -= 1/x;
  436. x += 1;
  437. }
  438. result += digamma_imp_1_2(x, t);
  439. }
  440. return result;
  441. }
  442. template <class T, class Policy>
  443. T digamma_imp(T x, const std::integral_constant<int, 0>* t, const Policy& pol)
  444. {
  445. //
  446. // This handles reflection of negative arguments, and all our
  447. // error handling, then forwards to the T-specific approximation.
  448. //
  449. BOOST_MATH_STD_USING // ADL of std functions.
  450. T result = 0;
  451. //
  452. // Check for negative arguments and use reflection:
  453. //
  454. if(x <= -1)
  455. {
  456. // Reflect:
  457. x = 1 - x;
  458. // Argument reduction for tan:
  459. T remainder = x - floor(x);
  460. // Shift to negative if > 0.5:
  461. if(remainder > 0.5)
  462. {
  463. remainder -= 1;
  464. }
  465. //
  466. // check for evaluation at a negative pole:
  467. //
  468. if(remainder == 0)
  469. {
  470. return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, (1 - x), pol);
  471. }
  472. result = constants::pi<T>() / tan(constants::pi<T>() * remainder);
  473. }
  474. if(x == 0)
  475. return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, x, pol);
  476. //
  477. // If we're above the lower-limit for the
  478. // asymptotic expansion then use it, the
  479. // limit is a linear interpolation with
  480. // limit = 10 at 50 bit precision and
  481. // limit = 250 at 1000 bit precision.
  482. //
  483. int lim = 10 + ((tools::digits<T>() - 50) * 240L) / 950;
  484. T two_x = ldexp(x, 1);
  485. if(x >= lim)
  486. {
  487. result += digamma_imp_large(x, pol, t);
  488. }
  489. else if(floor(x) == x)
  490. {
  491. //
  492. // Special case for integer arguments, see
  493. // http://functions.wolfram.com/06.14.03.0001.01
  494. //
  495. result = -constants::euler<T, Policy>();
  496. T val = 1;
  497. while(val < x)
  498. {
  499. result += 1 / val;
  500. val += 1;
  501. }
  502. }
  503. else if(floor(two_x) == two_x)
  504. {
  505. //
  506. // Special case for half integer arguments, see:
  507. // http://functions.wolfram.com/06.14.03.0007.01
  508. //
  509. result = -2 * constants::ln_two<T, Policy>() - constants::euler<T, Policy>();
  510. int n = itrunc(x);
  511. if(n)
  512. {
  513. for(int k = 1; k < n; ++k)
  514. result += 1 / T(k);
  515. for(int k = n; k <= 2 * n - 1; ++k)
  516. result += 2 / T(k);
  517. }
  518. }
  519. else
  520. {
  521. //
  522. // Rescale so we can use the asymptotic expansion:
  523. //
  524. while(x < lim)
  525. {
  526. result -= 1 / x;
  527. x += 1;
  528. }
  529. result += digamma_imp_large(x, pol, t);
  530. }
  531. return result;
  532. }
  533. //
  534. // Initializer: ensure all our constants are initialized prior to the first call of main:
  535. //
  536. template <class T, class Policy>
  537. struct digamma_initializer
  538. {
  539. struct init
  540. {
  541. init()
  542. {
  543. typedef typename policies::precision<T, Policy>::type precision_type;
  544. do_init(std::integral_constant<bool, precision_type::value && (precision_type::value <= 113)>());
  545. }
  546. void do_init(const std::true_type&)
  547. {
  548. boost::math::digamma(T(1.5), Policy());
  549. boost::math::digamma(T(500), Policy());
  550. }
  551. void do_init(const std::false_type&){}
  552. void force_instantiate()const{}
  553. };
  554. static const init initializer;
  555. static void force_instantiate()
  556. {
  557. initializer.force_instantiate();
  558. }
  559. };
  560. template <class T, class Policy>
  561. const typename digamma_initializer<T, Policy>::init digamma_initializer<T, Policy>::initializer;
  562. } // namespace detail
  563. template <class T, class Policy>
  564. inline typename tools::promote_args<T>::type
  565. digamma(T x, const Policy&)
  566. {
  567. typedef typename tools::promote_args<T>::type result_type;
  568. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  569. typedef typename policies::precision<T, Policy>::type precision_type;
  570. typedef std::integral_constant<int,
  571. (precision_type::value <= 0) || (precision_type::value > 113) ? 0 :
  572. precision_type::value <= 24 ? 24 :
  573. precision_type::value <= 53 ? 53 :
  574. precision_type::value <= 64 ? 64 :
  575. precision_type::value <= 113 ? 113 : 0 > tag_type;
  576. typedef typename policies::normalise<
  577. Policy,
  578. policies::promote_float<false>,
  579. policies::promote_double<false>,
  580. policies::discrete_quantile<>,
  581. policies::assert_undefined<> >::type forwarding_policy;
  582. // Force initialization of constants:
  583. detail::digamma_initializer<value_type, forwarding_policy>::force_instantiate();
  584. return policies::checked_narrowing_cast<result_type, Policy>(detail::digamma_imp(
  585. static_cast<value_type>(x),
  586. static_cast<const tag_type*>(0), forwarding_policy()), "boost::math::digamma<%1%>(%1%)");
  587. }
  588. template <class T>
  589. inline typename tools::promote_args<T>::type
  590. digamma(T x)
  591. {
  592. return digamma(x, policies::policy<>());
  593. }
  594. } // namespace math
  595. } // namespace boost
  596. #ifdef _MSC_VER
  597. #pragma warning(pop)
  598. #endif
  599. #endif