gamma.hpp 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220
  1. // Copyright John Maddock 2006-7, 2013-20.
  2. // Copyright Paul A. Bristow 2007, 2013-14.
  3. // Copyright Nikhar Agrawal 2013-14
  4. // Copyright Christopher Kormanyos 2013-14, 2020
  5. // Use, modification and distribution are subject to the
  6. // Boost Software License, Version 1.0. (See accompanying file
  7. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_MATH_SF_GAMMA_HPP
  9. #define BOOST_MATH_SF_GAMMA_HPP
  10. #ifdef _MSC_VER
  11. #pragma once
  12. #endif
  13. #include <boost/math/tools/series.hpp>
  14. #include <boost/math/tools/fraction.hpp>
  15. #include <boost/math/tools/precision.hpp>
  16. #include <boost/math/tools/promotion.hpp>
  17. #include <boost/math/tools/assert.hpp>
  18. #include <boost/math/tools/config.hpp>
  19. #include <boost/math/policies/error_handling.hpp>
  20. #include <boost/math/constants/constants.hpp>
  21. #include <boost/math/special_functions/math_fwd.hpp>
  22. #include <boost/math/special_functions/log1p.hpp>
  23. #include <boost/math/special_functions/trunc.hpp>
  24. #include <boost/math/special_functions/powm1.hpp>
  25. #include <boost/math/special_functions/sqrt1pm1.hpp>
  26. #include <boost/math/special_functions/lanczos.hpp>
  27. #include <boost/math/special_functions/fpclassify.hpp>
  28. #include <boost/math/special_functions/detail/igamma_large.hpp>
  29. #include <boost/math/special_functions/detail/unchecked_factorial.hpp>
  30. #include <boost/math/special_functions/detail/lgamma_small.hpp>
  31. #include <boost/math/special_functions/bernoulli.hpp>
  32. #include <boost/math/special_functions/polygamma.hpp>
  33. #include <cmath>
  34. #include <algorithm>
  35. #include <type_traits>
  36. #ifdef _MSC_VER
  37. # pragma warning(push)
  38. # pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
  39. # pragma warning(disable: 4127) // conditional expression is constant.
  40. # pragma warning(disable: 4100) // unreferenced formal parameter.
  41. # pragma warning(disable: 6326) // potential comparison of a constant with another constant
  42. // Several variables made comments,
  43. // but some difficulty as whether referenced on not may depend on macro values.
  44. // So to be safe, 4100 warnings suppressed.
  45. // TODO - revisit this?
  46. #endif
  47. namespace boost{ namespace math{
  48. namespace detail{
  49. template <class T>
  50. inline bool is_odd(T v, const std::true_type&)
  51. {
  52. int i = static_cast<int>(v);
  53. return i&1;
  54. }
  55. template <class T>
  56. inline bool is_odd(T v, const std::false_type&)
  57. {
  58. // Oh dear can't cast T to int!
  59. BOOST_MATH_STD_USING
  60. T modulus = v - 2 * floor(v/2);
  61. return static_cast<bool>(modulus != 0);
  62. }
  63. template <class T>
  64. inline bool is_odd(T v)
  65. {
  66. return is_odd(v, ::std::is_convertible<T, int>());
  67. }
  68. template <class T>
  69. T sinpx(T z)
  70. {
  71. // Ad hoc function calculates x * sin(pi * x),
  72. // taking extra care near when x is near a whole number.
  73. BOOST_MATH_STD_USING
  74. int sign = 1;
  75. if(z < 0)
  76. {
  77. z = -z;
  78. }
  79. T fl = floor(z);
  80. T dist;
  81. if(is_odd(fl))
  82. {
  83. fl += 1;
  84. dist = fl - z;
  85. sign = -sign;
  86. }
  87. else
  88. {
  89. dist = z - fl;
  90. }
  91. BOOST_MATH_ASSERT(fl >= 0);
  92. if(dist > T(0.5))
  93. dist = 1 - dist;
  94. T result = sin(dist*boost::math::constants::pi<T>());
  95. return sign*z*result;
  96. } // template <class T> T sinpx(T z)
  97. //
  98. // tgamma(z), with Lanczos support:
  99. //
  100. template <class T, class Policy, class Lanczos>
  101. T gamma_imp(T z, const Policy& pol, const Lanczos& l)
  102. {
  103. BOOST_MATH_STD_USING
  104. T result = 1;
  105. #ifdef BOOST_MATH_INSTRUMENT
  106. static bool b = false;
  107. if(!b)
  108. {
  109. std::cout << "tgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl;
  110. b = true;
  111. }
  112. #endif
  113. static const char* function = "boost::math::tgamma<%1%>(%1%)";
  114. if(z <= 0)
  115. {
  116. if(floor(z) == z)
  117. return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
  118. if(z <= -20)
  119. {
  120. result = gamma_imp(T(-z), pol, l) * sinpx(z);
  121. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  122. if((fabs(result) < 1) && (tools::max_value<T>() * fabs(result) < boost::math::constants::pi<T>()))
  123. return -boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
  124. result = -boost::math::constants::pi<T>() / result;
  125. if(result == 0)
  126. return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
  127. if((boost::math::fpclassify)(result) == (int)FP_SUBNORMAL)
  128. return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", result, pol);
  129. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  130. return result;
  131. }
  132. // shift z to > 1:
  133. while(z < 0)
  134. {
  135. result /= z;
  136. z += 1;
  137. }
  138. }
  139. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  140. if((floor(z) == z) && (z < max_factorial<T>::value))
  141. {
  142. result *= unchecked_factorial<T>(itrunc(z, pol) - 1);
  143. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  144. }
  145. else if (z < tools::root_epsilon<T>())
  146. {
  147. if (z < 1 / tools::max_value<T>())
  148. result = policies::raise_overflow_error<T>(function, nullptr, pol);
  149. result *= 1 / z - constants::euler<T>();
  150. }
  151. else
  152. {
  153. result *= Lanczos::lanczos_sum(z);
  154. T zgh = (z + static_cast<T>(Lanczos::g()) - boost::math::constants::half<T>());
  155. T lzgh = log(zgh);
  156. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  157. BOOST_MATH_INSTRUMENT_VARIABLE(tools::log_max_value<T>());
  158. if(z * lzgh > tools::log_max_value<T>())
  159. {
  160. // we're going to overflow unless this is done with care:
  161. BOOST_MATH_INSTRUMENT_VARIABLE(zgh);
  162. if(lzgh * z / 2 > tools::log_max_value<T>())
  163. return boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
  164. T hp = pow(zgh, T((z / 2) - T(0.25)));
  165. BOOST_MATH_INSTRUMENT_VARIABLE(hp);
  166. result *= hp / exp(zgh);
  167. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  168. if(tools::max_value<T>() / hp < result)
  169. return boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
  170. result *= hp;
  171. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  172. }
  173. else
  174. {
  175. BOOST_MATH_INSTRUMENT_VARIABLE(zgh);
  176. BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, T(z - boost::math::constants::half<T>())));
  177. BOOST_MATH_INSTRUMENT_VARIABLE(exp(zgh));
  178. result *= pow(zgh, T(z - boost::math::constants::half<T>())) / exp(zgh);
  179. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  180. }
  181. }
  182. return result;
  183. }
  184. //
  185. // lgamma(z) with Lanczos support:
  186. //
  187. template <class T, class Policy, class Lanczos>
  188. T lgamma_imp(T z, const Policy& pol, const Lanczos& l, int* sign = nullptr)
  189. {
  190. #ifdef BOOST_MATH_INSTRUMENT
  191. static bool b = false;
  192. if(!b)
  193. {
  194. std::cout << "lgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl;
  195. b = true;
  196. }
  197. #endif
  198. BOOST_MATH_STD_USING
  199. static const char* function = "boost::math::lgamma<%1%>(%1%)";
  200. T result = 0;
  201. int sresult = 1;
  202. if(z <= -tools::root_epsilon<T>())
  203. {
  204. // reflection formula:
  205. if(floor(z) == z)
  206. return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
  207. T t = sinpx(z);
  208. z = -z;
  209. if(t < 0)
  210. {
  211. t = -t;
  212. }
  213. else
  214. {
  215. sresult = -sresult;
  216. }
  217. result = log(boost::math::constants::pi<T>()) - lgamma_imp(z, pol, l) - log(t);
  218. }
  219. else if (z < tools::root_epsilon<T>())
  220. {
  221. if (0 == z)
  222. return policies::raise_pole_error<T>(function, "Evaluation of lgamma at %1%.", z, pol);
  223. if (4 * fabs(z) < tools::epsilon<T>())
  224. result = -log(fabs(z));
  225. else
  226. result = log(fabs(1 / z - constants::euler<T>()));
  227. if (z < 0)
  228. sresult = -1;
  229. }
  230. else if(z < 15)
  231. {
  232. typedef typename policies::precision<T, Policy>::type precision_type;
  233. typedef std::integral_constant<int,
  234. precision_type::value <= 0 ? 0 :
  235. precision_type::value <= 64 ? 64 :
  236. precision_type::value <= 113 ? 113 : 0
  237. > tag_type;
  238. result = lgamma_small_imp<T>(z, T(z - 1), T(z - 2), tag_type(), pol, l);
  239. }
  240. else if((z >= 3) && (z < 100) && (std::numeric_limits<T>::max_exponent >= 1024))
  241. {
  242. // taking the log of tgamma reduces the error, no danger of overflow here:
  243. result = log(gamma_imp(z, pol, l));
  244. }
  245. else
  246. {
  247. // regular evaluation:
  248. T zgh = static_cast<T>(z + T(Lanczos::g()) - boost::math::constants::half<T>());
  249. result = log(zgh) - 1;
  250. result *= z - 0.5f;
  251. //
  252. // Only add on the lanczos sum part if we're going to need it:
  253. //
  254. if(result * tools::epsilon<T>() < 20)
  255. result += log(Lanczos::lanczos_sum_expG_scaled(z));
  256. }
  257. if(sign)
  258. *sign = sresult;
  259. return result;
  260. }
  261. //
  262. // Incomplete gamma functions follow:
  263. //
  264. template <class T>
  265. struct upper_incomplete_gamma_fract
  266. {
  267. private:
  268. T z, a;
  269. int k;
  270. public:
  271. typedef std::pair<T,T> result_type;
  272. upper_incomplete_gamma_fract(T a1, T z1)
  273. : z(z1-a1+1), a(a1), k(0)
  274. {
  275. }
  276. result_type operator()()
  277. {
  278. ++k;
  279. z += 2;
  280. return result_type(k * (a - k), z);
  281. }
  282. };
  283. template <class T>
  284. inline T upper_gamma_fraction(T a, T z, T eps)
  285. {
  286. // Multiply result by z^a * e^-z to get the full
  287. // upper incomplete integral. Divide by tgamma(z)
  288. // to normalise.
  289. upper_incomplete_gamma_fract<T> f(a, z);
  290. return 1 / (z - a + 1 + boost::math::tools::continued_fraction_a(f, eps));
  291. }
  292. template <class T>
  293. struct lower_incomplete_gamma_series
  294. {
  295. private:
  296. T a, z, result;
  297. public:
  298. typedef T result_type;
  299. lower_incomplete_gamma_series(T a1, T z1) : a(a1), z(z1), result(1){}
  300. T operator()()
  301. {
  302. T r = result;
  303. a += 1;
  304. result *= z/a;
  305. return r;
  306. }
  307. };
  308. template <class T, class Policy>
  309. inline T lower_gamma_series(T a, T z, const Policy& pol, T init_value = 0)
  310. {
  311. // Multiply result by ((z^a) * (e^-z) / a) to get the full
  312. // lower incomplete integral. Then divide by tgamma(a)
  313. // to get the normalised value.
  314. lower_incomplete_gamma_series<T> s(a, z);
  315. std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
  316. T factor = policies::get_epsilon<T, Policy>();
  317. T result = boost::math::tools::sum_series(s, factor, max_iter, init_value);
  318. policies::check_series_iterations<T>("boost::math::detail::lower_gamma_series<%1%>(%1%)", max_iter, pol);
  319. return result;
  320. }
  321. //
  322. // Fully generic tgamma and lgamma use Stirling's approximation
  323. // with Bernoulli numbers.
  324. //
  325. template<class T>
  326. std::size_t highest_bernoulli_index()
  327. {
  328. const float digits10_of_type = (std::numeric_limits<T>::is_specialized
  329. ? static_cast<float>(std::numeric_limits<T>::digits10)
  330. : static_cast<float>(boost::math::tools::digits<T>() * 0.301F));
  331. // Find the high index n for Bn to produce the desired precision in Stirling's calculation.
  332. return static_cast<std::size_t>(18.0F + (0.6F * digits10_of_type));
  333. }
  334. template<class T>
  335. int minimum_argument_for_bernoulli_recursion()
  336. {
  337. BOOST_MATH_STD_USING
  338. const float digits10_of_type = (std::numeric_limits<T>::is_specialized
  339. ? (float) std::numeric_limits<T>::digits10
  340. : (float) (boost::math::tools::digits<T>() * 0.301F));
  341. int min_arg = (int) (digits10_of_type * 1.7F);
  342. if(digits10_of_type < 50.0F)
  343. {
  344. // The following code sequence has been modified
  345. // within the context of issue 396.
  346. // The calculation of the test-variable limit has now
  347. // been protected against overflow/underflow dangers.
  348. // The previous line looked like this and did, in fact,
  349. // underflow ldexp when using certain multiprecision types.
  350. // const float limit = std::ceil(std::pow(1.0f / std::ldexp(1.0f, 1-boost::math::tools::digits<T>()), 1.0f / 20.0f));
  351. // The new safe version of the limit check is now here.
  352. const float d2_minus_one = ((digits10_of_type / 0.301F) - 1.0F);
  353. const float limit = ceil(exp((d2_minus_one * log(2.0F)) / 20.0F));
  354. min_arg = (int) ((std::min)(digits10_of_type * 1.7F, limit));
  355. }
  356. return min_arg;
  357. }
  358. template <class T, class Policy>
  359. T scaled_tgamma_no_lanczos(const T& z, const Policy& pol, bool islog = false)
  360. {
  361. BOOST_MATH_STD_USING
  362. //
  363. // Calculates tgamma(z) / (z/e)^z
  364. // Requires that our argument is large enough for Sterling's approximation to hold.
  365. // Used internally when combining gamma's of similar magnitude without logarithms.
  366. //
  367. BOOST_MATH_ASSERT(minimum_argument_for_bernoulli_recursion<T>() <= z);
  368. // Perform the Bernoulli series expansion of Stirling's approximation.
  369. const std::size_t number_of_bernoullis_b2n = policies::get_max_series_iterations<Policy>();
  370. T one_over_x_pow_two_n_minus_one = 1 / z;
  371. const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one;
  372. T sum = (boost::math::bernoulli_b2n<T>(1) / 2) * one_over_x_pow_two_n_minus_one;
  373. const T target_epsilon_to_break_loop = sum * boost::math::tools::epsilon<T>();
  374. const T half_ln_two_pi_over_z = sqrt(boost::math::constants::two_pi<T>() / z);
  375. T last_term = 2 * sum;
  376. for (std::size_t n = 2U;; ++n)
  377. {
  378. one_over_x_pow_two_n_minus_one *= one_over_x2;
  379. const std::size_t n2 = static_cast<std::size_t>(n * 2U);
  380. const T term = (boost::math::bernoulli_b2n<T>(static_cast<int>(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U));
  381. if ((n >= 3U) && (abs(term) < target_epsilon_to_break_loop))
  382. {
  383. // We have reached the desired precision in Stirling's expansion.
  384. // Adding additional terms to the sum of this divergent asymptotic
  385. // expansion will not improve the result.
  386. // Break from the loop.
  387. break;
  388. }
  389. if (n > number_of_bernoullis_b2n)
  390. return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Exceeded maximum series iterations without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol);
  391. sum += term;
  392. // Sanity check for divergence:
  393. T fterm = fabs(term);
  394. if(fterm > last_term)
  395. return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Series became divergent without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol);
  396. last_term = fterm;
  397. }
  398. // Complete Stirling's approximation.
  399. T scaled_gamma_value = islog ? T(sum + log(half_ln_two_pi_over_z)) : T(exp(sum) * half_ln_two_pi_over_z);
  400. return scaled_gamma_value;
  401. }
  402. // Forward declaration of the lgamma_imp template specialization.
  403. template <class T, class Policy>
  404. T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign = nullptr);
  405. template <class T, class Policy>
  406. T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&)
  407. {
  408. BOOST_MATH_STD_USING
  409. static const char* function = "boost::math::tgamma<%1%>(%1%)";
  410. // Check if the argument of tgamma is identically zero.
  411. const bool is_at_zero = (z == 0);
  412. if((boost::math::isnan)(z) || (is_at_zero) || ((boost::math::isinf)(z) && (z < 0)))
  413. return policies::raise_domain_error<T>(function, "Evaluation of tgamma at %1%.", z, pol);
  414. const bool b_neg = (z < 0);
  415. const bool floor_of_z_is_equal_to_z = (floor(z) == z);
  416. // Special case handling of small factorials:
  417. if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial<T>::value))
  418. {
  419. return boost::math::unchecked_factorial<T>(itrunc(z) - 1);
  420. }
  421. // Make a local, unsigned copy of the input argument.
  422. T zz((!b_neg) ? z : -z);
  423. // Special case for ultra-small z:
  424. if(zz < tools::cbrt_epsilon<T>())
  425. {
  426. const T a0(1);
  427. const T a1(boost::math::constants::euler<T>());
  428. const T six_euler_squared((boost::math::constants::euler<T>() * boost::math::constants::euler<T>()) * 6);
  429. const T a2((six_euler_squared - boost::math::constants::pi_sqr<T>()) / 12);
  430. const T inverse_tgamma_series = z * ((a2 * z + a1) * z + a0);
  431. return 1 / inverse_tgamma_series;
  432. }
  433. // Scale the argument up for the calculation of lgamma,
  434. // and use downward recursion later for the final result.
  435. const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
  436. int n_recur;
  437. if(zz < min_arg_for_recursion)
  438. {
  439. n_recur = boost::math::itrunc(min_arg_for_recursion - zz) + 1;
  440. zz += n_recur;
  441. }
  442. else
  443. {
  444. n_recur = 0;
  445. }
  446. if (!n_recur)
  447. {
  448. if (zz > tools::log_max_value<T>())
  449. return policies::raise_overflow_error<T>(function, nullptr, pol);
  450. if (log(zz) * zz / 2 > tools::log_max_value<T>())
  451. return policies::raise_overflow_error<T>(function, nullptr, pol);
  452. }
  453. T gamma_value = scaled_tgamma_no_lanczos(zz, pol);
  454. T power_term = pow(zz, zz / 2);
  455. T exp_term = exp(-zz);
  456. gamma_value *= (power_term * exp_term);
  457. if(!n_recur && (tools::max_value<T>() / power_term < gamma_value))
  458. return policies::raise_overflow_error<T>(function, nullptr, pol);
  459. gamma_value *= power_term;
  460. // Rescale the result using downward recursion if necessary.
  461. if(n_recur)
  462. {
  463. // The order of divides is important, if we keep subtracting 1 from zz
  464. // we DO NOT get back to z (cancellation error). Further if z < epsilon
  465. // we would end up dividing by zero. Also in order to prevent spurious
  466. // overflow with the first division, we must save dividing by |z| till last,
  467. // so the optimal order of divides is z+1, z+2, z+3...z+n_recur-1,z.
  468. zz = fabs(z) + 1;
  469. for(int k = 1; k < n_recur; ++k)
  470. {
  471. gamma_value /= zz;
  472. zz += 1;
  473. }
  474. gamma_value /= fabs(z);
  475. }
  476. // Return the result, accounting for possible negative arguments.
  477. if(b_neg)
  478. {
  479. // Provide special error analysis for:
  480. // * arguments in the neighborhood of a negative integer
  481. // * arguments exactly equal to a negative integer.
  482. // Check if the argument of tgamma is exactly equal to a negative integer.
  483. if(floor_of_z_is_equal_to_z)
  484. return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
  485. gamma_value *= sinpx(z);
  486. BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value);
  487. const bool result_is_too_large_to_represent = ( (abs(gamma_value) < 1)
  488. && ((tools::max_value<T>() * abs(gamma_value)) < boost::math::constants::pi<T>()));
  489. if(result_is_too_large_to_represent)
  490. return policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
  491. gamma_value = -boost::math::constants::pi<T>() / gamma_value;
  492. BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value);
  493. if(gamma_value == 0)
  494. return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
  495. if((boost::math::fpclassify)(gamma_value) == static_cast<int>(FP_SUBNORMAL))
  496. return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", gamma_value, pol);
  497. }
  498. return gamma_value;
  499. }
  500. template <class T, class Policy>
  501. inline T log_gamma_near_1(const T& z, Policy const& pol)
  502. {
  503. //
  504. // This is for the multiprecision case where there is
  505. // no lanczos support, use a taylor series at z = 1,
  506. // see https://www.wolframalpha.com/input/?i=taylor+series+lgamma(x)+at+x+%3D+1
  507. //
  508. BOOST_MATH_STD_USING // ADL of std names
  509. BOOST_MATH_ASSERT(fabs(z) < 1);
  510. T result = -constants::euler<T>() * z;
  511. T power_term = z * z / 2;
  512. int n = 2;
  513. T term = 0;
  514. do
  515. {
  516. term = power_term * boost::math::polygamma(n - 1, T(1), pol);
  517. result += term;
  518. ++n;
  519. power_term *= z / n;
  520. } while (fabs(result) * tools::epsilon<T>() < fabs(term));
  521. return result;
  522. }
  523. template <class T, class Policy>
  524. T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign)
  525. {
  526. BOOST_MATH_STD_USING
  527. static const char* function = "boost::math::lgamma<%1%>(%1%)";
  528. // Check if the argument of lgamma is identically zero.
  529. const bool is_at_zero = (z == 0);
  530. if(is_at_zero)
  531. return policies::raise_domain_error<T>(function, "Evaluation of lgamma at zero %1%.", z, pol);
  532. if((boost::math::isnan)(z))
  533. return policies::raise_domain_error<T>(function, "Evaluation of lgamma at %1%.", z, pol);
  534. if((boost::math::isinf)(z))
  535. return policies::raise_overflow_error<T>(function, nullptr, pol);
  536. const bool b_neg = (z < 0);
  537. const bool floor_of_z_is_equal_to_z = (floor(z) == z);
  538. // Special case handling of small factorials:
  539. if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial<T>::value))
  540. {
  541. if (sign)
  542. *sign = 1;
  543. return log(boost::math::unchecked_factorial<T>(itrunc(z) - 1));
  544. }
  545. // Make a local, unsigned copy of the input argument.
  546. T zz((!b_neg) ? z : -z);
  547. const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
  548. T log_gamma_value;
  549. if (zz < min_arg_for_recursion)
  550. {
  551. // Here we simply take the logarithm of tgamma(). This is somewhat
  552. // inefficient, but simple. The rationale is that the argument here
  553. // is relatively small and overflow is not expected to be likely.
  554. if (sign)
  555. * sign = 1;
  556. if(fabs(z - 1) < 0.25)
  557. {
  558. log_gamma_value = log_gamma_near_1(T(zz - 1), pol);
  559. }
  560. else if(fabs(z - 2) < 0.25)
  561. {
  562. log_gamma_value = log_gamma_near_1(T(zz - 2), pol) + log(zz - 1);
  563. }
  564. else if (z > -tools::root_epsilon<T>())
  565. {
  566. // Reflection formula may fail if z is very close to zero, let the series
  567. // expansion for tgamma close to zero do the work:
  568. if (sign)
  569. *sign = z < 0 ? -1 : 1;
  570. return log(abs(gamma_imp(z, pol, lanczos::undefined_lanczos())));
  571. }
  572. else
  573. {
  574. // No issue with spurious overflow in reflection formula,
  575. // just fall through to regular code:
  576. T g = gamma_imp(zz, pol, lanczos::undefined_lanczos());
  577. if (sign)
  578. {
  579. *sign = g < 0 ? -1 : 1;
  580. }
  581. log_gamma_value = log(abs(g));
  582. }
  583. }
  584. else
  585. {
  586. // Perform the Bernoulli series expansion of Stirling's approximation.
  587. T sum = scaled_tgamma_no_lanczos(zz, pol, true);
  588. log_gamma_value = zz * (log(zz) - 1) + sum;
  589. }
  590. int sign_of_result = 1;
  591. if(b_neg)
  592. {
  593. // Provide special error analysis if the argument is exactly
  594. // equal to a negative integer.
  595. // Check if the argument of lgamma is exactly equal to a negative integer.
  596. if(floor_of_z_is_equal_to_z)
  597. return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
  598. T t = sinpx(z);
  599. if(t < 0)
  600. {
  601. t = -t;
  602. }
  603. else
  604. {
  605. sign_of_result = -sign_of_result;
  606. }
  607. log_gamma_value = - log_gamma_value
  608. + log(boost::math::constants::pi<T>())
  609. - log(t);
  610. }
  611. if(sign != static_cast<int*>(nullptr)) { *sign = sign_of_result; }
  612. return log_gamma_value;
  613. }
  614. //
  615. // This helper calculates tgamma(dz+1)-1 without cancellation errors,
  616. // used by the upper incomplete gamma with z < 1:
  617. //
  618. template <class T, class Policy, class Lanczos>
  619. T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l)
  620. {
  621. BOOST_MATH_STD_USING
  622. typedef typename policies::precision<T,Policy>::type precision_type;
  623. typedef std::integral_constant<int,
  624. precision_type::value <= 0 ? 0 :
  625. precision_type::value <= 64 ? 64 :
  626. precision_type::value <= 113 ? 113 : 0
  627. > tag_type;
  628. T result;
  629. if(dz < 0)
  630. {
  631. if(dz < T(-0.5))
  632. {
  633. // Best method is simply to subtract 1 from tgamma:
  634. result = boost::math::tgamma(1+dz, pol) - 1;
  635. BOOST_MATH_INSTRUMENT_CODE(result);
  636. }
  637. else
  638. {
  639. // Use expm1 on lgamma:
  640. result = boost::math::expm1(-boost::math::log1p(dz, pol)
  641. + lgamma_small_imp<T>(dz+2, dz + 1, dz, tag_type(), pol, l), pol);
  642. BOOST_MATH_INSTRUMENT_CODE(result);
  643. }
  644. }
  645. else
  646. {
  647. if(dz < 2)
  648. {
  649. // Use expm1 on lgamma:
  650. result = boost::math::expm1(lgamma_small_imp<T>(dz+1, dz, dz-1, tag_type(), pol, l), pol);
  651. BOOST_MATH_INSTRUMENT_CODE(result);
  652. }
  653. else
  654. {
  655. // Best method is simply to subtract 1 from tgamma:
  656. result = boost::math::tgamma(1+dz, pol) - 1;
  657. BOOST_MATH_INSTRUMENT_CODE(result);
  658. }
  659. }
  660. return result;
  661. }
  662. template <class T, class Policy>
  663. inline T tgammap1m1_imp(T z, Policy const& pol,
  664. const ::boost::math::lanczos::undefined_lanczos&)
  665. {
  666. BOOST_MATH_STD_USING // ADL of std names
  667. if(fabs(z) < T(0.55))
  668. {
  669. return boost::math::expm1(log_gamma_near_1(z, pol));
  670. }
  671. return boost::math::expm1(boost::math::lgamma(1 + z, pol));
  672. }
  673. //
  674. // Series representation for upper fraction when z is small:
  675. //
  676. template <class T>
  677. struct small_gamma2_series
  678. {
  679. typedef T result_type;
  680. small_gamma2_series(T a_, T x_) : result(-x_), x(-x_), apn(a_+1), n(1){}
  681. T operator()()
  682. {
  683. T r = result / (apn);
  684. result *= x;
  685. result /= ++n;
  686. apn += 1;
  687. return r;
  688. }
  689. private:
  690. T result, x, apn;
  691. int n;
  692. };
  693. //
  694. // calculate power term prefix (z^a)(e^-z) used in the non-normalised
  695. // incomplete gammas:
  696. //
  697. template <class T, class Policy>
  698. T full_igamma_prefix(T a, T z, const Policy& pol)
  699. {
  700. BOOST_MATH_STD_USING
  701. T prefix;
  702. if (z > tools::max_value<T>())
  703. return 0;
  704. T alz = a * log(z);
  705. if(z >= 1)
  706. {
  707. if((alz < tools::log_max_value<T>()) && (-z > tools::log_min_value<T>()))
  708. {
  709. prefix = pow(z, a) * exp(-z);
  710. }
  711. else if(a >= 1)
  712. {
  713. prefix = pow(T(z / exp(z/a)), a);
  714. }
  715. else
  716. {
  717. prefix = exp(alz - z);
  718. }
  719. }
  720. else
  721. {
  722. if(alz > tools::log_min_value<T>())
  723. {
  724. prefix = pow(z, a) * exp(-z);
  725. }
  726. else if(z/a < tools::log_max_value<T>())
  727. {
  728. prefix = pow(T(z / exp(z/a)), a);
  729. }
  730. else
  731. {
  732. prefix = exp(alz - z);
  733. }
  734. }
  735. //
  736. // This error handling isn't very good: it happens after the fact
  737. // rather than before it...
  738. //
  739. if((boost::math::fpclassify)(prefix) == (int)FP_INFINITE)
  740. return policies::raise_overflow_error<T>("boost::math::detail::full_igamma_prefix<%1%>(%1%, %1%)", "Result of incomplete gamma function is too large to represent.", pol);
  741. return prefix;
  742. }
  743. //
  744. // Compute (z^a)(e^-z)/tgamma(a)
  745. // most if the error occurs in this function:
  746. //
  747. template <class T, class Policy, class Lanczos>
  748. T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l)
  749. {
  750. BOOST_MATH_STD_USING
  751. if (z >= tools::max_value<T>())
  752. return 0;
  753. T agh = a + static_cast<T>(Lanczos::g()) - T(0.5);
  754. T prefix;
  755. T d = ((z - a) - static_cast<T>(Lanczos::g()) + T(0.5)) / agh;
  756. if(a < 1)
  757. {
  758. //
  759. // We have to treat a < 1 as a special case because our Lanczos
  760. // approximations are optimised against the factorials with a > 1,
  761. // and for high precision types especially (128-bit reals for example)
  762. // very small values of a can give rather erroneous results for gamma
  763. // unless we do this:
  764. //
  765. // TODO: is this still required? Lanczos approx should be better now?
  766. //
  767. if((z <= tools::log_min_value<T>()) || (a < 1 / tools::max_value<T>()))
  768. {
  769. // Oh dear, have to use logs, should be free of cancellation errors though:
  770. return exp(a * log(z) - z - lgamma_imp(a, pol, l));
  771. }
  772. else
  773. {
  774. // direct calculation, no danger of overflow as gamma(a) < 1/a
  775. // for small a.
  776. return pow(z, a) * exp(-z) / gamma_imp(a, pol, l);
  777. }
  778. }
  779. else if((fabs(d*d*a) <= 100) && (a > 150))
  780. {
  781. // special case for large a and a ~ z.
  782. prefix = a * boost::math::log1pmx(d, pol) + z * static_cast<T>(0.5 - Lanczos::g()) / agh;
  783. prefix = exp(prefix);
  784. }
  785. else
  786. {
  787. //
  788. // general case.
  789. // direct computation is most accurate, but use various fallbacks
  790. // for different parts of the problem domain:
  791. //
  792. T alz = a * log(z / agh);
  793. T amz = a - z;
  794. if(((std::min)(alz, amz) <= tools::log_min_value<T>()) || ((std::max)(alz, amz) >= tools::log_max_value<T>()))
  795. {
  796. T amza = amz / a;
  797. if(((std::min)(alz, amz)/2 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/2 < tools::log_max_value<T>()))
  798. {
  799. // compute square root of the result and then square it:
  800. T sq = pow(z / agh, a / 2) * exp(amz / 2);
  801. prefix = sq * sq;
  802. }
  803. else if(((std::min)(alz, amz)/4 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/4 < tools::log_max_value<T>()) && (z > a))
  804. {
  805. // compute the 4th root of the result then square it twice:
  806. T sq = pow(z / agh, a / 4) * exp(amz / 4);
  807. prefix = sq * sq;
  808. prefix *= prefix;
  809. }
  810. else if((amza > tools::log_min_value<T>()) && (amza < tools::log_max_value<T>()))
  811. {
  812. prefix = pow(T((z * exp(amza)) / agh), a);
  813. }
  814. else
  815. {
  816. prefix = exp(alz + amz);
  817. }
  818. }
  819. else
  820. {
  821. prefix = pow(T(z / agh), a) * exp(amz);
  822. }
  823. }
  824. prefix *= sqrt(agh / boost::math::constants::e<T>()) / Lanczos::lanczos_sum_expG_scaled(a);
  825. return prefix;
  826. }
  827. //
  828. // And again, without Lanczos support:
  829. //
  830. template <class T, class Policy>
  831. T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined_lanczos& l)
  832. {
  833. BOOST_MATH_STD_USING
  834. if((a < 1) && (z < 1))
  835. {
  836. // No overflow possible since the power terms tend to unity as a,z -> 0
  837. return pow(z, a) * exp(-z) / boost::math::tgamma(a, pol);
  838. }
  839. else if(a > minimum_argument_for_bernoulli_recursion<T>())
  840. {
  841. T scaled_gamma = scaled_tgamma_no_lanczos(a, pol);
  842. T power_term = pow(z / a, a / 2);
  843. T a_minus_z = a - z;
  844. if ((0 == power_term) || (fabs(a_minus_z) > tools::log_max_value<T>()))
  845. {
  846. // The result is probably zero, but we need to be sure:
  847. return exp(a * log(z / a) + a_minus_z - log(scaled_gamma));
  848. }
  849. return (power_term * exp(a_minus_z)) * (power_term / scaled_gamma);
  850. }
  851. else
  852. {
  853. //
  854. // Usual case is to calculate the prefix at a+shift and recurse down
  855. // to the value we want:
  856. //
  857. const int min_z = minimum_argument_for_bernoulli_recursion<T>();
  858. long shift = 1 + ltrunc(min_z - a);
  859. T result = regularised_gamma_prefix(T(a + shift), z, pol, l);
  860. if (result != 0)
  861. {
  862. for (long i = 0; i < shift; ++i)
  863. {
  864. result /= z;
  865. result *= a + i;
  866. }
  867. return result;
  868. }
  869. else
  870. {
  871. //
  872. // We failed, most probably we have z << 1, try again, this time
  873. // we calculate z^a e^-z / tgamma(a+shift), combining power terms
  874. // as we go. And again recurse down to the result.
  875. //
  876. T scaled_gamma = scaled_tgamma_no_lanczos(T(a + shift), pol);
  877. T power_term_1 = pow(T(z / (a + shift)), a);
  878. T power_term_2 = pow(T(a + shift), T(-shift));
  879. T power_term_3 = exp(a + shift - z);
  880. if ((0 == power_term_1) || (0 == power_term_2) || (0 == power_term_3) || (fabs(a + shift - z) > tools::log_max_value<T>()))
  881. {
  882. // We have no test case that gets here, most likely the type T
  883. // has a high precision but low exponent range:
  884. return exp(a * log(z) - z - boost::math::lgamma(a, pol));
  885. }
  886. result = power_term_1 * power_term_2 * power_term_3 / scaled_gamma;
  887. for (long i = 0; i < shift; ++i)
  888. {
  889. result *= a + i;
  890. }
  891. return result;
  892. }
  893. }
  894. }
  895. //
  896. // Upper gamma fraction for very small a:
  897. //
  898. template <class T, class Policy>
  899. inline T tgamma_small_upper_part(T a, T x, const Policy& pol, T* pgam = 0, bool invert = false, T* pderivative = 0)
  900. {
  901. BOOST_MATH_STD_USING // ADL of std functions.
  902. //
  903. // Compute the full upper fraction (Q) when a is very small:
  904. //
  905. T result;
  906. result = boost::math::tgamma1pm1(a, pol);
  907. if(pgam)
  908. *pgam = (result + 1) / a;
  909. T p = boost::math::powm1(x, a, pol);
  910. result -= p;
  911. result /= a;
  912. detail::small_gamma2_series<T> s(a, x);
  913. std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>() - 10;
  914. p += 1;
  915. if(pderivative)
  916. *pderivative = p / (*pgam * exp(x));
  917. T init_value = invert ? *pgam : 0;
  918. result = -p * tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, (init_value - result) / p);
  919. policies::check_series_iterations<T>("boost::math::tgamma_small_upper_part<%1%>(%1%, %1%)", max_iter, pol);
  920. if(invert)
  921. result = -result;
  922. return result;
  923. }
  924. //
  925. // Upper gamma fraction for integer a:
  926. //
  927. template <class T, class Policy>
  928. inline T finite_gamma_q(T a, T x, Policy const& pol, T* pderivative = 0)
  929. {
  930. //
  931. // Calculates normalised Q when a is an integer:
  932. //
  933. BOOST_MATH_STD_USING
  934. T e = exp(-x);
  935. T sum = e;
  936. if(sum != 0)
  937. {
  938. T term = sum;
  939. for(unsigned n = 1; n < a; ++n)
  940. {
  941. term /= n;
  942. term *= x;
  943. sum += term;
  944. }
  945. }
  946. if(pderivative)
  947. {
  948. *pderivative = e * pow(x, a) / boost::math::unchecked_factorial<T>(itrunc(T(a - 1), pol));
  949. }
  950. return sum;
  951. }
  952. //
  953. // Upper gamma fraction for half integer a:
  954. //
  955. template <class T, class Policy>
  956. T finite_half_gamma_q(T a, T x, T* p_derivative, const Policy& pol)
  957. {
  958. //
  959. // Calculates normalised Q when a is a half-integer:
  960. //
  961. BOOST_MATH_STD_USING
  962. T e = boost::math::erfc(sqrt(x), pol);
  963. if((e != 0) && (a > 1))
  964. {
  965. T term = exp(-x) / sqrt(constants::pi<T>() * x);
  966. term *= x;
  967. static const T half = T(1) / 2;
  968. term /= half;
  969. T sum = term;
  970. for(unsigned n = 2; n < a; ++n)
  971. {
  972. term /= n - half;
  973. term *= x;
  974. sum += term;
  975. }
  976. e += sum;
  977. if(p_derivative)
  978. {
  979. *p_derivative = 0;
  980. }
  981. }
  982. else if(p_derivative)
  983. {
  984. // We'll be dividing by x later, so calculate derivative * x:
  985. *p_derivative = sqrt(x) * exp(-x) / constants::root_pi<T>();
  986. }
  987. return e;
  988. }
  989. //
  990. // Asymptotic approximation for large argument, see: https://dlmf.nist.gov/8.11#E2
  991. //
  992. template <class T>
  993. struct incomplete_tgamma_large_x_series
  994. {
  995. typedef T result_type;
  996. incomplete_tgamma_large_x_series(const T& a, const T& x)
  997. : a_poch(a - 1), z(x), term(1) {}
  998. T operator()()
  999. {
  1000. T result = term;
  1001. term *= a_poch / z;
  1002. a_poch -= 1;
  1003. return result;
  1004. }
  1005. T a_poch, z, term;
  1006. };
  1007. template <class T, class Policy>
  1008. T incomplete_tgamma_large_x(const T& a, const T& x, const Policy& pol)
  1009. {
  1010. BOOST_MATH_STD_USING
  1011. incomplete_tgamma_large_x_series<T> s(a, x);
  1012. std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations<Policy>();
  1013. T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
  1014. boost::math::policies::check_series_iterations<T>("boost::math::tgamma<%1%>(%1%,%1%)", max_iter, pol);
  1015. return result;
  1016. }
  1017. //
  1018. // Main incomplete gamma entry point, handles all four incomplete gamma's:
  1019. //
  1020. template <class T, class Policy>
  1021. T gamma_incomplete_imp(T a, T x, bool normalised, bool invert,
  1022. const Policy& pol, T* p_derivative)
  1023. {
  1024. static const char* function = "boost::math::gamma_p<%1%>(%1%, %1%)";
  1025. if(a <= 0)
  1026. return policies::raise_domain_error<T>(function, "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
  1027. if(x < 0)
  1028. return policies::raise_domain_error<T>(function, "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
  1029. BOOST_MATH_STD_USING
  1030. typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
  1031. T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used
  1032. if(a >= max_factorial<T>::value && !normalised)
  1033. {
  1034. //
  1035. // When we're computing the non-normalized incomplete gamma
  1036. // and a is large the result is rather hard to compute unless
  1037. // we use logs. There are really two options - if x is a long
  1038. // way from a in value then we can reliably use methods 2 and 4
  1039. // below in logarithmic form and go straight to the result.
  1040. // Otherwise we let the regularized gamma take the strain
  1041. // (the result is unlikely to underflow in the central region anyway)
  1042. // and combine with lgamma in the hopes that we get a finite result.
  1043. //
  1044. if(invert && (a * 4 < x))
  1045. {
  1046. // This is method 4 below, done in logs:
  1047. result = a * log(x) - x;
  1048. if(p_derivative)
  1049. *p_derivative = exp(result);
  1050. result += log(upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>()));
  1051. }
  1052. else if(!invert && (a > 4 * x))
  1053. {
  1054. // This is method 2 below, done in logs:
  1055. result = a * log(x) - x;
  1056. if(p_derivative)
  1057. *p_derivative = exp(result);
  1058. T init_value = 0;
  1059. result += log(detail::lower_gamma_series(a, x, pol, init_value) / a);
  1060. }
  1061. else
  1062. {
  1063. result = gamma_incomplete_imp(a, x, true, invert, pol, p_derivative);
  1064. if(result == 0)
  1065. {
  1066. if(invert)
  1067. {
  1068. // Try http://functions.wolfram.com/06.06.06.0039.01
  1069. result = 1 + 1 / (12 * a) + 1 / (288 * a * a);
  1070. result = log(result) - a + (a - 0.5f) * log(a) + log(boost::math::constants::root_two_pi<T>());
  1071. if(p_derivative)
  1072. *p_derivative = exp(a * log(x) - x);
  1073. }
  1074. else
  1075. {
  1076. // This is method 2 below, done in logs, we're really outside the
  1077. // range of this method, but since the result is almost certainly
  1078. // infinite, we should probably be OK:
  1079. result = a * log(x) - x;
  1080. if(p_derivative)
  1081. *p_derivative = exp(result);
  1082. T init_value = 0;
  1083. result += log(detail::lower_gamma_series(a, x, pol, init_value) / a);
  1084. }
  1085. }
  1086. else
  1087. {
  1088. result = log(result) + boost::math::lgamma(a, pol);
  1089. }
  1090. }
  1091. if(result > tools::log_max_value<T>())
  1092. return policies::raise_overflow_error<T>(function, nullptr, pol);
  1093. return exp(result);
  1094. }
  1095. BOOST_MATH_ASSERT((p_derivative == nullptr) || normalised);
  1096. bool is_int, is_half_int;
  1097. bool is_small_a = (a < 30) && (a <= x + 1) && (x < tools::log_max_value<T>());
  1098. if(is_small_a)
  1099. {
  1100. T fa = floor(a);
  1101. is_int = (fa == a);
  1102. is_half_int = is_int ? false : (fabs(fa - a) == 0.5f);
  1103. }
  1104. else
  1105. {
  1106. is_int = is_half_int = false;
  1107. }
  1108. int eval_method;
  1109. if(is_int && (x > 0.6))
  1110. {
  1111. // calculate Q via finite sum:
  1112. invert = !invert;
  1113. eval_method = 0;
  1114. }
  1115. else if(is_half_int && (x > 0.2))
  1116. {
  1117. // calculate Q via finite sum for half integer a:
  1118. invert = !invert;
  1119. eval_method = 1;
  1120. }
  1121. else if((x < tools::root_epsilon<T>()) && (a > 1))
  1122. {
  1123. eval_method = 6;
  1124. }
  1125. else if ((x > 1000) && ((a < x) || (fabs(a - 50) / x < 1)))
  1126. {
  1127. // calculate Q via asymptotic approximation:
  1128. invert = !invert;
  1129. eval_method = 7;
  1130. }
  1131. else if(x < T(0.5))
  1132. {
  1133. //
  1134. // Changeover criterion chosen to give a changeover at Q ~ 0.33
  1135. //
  1136. if(T(-0.4) / log(x) < a)
  1137. {
  1138. eval_method = 2;
  1139. }
  1140. else
  1141. {
  1142. eval_method = 3;
  1143. }
  1144. }
  1145. else if(x < T(1.1))
  1146. {
  1147. //
  1148. // Changeover here occurs when P ~ 0.75 or Q ~ 0.25:
  1149. //
  1150. if(x * 0.75f < a)
  1151. {
  1152. eval_method = 2;
  1153. }
  1154. else
  1155. {
  1156. eval_method = 3;
  1157. }
  1158. }
  1159. else
  1160. {
  1161. //
  1162. // Begin by testing whether we're in the "bad" zone
  1163. // where the result will be near 0.5 and the usual
  1164. // series and continued fractions are slow to converge:
  1165. //
  1166. bool use_temme = false;
  1167. if(normalised && std::numeric_limits<T>::is_specialized && (a > 20))
  1168. {
  1169. T sigma = fabs((x-a)/a);
  1170. if((a > 200) && (policies::digits<T, Policy>() <= 113))
  1171. {
  1172. //
  1173. // This limit is chosen so that we use Temme's expansion
  1174. // only if the result would be larger than about 10^-6.
  1175. // Below that the regular series and continued fractions
  1176. // converge OK, and if we use Temme's method we get increasing
  1177. // errors from the dominant erfc term as it's (inexact) argument
  1178. // increases in magnitude.
  1179. //
  1180. if(20 / a > sigma * sigma)
  1181. use_temme = true;
  1182. }
  1183. else if(policies::digits<T, Policy>() <= 64)
  1184. {
  1185. // Note in this zone we can't use Temme's expansion for
  1186. // types longer than an 80-bit real:
  1187. // it would require too many terms in the polynomials.
  1188. if(sigma < 0.4)
  1189. use_temme = true;
  1190. }
  1191. }
  1192. if(use_temme)
  1193. {
  1194. eval_method = 5;
  1195. }
  1196. else
  1197. {
  1198. //
  1199. // Regular case where the result will not be too close to 0.5.
  1200. //
  1201. // Changeover here occurs at P ~ Q ~ 0.5
  1202. // Note that series computation of P is about x2 faster than continued fraction
  1203. // calculation of Q, so try and use the CF only when really necessary, especially
  1204. // for small x.
  1205. //
  1206. if(x - (1 / (3 * x)) < a)
  1207. {
  1208. eval_method = 2;
  1209. }
  1210. else
  1211. {
  1212. eval_method = 4;
  1213. invert = !invert;
  1214. }
  1215. }
  1216. }
  1217. switch(eval_method)
  1218. {
  1219. case 0:
  1220. {
  1221. result = finite_gamma_q(a, x, pol, p_derivative);
  1222. if(!normalised)
  1223. result *= boost::math::tgamma(a, pol);
  1224. break;
  1225. }
  1226. case 1:
  1227. {
  1228. result = finite_half_gamma_q(a, x, p_derivative, pol);
  1229. if(!normalised)
  1230. result *= boost::math::tgamma(a, pol);
  1231. if(p_derivative && (*p_derivative == 0))
  1232. *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
  1233. break;
  1234. }
  1235. case 2:
  1236. {
  1237. // Compute P:
  1238. result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
  1239. if(p_derivative)
  1240. *p_derivative = result;
  1241. if(result != 0)
  1242. {
  1243. //
  1244. // If we're going to be inverting the result then we can
  1245. // reduce the number of series evaluations by quite
  1246. // a few iterations if we set an initial value for the
  1247. // series sum based on what we'll end up subtracting it from
  1248. // at the end.
  1249. // Have to be careful though that this optimization doesn't
  1250. // lead to spurious numeric overflow. Note that the
  1251. // scary/expensive overflow checks below are more often
  1252. // than not bypassed in practice for "sensible" input
  1253. // values:
  1254. //
  1255. T init_value = 0;
  1256. bool optimised_invert = false;
  1257. if(invert)
  1258. {
  1259. init_value = (normalised ? 1 : boost::math::tgamma(a, pol));
  1260. if(normalised || (result >= 1) || (tools::max_value<T>() * result > init_value))
  1261. {
  1262. init_value /= result;
  1263. if(normalised || (a < 1) || (tools::max_value<T>() / a > init_value))
  1264. {
  1265. init_value *= -a;
  1266. optimised_invert = true;
  1267. }
  1268. else
  1269. init_value = 0;
  1270. }
  1271. else
  1272. init_value = 0;
  1273. }
  1274. result *= detail::lower_gamma_series(a, x, pol, init_value) / a;
  1275. if(optimised_invert)
  1276. {
  1277. invert = false;
  1278. result = -result;
  1279. }
  1280. }
  1281. break;
  1282. }
  1283. case 3:
  1284. {
  1285. // Compute Q:
  1286. invert = !invert;
  1287. T g;
  1288. result = tgamma_small_upper_part(a, x, pol, &g, invert, p_derivative);
  1289. invert = false;
  1290. if(normalised)
  1291. result /= g;
  1292. break;
  1293. }
  1294. case 4:
  1295. {
  1296. // Compute Q:
  1297. result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
  1298. if(p_derivative)
  1299. *p_derivative = result;
  1300. if(result != 0)
  1301. result *= upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>());
  1302. break;
  1303. }
  1304. case 5:
  1305. {
  1306. //
  1307. // Use compile time dispatch to the appropriate
  1308. // Temme asymptotic expansion. This may be dead code
  1309. // if T does not have numeric limits support, or has
  1310. // too many digits for the most precise version of
  1311. // these expansions, in that case we'll be calling
  1312. // an empty function.
  1313. //
  1314. typedef typename policies::precision<T, Policy>::type precision_type;
  1315. typedef std::integral_constant<int,
  1316. precision_type::value <= 0 ? 0 :
  1317. precision_type::value <= 53 ? 53 :
  1318. precision_type::value <= 64 ? 64 :
  1319. precision_type::value <= 113 ? 113 : 0
  1320. > tag_type;
  1321. result = igamma_temme_large(a, x, pol, static_cast<tag_type const*>(nullptr));
  1322. if(x >= a)
  1323. invert = !invert;
  1324. if(p_derivative)
  1325. *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
  1326. break;
  1327. }
  1328. case 6:
  1329. {
  1330. // x is so small that P is necessarily very small too,
  1331. // use http://functions.wolfram.com/GammaBetaErf/GammaRegularized/06/01/05/01/01/
  1332. if(!normalised)
  1333. result = pow(x, a) / (a);
  1334. else
  1335. {
  1336. #ifndef BOOST_NO_EXCEPTIONS
  1337. try
  1338. {
  1339. #endif
  1340. result = pow(x, a) / boost::math::tgamma(a + 1, pol);
  1341. #ifndef BOOST_NO_EXCEPTIONS
  1342. }
  1343. catch (const std::overflow_error&)
  1344. {
  1345. result = 0;
  1346. }
  1347. #endif
  1348. }
  1349. result *= 1 - a * x / (a + 1);
  1350. if (p_derivative)
  1351. *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
  1352. break;
  1353. }
  1354. case 7:
  1355. {
  1356. // x is large,
  1357. // Compute Q:
  1358. result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
  1359. if (p_derivative)
  1360. *p_derivative = result;
  1361. result /= x;
  1362. if (result != 0)
  1363. result *= incomplete_tgamma_large_x(a, x, pol);
  1364. break;
  1365. }
  1366. }
  1367. if(normalised && (result > 1))
  1368. result = 1;
  1369. if(invert)
  1370. {
  1371. T gam = normalised ? 1 : boost::math::tgamma(a, pol);
  1372. result = gam - result;
  1373. }
  1374. if(p_derivative)
  1375. {
  1376. //
  1377. // Need to convert prefix term to derivative:
  1378. //
  1379. if((x < 1) && (tools::max_value<T>() * x < *p_derivative))
  1380. {
  1381. // overflow, just return an arbitrarily large value:
  1382. *p_derivative = tools::max_value<T>() / 2;
  1383. }
  1384. *p_derivative /= x;
  1385. }
  1386. return result;
  1387. }
  1388. //
  1389. // Ratios of two gamma functions:
  1390. //
  1391. template <class T, class Policy, class Lanczos>
  1392. T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& l)
  1393. {
  1394. BOOST_MATH_STD_USING
  1395. if(z < tools::epsilon<T>())
  1396. {
  1397. //
  1398. // We get spurious numeric overflow unless we're very careful, this
  1399. // can occur either inside Lanczos::lanczos_sum(z) or in the
  1400. // final combination of terms, to avoid this, split the product up
  1401. // into 2 (or 3) parts:
  1402. //
  1403. // G(z) / G(L) = 1 / (z * G(L)) ; z < eps, L = z + delta = delta
  1404. // z * G(L) = z * G(lim) * (G(L)/G(lim)) ; lim = largest factorial
  1405. //
  1406. if(boost::math::max_factorial<T>::value < delta)
  1407. {
  1408. T ratio = tgamma_delta_ratio_imp_lanczos(delta, T(boost::math::max_factorial<T>::value - delta), pol, l);
  1409. ratio *= z;
  1410. ratio *= boost::math::unchecked_factorial<T>(boost::math::max_factorial<T>::value - 1);
  1411. return 1 / ratio;
  1412. }
  1413. else
  1414. {
  1415. return 1 / (z * boost::math::tgamma(z + delta, pol));
  1416. }
  1417. }
  1418. T zgh = static_cast<T>(z + T(Lanczos::g()) - constants::half<T>());
  1419. T result;
  1420. if(z + delta == z)
  1421. {
  1422. if (fabs(delta / zgh) < boost::math::tools::epsilon<T>())
  1423. {
  1424. // We have:
  1425. // result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
  1426. // 0.5 - z == -z
  1427. // log1p(delta / zgh) = delta / zgh = delta / z
  1428. // multiplying we get -delta.
  1429. result = exp(-delta);
  1430. }
  1431. else
  1432. // from the pow formula below... but this may actually be wrong, we just can't really calculate it :(
  1433. result = 1;
  1434. }
  1435. else
  1436. {
  1437. if(fabs(delta) < 10)
  1438. {
  1439. result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
  1440. }
  1441. else
  1442. {
  1443. result = pow(T(zgh / (zgh + delta)), T(z - constants::half<T>()));
  1444. }
  1445. // Split the calculation up to avoid spurious overflow:
  1446. result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta));
  1447. }
  1448. result *= pow(T(constants::e<T>() / (zgh + delta)), delta);
  1449. return result;
  1450. }
  1451. //
  1452. // And again without Lanczos support this time:
  1453. //
  1454. template <class T, class Policy>
  1455. T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos::undefined_lanczos& l)
  1456. {
  1457. BOOST_MATH_STD_USING
  1458. //
  1459. // We adjust z and delta so that both z and z+delta are large enough for
  1460. // Sterling's approximation to hold. We can then calculate the ratio
  1461. // for the adjusted values, and rescale back down to z and z+delta.
  1462. //
  1463. // Get the required shifts first:
  1464. //
  1465. long numerator_shift = 0;
  1466. long denominator_shift = 0;
  1467. const int min_z = minimum_argument_for_bernoulli_recursion<T>();
  1468. if (min_z > z)
  1469. numerator_shift = 1 + ltrunc(min_z - z);
  1470. if (min_z > z + delta)
  1471. denominator_shift = 1 + ltrunc(min_z - z - delta);
  1472. //
  1473. // If the shifts are zero, then we can just combine scaled tgamma's
  1474. // and combine the remaining terms:
  1475. //
  1476. if (numerator_shift == 0 && denominator_shift == 0)
  1477. {
  1478. T scaled_tgamma_num = scaled_tgamma_no_lanczos(z, pol);
  1479. T scaled_tgamma_denom = scaled_tgamma_no_lanczos(T(z + delta), pol);
  1480. T result = scaled_tgamma_num / scaled_tgamma_denom;
  1481. result *= exp(z * boost::math::log1p(-delta / (z + delta), pol)) * pow(T((delta + z) / constants::e<T>()), -delta);
  1482. return result;
  1483. }
  1484. //
  1485. // We're going to have to rescale first, get the adjusted z and delta values,
  1486. // plus the ratio for the adjusted values:
  1487. //
  1488. T zz = z + numerator_shift;
  1489. T dd = delta - (numerator_shift - denominator_shift);
  1490. T ratio = tgamma_delta_ratio_imp_lanczos(zz, dd, pol, l);
  1491. //
  1492. // Use gamma recurrence relations to get back to the original
  1493. // z and z+delta:
  1494. //
  1495. for (long long i = 0; i < numerator_shift; ++i)
  1496. {
  1497. ratio /= (z + i);
  1498. if (i < denominator_shift)
  1499. ratio *= (z + delta + i);
  1500. }
  1501. for (long long i = numerator_shift; i < denominator_shift; ++i)
  1502. {
  1503. ratio *= (z + delta + i);
  1504. }
  1505. return ratio;
  1506. }
  1507. template <class T, class Policy>
  1508. T tgamma_delta_ratio_imp(T z, T delta, const Policy& pol)
  1509. {
  1510. BOOST_MATH_STD_USING
  1511. if((z <= 0) || (z + delta <= 0))
  1512. {
  1513. // This isn't very sophisticated, or accurate, but it does work:
  1514. return boost::math::tgamma(z, pol) / boost::math::tgamma(z + delta, pol);
  1515. }
  1516. if(floor(delta) == delta)
  1517. {
  1518. if(floor(z) == z)
  1519. {
  1520. //
  1521. // Both z and delta are integers, see if we can just use table lookup
  1522. // of the factorials to get the result:
  1523. //
  1524. if((z <= max_factorial<T>::value) && (z + delta <= max_factorial<T>::value))
  1525. {
  1526. return unchecked_factorial<T>((unsigned)itrunc(z, pol) - 1) / unchecked_factorial<T>((unsigned)itrunc(T(z + delta), pol) - 1);
  1527. }
  1528. }
  1529. if(fabs(delta) < 20)
  1530. {
  1531. //
  1532. // delta is a small integer, we can use a finite product:
  1533. //
  1534. if(delta == 0)
  1535. return 1;
  1536. if(delta < 0)
  1537. {
  1538. z -= 1;
  1539. T result = z;
  1540. while(0 != (delta += 1))
  1541. {
  1542. z -= 1;
  1543. result *= z;
  1544. }
  1545. return result;
  1546. }
  1547. else
  1548. {
  1549. T result = 1 / z;
  1550. while(0 != (delta -= 1))
  1551. {
  1552. z += 1;
  1553. result /= z;
  1554. }
  1555. return result;
  1556. }
  1557. }
  1558. }
  1559. typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
  1560. return tgamma_delta_ratio_imp_lanczos(z, delta, pol, lanczos_type());
  1561. }
  1562. template <class T, class Policy>
  1563. T tgamma_ratio_imp(T x, T y, const Policy& pol)
  1564. {
  1565. BOOST_MATH_STD_USING
  1566. if((x <= 0) || (boost::math::isinf)(x))
  1567. return policies::raise_domain_error<T>("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got a=%1%).", x, pol);
  1568. if((y <= 0) || (boost::math::isinf)(y))
  1569. return policies::raise_domain_error<T>("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got b=%1%).", y, pol);
  1570. if(x <= tools::min_value<T>())
  1571. {
  1572. // Special case for denorms...Ugh.
  1573. T shift = ldexp(T(1), tools::digits<T>());
  1574. return shift * tgamma_ratio_imp(T(x * shift), y, pol);
  1575. }
  1576. if((x < max_factorial<T>::value) && (y < max_factorial<T>::value))
  1577. {
  1578. // Rather than subtracting values, lets just call the gamma functions directly:
  1579. return boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
  1580. }
  1581. T prefix = 1;
  1582. if(x < 1)
  1583. {
  1584. if(y < 2 * max_factorial<T>::value)
  1585. {
  1586. // We need to sidestep on x as well, otherwise we'll underflow
  1587. // before we get to factor in the prefix term:
  1588. prefix /= x;
  1589. x += 1;
  1590. while(y >= max_factorial<T>::value)
  1591. {
  1592. y -= 1;
  1593. prefix /= y;
  1594. }
  1595. return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
  1596. }
  1597. //
  1598. // result is almost certainly going to underflow to zero, try logs just in case:
  1599. //
  1600. return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
  1601. }
  1602. if(y < 1)
  1603. {
  1604. if(x < 2 * max_factorial<T>::value)
  1605. {
  1606. // We need to sidestep on y as well, otherwise we'll overflow
  1607. // before we get to factor in the prefix term:
  1608. prefix *= y;
  1609. y += 1;
  1610. while(x >= max_factorial<T>::value)
  1611. {
  1612. x -= 1;
  1613. prefix *= x;
  1614. }
  1615. return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
  1616. }
  1617. //
  1618. // Result will almost certainly overflow, try logs just in case:
  1619. //
  1620. return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
  1621. }
  1622. //
  1623. // Regular case, x and y both large and similar in magnitude:
  1624. //
  1625. return boost::math::tgamma_delta_ratio(x, y - x, pol);
  1626. }
  1627. template <class T, class Policy>
  1628. T gamma_p_derivative_imp(T a, T x, const Policy& pol)
  1629. {
  1630. BOOST_MATH_STD_USING
  1631. //
  1632. // Usual error checks first:
  1633. //
  1634. if(a <= 0)
  1635. return policies::raise_domain_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
  1636. if(x < 0)
  1637. return policies::raise_domain_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
  1638. //
  1639. // Now special cases:
  1640. //
  1641. if(x == 0)
  1642. {
  1643. return (a > 1) ? 0 :
  1644. (a == 1) ? 1 : policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", nullptr, pol);
  1645. }
  1646. //
  1647. // Normal case:
  1648. //
  1649. typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
  1650. T f1 = detail::regularised_gamma_prefix(a, x, pol, lanczos_type());
  1651. if((x < 1) && (tools::max_value<T>() * x < f1))
  1652. {
  1653. // overflow:
  1654. return policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", nullptr, pol);
  1655. }
  1656. if(f1 == 0)
  1657. {
  1658. // Underflow in calculation, use logs instead:
  1659. f1 = a * log(x) - x - lgamma(a, pol) - log(x);
  1660. f1 = exp(f1);
  1661. }
  1662. else
  1663. f1 /= x;
  1664. return f1;
  1665. }
  1666. template <class T, class Policy>
  1667. inline typename tools::promote_args<T>::type
  1668. tgamma(T z, const Policy& /* pol */, const std::true_type)
  1669. {
  1670. BOOST_FPU_EXCEPTION_GUARD
  1671. typedef typename tools::promote_args<T>::type result_type;
  1672. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1673. typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1674. typedef typename policies::normalise<
  1675. Policy,
  1676. policies::promote_float<false>,
  1677. policies::promote_double<false>,
  1678. policies::discrete_quantile<>,
  1679. policies::assert_undefined<> >::type forwarding_policy;
  1680. return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::gamma_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma<%1%>(%1%)");
  1681. }
  1682. template <class T, class Policy>
  1683. struct igamma_initializer
  1684. {
  1685. struct init
  1686. {
  1687. init()
  1688. {
  1689. typedef typename policies::precision<T, Policy>::type precision_type;
  1690. typedef std::integral_constant<int,
  1691. precision_type::value <= 0 ? 0 :
  1692. precision_type::value <= 53 ? 53 :
  1693. precision_type::value <= 64 ? 64 :
  1694. precision_type::value <= 113 ? 113 : 0
  1695. > tag_type;
  1696. do_init(tag_type());
  1697. }
  1698. template <int N>
  1699. static void do_init(const std::integral_constant<int, N>&)
  1700. {
  1701. // If std::numeric_limits<T>::digits is zero, we must not call
  1702. // our initialization code here as the precision presumably
  1703. // varies at runtime, and will not have been set yet. Plus the
  1704. // code requiring initialization isn't called when digits == 0.
  1705. if(std::numeric_limits<T>::digits)
  1706. {
  1707. boost::math::gamma_p(static_cast<T>(400), static_cast<T>(400), Policy());
  1708. }
  1709. }
  1710. static void do_init(const std::integral_constant<int, 53>&){}
  1711. void force_instantiate()const{}
  1712. };
  1713. static const init initializer;
  1714. static void force_instantiate()
  1715. {
  1716. initializer.force_instantiate();
  1717. }
  1718. };
  1719. template <class T, class Policy>
  1720. const typename igamma_initializer<T, Policy>::init igamma_initializer<T, Policy>::initializer;
  1721. template <class T, class Policy>
  1722. struct lgamma_initializer
  1723. {
  1724. struct init
  1725. {
  1726. init()
  1727. {
  1728. typedef typename policies::precision<T, Policy>::type precision_type;
  1729. typedef std::integral_constant<int,
  1730. precision_type::value <= 0 ? 0 :
  1731. precision_type::value <= 64 ? 64 :
  1732. precision_type::value <= 113 ? 113 : 0
  1733. > tag_type;
  1734. do_init(tag_type());
  1735. }
  1736. static void do_init(const std::integral_constant<int, 64>&)
  1737. {
  1738. boost::math::lgamma(static_cast<T>(2.5), Policy());
  1739. boost::math::lgamma(static_cast<T>(1.25), Policy());
  1740. boost::math::lgamma(static_cast<T>(1.75), Policy());
  1741. }
  1742. static void do_init(const std::integral_constant<int, 113>&)
  1743. {
  1744. boost::math::lgamma(static_cast<T>(2.5), Policy());
  1745. boost::math::lgamma(static_cast<T>(1.25), Policy());
  1746. boost::math::lgamma(static_cast<T>(1.5), Policy());
  1747. boost::math::lgamma(static_cast<T>(1.75), Policy());
  1748. }
  1749. static void do_init(const std::integral_constant<int, 0>&)
  1750. {
  1751. }
  1752. void force_instantiate()const{}
  1753. };
  1754. static const init initializer;
  1755. static void force_instantiate()
  1756. {
  1757. initializer.force_instantiate();
  1758. }
  1759. };
  1760. template <class T, class Policy>
  1761. const typename lgamma_initializer<T, Policy>::init lgamma_initializer<T, Policy>::initializer;
  1762. template <class T1, class T2, class Policy>
  1763. inline tools::promote_args_t<T1, T2>
  1764. tgamma(T1 a, T2 z, const Policy&, const std::false_type)
  1765. {
  1766. BOOST_FPU_EXCEPTION_GUARD
  1767. typedef tools::promote_args_t<T1, T2> result_type;
  1768. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1769. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1770. typedef typename policies::normalise<
  1771. Policy,
  1772. policies::promote_float<false>,
  1773. policies::promote_double<false>,
  1774. policies::discrete_quantile<>,
  1775. policies::assert_undefined<> >::type forwarding_policy;
  1776. igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1777. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1778. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1779. static_cast<value_type>(z), false, true,
  1780. forwarding_policy(), static_cast<value_type*>(nullptr)), "boost::math::tgamma<%1%>(%1%, %1%)");
  1781. }
  1782. template <class T1, class T2>
  1783. inline tools::promote_args_t<T1, T2>
  1784. tgamma(T1 a, T2 z, const std::false_type& tag)
  1785. {
  1786. return tgamma(a, z, policies::policy<>(), tag);
  1787. }
  1788. } // namespace detail
  1789. template <class T>
  1790. inline typename tools::promote_args<T>::type
  1791. tgamma(T z)
  1792. {
  1793. return tgamma(z, policies::policy<>());
  1794. }
  1795. template <class T, class Policy>
  1796. inline typename tools::promote_args<T>::type
  1797. lgamma(T z, int* sign, const Policy&)
  1798. {
  1799. BOOST_FPU_EXCEPTION_GUARD
  1800. typedef typename tools::promote_args<T>::type result_type;
  1801. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1802. typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1803. typedef typename policies::normalise<
  1804. Policy,
  1805. policies::promote_float<false>,
  1806. policies::promote_double<false>,
  1807. policies::discrete_quantile<>,
  1808. policies::assert_undefined<> >::type forwarding_policy;
  1809. detail::lgamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1810. return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::lgamma_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type(), sign), "boost::math::lgamma<%1%>(%1%)");
  1811. }
  1812. template <class T>
  1813. inline typename tools::promote_args<T>::type
  1814. lgamma(T z, int* sign)
  1815. {
  1816. return lgamma(z, sign, policies::policy<>());
  1817. }
  1818. template <class T, class Policy>
  1819. inline typename tools::promote_args<T>::type
  1820. lgamma(T x, const Policy& pol)
  1821. {
  1822. return ::boost::math::lgamma(x, nullptr, pol);
  1823. }
  1824. template <class T>
  1825. inline typename tools::promote_args<T>::type
  1826. lgamma(T x)
  1827. {
  1828. return ::boost::math::lgamma(x, nullptr, policies::policy<>());
  1829. }
  1830. template <class T, class Policy>
  1831. inline typename tools::promote_args<T>::type
  1832. tgamma1pm1(T z, const Policy& /* pol */)
  1833. {
  1834. BOOST_FPU_EXCEPTION_GUARD
  1835. typedef typename tools::promote_args<T>::type result_type;
  1836. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1837. typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1838. typedef typename policies::normalise<
  1839. Policy,
  1840. policies::promote_float<false>,
  1841. policies::promote_double<false>,
  1842. policies::discrete_quantile<>,
  1843. policies::assert_undefined<> >::type forwarding_policy;
  1844. return policies::checked_narrowing_cast<typename std::remove_cv<result_type>::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)");
  1845. }
  1846. template <class T>
  1847. inline typename tools::promote_args<T>::type
  1848. tgamma1pm1(T z)
  1849. {
  1850. return tgamma1pm1(z, policies::policy<>());
  1851. }
  1852. //
  1853. // Full upper incomplete gamma:
  1854. //
  1855. template <class T1, class T2>
  1856. inline tools::promote_args_t<T1, T2>
  1857. tgamma(T1 a, T2 z)
  1858. {
  1859. //
  1860. // Type T2 could be a policy object, or a value, select the
  1861. // right overload based on T2:
  1862. //
  1863. using maybe_policy = typename policies::is_policy<T2>::type;
  1864. using result_type = tools::promote_args_t<T1, T2>;
  1865. return static_cast<result_type>(detail::tgamma(a, z, maybe_policy()));
  1866. }
  1867. template <class T1, class T2, class Policy>
  1868. inline tools::promote_args_t<T1, T2>
  1869. tgamma(T1 a, T2 z, const Policy& pol)
  1870. {
  1871. using result_type = tools::promote_args_t<T1, T2>;
  1872. return static_cast<result_type>(detail::tgamma(a, z, pol, std::false_type()));
  1873. }
  1874. //
  1875. // Full lower incomplete gamma:
  1876. //
  1877. template <class T1, class T2, class Policy>
  1878. inline tools::promote_args_t<T1, T2>
  1879. tgamma_lower(T1 a, T2 z, const Policy&)
  1880. {
  1881. BOOST_FPU_EXCEPTION_GUARD
  1882. typedef tools::promote_args_t<T1, T2> result_type;
  1883. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1884. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1885. typedef typename policies::normalise<
  1886. Policy,
  1887. policies::promote_float<false>,
  1888. policies::promote_double<false>,
  1889. policies::discrete_quantile<>,
  1890. policies::assert_undefined<> >::type forwarding_policy;
  1891. detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1892. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1893. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1894. static_cast<value_type>(z), false, false,
  1895. forwarding_policy(), static_cast<value_type*>(nullptr)), "tgamma_lower<%1%>(%1%, %1%)");
  1896. }
  1897. template <class T1, class T2>
  1898. inline tools::promote_args_t<T1, T2>
  1899. tgamma_lower(T1 a, T2 z)
  1900. {
  1901. return tgamma_lower(a, z, policies::policy<>());
  1902. }
  1903. //
  1904. // Regularised upper incomplete gamma:
  1905. //
  1906. template <class T1, class T2, class Policy>
  1907. inline tools::promote_args_t<T1, T2>
  1908. gamma_q(T1 a, T2 z, const Policy& /* pol */)
  1909. {
  1910. BOOST_FPU_EXCEPTION_GUARD
  1911. typedef tools::promote_args_t<T1, T2> result_type;
  1912. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1913. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1914. typedef typename policies::normalise<
  1915. Policy,
  1916. policies::promote_float<false>,
  1917. policies::promote_double<false>,
  1918. policies::discrete_quantile<>,
  1919. policies::assert_undefined<> >::type forwarding_policy;
  1920. detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1921. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1922. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1923. static_cast<value_type>(z), true, true,
  1924. forwarding_policy(), static_cast<value_type*>(nullptr)), "gamma_q<%1%>(%1%, %1%)");
  1925. }
  1926. template <class T1, class T2>
  1927. inline tools::promote_args_t<T1, T2>
  1928. gamma_q(T1 a, T2 z)
  1929. {
  1930. return gamma_q(a, z, policies::policy<>());
  1931. }
  1932. //
  1933. // Regularised lower incomplete gamma:
  1934. //
  1935. template <class T1, class T2, class Policy>
  1936. inline tools::promote_args_t<T1, T2>
  1937. gamma_p(T1 a, T2 z, const Policy&)
  1938. {
  1939. BOOST_FPU_EXCEPTION_GUARD
  1940. typedef tools::promote_args_t<T1, T2> result_type;
  1941. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1942. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1943. typedef typename policies::normalise<
  1944. Policy,
  1945. policies::promote_float<false>,
  1946. policies::promote_double<false>,
  1947. policies::discrete_quantile<>,
  1948. policies::assert_undefined<> >::type forwarding_policy;
  1949. detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1950. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1951. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1952. static_cast<value_type>(z), true, false,
  1953. forwarding_policy(), static_cast<value_type*>(nullptr)), "gamma_p<%1%>(%1%, %1%)");
  1954. }
  1955. template <class T1, class T2>
  1956. inline tools::promote_args_t<T1, T2>
  1957. gamma_p(T1 a, T2 z)
  1958. {
  1959. return gamma_p(a, z, policies::policy<>());
  1960. }
  1961. // ratios of gamma functions:
  1962. template <class T1, class T2, class Policy>
  1963. inline tools::promote_args_t<T1, T2>
  1964. tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */)
  1965. {
  1966. BOOST_FPU_EXCEPTION_GUARD
  1967. typedef tools::promote_args_t<T1, T2> result_type;
  1968. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1969. typedef typename policies::normalise<
  1970. Policy,
  1971. policies::promote_float<false>,
  1972. policies::promote_double<false>,
  1973. policies::discrete_quantile<>,
  1974. policies::assert_undefined<> >::type forwarding_policy;
  1975. return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::tgamma_delta_ratio_imp(static_cast<value_type>(z), static_cast<value_type>(delta), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)");
  1976. }
  1977. template <class T1, class T2>
  1978. inline tools::promote_args_t<T1, T2>
  1979. tgamma_delta_ratio(T1 z, T2 delta)
  1980. {
  1981. return tgamma_delta_ratio(z, delta, policies::policy<>());
  1982. }
  1983. template <class T1, class T2, class Policy>
  1984. inline tools::promote_args_t<T1, T2>
  1985. tgamma_ratio(T1 a, T2 b, const Policy&)
  1986. {
  1987. typedef tools::promote_args_t<T1, T2> result_type;
  1988. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1989. typedef typename policies::normalise<
  1990. Policy,
  1991. policies::promote_float<false>,
  1992. policies::promote_double<false>,
  1993. policies::discrete_quantile<>,
  1994. policies::assert_undefined<> >::type forwarding_policy;
  1995. return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::tgamma_ratio_imp(static_cast<value_type>(a), static_cast<value_type>(b), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)");
  1996. }
  1997. template <class T1, class T2>
  1998. inline tools::promote_args_t<T1, T2>
  1999. tgamma_ratio(T1 a, T2 b)
  2000. {
  2001. return tgamma_ratio(a, b, policies::policy<>());
  2002. }
  2003. template <class T1, class T2, class Policy>
  2004. inline tools::promote_args_t<T1, T2>
  2005. gamma_p_derivative(T1 a, T2 x, const Policy&)
  2006. {
  2007. BOOST_FPU_EXCEPTION_GUARD
  2008. typedef tools::promote_args_t<T1, T2> result_type;
  2009. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  2010. typedef typename policies::normalise<
  2011. Policy,
  2012. policies::promote_float<false>,
  2013. policies::promote_double<false>,
  2014. policies::discrete_quantile<>,
  2015. policies::assert_undefined<> >::type forwarding_policy;
  2016. return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::gamma_p_derivative_imp(static_cast<value_type>(a), static_cast<value_type>(x), forwarding_policy()), "boost::math::gamma_p_derivative<%1%>(%1%, %1%)");
  2017. }
  2018. template <class T1, class T2>
  2019. inline tools::promote_args_t<T1, T2>
  2020. gamma_p_derivative(T1 a, T2 x)
  2021. {
  2022. return gamma_p_derivative(a, x, policies::policy<>());
  2023. }
  2024. } // namespace math
  2025. } // namespace boost
  2026. #ifdef _MSC_VER
  2027. # pragma warning(pop)
  2028. #endif
  2029. #include <boost/math/special_functions/detail/igamma_inverse.hpp>
  2030. #include <boost/math/special_functions/detail/gamma_inva.hpp>
  2031. #include <boost/math/special_functions/erf.hpp>
  2032. #endif // BOOST_MATH_SF_GAMMA_HPP