gamma.hpp 66 KB

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