1 [section:lgamma Log Gamma]
6 #include <boost/math/special_functions/gamma.hpp>
9 namespace boost{ namespace math{
12 ``__sf_result`` lgamma(T z);
14 template <class T, class ``__Policy``>
15 ``__sf_result`` lgamma(T z, const ``__Policy``&);
18 ``__sf_result`` lgamma(T z, int* sign);
20 template <class T, class ``__Policy``>
21 ``__sf_result`` lgamma(T z, int* sign, const ``__Policy``&);
27 The [@http://en.wikipedia.org/wiki/Gamma_function lgamma function] is defined by:
31 The second form of the function takes a pointer to an integer,
32 which if non-null is set on output to the sign of tgamma(z).
38 There are effectively two versions of this function internally: a fully
39 generic version that is slow, but reasonably accurate, and a much more
40 efficient approximation that is used where the number of digits in the significand
41 of T correspond to a certain __lanczos. In practice, any built-in
42 floating-point type you will encounter has an appropriate __lanczos
43 defined for it. It is also possible, given enough machine time, to generate
44 further __lanczos's using the program libs/math/tools/lanczos_generator.cpp.
46 The return type of these functions is computed using the __arg_pomotion_rules:
47 the result is of type `double` if T is an integer type, or type T otherwise.
51 The following table shows the peak errors (in units of epsilon)
52 found on various platforms
53 with various floating point types, along with comparisons to the
54 __gsl, __glibc, __hpc and
55 __cephes libraries. Unless otherwise specified any
56 floating point type that is narrower than the one shown will have
59 Note that while the relative errors near the positive roots of lgamma
60 are very low, the lgamma function has an infinite number of irrational
61 roots for negative arguments: very close to these negative roots only
62 a low absolute error can be guaranteed.
65 [[Significand Size] [Platform and Compiler] [Factorials and Half factorials] [Values Near Zero] [Values Near 1 or 2] [Values Near a Negative Pole]]
66 [[53] [Win32 Visual C++ 8]
69 (GSL=33) (__cephes=1.5)]
72 (GSL=5.2) (__cephes=1.1)]
75 (GSL=1168) (__cephes~500000)]
78 (GSL=25) (__cephes=1.6)] ]
79 [[64] [Linux IA32 / GCC]
82 (__glibc Peak=1.7 Mean=0.49)]
85 (__glibc Peak= 0.96 Mean=0.54)]
88 (__glibc Peak=0.74 Mean=0.26)]
92 (__glibc Peak=3.0 Mean=0.86)] ]
93 [[64] [Linux IA64 / GCC]
107 [[113] [HPUX IA64, aCC A.06.06]
124 The main tests for this function involve comparisons against the logs of
125 the factorials which can be independently calculated to very high accuracy.
127 Random tests in key problem areas are also used.
131 The generic version of this function is implemented using Sterling's approximation
136 For small arguments, the logarithm of tgamma is used.
138 For negative /z/ the logarithm version of the
139 reflection formula is used:
143 For types of known precision, the __lanczos is used, a traits class
144 `boost::math::lanczos::lanczos_traits` maps type T to an appropriate
145 approximation. The logarithmic version of the __lanczos is:
149 Where L[sub e,g][space] is the Lanczos sum, scaled by e[super g].
151 As before the reflection formula is used for /z < 0/.
153 When z is very near 1 or 2, then the logarithmic version of the __lanczos
154 suffers very badly from cancellation error: indeed for values sufficiently
155 close to 1 or 2, arbitrarily large relative errors can be obtained (even though
156 the absolute error is tiny).
158 For types with up to 113 bits of precision
159 (up to and including 128-bit long doubles), root-preserving
160 rational approximations [jm_rationals] are used
161 over the intervals [1,2] and [2,3]. Over the interval [2,3] the approximation
164 lgamma(z) = (z-2)(z+1)(Y + R(z-2));
166 Where Y is a constant, and R(z-2) is the rational approximation: optimised
167 so that it's absolute error is tiny compared to Y. In addition
168 small values of z greater
169 than 3 can handled by argument reduction using the recurrence relation:
171 lgamma(z+1) = log(z) + lgamma(z);
173 Over the interval [1,2] two approximations have to be used, one for small z uses:
175 lgamma(z) = (z-1)(z-2)(Y + R(z-1));
177 Once again Y is a constant, and R(z-1) is optimised for low absolute error
178 compared to Y. For z > 1.5 the above form wouldn't converge to a
179 minimax solution but this similar form does:
181 lgamma(z) = (2-z)(1-z)(Y + R(2-z));
183 Finally for z < 1 the recurrence relation can be used to move to z > 1:
185 lgamma(z) = lgamma(z+1) - log(z);
187 Note that while this involves a subtraction, it appears not
188 to suffer from cancellation error: as z decreases from 1
189 the `-log(z)` term grows positive much more
190 rapidly than the `lgamma(z+1)` term becomes negative. So in this
191 specific case, significant digits are preserved, rather than cancelled.
193 For other types which do have a __lanczos defined for them
194 the current solution is as follows: imagine we
195 balance the two terms in the __lanczos by dividing the power term by its value
196 at /z = 1/, and then multiplying the Lanczos coefficients by the same value.
197 Now each term will take the value 1 at /z = 1/ and we can rearrange the power terms
198 in terms of log1p. Likewise if we subtract 1 from the Lanczos sum part
199 (algebraically, by subtracting the value of each term at /z = 1/), we obtain
200 a new summation that can be also be fed into log1p. Crucially, all of the
201 terms tend to zero, as /z -> 1/:
205 The C[sub k][space] terms in the above are the same as in the __lanczos.
207 A similar rearrangement can be performed at /z = 2/:
211 [endsect][/section:lgamma The Log Gamma Function]
214 Copyright 2006 John Maddock and Paul A. Bristow.
215 Distributed under the Boost Software License, Version 1.0.
216 (See accompanying file LICENSE_1_0.txt or copy at
217 http://www.boost.org/LICENSE_1_0.txt).