Skip to content

Commit 229d13a

Browse files
authored
Merge pull request #313 from devmotion/dw/logexpfunctions
Use LogExpFunctions
2 parents d24f19e + 1313964 commit 229d13a

File tree

4 files changed

+12
-68
lines changed

4 files changed

+12
-68
lines changed

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
name = "SpecialFunctions"
22
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
3-
version = "1.3"
3+
version = "1.4.0"
44

55
[deps]
66
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
7+
LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
78
OpenSpecFun_jll = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
89

910
[compat]
1011
ChainRulesCore = "0.9"
1112
ChainRulesTestUtils = "0.6.3"
13+
LogExpFunctions = "0.2"
1214
OpenSpecFun_jll = "0.5"
1315
julia = "1.3"
1416

src/SpecialFunctions.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module SpecialFunctions
22

33
import ChainRulesCore
4+
import LogExpFunctions
45

56
using OpenSpecFun_jll
67

src/beta_inc.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ function beta_integrand(a::Float64,b::Float64,x::Float64,y::Float64,mu::Float64=
109109
lambda = a - (a+b)*x
110110
end
111111
e = -lambda/a
112-
u = abs(e) > 0.6 ? u = e - log(x/x0) : - log1pmx(e)
112+
u = abs(e) > 0.6 ? e - log(x/x0) : - LogExpFunctions.log1pmx(e)
113113
e = lambda/b
114-
v = abs(e) > 0.6 ? e - log(y/y0) : - log1pmx(e)
114+
v = abs(e) > 0.6 ? e - log(y/y0) : - LogExpFunctions.log1pmx(e)
115115
z = esum(mu, -(a*u + b*v))
116116
return (1.0/sqrt(2*pi))*sqrt(b*x0)*z*exp(-stirling_corr(a,b))
117117
elseif x > 0.375
@@ -271,7 +271,7 @@ function beta_inc_asymptotic_symmetric(a::Float64, b::Float64, lambda::Float64,
271271
r1 = (b-a)/b
272272
w0 = 1.0/sqrt(a*(1.0+h))
273273
end
274-
f = -a*log1pmx(-(lambda/a)) - b*log1pmx((lambda/b))
274+
f = -a*LogExpFunctions.log1pmx(-(lambda/a)) - b*LogExpFunctions.log1pmx(lambda/b)
275275
t = exp(-f)
276276
if t == 0.0
277277
return ans

src/gamma_inc.jl

Lines changed: 5 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -30,65 +30,6 @@ const d60 = .531307936463992E-03
3030
const d6=[-.592166437353694E-03]
3131
const d70 = .344367606892378E-03
3232
const d80 = -.652623918595309E-03
33-
#Source of logmxp1(x): https://github.com/JuliaStats/StatsFuns.jl/blob/master/src/basicfuns.jl
34-
# The kernel of log1pmx
35-
# Accuracy within ~2ulps for -0.227 < x < 0.315
36-
function _log1pmx_ker(x::Float64)
37-
r = x/(x+2.0)
38-
t = r*r
39-
w = @horner(t,
40-
6.66666666666666667e-1, # 2/3
41-
4.00000000000000000e-1, # 2/5
42-
2.85714285714285714e-1, # 2/7
43-
2.22222222222222222e-1, # 2/9
44-
1.81818181818181818e-1, # 2/11
45-
1.53846153846153846e-1, # 2/13
46-
1.33333333333333333e-1, # 2/15
47-
1.17647058823529412e-1) # 2/17
48-
hxsq = 0.5*x*x
49-
r*(hxsq+w*t)-hxsq
50-
end
51-
"""
52-
log1pmx(x::Float64)
53-
Return `log(1 + x) - x`
54-
Use naive calculation or range reduction outside kernel range. Accurate ~2ulps for all `x`.
55-
"""
56-
function log1pmx(x::Float64)
57-
if !(-0.7 < x < 0.9)
58-
return log1p(x) - x
59-
elseif x > 0.315
60-
u = (x-0.5)/1.5
61-
return _log1pmx_ker(u) - 9.45348918918356180e-2 - 0.5*u
62-
elseif x > -0.227
63-
return _log1pmx_ker(x)
64-
elseif x > -0.4
65-
u = (x+0.25)/0.75
66-
return _log1pmx_ker(u) - 3.76820724517809274e-2 + 0.25*u
67-
elseif x > -0.6
68-
u = (x+0.5)*2.0
69-
return _log1pmx_ker(u) - 1.93147180559945309e-1 + 0.5*u
70-
else
71-
u = (x+0.625)/0.375
72-
return _log1pmx_ker(u) - 3.55829253011726237e-1 + 0.625*u
73-
end
74-
end
75-
"""
76-
logmxp1(x::Float64)
77-
Return `log(x) - x + 1` carefully evaluated.
78-
"""
79-
function logmxp1(x::Float64)
80-
if x <= 0.3
81-
return (log(x) + 1.0) - x
82-
elseif x <= 0.4
83-
u = (x-0.375)/0.375
84-
return _log1pmx_ker(u) - 3.55829253011726237e-1 + 0.625*u
85-
elseif x <= 0.6
86-
u = 2.0*(x-0.5)
87-
return _log1pmx_ker(u) - 1.93147180559945309e-1 + 0.5*u
88-
else
89-
return log1pmx(x - 1.0)
90-
end
91-
end
9233

9334
"""
9435
rgamma1pm1(a)
@@ -129,7 +70,7 @@ function rgammax(a::Float64,x::Float64)
12970
end
13071
t = (1.0/a)^2
13172
t1 = (((0.75*t - 1.0)*t + 3.5)*t - 105.0)/(a*1260.0) #Using stirling Series : https://dlmf.nist.gov/5.11.1
132-
t1 = t1 + a*logmxp1(u)
73+
t1 = t1 + a*LogExpFunctions.logmxp1(u)
13374
if t1 >= exparg
13475
return rt2pin*sqrt(a)*exp(t1)
13576
end
@@ -554,7 +495,7 @@ See also: [`gamma_inc(a,x,ind)`](@ref SpecialFunctions.gamma_inc)
554495
function gamma_inc_minimax(a::Float64, x::Float64, z::Float64)
555496
l = x/a
556497
s = 1.0 - l
557-
y = -a*logmxp1(l)
498+
y = -a*LogExpFunctions.logmxp1(l)
558499
c = exp(-y)
559500
w = 0.5*erfcx(sqrt(y))
560501

@@ -614,7 +555,7 @@ See also: [`gamma_inc(a,x,ind)`](@ref SpecialFunctions.gamma_inc)
614555
"""
615556
function gamma_inc_temme(a::Float64, x::Float64, z::Float64)
616557
l = x/a
617-
y = -a*logmxp1(x/a)
558+
y = -a*LogExpFunctions.logmxp1(x/a)
618559
c = exp(-y)
619560
w = 0.5*erfcx(sqrt(y))
620561
c0 = @horner(z , d00 , d0[1] , d0[2] , d0[3] , d0[4] , d0[5] , d0[6])
@@ -647,7 +588,7 @@ External links: [DLMF](https://dlmf.nist.gov/8.12.8)
647588
function gamma_inc_temme_1(a::Float64, x::Float64, z::Float64, ind::Integer)
648589
iop = ind + 1
649590
l = x/a
650-
y = -a * logmxp1(l)
591+
y = -a * LogExpFunctions.logmxp1(l)
651592
if a*eps()*eps() > 3.28e-3
652593
throw(DomainError((a,x,ind,"P(a,x) or Q(a,x) is computationally indeterminant in this case.")))
653594
end
@@ -863,7 +804,7 @@ function _gamma_inc(a::Float64,x::Float64,ind::Integer)
863804
return (0.0,1.0)
864805
end
865806
s = 1.0 - l
866-
z = -logmxp1(l)
807+
z = -LogExpFunctions.logmxp1(l)
867808
if z >= 700.0/a
868809
return (0.0,1.0)
869810
end

0 commit comments

Comments
 (0)