gamma.hpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081
  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. return log(boost::math::unchecked_factorial<T>(itrunc(z) - 1));
  480. }
  481. // Make a local, unsigned copy of the input argument.
  482. T zz((!b_neg) ? z : -z);
  483. const T min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
  484. T log_gamma_value;
  485. if (zz < min_arg_for_recursion)
  486. {
  487. // Here we simply take the logarithm of tgamma(). This is somewhat
  488. // inefficient, but simple. The rationale is that the argument here
  489. // is relatively small and overflow is not expected to be likely.
  490. if(fabs(z - 1) < 0.25)
  491. {
  492. return log_gamma_near_1(T(zz - 1), pol);
  493. }
  494. else if(fabs(z - 2) < 0.25)
  495. {
  496. return log_gamma_near_1(T(zz - 2), pol) + log(zz - 1);
  497. }
  498. else if (z > -tools::root_epsilon<T>())
  499. {
  500. // Reflection formula may fail if z is very close to zero, let the series
  501. // expansion for tgamma close to zero do the work:
  502. log_gamma_value = log(abs(gamma_imp(z, pol, lanczos::undefined_lanczos())));
  503. if (sign)
  504. {
  505. *sign = z < 0 ? -1 : 1;
  506. }
  507. return log_gamma_value;
  508. }
  509. else
  510. {
  511. // No issue with spurious overflow in reflection formula,
  512. // just fall through to regular code:
  513. log_gamma_value = log(abs(gamma_imp(zz, pol, lanczos::undefined_lanczos())));
  514. }
  515. }
  516. else
  517. {
  518. // Perform the Bernoulli series expansion of Stirling's approximation.
  519. const std::size_t number_of_bernoullis_b2n = highest_bernoulli_index<T>();
  520. T one_over_x_pow_two_n_minus_one = 1 / zz;
  521. const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one;
  522. T sum = (boost::math::bernoulli_b2n<T>(1) / 2) * one_over_x_pow_two_n_minus_one;
  523. const T target_epsilon_to_break_loop = (sum * boost::math::tools::epsilon<T>()) * T(1.0E-10F);
  524. for(std::size_t n = 2U; n < number_of_bernoullis_b2n; ++n)
  525. {
  526. one_over_x_pow_two_n_minus_one *= one_over_x2;
  527. const std::size_t n2 = static_cast<std::size_t>(n * 2U);
  528. const T term = (boost::math::bernoulli_b2n<T>(static_cast<int>(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U));
  529. if((n >= 8U) && (abs(term) < target_epsilon_to_break_loop))
  530. {
  531. // We have reached the desired precision in Stirling's expansion.
  532. // Adding additional terms to the sum of this divergent asymptotic
  533. // expansion will not improve the result.
  534. // Break from the loop.
  535. break;
  536. }
  537. sum += term;
  538. }
  539. // Complete Stirling's approximation.
  540. const T half_ln_two_pi = log(boost::math::constants::two_pi<T>()) / 2;
  541. log_gamma_value = ((((zz - boost::math::constants::half<T>()) * log(zz)) - zz) + half_ln_two_pi) + sum;
  542. }
  543. int sign_of_result = 1;
  544. if(b_neg)
  545. {
  546. // Provide special error analysis if the argument is exactly
  547. // equal to a negative integer.
  548. // Check if the argument of lgamma is exactly equal to a negative integer.
  549. if(floor_of_z_is_equal_to_z)
  550. return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
  551. T t = sinpx(z);
  552. if(t < 0)
  553. {
  554. t = -t;
  555. }
  556. else
  557. {
  558. sign_of_result = -sign_of_result;
  559. }
  560. log_gamma_value = - log_gamma_value
  561. + log(boost::math::constants::pi<T>())
  562. - log(t);
  563. }
  564. if(sign != static_cast<int*>(0U)) { *sign = sign_of_result; }
  565. return log_gamma_value;
  566. }
  567. //
  568. // This helper calculates tgamma(dz+1)-1 without cancellation errors,
  569. // used by the upper incomplete gamma with z < 1:
  570. //
  571. template <class T, class Policy, class Lanczos>
  572. T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l)
  573. {
  574. BOOST_MATH_STD_USING
  575. typedef typename policies::precision<T,Policy>::type precision_type;
  576. typedef typename mpl::if_<
  577. mpl::or_<
  578. mpl::less_equal<precision_type, mpl::int_<0> >,
  579. mpl::greater<precision_type, mpl::int_<113> >
  580. >,
  581. typename mpl::if_<
  582. mpl::and_<is_same<Lanczos, lanczos::lanczos24m113>, mpl::greater<precision_type, mpl::int_<0> > >,
  583. mpl::int_<113>,
  584. mpl::int_<0>
  585. >::type,
  586. typename mpl::if_<
  587. mpl::less_equal<precision_type, mpl::int_<64> >,
  588. mpl::int_<64>, mpl::int_<113> >::type
  589. >::type tag_type;
  590. T result;
  591. if(dz < 0)
  592. {
  593. if(dz < -0.5)
  594. {
  595. // Best method is simply to subtract 1 from tgamma:
  596. result = boost::math::tgamma(1+dz, pol) - 1;
  597. BOOST_MATH_INSTRUMENT_CODE(result);
  598. }
  599. else
  600. {
  601. // Use expm1 on lgamma:
  602. result = boost::math::expm1(-boost::math::log1p(dz, pol)
  603. + lgamma_small_imp<T>(dz+2, dz + 1, dz, tag_type(), pol, l));
  604. BOOST_MATH_INSTRUMENT_CODE(result);
  605. }
  606. }
  607. else
  608. {
  609. if(dz < 2)
  610. {
  611. // Use expm1 on lgamma:
  612. result = boost::math::expm1(lgamma_small_imp<T>(dz+1, dz, dz-1, tag_type(), pol, l), pol);
  613. BOOST_MATH_INSTRUMENT_CODE(result);
  614. }
  615. else
  616. {
  617. // Best method is simply to subtract 1 from tgamma:
  618. result = boost::math::tgamma(1+dz, pol) - 1;
  619. BOOST_MATH_INSTRUMENT_CODE(result);
  620. }
  621. }
  622. return result;
  623. }
  624. template <class T, class Policy>
  625. inline T tgammap1m1_imp(T z, Policy const& pol,
  626. const ::boost::math::lanczos::undefined_lanczos&)
  627. {
  628. BOOST_MATH_STD_USING // ADL of std names
  629. if(fabs(z) < 0.55)
  630. {
  631. return boost::math::expm1(log_gamma_near_1(z, pol));
  632. }
  633. return boost::math::expm1(boost::math::lgamma(1 + z, pol));
  634. }
  635. //
  636. // Series representation for upper fraction when z is small:
  637. //
  638. template <class T>
  639. struct small_gamma2_series
  640. {
  641. typedef T result_type;
  642. small_gamma2_series(T a_, T x_) : result(-x_), x(-x_), apn(a_+1), n(1){}
  643. T operator()()
  644. {
  645. T r = result / (apn);
  646. result *= x;
  647. result /= ++n;
  648. apn += 1;
  649. return r;
  650. }
  651. private:
  652. T result, x, apn;
  653. int n;
  654. };
  655. //
  656. // calculate power term prefix (z^a)(e^-z) used in the non-normalised
  657. // incomplete gammas:
  658. //
  659. template <class T, class Policy>
  660. T full_igamma_prefix(T a, T z, const Policy& pol)
  661. {
  662. BOOST_MATH_STD_USING
  663. T prefix;
  664. T alz = a * log(z);
  665. if(z >= 1)
  666. {
  667. if((alz < tools::log_max_value<T>()) && (-z > tools::log_min_value<T>()))
  668. {
  669. prefix = pow(z, a) * exp(-z);
  670. }
  671. else if(a >= 1)
  672. {
  673. prefix = pow(z / exp(z/a), a);
  674. }
  675. else
  676. {
  677. prefix = exp(alz - z);
  678. }
  679. }
  680. else
  681. {
  682. if(alz > tools::log_min_value<T>())
  683. {
  684. prefix = pow(z, a) * exp(-z);
  685. }
  686. else if(z/a < tools::log_max_value<T>())
  687. {
  688. prefix = pow(z / exp(z/a), a);
  689. }
  690. else
  691. {
  692. prefix = exp(alz - z);
  693. }
  694. }
  695. //
  696. // This error handling isn't very good: it happens after the fact
  697. // rather than before it...
  698. //
  699. if((boost::math::fpclassify)(prefix) == (int)FP_INFINITE)
  700. 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);
  701. return prefix;
  702. }
  703. //
  704. // Compute (z^a)(e^-z)/tgamma(a)
  705. // most if the error occurs in this function:
  706. //
  707. template <class T, class Policy, class Lanczos>
  708. T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l)
  709. {
  710. BOOST_MATH_STD_USING
  711. T agh = a + static_cast<T>(Lanczos::g()) - T(0.5);
  712. T prefix;
  713. T d = ((z - a) - static_cast<T>(Lanczos::g()) + T(0.5)) / agh;
  714. if(a < 1)
  715. {
  716. //
  717. // We have to treat a < 1 as a special case because our Lanczos
  718. // approximations are optimised against the factorials with a > 1,
  719. // and for high precision types especially (128-bit reals for example)
  720. // very small values of a can give rather eroneous results for gamma
  721. // unless we do this:
  722. //
  723. // TODO: is this still required? Lanczos approx should be better now?
  724. //
  725. if(z <= tools::log_min_value<T>())
  726. {
  727. // Oh dear, have to use logs, should be free of cancellation errors though:
  728. return exp(a * log(z) - z - lgamma_imp(a, pol, l));
  729. }
  730. else
  731. {
  732. // direct calculation, no danger of overflow as gamma(a) < 1/a
  733. // for small a.
  734. return pow(z, a) * exp(-z) / gamma_imp(a, pol, l);
  735. }
  736. }
  737. else if((fabs(d*d*a) <= 100) && (a > 150))
  738. {
  739. // special case for large a and a ~ z.
  740. prefix = a * boost::math::log1pmx(d, pol) + z * static_cast<T>(0.5 - Lanczos::g()) / agh;
  741. prefix = exp(prefix);
  742. }
  743. else
  744. {
  745. //
  746. // general case.
  747. // direct computation is most accurate, but use various fallbacks
  748. // for different parts of the problem domain:
  749. //
  750. T alz = a * log(z / agh);
  751. T amz = a - z;
  752. if(((std::min)(alz, amz) <= tools::log_min_value<T>()) || ((std::max)(alz, amz) >= tools::log_max_value<T>()))
  753. {
  754. T amza = amz / a;
  755. if(((std::min)(alz, amz)/2 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/2 < tools::log_max_value<T>()))
  756. {
  757. // compute square root of the result and then square it:
  758. T sq = pow(z / agh, a / 2) * exp(amz / 2);
  759. prefix = sq * sq;
  760. }
  761. else if(((std::min)(alz, amz)/4 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/4 < tools::log_max_value<T>()) && (z > a))
  762. {
  763. // compute the 4th root of the result then square it twice:
  764. T sq = pow(z / agh, a / 4) * exp(amz / 4);
  765. prefix = sq * sq;
  766. prefix *= prefix;
  767. }
  768. else if((amza > tools::log_min_value<T>()) && (amza < tools::log_max_value<T>()))
  769. {
  770. prefix = pow((z * exp(amza)) / agh, a);
  771. }
  772. else
  773. {
  774. prefix = exp(alz + amz);
  775. }
  776. }
  777. else
  778. {
  779. prefix = pow(z / agh, a) * exp(amz);
  780. }
  781. }
  782. prefix *= sqrt(agh / boost::math::constants::e<T>()) / Lanczos::lanczos_sum_expG_scaled(a);
  783. return prefix;
  784. }
  785. //
  786. // And again, without Lanczos support:
  787. //
  788. template <class T, class Policy>
  789. T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined_lanczos&)
  790. {
  791. BOOST_MATH_STD_USING
  792. T limit = (std::max)(T(10), a);
  793. T sum = detail::lower_gamma_series(a, limit, pol) / a;
  794. sum += detail::upper_gamma_fraction(a, limit, ::boost::math::policies::get_epsilon<T, Policy>());
  795. if(a < 10)
  796. {
  797. // special case for small a:
  798. T prefix = pow(z / 10, a);
  799. prefix *= exp(10-z);
  800. if(0 == prefix)
  801. {
  802. prefix = pow((z * exp((10-z)/a)) / 10, a);
  803. }
  804. prefix /= sum;
  805. return prefix;
  806. }
  807. T zoa = z / a;
  808. T amz = a - z;
  809. T alzoa = a * log(zoa);
  810. T prefix;
  811. if(((std::min)(alzoa, amz) <= tools::log_min_value<T>()) || ((std::max)(alzoa, amz) >= tools::log_max_value<T>()))
  812. {
  813. T amza = amz / a;
  814. if((amza <= tools::log_min_value<T>()) || (amza >= tools::log_max_value<T>()))
  815. {
  816. prefix = exp(alzoa + amz);
  817. }
  818. else
  819. {
  820. prefix = pow(zoa * exp(amza), a);
  821. }
  822. }
  823. else
  824. {
  825. prefix = pow(zoa, a) * exp(amz);
  826. }
  827. prefix /= sum;
  828. return prefix;
  829. }
  830. //
  831. // Upper gamma fraction for very small a:
  832. //
  833. template <class T, class Policy>
  834. inline T tgamma_small_upper_part(T a, T x, const Policy& pol, T* pgam = 0, bool invert = false, T* pderivative = 0)
  835. {
  836. BOOST_MATH_STD_USING // ADL of std functions.
  837. //
  838. // Compute the full upper fraction (Q) when a is very small:
  839. //
  840. T result;
  841. result = boost::math::tgamma1pm1(a, pol);
  842. if(pgam)
  843. *pgam = (result + 1) / a;
  844. T p = boost::math::powm1(x, a, pol);
  845. result -= p;
  846. result /= a;
  847. detail::small_gamma2_series<T> s(a, x);
  848. boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>() - 10;
  849. p += 1;
  850. if(pderivative)
  851. *pderivative = p / (*pgam * exp(x));
  852. T init_value = invert ? *pgam : 0;
  853. result = -p * tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, (init_value - result) / p);
  854. policies::check_series_iterations<T>("boost::math::tgamma_small_upper_part<%1%>(%1%, %1%)", max_iter, pol);
  855. if(invert)
  856. result = -result;
  857. return result;
  858. }
  859. //
  860. // Upper gamma fraction for integer a:
  861. //
  862. template <class T, class Policy>
  863. inline T finite_gamma_q(T a, T x, Policy const& pol, T* pderivative = 0)
  864. {
  865. //
  866. // Calculates normalised Q when a is an integer:
  867. //
  868. BOOST_MATH_STD_USING
  869. T e = exp(-x);
  870. T sum = e;
  871. if(sum != 0)
  872. {
  873. T term = sum;
  874. for(unsigned n = 1; n < a; ++n)
  875. {
  876. term /= n;
  877. term *= x;
  878. sum += term;
  879. }
  880. }
  881. if(pderivative)
  882. {
  883. *pderivative = e * pow(x, a) / boost::math::unchecked_factorial<T>(itrunc(T(a - 1), pol));
  884. }
  885. return sum;
  886. }
  887. //
  888. // Upper gamma fraction for half integer a:
  889. //
  890. template <class T, class Policy>
  891. T finite_half_gamma_q(T a, T x, T* p_derivative, const Policy& pol)
  892. {
  893. //
  894. // Calculates normalised Q when a is a half-integer:
  895. //
  896. BOOST_MATH_STD_USING
  897. T e = boost::math::erfc(sqrt(x), pol);
  898. if((e != 0) && (a > 1))
  899. {
  900. T term = exp(-x) / sqrt(constants::pi<T>() * x);
  901. term *= x;
  902. static const T half = T(1) / 2;
  903. term /= half;
  904. T sum = term;
  905. for(unsigned n = 2; n < a; ++n)
  906. {
  907. term /= n - half;
  908. term *= x;
  909. sum += term;
  910. }
  911. e += sum;
  912. if(p_derivative)
  913. {
  914. *p_derivative = 0;
  915. }
  916. }
  917. else if(p_derivative)
  918. {
  919. // We'll be dividing by x later, so calculate derivative * x:
  920. *p_derivative = sqrt(x) * exp(-x) / constants::root_pi<T>();
  921. }
  922. return e;
  923. }
  924. //
  925. // Main incomplete gamma entry point, handles all four incomplete gamma's:
  926. //
  927. template <class T, class Policy>
  928. T gamma_incomplete_imp(T a, T x, bool normalised, bool invert,
  929. const Policy& pol, T* p_derivative)
  930. {
  931. static const char* function = "boost::math::gamma_p<%1%>(%1%, %1%)";
  932. if(a <= 0)
  933. return policies::raise_domain_error<T>(function, "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
  934. if(x < 0)
  935. return policies::raise_domain_error<T>(function, "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
  936. BOOST_MATH_STD_USING
  937. typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
  938. T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used
  939. if(a >= max_factorial<T>::value && !normalised)
  940. {
  941. //
  942. // When we're computing the non-normalized incomplete gamma
  943. // and a is large the result is rather hard to compute unless
  944. // we use logs. There are really two options - if x is a long
  945. // way from a in value then we can reliably use methods 2 and 4
  946. // below in logarithmic form and go straight to the result.
  947. // Otherwise we let the regularized gamma take the strain
  948. // (the result is unlikely to unerflow in the central region anyway)
  949. // and combine with lgamma in the hopes that we get a finite result.
  950. //
  951. if(invert && (a * 4 < x))
  952. {
  953. // This is method 4 below, done in logs:
  954. result = a * log(x) - x;
  955. if(p_derivative)
  956. *p_derivative = exp(result);
  957. result += log(upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>()));
  958. }
  959. else if(!invert && (a > 4 * x))
  960. {
  961. // This is method 2 below, done in logs:
  962. result = a * log(x) - x;
  963. if(p_derivative)
  964. *p_derivative = exp(result);
  965. T init_value = 0;
  966. result += log(detail::lower_gamma_series(a, x, pol, init_value) / a);
  967. }
  968. else
  969. {
  970. result = gamma_incomplete_imp(a, x, true, invert, pol, p_derivative);
  971. if(result == 0)
  972. {
  973. if(invert)
  974. {
  975. // Try http://functions.wolfram.com/06.06.06.0039.01
  976. result = 1 + 1 / (12 * a) + 1 / (288 * a * a);
  977. result = log(result) - a + (a - 0.5f) * log(a) + log(boost::math::constants::root_two_pi<T>());
  978. if(p_derivative)
  979. *p_derivative = exp(a * log(x) - x);
  980. }
  981. else
  982. {
  983. // This is method 2 below, done in logs, we're really outside the
  984. // range of this method, but since the result is almost certainly
  985. // infinite, we should probably be OK:
  986. result = a * log(x) - x;
  987. if(p_derivative)
  988. *p_derivative = exp(result);
  989. T init_value = 0;
  990. result += log(detail::lower_gamma_series(a, x, pol, init_value) / a);
  991. }
  992. }
  993. else
  994. {
  995. result = log(result) + boost::math::lgamma(a, pol);
  996. }
  997. }
  998. if(result > tools::log_max_value<T>())
  999. return policies::raise_overflow_error<T>(function, 0, pol);
  1000. return exp(result);
  1001. }
  1002. BOOST_ASSERT((p_derivative == 0) || (normalised == true));
  1003. bool is_int, is_half_int;
  1004. bool is_small_a = (a < 30) && (a <= x + 1) && (x < tools::log_max_value<T>());
  1005. if(is_small_a)
  1006. {
  1007. T fa = floor(a);
  1008. is_int = (fa == a);
  1009. is_half_int = is_int ? false : (fabs(fa - a) == 0.5f);
  1010. }
  1011. else
  1012. {
  1013. is_int = is_half_int = false;
  1014. }
  1015. int eval_method;
  1016. if(is_int && (x > 0.6))
  1017. {
  1018. // calculate Q via finite sum:
  1019. invert = !invert;
  1020. eval_method = 0;
  1021. }
  1022. else if(is_half_int && (x > 0.2))
  1023. {
  1024. // calculate Q via finite sum for half integer a:
  1025. invert = !invert;
  1026. eval_method = 1;
  1027. }
  1028. else if((x < tools::root_epsilon<T>()) && (a > 1))
  1029. {
  1030. eval_method = 6;
  1031. }
  1032. else if(x < 0.5)
  1033. {
  1034. //
  1035. // Changeover criterion chosen to give a changeover at Q ~ 0.33
  1036. //
  1037. if(-0.4 / log(x) < a)
  1038. {
  1039. eval_method = 2;
  1040. }
  1041. else
  1042. {
  1043. eval_method = 3;
  1044. }
  1045. }
  1046. else if(x < 1.1)
  1047. {
  1048. //
  1049. // Changover here occurs when P ~ 0.75 or Q ~ 0.25:
  1050. //
  1051. if(x * 0.75f < a)
  1052. {
  1053. eval_method = 2;
  1054. }
  1055. else
  1056. {
  1057. eval_method = 3;
  1058. }
  1059. }
  1060. else
  1061. {
  1062. //
  1063. // Begin by testing whether we're in the "bad" zone
  1064. // where the result will be near 0.5 and the usual
  1065. // series and continued fractions are slow to converge:
  1066. //
  1067. bool use_temme = false;
  1068. if(normalised && std::numeric_limits<T>::is_specialized && (a > 20))
  1069. {
  1070. T sigma = fabs((x-a)/a);
  1071. if((a > 200) && (policies::digits<T, Policy>() <= 113))
  1072. {
  1073. //
  1074. // This limit is chosen so that we use Temme's expansion
  1075. // only if the result would be larger than about 10^-6.
  1076. // Below that the regular series and continued fractions
  1077. // converge OK, and if we use Temme's method we get increasing
  1078. // errors from the dominant erfc term as it's (inexact) argument
  1079. // increases in magnitude.
  1080. //
  1081. if(20 / a > sigma * sigma)
  1082. use_temme = true;
  1083. }
  1084. else if(policies::digits<T, Policy>() <= 64)
  1085. {
  1086. // Note in this zone we can't use Temme's expansion for
  1087. // types longer than an 80-bit real:
  1088. // it would require too many terms in the polynomials.
  1089. if(sigma < 0.4)
  1090. use_temme = true;
  1091. }
  1092. }
  1093. if(use_temme)
  1094. {
  1095. eval_method = 5;
  1096. }
  1097. else
  1098. {
  1099. //
  1100. // Regular case where the result will not be too close to 0.5.
  1101. //
  1102. // Changeover here occurs at P ~ Q ~ 0.5
  1103. // Note that series computation of P is about x2 faster than continued fraction
  1104. // calculation of Q, so try and use the CF only when really necessary, especially
  1105. // for small x.
  1106. //
  1107. if(x - (1 / (3 * x)) < a)
  1108. {
  1109. eval_method = 2;
  1110. }
  1111. else
  1112. {
  1113. eval_method = 4;
  1114. invert = !invert;
  1115. }
  1116. }
  1117. }
  1118. switch(eval_method)
  1119. {
  1120. case 0:
  1121. {
  1122. result = finite_gamma_q(a, x, pol, p_derivative);
  1123. if(normalised == false)
  1124. result *= boost::math::tgamma(a, pol);
  1125. break;
  1126. }
  1127. case 1:
  1128. {
  1129. result = finite_half_gamma_q(a, x, p_derivative, pol);
  1130. if(normalised == false)
  1131. result *= boost::math::tgamma(a, pol);
  1132. if(p_derivative && (*p_derivative == 0))
  1133. *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
  1134. break;
  1135. }
  1136. case 2:
  1137. {
  1138. // Compute P:
  1139. result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
  1140. if(p_derivative)
  1141. *p_derivative = result;
  1142. if(result != 0)
  1143. {
  1144. //
  1145. // If we're going to be inverting the result then we can
  1146. // reduce the number of series evaluations by quite
  1147. // a few iterations if we set an initial value for the
  1148. // series sum based on what we'll end up subtracting it from
  1149. // at the end.
  1150. // Have to be careful though that this optimization doesn't
  1151. // lead to spurious numberic overflow. Note that the
  1152. // scary/expensive overflow checks below are more often
  1153. // than not bypassed in practice for "sensible" input
  1154. // values:
  1155. //
  1156. T init_value = 0;
  1157. bool optimised_invert = false;
  1158. if(invert)
  1159. {
  1160. init_value = (normalised ? 1 : boost::math::tgamma(a, pol));
  1161. if(normalised || (result >= 1) || (tools::max_value<T>() * result > init_value))
  1162. {
  1163. init_value /= result;
  1164. if(normalised || (a < 1) || (tools::max_value<T>() / a > init_value))
  1165. {
  1166. init_value *= -a;
  1167. optimised_invert = true;
  1168. }
  1169. else
  1170. init_value = 0;
  1171. }
  1172. else
  1173. init_value = 0;
  1174. }
  1175. result *= detail::lower_gamma_series(a, x, pol, init_value) / a;
  1176. if(optimised_invert)
  1177. {
  1178. invert = false;
  1179. result = -result;
  1180. }
  1181. }
  1182. break;
  1183. }
  1184. case 3:
  1185. {
  1186. // Compute Q:
  1187. invert = !invert;
  1188. T g;
  1189. result = tgamma_small_upper_part(a, x, pol, &g, invert, p_derivative);
  1190. invert = false;
  1191. if(normalised)
  1192. result /= g;
  1193. break;
  1194. }
  1195. case 4:
  1196. {
  1197. // Compute Q:
  1198. result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
  1199. if(p_derivative)
  1200. *p_derivative = result;
  1201. if(result != 0)
  1202. result *= upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>());
  1203. break;
  1204. }
  1205. case 5:
  1206. {
  1207. //
  1208. // Use compile time dispatch to the appropriate
  1209. // Temme asymptotic expansion. This may be dead code
  1210. // if T does not have numeric limits support, or has
  1211. // too many digits for the most precise version of
  1212. // these expansions, in that case we'll be calling
  1213. // an empty function.
  1214. //
  1215. typedef typename policies::precision<T, Policy>::type precision_type;
  1216. typedef typename mpl::if_<
  1217. mpl::or_<mpl::equal_to<precision_type, mpl::int_<0> >,
  1218. mpl::greater<precision_type, mpl::int_<113> > >,
  1219. mpl::int_<0>,
  1220. typename mpl::if_<
  1221. mpl::less_equal<precision_type, mpl::int_<53> >,
  1222. mpl::int_<53>,
  1223. typename mpl::if_<
  1224. mpl::less_equal<precision_type, mpl::int_<64> >,
  1225. mpl::int_<64>,
  1226. mpl::int_<113>
  1227. >::type
  1228. >::type
  1229. >::type tag_type;
  1230. result = igamma_temme_large(a, x, pol, static_cast<tag_type const*>(0));
  1231. if(x >= a)
  1232. invert = !invert;
  1233. if(p_derivative)
  1234. *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
  1235. break;
  1236. }
  1237. case 6:
  1238. {
  1239. // x is so small that P is necessarily very small too,
  1240. // use http://functions.wolfram.com/GammaBetaErf/GammaRegularized/06/01/05/01/01/
  1241. result = !normalised ? pow(x, a) / (a) : pow(x, a) / boost::math::tgamma(a + 1, pol);
  1242. result *= 1 - a * x / (a + 1);
  1243. }
  1244. }
  1245. if(normalised && (result > 1))
  1246. result = 1;
  1247. if(invert)
  1248. {
  1249. T gam = normalised ? 1 : boost::math::tgamma(a, pol);
  1250. result = gam - result;
  1251. }
  1252. if(p_derivative)
  1253. {
  1254. //
  1255. // Need to convert prefix term to derivative:
  1256. //
  1257. if((x < 1) && (tools::max_value<T>() * x < *p_derivative))
  1258. {
  1259. // overflow, just return an arbitrarily large value:
  1260. *p_derivative = tools::max_value<T>() / 2;
  1261. }
  1262. *p_derivative /= x;
  1263. }
  1264. return result;
  1265. }
  1266. //
  1267. // Ratios of two gamma functions:
  1268. //
  1269. template <class T, class Policy, class Lanczos>
  1270. T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& l)
  1271. {
  1272. BOOST_MATH_STD_USING
  1273. if(z < tools::epsilon<T>())
  1274. {
  1275. //
  1276. // We get spurious numeric overflow unless we're very careful, this
  1277. // can occur either inside Lanczos::lanczos_sum(z) or in the
  1278. // final combination of terms, to avoid this, split the product up
  1279. // into 2 (or 3) parts:
  1280. //
  1281. // G(z) / G(L) = 1 / (z * G(L)) ; z < eps, L = z + delta = delta
  1282. // z * G(L) = z * G(lim) * (G(L)/G(lim)) ; lim = largest factorial
  1283. //
  1284. if(boost::math::max_factorial<T>::value < delta)
  1285. {
  1286. T ratio = tgamma_delta_ratio_imp_lanczos(delta, T(boost::math::max_factorial<T>::value - delta), pol, l);
  1287. ratio *= z;
  1288. ratio *= boost::math::unchecked_factorial<T>(boost::math::max_factorial<T>::value - 1);
  1289. return 1 / ratio;
  1290. }
  1291. else
  1292. {
  1293. return 1 / (z * boost::math::tgamma(z + delta, pol));
  1294. }
  1295. }
  1296. T zgh = static_cast<T>(z + Lanczos::g() - constants::half<T>());
  1297. T result;
  1298. if(z + delta == z)
  1299. {
  1300. if(fabs(delta) < 10)
  1301. result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
  1302. else
  1303. result = 1;
  1304. }
  1305. else
  1306. {
  1307. if(fabs(delta) < 10)
  1308. {
  1309. result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
  1310. }
  1311. else
  1312. {
  1313. result = pow(zgh / (zgh + delta), z - constants::half<T>());
  1314. }
  1315. // Split the calculation up to avoid spurious overflow:
  1316. result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta));
  1317. }
  1318. result *= pow(constants::e<T>() / (zgh + delta), delta);
  1319. return result;
  1320. }
  1321. //
  1322. // And again without Lanczos support this time:
  1323. //
  1324. template <class T, class Policy>
  1325. T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos::undefined_lanczos&)
  1326. {
  1327. BOOST_MATH_STD_USING
  1328. //
  1329. // The upper gamma fraction is *very* slow for z < 6, actually it's very
  1330. // slow to converge everywhere but recursing until z > 6 gets rid of the
  1331. // worst of it's behaviour.
  1332. //
  1333. T prefix = 1;
  1334. T zd = z + delta;
  1335. while((zd < 6) && (z < 6))
  1336. {
  1337. prefix /= z;
  1338. prefix *= zd;
  1339. z += 1;
  1340. zd += 1;
  1341. }
  1342. if(delta < 10)
  1343. {
  1344. prefix *= exp(-z * boost::math::log1p(delta / z, pol));
  1345. }
  1346. else
  1347. {
  1348. prefix *= pow(z / zd, z);
  1349. }
  1350. prefix *= pow(constants::e<T>() / zd, delta);
  1351. T sum = detail::lower_gamma_series(z, z, pol) / z;
  1352. sum += detail::upper_gamma_fraction(z, z, ::boost::math::policies::get_epsilon<T, Policy>());
  1353. T sumd = detail::lower_gamma_series(zd, zd, pol) / zd;
  1354. sumd += detail::upper_gamma_fraction(zd, zd, ::boost::math::policies::get_epsilon<T, Policy>());
  1355. sum /= sumd;
  1356. if(fabs(tools::max_value<T>() / prefix) < fabs(sum))
  1357. return policies::raise_overflow_error<T>("boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)", "Result of tgamma is too large to represent.", pol);
  1358. return sum * prefix;
  1359. }
  1360. template <class T, class Policy>
  1361. T tgamma_delta_ratio_imp(T z, T delta, const Policy& pol)
  1362. {
  1363. BOOST_MATH_STD_USING
  1364. if((z <= 0) || (z + delta <= 0))
  1365. {
  1366. // This isn't very sofisticated, or accurate, but it does work:
  1367. return boost::math::tgamma(z, pol) / boost::math::tgamma(z + delta, pol);
  1368. }
  1369. if(floor(delta) == delta)
  1370. {
  1371. if(floor(z) == z)
  1372. {
  1373. //
  1374. // Both z and delta are integers, see if we can just use table lookup
  1375. // of the factorials to get the result:
  1376. //
  1377. if((z <= max_factorial<T>::value) && (z + delta <= max_factorial<T>::value))
  1378. {
  1379. return unchecked_factorial<T>((unsigned)itrunc(z, pol) - 1) / unchecked_factorial<T>((unsigned)itrunc(T(z + delta), pol) - 1);
  1380. }
  1381. }
  1382. if(fabs(delta) < 20)
  1383. {
  1384. //
  1385. // delta is a small integer, we can use a finite product:
  1386. //
  1387. if(delta == 0)
  1388. return 1;
  1389. if(delta < 0)
  1390. {
  1391. z -= 1;
  1392. T result = z;
  1393. while(0 != (delta += 1))
  1394. {
  1395. z -= 1;
  1396. result *= z;
  1397. }
  1398. return result;
  1399. }
  1400. else
  1401. {
  1402. T result = 1 / z;
  1403. while(0 != (delta -= 1))
  1404. {
  1405. z += 1;
  1406. result /= z;
  1407. }
  1408. return result;
  1409. }
  1410. }
  1411. }
  1412. typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
  1413. return tgamma_delta_ratio_imp_lanczos(z, delta, pol, lanczos_type());
  1414. }
  1415. template <class T, class Policy>
  1416. T tgamma_ratio_imp(T x, T y, const Policy& pol)
  1417. {
  1418. BOOST_MATH_STD_USING
  1419. if((x <= 0) || (boost::math::isinf)(x))
  1420. 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);
  1421. if((y <= 0) || (boost::math::isinf)(y))
  1422. 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);
  1423. if(x <= tools::min_value<T>())
  1424. {
  1425. // Special case for denorms...Ugh.
  1426. T shift = ldexp(T(1), tools::digits<T>());
  1427. return shift * tgamma_ratio_imp(T(x * shift), y, pol);
  1428. }
  1429. if((x < max_factorial<T>::value) && (y < max_factorial<T>::value))
  1430. {
  1431. // Rather than subtracting values, lets just call the gamma functions directly:
  1432. return boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
  1433. }
  1434. T prefix = 1;
  1435. if(x < 1)
  1436. {
  1437. if(y < 2 * max_factorial<T>::value)
  1438. {
  1439. // We need to sidestep on x as well, otherwise we'll underflow
  1440. // before we get to factor in the prefix term:
  1441. prefix /= x;
  1442. x += 1;
  1443. while(y >= max_factorial<T>::value)
  1444. {
  1445. y -= 1;
  1446. prefix /= y;
  1447. }
  1448. return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
  1449. }
  1450. //
  1451. // result is almost certainly going to underflow to zero, try logs just in case:
  1452. //
  1453. return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
  1454. }
  1455. if(y < 1)
  1456. {
  1457. if(x < 2 * max_factorial<T>::value)
  1458. {
  1459. // We need to sidestep on y as well, otherwise we'll overflow
  1460. // before we get to factor in the prefix term:
  1461. prefix *= y;
  1462. y += 1;
  1463. while(x >= max_factorial<T>::value)
  1464. {
  1465. x -= 1;
  1466. prefix *= x;
  1467. }
  1468. return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
  1469. }
  1470. //
  1471. // Result will almost certainly overflow, try logs just in case:
  1472. //
  1473. return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
  1474. }
  1475. //
  1476. // Regular case, x and y both large and similar in magnitude:
  1477. //
  1478. return boost::math::tgamma_delta_ratio(x, y - x, pol);
  1479. }
  1480. template <class T, class Policy>
  1481. T gamma_p_derivative_imp(T a, T x, const Policy& pol)
  1482. {
  1483. BOOST_MATH_STD_USING
  1484. //
  1485. // Usual error checks first:
  1486. //
  1487. if(a <= 0)
  1488. 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);
  1489. if(x < 0)
  1490. 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);
  1491. //
  1492. // Now special cases:
  1493. //
  1494. if(x == 0)
  1495. {
  1496. return (a > 1) ? 0 :
  1497. (a == 1) ? 1 : policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", 0, pol);
  1498. }
  1499. //
  1500. // Normal case:
  1501. //
  1502. typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
  1503. T f1 = detail::regularised_gamma_prefix(a, x, pol, lanczos_type());
  1504. if((x < 1) && (tools::max_value<T>() * x < f1))
  1505. {
  1506. // overflow:
  1507. return policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", 0, pol);
  1508. }
  1509. if(f1 == 0)
  1510. {
  1511. // Underflow in calculation, use logs instead:
  1512. f1 = a * log(x) - x - lgamma(a, pol) - log(x);
  1513. f1 = exp(f1);
  1514. }
  1515. else
  1516. f1 /= x;
  1517. return f1;
  1518. }
  1519. template <class T, class Policy>
  1520. inline typename tools::promote_args<T>::type
  1521. tgamma(T z, const Policy& /* pol */, const mpl::true_)
  1522. {
  1523. BOOST_FPU_EXCEPTION_GUARD
  1524. typedef typename tools::promote_args<T>::type result_type;
  1525. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1526. typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1527. typedef typename policies::normalise<
  1528. Policy,
  1529. policies::promote_float<false>,
  1530. policies::promote_double<false>,
  1531. policies::discrete_quantile<>,
  1532. policies::assert_undefined<> >::type forwarding_policy;
  1533. 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%)");
  1534. }
  1535. template <class T, class Policy>
  1536. struct igamma_initializer
  1537. {
  1538. struct init
  1539. {
  1540. init()
  1541. {
  1542. typedef typename policies::precision<T, Policy>::type precision_type;
  1543. typedef typename mpl::if_<
  1544. mpl::or_<mpl::equal_to<precision_type, mpl::int_<0> >,
  1545. mpl::greater<precision_type, mpl::int_<113> > >,
  1546. mpl::int_<0>,
  1547. typename mpl::if_<
  1548. mpl::less_equal<precision_type, mpl::int_<53> >,
  1549. mpl::int_<53>,
  1550. typename mpl::if_<
  1551. mpl::less_equal<precision_type, mpl::int_<64> >,
  1552. mpl::int_<64>,
  1553. mpl::int_<113>
  1554. >::type
  1555. >::type
  1556. >::type tag_type;
  1557. do_init(tag_type());
  1558. }
  1559. template <int N>
  1560. static void do_init(const mpl::int_<N>&)
  1561. {
  1562. // If std::numeric_limits<T>::digits is zero, we must not call
  1563. // our inituialization code here as the precision presumably
  1564. // varies at runtime, and will not have been set yet. Plus the
  1565. // code requiring initialization isn't called when digits == 0.
  1566. if(std::numeric_limits<T>::digits)
  1567. {
  1568. boost::math::gamma_p(static_cast<T>(400), static_cast<T>(400), Policy());
  1569. }
  1570. }
  1571. static void do_init(const mpl::int_<53>&){}
  1572. void force_instantiate()const{}
  1573. };
  1574. static const init initializer;
  1575. static void force_instantiate()
  1576. {
  1577. initializer.force_instantiate();
  1578. }
  1579. };
  1580. template <class T, class Policy>
  1581. const typename igamma_initializer<T, Policy>::init igamma_initializer<T, Policy>::initializer;
  1582. template <class T, class Policy>
  1583. struct lgamma_initializer
  1584. {
  1585. struct init
  1586. {
  1587. init()
  1588. {
  1589. typedef typename policies::precision<T, Policy>::type precision_type;
  1590. typedef typename mpl::if_<
  1591. mpl::and_<
  1592. mpl::less_equal<precision_type, mpl::int_<64> >,
  1593. mpl::greater<precision_type, mpl::int_<0> >
  1594. >,
  1595. mpl::int_<64>,
  1596. typename mpl::if_<
  1597. mpl::and_<
  1598. mpl::less_equal<precision_type, mpl::int_<113> >,
  1599. mpl::greater<precision_type, mpl::int_<0> >
  1600. >,
  1601. mpl::int_<113>, mpl::int_<0> >::type
  1602. >::type tag_type;
  1603. do_init(tag_type());
  1604. }
  1605. static void do_init(const mpl::int_<64>&)
  1606. {
  1607. boost::math::lgamma(static_cast<T>(2.5), Policy());
  1608. boost::math::lgamma(static_cast<T>(1.25), Policy());
  1609. boost::math::lgamma(static_cast<T>(1.75), Policy());
  1610. }
  1611. static void do_init(const mpl::int_<113>&)
  1612. {
  1613. boost::math::lgamma(static_cast<T>(2.5), Policy());
  1614. boost::math::lgamma(static_cast<T>(1.25), Policy());
  1615. boost::math::lgamma(static_cast<T>(1.5), Policy());
  1616. boost::math::lgamma(static_cast<T>(1.75), Policy());
  1617. }
  1618. static void do_init(const mpl::int_<0>&)
  1619. {
  1620. }
  1621. void force_instantiate()const{}
  1622. };
  1623. static const init initializer;
  1624. static void force_instantiate()
  1625. {
  1626. initializer.force_instantiate();
  1627. }
  1628. };
  1629. template <class T, class Policy>
  1630. const typename lgamma_initializer<T, Policy>::init lgamma_initializer<T, Policy>::initializer;
  1631. template <class T1, class T2, class Policy>
  1632. inline typename tools::promote_args<T1, T2>::type
  1633. tgamma(T1 a, T2 z, const Policy&, const mpl::false_)
  1634. {
  1635. BOOST_FPU_EXCEPTION_GUARD
  1636. typedef typename tools::promote_args<T1, T2>::type result_type;
  1637. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1638. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1639. typedef typename policies::normalise<
  1640. Policy,
  1641. policies::promote_float<false>,
  1642. policies::promote_double<false>,
  1643. policies::discrete_quantile<>,
  1644. policies::assert_undefined<> >::type forwarding_policy;
  1645. igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1646. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1647. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1648. static_cast<value_type>(z), false, true,
  1649. forwarding_policy(), static_cast<value_type*>(0)), "boost::math::tgamma<%1%>(%1%, %1%)");
  1650. }
  1651. template <class T1, class T2>
  1652. inline typename tools::promote_args<T1, T2>::type
  1653. tgamma(T1 a, T2 z, const mpl::false_ tag)
  1654. {
  1655. return tgamma(a, z, policies::policy<>(), tag);
  1656. }
  1657. } // namespace detail
  1658. template <class T>
  1659. inline typename tools::promote_args<T>::type
  1660. tgamma(T z)
  1661. {
  1662. return tgamma(z, policies::policy<>());
  1663. }
  1664. template <class T, class Policy>
  1665. inline typename tools::promote_args<T>::type
  1666. lgamma(T z, int* sign, const Policy&)
  1667. {
  1668. BOOST_FPU_EXCEPTION_GUARD
  1669. typedef typename tools::promote_args<T>::type result_type;
  1670. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1671. typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1672. typedef typename policies::normalise<
  1673. Policy,
  1674. policies::promote_float<false>,
  1675. policies::promote_double<false>,
  1676. policies::discrete_quantile<>,
  1677. policies::assert_undefined<> >::type forwarding_policy;
  1678. detail::lgamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1679. 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%)");
  1680. }
  1681. template <class T>
  1682. inline typename tools::promote_args<T>::type
  1683. lgamma(T z, int* sign)
  1684. {
  1685. return lgamma(z, sign, policies::policy<>());
  1686. }
  1687. template <class T, class Policy>
  1688. inline typename tools::promote_args<T>::type
  1689. lgamma(T x, const Policy& pol)
  1690. {
  1691. return ::boost::math::lgamma(x, 0, pol);
  1692. }
  1693. template <class T>
  1694. inline typename tools::promote_args<T>::type
  1695. lgamma(T x)
  1696. {
  1697. return ::boost::math::lgamma(x, 0, policies::policy<>());
  1698. }
  1699. template <class T, class Policy>
  1700. inline typename tools::promote_args<T>::type
  1701. tgamma1pm1(T z, const Policy& /* pol */)
  1702. {
  1703. BOOST_FPU_EXCEPTION_GUARD
  1704. typedef typename tools::promote_args<T>::type result_type;
  1705. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1706. typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1707. typedef typename policies::normalise<
  1708. Policy,
  1709. policies::promote_float<false>,
  1710. policies::promote_double<false>,
  1711. policies::discrete_quantile<>,
  1712. policies::assert_undefined<> >::type forwarding_policy;
  1713. 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%)");
  1714. }
  1715. template <class T>
  1716. inline typename tools::promote_args<T>::type
  1717. tgamma1pm1(T z)
  1718. {
  1719. return tgamma1pm1(z, policies::policy<>());
  1720. }
  1721. //
  1722. // Full upper incomplete gamma:
  1723. //
  1724. template <class T1, class T2>
  1725. inline typename tools::promote_args<T1, T2>::type
  1726. tgamma(T1 a, T2 z)
  1727. {
  1728. //
  1729. // Type T2 could be a policy object, or a value, select the
  1730. // right overload based on T2:
  1731. //
  1732. typedef typename policies::is_policy<T2>::type maybe_policy;
  1733. return detail::tgamma(a, z, maybe_policy());
  1734. }
  1735. template <class T1, class T2, class Policy>
  1736. inline typename tools::promote_args<T1, T2>::type
  1737. tgamma(T1 a, T2 z, const Policy& pol)
  1738. {
  1739. return detail::tgamma(a, z, pol, mpl::false_());
  1740. }
  1741. //
  1742. // Full lower incomplete gamma:
  1743. //
  1744. template <class T1, class T2, class Policy>
  1745. inline typename tools::promote_args<T1, T2>::type
  1746. tgamma_lower(T1 a, T2 z, const Policy&)
  1747. {
  1748. BOOST_FPU_EXCEPTION_GUARD
  1749. typedef typename tools::promote_args<T1, T2>::type result_type;
  1750. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1751. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1752. typedef typename policies::normalise<
  1753. Policy,
  1754. policies::promote_float<false>,
  1755. policies::promote_double<false>,
  1756. policies::discrete_quantile<>,
  1757. policies::assert_undefined<> >::type forwarding_policy;
  1758. detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1759. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1760. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1761. static_cast<value_type>(z), false, false,
  1762. forwarding_policy(), static_cast<value_type*>(0)), "tgamma_lower<%1%>(%1%, %1%)");
  1763. }
  1764. template <class T1, class T2>
  1765. inline typename tools::promote_args<T1, T2>::type
  1766. tgamma_lower(T1 a, T2 z)
  1767. {
  1768. return tgamma_lower(a, z, policies::policy<>());
  1769. }
  1770. //
  1771. // Regularised upper incomplete gamma:
  1772. //
  1773. template <class T1, class T2, class Policy>
  1774. inline typename tools::promote_args<T1, T2>::type
  1775. gamma_q(T1 a, T2 z, const Policy& /* pol */)
  1776. {
  1777. BOOST_FPU_EXCEPTION_GUARD
  1778. typedef typename tools::promote_args<T1, T2>::type result_type;
  1779. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1780. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1781. typedef typename policies::normalise<
  1782. Policy,
  1783. policies::promote_float<false>,
  1784. policies::promote_double<false>,
  1785. policies::discrete_quantile<>,
  1786. policies::assert_undefined<> >::type forwarding_policy;
  1787. detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1788. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1789. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1790. static_cast<value_type>(z), true, true,
  1791. forwarding_policy(), static_cast<value_type*>(0)), "gamma_q<%1%>(%1%, %1%)");
  1792. }
  1793. template <class T1, class T2>
  1794. inline typename tools::promote_args<T1, T2>::type
  1795. gamma_q(T1 a, T2 z)
  1796. {
  1797. return gamma_q(a, z, policies::policy<>());
  1798. }
  1799. //
  1800. // Regularised lower incomplete gamma:
  1801. //
  1802. template <class T1, class T2, class Policy>
  1803. inline typename tools::promote_args<T1, T2>::type
  1804. gamma_p(T1 a, T2 z, const Policy&)
  1805. {
  1806. BOOST_FPU_EXCEPTION_GUARD
  1807. typedef typename tools::promote_args<T1, T2>::type result_type;
  1808. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1809. // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
  1810. typedef typename policies::normalise<
  1811. Policy,
  1812. policies::promote_float<false>,
  1813. policies::promote_double<false>,
  1814. policies::discrete_quantile<>,
  1815. policies::assert_undefined<> >::type forwarding_policy;
  1816. detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
  1817. return policies::checked_narrowing_cast<result_type, forwarding_policy>(
  1818. detail::gamma_incomplete_imp(static_cast<value_type>(a),
  1819. static_cast<value_type>(z), true, false,
  1820. forwarding_policy(), static_cast<value_type*>(0)), "gamma_p<%1%>(%1%, %1%)");
  1821. }
  1822. template <class T1, class T2>
  1823. inline typename tools::promote_args<T1, T2>::type
  1824. gamma_p(T1 a, T2 z)
  1825. {
  1826. return gamma_p(a, z, policies::policy<>());
  1827. }
  1828. // ratios of gamma functions:
  1829. template <class T1, class T2, class Policy>
  1830. inline typename tools::promote_args<T1, T2>::type
  1831. tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */)
  1832. {
  1833. BOOST_FPU_EXCEPTION_GUARD
  1834. typedef typename tools::promote_args<T1, T2>::type result_type;
  1835. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1836. typedef typename policies::normalise<
  1837. Policy,
  1838. policies::promote_float<false>,
  1839. policies::promote_double<false>,
  1840. policies::discrete_quantile<>,
  1841. policies::assert_undefined<> >::type forwarding_policy;
  1842. 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%)");
  1843. }
  1844. template <class T1, class T2>
  1845. inline typename tools::promote_args<T1, T2>::type
  1846. tgamma_delta_ratio(T1 z, T2 delta)
  1847. {
  1848. return tgamma_delta_ratio(z, delta, policies::policy<>());
  1849. }
  1850. template <class T1, class T2, class Policy>
  1851. inline typename tools::promote_args<T1, T2>::type
  1852. tgamma_ratio(T1 a, T2 b, const Policy&)
  1853. {
  1854. typedef typename tools::promote_args<T1, T2>::type result_type;
  1855. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1856. typedef typename policies::normalise<
  1857. Policy,
  1858. policies::promote_float<false>,
  1859. policies::promote_double<false>,
  1860. policies::discrete_quantile<>,
  1861. policies::assert_undefined<> >::type forwarding_policy;
  1862. 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%)");
  1863. }
  1864. template <class T1, class T2>
  1865. inline typename tools::promote_args<T1, T2>::type
  1866. tgamma_ratio(T1 a, T2 b)
  1867. {
  1868. return tgamma_ratio(a, b, policies::policy<>());
  1869. }
  1870. template <class T1, class T2, class Policy>
  1871. inline typename tools::promote_args<T1, T2>::type
  1872. gamma_p_derivative(T1 a, T2 x, const Policy&)
  1873. {
  1874. BOOST_FPU_EXCEPTION_GUARD
  1875. typedef typename tools::promote_args<T1, T2>::type result_type;
  1876. typedef typename policies::evaluation<result_type, Policy>::type value_type;
  1877. typedef typename policies::normalise<
  1878. Policy,
  1879. policies::promote_float<false>,
  1880. policies::promote_double<false>,
  1881. policies::discrete_quantile<>,
  1882. policies::assert_undefined<> >::type forwarding_policy;
  1883. 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%)");
  1884. }
  1885. template <class T1, class T2>
  1886. inline typename tools::promote_args<T1, T2>::type
  1887. gamma_p_derivative(T1 a, T2 x)
  1888. {
  1889. return gamma_p_derivative(a, x, policies::policy<>());
  1890. }
  1891. } // namespace math
  1892. } // namespace boost
  1893. #ifdef BOOST_MSVC
  1894. # pragma warning(pop)
  1895. #endif
  1896. #include <boost/math/special_functions/detail/igamma_inverse.hpp>
  1897. #include <boost/math/special_functions/detail/gamma_inva.hpp>
  1898. #include <boost/math/special_functions/erf.hpp>
  1899. #endif // BOOST_MATH_SF_GAMMA_HPP