Skip to content

Commit 0a2d5c9

Browse files
committed
Add unnormalized log pdf functions
1 parent 5115bd6 commit 0a2d5c9

File tree

19 files changed

+276
-26
lines changed

19 files changed

+276
-26
lines changed

ext/StatsFunsChainRulesCoreExt.jl

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,25 @@ ChainRulesCore.@scalar_rule(
1313
- 1) / x + (1 - β) / (1 - x),
1414
),
1515
)
16+
ChainRulesCore.@scalar_rule(
17+
betalogupdf::Real, β::Real, x::Number),
18+
(
19+
log(x),
20+
log1p(-x),
21+
- 1) / x + (1 - β) / (1 - x),
22+
),
23+
)
1624

1725
ChainRulesCore.@scalar_rule(
1826
binomlogpdf(n::Real, p::Real, k::Real),
19-
@setup(z = digamma(n - k + 1)),
27+
(
28+
ChainRulesCore.NoTangent(),
29+
(k / p - n) / (1 - p),
30+
ChainRulesCore.NoTangent(),
31+
),
32+
)
33+
ChainRulesCore.@scalar_rule(
34+
binomlogupdf(n::Real, p::Real, k::Real),
2035
(
2136
ChainRulesCore.NoTangent(),
2237
(k / p - n) / (1 - p),
@@ -28,7 +43,15 @@ ChainRulesCore.@scalar_rule(
2843
chisqlogpdf(k::Real, x::Number),
2944
@setup(hk = k / 2),
3045
(
31-
(log(x) - logtwo - digamma(hk)) / 2,
46+
(log(x / 2) - digamma(hk)) / 2,
47+
(hk - 1) / x - one(hk) / 2,
48+
),
49+
)
50+
ChainRulesCore.@scalar_rule(
51+
chisqlogupdf(k::Real, x::Number),
52+
@setup(hk = k / 2),
53+
(
54+
log(x / 2) / 2,
3255
(hk - 1) / x - one(hk) / 2,
3356
),
3457
)
@@ -48,6 +71,19 @@ ChainRulesCore.@scalar_rule(
4871
((ν1 - 2) / x - ν1 * νsum / temp1) / 2,
4972
),
5073
)
74+
ChainRulesCore.@scalar_rule(
75+
fdistlogupdf(ν1::Real, ν2::Real, x::Number),
76+
@setup(
77+
tmp = x * ν1 + ν2,
78+
a = x * (ν1 + ν2) / tmp,
79+
b = ν2 / tmp,
80+
),
81+
(
82+
(log(x * b) - a) / 2,
83+
(log(b) + (ν1 / ν2) * a) / 2,
84+
(ν1 * (1 - a) - 2) / (2 * x),
85+
),
86+
)
5187

5288
ChainRulesCore.@scalar_rule(
5389
gammalogpdf(k::Real, θ::Real, x::Number),
@@ -62,11 +98,32 @@ ChainRulesCore.@scalar_rule(
6298
- (1 + z) / x,
6399
),
64100
)
101+
ChainRulesCore.@scalar_rule(
102+
gammalogupdf(k::Real, θ::Real, x::Number),
103+
@setup(
104+
invθ = inv(θ),
105+
xoθ = invθ * x,
106+
z = xoθ - (k - 1),
107+
),
108+
(
109+
log(xoθ),
110+
invθ * z,
111+
- z / x,
112+
),
113+
)
65114

66115
ChainRulesCore.@scalar_rule(
67116
poislogpdf::Number, x::Number),
68117
((iszero(x) && iszero(λ) ? zero(x / λ) : x / λ) - 1, ChainRulesCore.NoTangent()),
69118
)
119+
ChainRulesCore.@scalar_rule(
120+
poislogupdf::Number, x::Number),
121+
((iszero(x) && iszero(λ) ? zero(x / λ) : x / λ), ChainRulesCore.NoTangent()),
122+
)
123+
ChainRulesCore.@scalar_rule(
124+
poislogulikelihood::Number, x::Number),
125+
((iszero(x) && iszero(λ) ? zero(x / λ) : x / λ) - 1, ChainRulesCore.NoTangent()),
126+
)
70127

71128
ChainRulesCore.@scalar_rule(
72129
tdistlogpdf::Real, x::Number),
@@ -82,5 +139,17 @@ ChainRulesCore.@scalar_rule(
82139
- x * b,
83140
),
84141
)
142+
ChainRulesCore.@scalar_rule(
143+
tdistlogupdf::Real, x::Number),
144+
@setup(
145+
xsq = x^2,
146+
a = xsq / ν,
147+
b =+ 1) /+ xsq),
148+
),
149+
(
150+
(a * b - log1p(a)) / 2,
151+
- x * b,
152+
),
153+
)
85154

86155
end # module

src/StatsFuns.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export
5454
# distrs/beta
5555
betapdf, # pdf of beta distribution
5656
betalogpdf, # logpdf of beta distribution
57+
betalogupdf, # unnormalized logpdf of beta distribution (parameters constant)
58+
betalogulikelihood, # unnormalized logpdf of beta distribution (data constant)
5759
betacdf, # cdf of beta distribution
5860
betaccdf, # ccdf of beta distribution
5961
betalogcdf, # logcdf of beta distribution
@@ -66,6 +68,8 @@ export
6668
# distrs/binom
6769
binompdf, # pdf of binomial distribution
6870
binomlogpdf, # logpdf of binomial distribution
71+
binomlogupdf, # unnormalized logpdf of binomial distribution (parameters constant)
72+
binomlogulikelihood, # unnormalized logpdf of binomial distribution (data constant)
6973
binomcdf, # cdf of binomial distribution
7074
binomccdf, # ccdf of binomial distribution
7175
binomlogcdf, # logcdf of binomial distribution
@@ -78,6 +82,8 @@ export
7882
# distrs/chisq
7983
chisqpdf, # pdf of chi-square distribution
8084
chisqlogpdf, # logpdf of chi-square distribution
85+
chisqlogupdf, # unnormalized logpdf of chi-square distribution (parameters constant)
86+
chisqlogulikelihood, # unnormalized logpdf of chi-square distribution (data constant)
8187
chisqcdf, # cdf of chi-square distribution
8288
chisqccdf, # ccdf of chi-square distribution
8389
chisqlogcdf, # logcdf of chi-square distribution
@@ -90,6 +96,8 @@ export
9096
# distrs/fdist
9197
fdistpdf, # pdf of F distribution
9298
fdistlogpdf, # logpdf of F distribution
99+
fdistlogupdf, # unnormalized logpdf of F distribution (parameters constant)
100+
fdistlogulikelihood, # unnormalized logpdf of F distribution (data constant)
93101
fdistcdf, # cdf of F distribution
94102
fdistccdf, # ccdf of F distribution
95103
fdistlogcdf, # logcdf of F distribution
@@ -102,6 +110,8 @@ export
102110
# distrs/gamma
103111
gammapdf, # pdf of gamma distribution
104112
gammalogpdf, # logpdf of gamma distribution
113+
gammalogupdf, # unnormalized logpdf of gamma distribution (parameters constant)
114+
gammalogulikelihood, # unnormalized logpdf of gamma distribution (data constant)
105115
gammacdf, # cdf of gamma distribution
106116
gammaccdf, # ccdf of gamma distribution
107117
gammalogcdf, # logcdf of gamma distribution
@@ -114,6 +124,8 @@ export
114124
# distrs/hyper
115125
hyperpdf, # pdf of hypergeometric distribution
116126
hyperlogpdf, # logpdf of hypergeometric distribution
127+
hyperlogupdf, # unnormalized logpdf of hypergeometric distribution (parameters constant)
128+
hyperlogulikelihood, # unnormalized logpdf of hypergeometric distribution (data constant)
117129
hypercdf, # cdf of hypergeometric distribution
118130
hyperccdf, # ccdf of hypergeometric distribution
119131
hyperlogcdf, # logcdf of hypergeometric distribution
@@ -126,6 +138,8 @@ export
126138
# distrs/nbeta
127139
nbetapdf, # pdf of noncentral beta distribution
128140
nbetalogpdf, # logpdf of noncentral beta distribution
141+
nbetalogupdf, # unnormalized logpdf of noncentral beta distribution (parameters constant)
142+
nbetalogulikelihood, # unnormalized logpdf of noncentral beta distribution (data constant)
129143
nbetacdf, # cdf of noncentral beta distribution
130144
nbetaccdf, # ccdf of noncentral beta distribution
131145
nbetalogcdf, # logcdf of noncentral beta distribution
@@ -138,6 +152,8 @@ export
138152
# distrs/nbinom
139153
nbinompdf, # pdf of negative nbinomial distribution
140154
nbinomlogpdf, # logpdf of negative nbinomial distribution
155+
nbinomlogupdf, # unnormalized logpdf of negative nbinomial distribution (parameters constant)
156+
nbinomlogulikelihood, # unnormalized logpdf of negative nbinomial distribution (data constant)
141157
nbinomcdf, # cdf of negative nbinomial distribution
142158
nbinomccdf, # ccdf of negative nbinomial distribution
143159
nbinomlogcdf, # logcdf of negative nbinomial distribution
@@ -150,6 +166,8 @@ export
150166
# distrs/nchisq
151167
nchisqpdf, # pdf of noncentral chi-square distribution
152168
nchisqlogpdf, # logpdf of noncentral chi-square distribution
169+
nchisqlogupdf, # unnormalized logpdf of noncentral chi-square distribution (parameters constant)
170+
nchisqlogulikelihood, # unnormalized logpdf of noncentral chi-square distribution (data constant)
153171
nchisqcdf, # cdf of noncentral chi-square distribution
154172
nchisqccdf, # ccdf of noncentral chi-square distribution
155173
nchisqlogcdf, # logcdf of noncentral chi-square distribution
@@ -162,6 +180,8 @@ export
162180
# distrs/nfdist
163181
nfdistpdf, # pdf of noncentral F distribution
164182
nfdistlogpdf, # logpdf of noncentral F distribution
183+
nfdistlogupdf, # unnormalized logpdf of noncentral F distribution (parameters constant)
184+
nfdistlogulikelihood, # unnormalized logpdf of noncentral F distribution (data constant)
165185
nfdistcdf, # cdf of noncentral F distribution
166186
nfdistccdf, # ccdf of noncentral F distribution
167187
nfdistlogcdf, # logcdf of noncentral F distribution
@@ -174,6 +194,8 @@ export
174194
# distrs/norm
175195
normpdf, # pdf of normal distribution
176196
normlogpdf, # logpdf of normal distribution
197+
normlogupdf, # unnormalized logpdf of normal distribution (parameters constant)
198+
normlogulikelihood, # unnormalized logpdf of normal distribution (data constant)
177199
normcdf, # cdf of normal distribution
178200
normccdf, # ccdf of normal distribution
179201
normlogcdf, # logcdf of normal distribution
@@ -186,6 +208,8 @@ export
186208
# distrs/ntdist
187209
ntdistpdf, # pdf of noncentral t distribution
188210
ntdistlogpdf, # logpdf of noncentral t distribution
211+
ntdistlogupdf, # unnormalized logpdf of noncentral t distribution (parameters constant)
212+
ntdistlogulikelihood, # unnormalized logpdf of noncentral t distribution (data constant)
189213
ntdistcdf, # cdf of noncentral t distribution
190214
ntdistccdf, # ccdf of noncentral t distribution
191215
ntdistlogcdf, # logcdf of noncentral t distribution
@@ -198,6 +222,8 @@ export
198222
# distrs/pois
199223
poispdf, # pdf of Poisson distribution
200224
poislogpdf, # logpdf of Poisson distribution
225+
poislogupdf, # unnormalized logpdf of Poisson distribution (parameters constant)
226+
poislogulikelihood, # unnormalized logpdf of Poisson distribution (data constant)
201227
poiscdf, # cdf of Poisson distribution
202228
poisccdf, # ccdf of Poisson distribution
203229
poislogcdf, # logcdf of Poisson distribution
@@ -210,6 +236,8 @@ export
210236
# distrs/tdist
211237
tdistpdf, # pdf of student's t distribution
212238
tdistlogpdf, # logpdf of student's t distribution
239+
tdistlogupdf, # unnormalized logpdf of student's t distribution (parameters constant)
240+
tdistlogulikelihood, # unnormalized logpdf of student's t distribution (data constant)
213241
tdistcdf, # cdf of student's t distribution
214242
tdistccdf, # ccdf of student's t distribution
215243
tdistlogcdf, # logcdf of student's t distribution
@@ -222,6 +250,8 @@ export
222250
# distrs/signrank
223251
signrankpdf,
224252
signranklogpdf,
253+
signranklogupdf,
254+
signranklogulikelihood,
225255
signrankcdf,
226256
signranklogcdf,
227257
signrankccdf,
@@ -244,6 +274,8 @@ export
244274
# distrs/wilcox
245275
wilcoxpdf,
246276
wilcoxlogpdf,
277+
wilcoxlogupdf,
278+
wilcoxlogulikelihood,
247279
wilcoxcdf,
248280
wilcoxlogcdf,
249281
wilcoxccdf,

src/distrs/beta.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,20 @@ betapdf(α::Real, β::Real, x::Real) = exp(betalogpdf(α, β, x))
2020

2121
betalogpdf::Real, β::Real, x::Real) = betalogpdf(promote(α, β, x)...)
2222
function betalogpdf::T, β::T, x::T) where {T <: Real}
23+
logupdf = betalogupdf(α, β, x)
24+
return isfinite(logupdf) ? logupdf - logbeta(α, β) : logupdf
25+
end
26+
27+
betalogupdf::Real, β::Real, x::Real) = betalogupdf(promote(α, β, x)...)
28+
function betalogupdf::T, β::T, x::T) where {T <: Real}
2329
# we ensure that `log(x)` and `log1p(-x)` do not error
2430
y = clamp(x, 0, 1)
25-
val = xlogy- 1, y) + xlog1py- 1, -y) - logbeta(α, β)
31+
val = xlogy- 1, y) + xlog1py- 1, -y)
2632
return x < 0 || x > 1 ? oftype(val, -Inf) : val
2733
end
2834

35+
betalogulikelihood::Real, β::Real, x::Real) = betalogpdf(α, β, x)
36+
2937
function betacdf::Real, β::Real, x::Real)
3038
# Handle degenerate cases
3139
if iszero(α) && β > 0

src/distrs/binom.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,23 @@ binompdf(n::Real, p::Real, k::Real) = exp(binomlogpdf(n, p, k))
1818

1919
binomlogpdf(n::Real, p::Real, k::Real) = binomlogpdf(promote(n, p, k)...)
2020
function binomlogpdf(n::T, p::T, k::T) where {T <: Real}
21+
logupdf = binomlogupdf(n, p, k)
22+
if isfinite(logupdf)
23+
return min(0, logupdf - log(n + 1))
24+
else
25+
return logupdf
26+
end
27+
end
28+
29+
binomlogupdf(n::Real, p::Real, k::Real) = binomlogupdf(promote(n, p, k)...)
30+
function binomlogupdf(n::T, p::T, k::T) where {T <: Real}
2131
m = clamp(k, 0, n)
22-
val = min(0, betalogpdf(m + 1, n - m + 1, p) - log(n + 1))
32+
val = betalogpdf(m + 1, n - m + 1, p)
2333
return 0 <= k <= n && isinteger(k) ? val : oftype(val, -Inf)
2434
end
2535

36+
binomlogulikelihood(n::Real, p::Real, k::Real) = binomlogpdf(n, p, k)
37+
2638
for l in ("", "log"), compl in (false, true)
2739
fbinom = Symbol(string("binom", l, ifelse(compl, "c", ""), "cdf"))
2840
fbeta = Symbol(string("beta", l, ifelse(compl, "", "c"), "cdf"))

src/distrs/chisq.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# functions related to chi-square distribution
22

33
# Just use the Gamma definitions
4-
for f in ("pdf", "logpdf", "cdf", "ccdf", "logcdf", "logccdf", "invcdf", "invccdf", "invlogcdf", "invlogccdf")
4+
for f in ("pdf", "logpdf", "logupdf", "logulikelihood", "cdf", "ccdf", "logcdf", "logccdf", "invcdf", "invccdf", "invlogcdf", "invlogccdf")
55
_chisqf = Symbol("chisq" * f)
66
_gammaf = Symbol("gamma" * f)
77
@eval begin

src/distrs/fdist.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ function fdistlogpdf(ν1::T, ν2::T, x::T) where {T <: Real}
1212
return x < 0 ? oftype(val, -Inf) : val
1313
end
1414

15+
fdistlogupdf(ν1::Real, ν2::Real, x::Real) = fdistlogupdf(promote(ν1, ν2, x)...)
16+
function fdistlogupdf(ν1::T, ν2::T, x::T) where {T <: Real}
17+
# we ensure that `log(x)` does not error if `x < 0`
18+
ν1ν2 = ν1 / ν2
19+
y = max(x, 0)
20+
val = (xlogy(ν1 - 2, y) - xlogy(ν1 + ν2, 1 + ν1ν2 * y)) / 2
21+
return x < 0 ? oftype(val, -Inf) : val
22+
end
23+
24+
fdistlogulikelihood(ν1::Real, ν2::Real, x::Real) = fdistlogpdf(ν1, ν2, x)
25+
1526
for f in ("cdf", "ccdf", "logcdf", "logccdf")
1627
ff = Symbol("fdist" * f)
1728
bf = Symbol("beta" * f)

src/distrs/gamma.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ gammapdf(k::Real, θ::Real, x::Real) = exp(gammalogpdf(k, θ, x))
2020

2121
gammalogpdf(k::Real, θ::Real, x::Real) = gammalogpdf(promote(k, θ, x)...)
2222
function gammalogpdf(k::T, θ::T, x::T) where {T <: Real}
23+
logupdf = gammalogupdf(k, θ, x)
24+
return isfinite(logupdf) ? logupdf - loggamma(k) - log(θ) : logupdf
25+
end
26+
27+
gammalogupdf(k::Real, θ::Real, x::Real) = gammalogupdf(promote(k, θ, x)...)
28+
function gammalogupdf(k::T, θ::T, x::T) where {T <: Real}
2329
# we ensure that `log(x)` does not error if `x < 0`
2430
= max(x, 0) / θ
25-
val = -loggamma(k) - log(θ) -
31+
val = -float(xθ)
2632
# xlogy(k - 1, xθ) - xθ -> -∞ for xθ -> ∞ so we only add the first term
2733
# when it's safe
2834
if isfinite(xθ)
@@ -31,6 +37,8 @@ function gammalogpdf(k::T, θ::T, x::T) where {T <: Real}
3137
return x < 0 ? oftype(val, -Inf) : val
3238
end
3339

40+
gammalogulikelihood(k::Real, θ::Real, x::Real) = gammalogpdf(k, θ, x)
41+
3442
function gammacdf(k::T, θ::T, x::T) where {T <: Real}
3543
# Handle the degenerate case
3644
if iszero(k)

src/distrs/hyper.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ using .RFunctions:
1212
hyperinvccdf,
1313
hyperinvlogcdf,
1414
hyperinvlogccdf
15+
16+
17+
hyperlogupdf(ms::Real, mf::Real, n::Real, x::Real) = hyperlogpdf(ms, mf, n, x)
18+
hyperlogulikelihood(ms::Real, mf::Real, n::Real, x::Real) = hyperlogpdf(ms, mf, n, x)

src/distrs/nbeta.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ using .RFunctions:
1212
nbetainvccdf,
1313
nbetainvlogcdf,
1414
nbetainvlogccdf
15+
16+
nbetalogupdf::Real, β::Real, λ::Real, x::Real) = nbetalogpdf(α, β, λ, x)
17+
nbetalogulikelihood::Real, β::Real, λ::Real, x::Real) = nbetalogpdf(α, β, λ, x)

src/distrs/nbinom.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ using .RFunctions:
1212
nbinominvccdf,
1313
nbinominvlogcdf,
1414
nbinominvlogccdf
15+
16+
nbinomlogupdf(r::Real, p::Real, x::Real) = nbinomlogpdf(r, p, x)
17+
nbinomlogulikelihood(r::Real, p::Real, x::Real) = nbinomlogpdf(r, p, x)

0 commit comments

Comments
 (0)