lgamma.qbk 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. [section:lgamma Log Gamma]
  2. [h4 Synopsis]
  3. ``
  4. #include <boost/math/special_functions/gamma.hpp>
  5. ``
  6. namespace boost{ namespace math{
  7. template <class T>
  8. ``__sf_result`` lgamma(T z);
  9. template <class T, class ``__Policy``>
  10. ``__sf_result`` lgamma(T z, const ``__Policy``&);
  11. template <class T>
  12. ``__sf_result`` lgamma(T z, int* sign);
  13. template <class T, class ``__Policy``>
  14. ``__sf_result`` lgamma(T z, int* sign, const ``__Policy``&);
  15. }} // namespaces
  16. [h4 Description]
  17. The [@http://en.wikipedia.org/wiki/Gamma_function lgamma function] is defined by:
  18. [equation lgamm1]
  19. The second form of the function takes a pointer to an integer,
  20. which if non-null is set on output to the sign of tgamma(z).
  21. [optional_policy]
  22. [graph lgamma]
  23. The return type of these functions is computed using the __arg_promotion_rules:
  24. the result is of type `double` if T is an integer type, or type T otherwise.
  25. [h4 Accuracy]
  26. The following table shows the peak errors (in units of epsilon)
  27. found on various platforms
  28. with various floating point types, along with comparisons to
  29. various other libraries. Unless otherwise specified any
  30. floating point type that is narrower than the one shown will have
  31. __zero_error.
  32. Note that while the relative errors near the positive roots of lgamma
  33. are very low, the lgamma function has an infinite number of irrational
  34. roots for negative arguments: very close to these negative roots only
  35. a low absolute error can be guaranteed.
  36. [table_lgamma]
  37. The following error plot are based on an exhaustive search of the functions domain, MSVC-15.5 at `double` precision,
  38. and GCC-7.1/Ubuntu for `long double` and `__float128`.
  39. [graph lgamma__double]
  40. [graph lgamma__80_bit_long_double]
  41. [graph lgamma____float128]
  42. [h4 Testing]
  43. The main tests for this function involve comparisons against the logs of
  44. the factorials which can be independently calculated to very high accuracy.
  45. Random tests in key problem areas are also used.
  46. [h4 Implementation]
  47. The generic version of this function is implemented using Sterling's approximation
  48. for large arguments:
  49. [equation gamma6]
  50. For small arguments, the logarithm of tgamma is used.
  51. For negative /z/ the logarithm version of the
  52. reflection formula is used:
  53. [equation lgamm3]
  54. For types of known precision, the __lanczos is used, a traits class
  55. `boost::math::lanczos::lanczos_traits` maps type T to an appropriate
  56. approximation. The logarithmic version of the __lanczos is:
  57. [equation lgamm4]
  58. Where L[sub e,g] is the Lanczos sum, scaled by e[super g].
  59. As before the reflection formula is used for /z < 0/.
  60. When z is very near 1 or 2, then the logarithmic version of the __lanczos
  61. suffers very badly from cancellation error: indeed for values sufficiently
  62. close to 1 or 2, arbitrarily large relative errors can be obtained (even though
  63. the absolute error is tiny).
  64. For types with up to 113 bits of precision
  65. (up to and including 128-bit long doubles), root-preserving
  66. rational approximations [jm_rationals] are used
  67. over the intervals [1,2] and [2,3]. Over the interval [2,3] the approximation
  68. form used is:
  69. lgamma(z) = (z-2)(z+1)(Y + R(z-2));
  70. Where Y is a constant, and R(z-2) is the rational approximation: optimised
  71. so that its absolute error is tiny compared to Y. In addition, small values of z greater
  72. than 3 can handled by argument reduction using the recurrence relation:
  73. lgamma(z+1) = log(z) + lgamma(z);
  74. Over the interval [1,2] two approximations have to be used, one for small z uses:
  75. lgamma(z) = (z-1)(z-2)(Y + R(z-1));
  76. Once again Y is a constant, and R(z-1) is optimised for low absolute error
  77. compared to Y. For z > 1.5 the above form wouldn't converge to a
  78. minimax solution but this similar form does:
  79. lgamma(z) = (2-z)(1-z)(Y + R(2-z));
  80. Finally for z < 1 the recurrence relation can be used to move to z > 1:
  81. lgamma(z) = lgamma(z+1) - log(z);
  82. Note that while this involves a subtraction, it appears not
  83. to suffer from cancellation error: as z decreases from 1
  84. the `-log(z)` term grows positive much more
  85. rapidly than the `lgamma(z+1)` term becomes negative. So in this
  86. specific case, significant digits are preserved, rather than cancelled.
  87. For other types which do have a __lanczos defined for them
  88. the current solution is as follows: imagine we
  89. balance the two terms in the __lanczos by dividing the power term by its value
  90. at /z = 1/, and then multiplying the Lanczos coefficients by the same value.
  91. Now each term will take the value 1 at /z = 1/ and we can rearrange the power terms
  92. in terms of log1p. Likewise if we subtract 1 from the Lanczos sum part
  93. (algebraically, by subtracting the value of each term at /z = 1/), we obtain
  94. a new summation that can be also be fed into log1p. Crucially, all of the
  95. terms tend to zero, as /z -> 1/:
  96. [equation lgamm5]
  97. The C[sub k] terms in the above are the same as in the __lanczos.
  98. A similar rearrangement can be performed at /z = 2/:
  99. [equation lgamm6]
  100. [endsect] [/section:lgamma The Log Gamma Function]
  101. [/
  102. Copyright 2006 John Maddock and Paul A. Bristow.
  103. Distributed under the Boost Software License, Version 1.0.
  104. (See accompanying file LICENSE_1_0.txt or copy at
  105. http://www.boost.org/LICENSE_1_0.txt).
  106. ]