@@ -67,96 +67,3 @@ function small_gamma(x)
67
67
return z * p / q
68
68
end
69
69
70
- _gamma (z:: Complex ) = exp (loggamma (z))
71
-
72
- loggamma (z:: Complex ) = _loggamma (float (z))
73
-
74
- _loggamma (x:: Complex{Float32} ) = ComplexF32 (gamma (ComplexF64 (x)))
75
-
76
- # copied from https://github.com/JuliaMath/SpecialFunctions.jl/blob/master/src/gamma.jl
77
-
78
- # Compute the logΓ(z) function using a combination of the asymptotic series,
79
- # the Taylor series around z=1 and z=2, the reflection formula, and the shift formula.
80
- # Many details of these techniques are discussed in D. E. G. Hare,
81
- # "Computing the principal branch of log-Gamma," J. Algorithms 25, pp. 221-236 (1997),
82
- # and similar techniques are used (in a somewhat different way) by the
83
- # SciPy loggamma function. The key identities are also described
84
- # at http://functions.wolfram.com/GammaBetaErf/LogGamma/
85
- function _loggamma (z:: Complex{Float64} )
86
- x, y = reim (z)
87
- yabs = abs (y)
88
- if ! isfinite (x) || ! isfinite (y) # Inf or NaN
89
- if isinf (x) && isfinite (y)
90
- return Complex (x, x > 0 ? (y == 0 ? y : copysign (Inf , y)) : copysign (Inf , - y))
91
- elseif isfinite (x) && isinf (y)
92
- return Complex (- Inf , y)
93
- else
94
- return Complex (NaN , NaN )
95
- end
96
- elseif x > 7 || yabs > 7 # use the Stirling asymptotic series for sufficiently large x or |y|
97
- return loggamma_asymptotic (z)
98
- elseif x < 0.1 # use reflection formula to transform to x > 0
99
- if x == 0 && y == 0 # return Inf with the correct imaginary part for z == 0
100
- return Complex (Inf , signbit (x) ? copysign (Float64 (π), - y) : - y)
101
- end
102
- # the 2pi * floor(...) stuff is to choose the correct branch cut for log(sinpi(z))
103
- return Complex (Float64 (logπ), copysign (Float64 (twoπ), y) * floor (0.5 * x+ 0.25 )) -
104
- log (sinpi (z)) - loggamma (1 - z)
105
- elseif abs (x - 1 ) + yabs < 0.1
106
- # taylor series at z=1
107
- # ... coefficients are [-eulergamma; [(-1)^k * zeta(k)/k for k in 2:15]]
108
- w = Complex (x - 1 , y)
109
- return w * @evalpoly (w, - 5.7721566490153286060651188e-01 ,8.2246703342411321823620794e-01 ,
110
- - 4.0068563438653142846657956e-01 ,2.705808084277845478790009e-01 ,
111
- - 2.0738555102867398526627303e-01 ,1.6955717699740818995241986e-01 ,
112
- - 1.4404989676884611811997107e-01 ,1.2550966952474304242233559e-01 ,
113
- - 1.1133426586956469049087244e-01 ,1.000994575127818085337147e-01 ,
114
- - 9.0954017145829042232609344e-02 ,8.3353840546109004024886499e-02 ,
115
- - 7.6932516411352191472827157e-02 ,7.1432946295361336059232779e-02 ,
116
- - 6.6668705882420468032903454e-02 )
117
- elseif abs (x - 2 ) + yabs < 0.1
118
- # taylor series at z=2
119
- # ... coefficients are [1-eulergamma; [(-1)^k * (zeta(k)-1)/k for k in 2:12]]
120
- w = Complex (x - 2 , y)
121
- return w * @evalpoly (w, 4.2278433509846713939348812e-01 ,3.2246703342411321823620794e-01 ,
122
- - 6.7352301053198095133246196e-02 ,2.0580808427784547879000897e-02 ,
123
- - 7.3855510286739852662729527e-03 ,2.8905103307415232857531201e-03 ,
124
- - 1.1927539117032609771139825e-03 ,5.0966952474304242233558822e-04 ,
125
- - 2.2315475845357937976132853e-04 ,9.9457512781808533714662972e-05 ,
126
- - 4.4926236738133141700224489e-05 ,2.0507212775670691553131246e-05 )
127
- end
128
- # use recurrence relation loggamma(z) = loggamma(z+1) - log(z) to shift to x > 7 for asymptotic series
129
- shiftprod = Complex (x,yabs)
130
- x += 1
131
- sb = false # == signbit(imag(shiftprod)) == signbit(yabs)
132
- # To use log(product of shifts) rather than sum(logs of shifts),
133
- # we need to keep track of the number of + to - sign flips in
134
- # imag(shiftprod), as described in Hare (1997), proposition 2.2.
135
- signflips = 0
136
- while x <= 7
137
- shiftprod *= Complex (x,yabs)
138
- sb′ = signbit (imag (shiftprod))
139
- signflips += sb′ & (sb′ != sb)
140
- sb = sb′
141
- x += 1
142
- end
143
- shift = log (shiftprod)
144
- if signbit (y) # if y is negative, conjugate the shift
145
- shift = Complex (real (shift), signflips*- 6.2831853071795864769252842 - imag (shift))
146
- else
147
- shift = Complex (real (shift), imag (shift) + signflips* 6.2831853071795864769252842 )
148
- end
149
- return loggamma_asymptotic (Complex (x,y)) - shift
150
- end
151
-
152
- # asymptotic series for log(gamma(z)), valid for sufficiently large real(z) or |imag(z)|
153
- function loggamma_asymptotic (z:: Complex{Float64} )
154
- zinv = inv (z)
155
- t = zinv* zinv
156
- # coefficients are bernoulli[2:n+1] .// (2*(1:n).*(2*(1:n) - 1))
157
- return (z- 0.5 )* log (z) - z + 9.1893853320467274178032927e-01 + # <-- log(2pi)/2
158
- zinv* @evalpoly (t, 8.3333333333333333333333368e-02 ,- 2.7777777777777777777777776e-03 ,
159
- 7.9365079365079365079365075e-04 ,- 5.9523809523809523809523806e-04 ,
160
- 8.4175084175084175084175104e-04 ,- 1.9175269175269175269175262e-03 ,
161
- 6.4102564102564102564102561e-03 ,- 2.9550653594771241830065352e-02 )
162
- end
0 commit comments