Skip to content

Commit 40f40bc

Browse files
authored
Fix method ambiguities & unbound parameters + add Aqua tests (#1804)
* Fix method ambiguities & unbound parameters + add Aqua tests * Fix compat entries for Julia 1.3 * Update aqua.jl
1 parent 7e232ca commit 40f40bc

File tree

12 files changed

+112
-84
lines changed

12 files changed

+112
-84
lines changed

Project.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,26 @@ DistributionsDensityInterfaceExt = "DensityInterface"
3030
DistributionsTestExt = "Test"
3131

3232
[compat]
33+
Aqua = "0.8"
34+
Calculus = "0.5"
3335
ChainRulesCore = "1"
36+
ChainRulesTestUtils = "1"
3437
DensityInterface = "0.4"
38+
Distributed = "<0.0.1, 1"
3539
FillArrays = "0.9, 0.10, 0.11, 0.12, 0.13, 1"
40+
FiniteDifferences = "0.12"
41+
ForwardDiff = "0.10"
42+
JSON = "0.21"
3643
LinearAlgebra = "<0.0.1, 1"
44+
OffsetArrays = "1"
3745
PDMats = "0.10, 0.11"
3846
Printf = "<0.0.1, 1"
3947
QuadGK = "2"
4048
Random = "<0.0.1, 1"
49+
SparseArrays = "<0.0.1, 1"
4150
SpecialFunctions = "1.2, 2"
51+
StableRNGs = "1"
52+
StaticArrays = "1"
4253
Statistics = "1"
4354
StatsAPI = "1.6"
4455
StatsBase = "0.32, 0.33, 0.34"
@@ -47,6 +58,7 @@ Test = "<0.0.1, 1"
4758
julia = "1.3"
4859

4960
[extras]
61+
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
5062
Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
5163
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
5264
ChainRulesTestUtils = "cdddcdb0-9152-4a09-a978-84456f9df70a"
@@ -62,4 +74,4 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
6274
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6375

6476
[targets]
65-
test = ["StableRNGs", "Calculus", "ChainRulesCore", "ChainRulesTestUtils", "DensityInterface", "Distributed", "FiniteDifferences", "ForwardDiff", "JSON", "SparseArrays", "StaticArrays", "Test", "OffsetArrays"]
77+
test = ["Aqua", "StableRNGs", "Calculus", "ChainRulesCore", "ChainRulesTestUtils", "DensityInterface", "Distributed", "FiniteDifferences", "ForwardDiff", "JSON", "SparseArrays", "StaticArrays", "Test", "OffsetArrays"]

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Distributions.jl
44
[![Build Status](https://github.com/JuliaStats/Distributions.jl/workflows/CI/badge.svg)](https://github.com/JuliaStats/Distributions.jl/actions)
55
[![](https://zenodo.org/badge/DOI/10.5281/zenodo.2647458.svg)](https://zenodo.org/record/2647458)
66
[![Coverage Status](https://coveralls.io/repos/JuliaStats/Distributions.jl/badge.svg?branch=master)](https://coveralls.io/r/JuliaStats/Distributions.jl?branch=master)
7+
[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)
78

89
[![](https://img.shields.io/badge/docs-latest-blue.svg)](https://JuliaStats.github.io/Distributions.jl/latest/)
910
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaStats.github.io/Distributions.jl/stable/)

src/censored.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ _in_open_interval(x::Real, l::Real, ::Nothing) = x > l
431431
_clamp(x, l, u) = clamp(x, l, u)
432432
_clamp(x, ::Nothing, u) = min(x, u)
433433
_clamp(x, l, ::Nothing) = max(x, l)
434+
_clamp(x, ::Nothing, u::Nothing) = x
434435

435436
_to_truncated(d::Censored) = truncated(d.uncensored, d.lower, d.upper)
436437

src/common.jl

Lines changed: 51 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,25 @@ usually it is sufficient to implement `logpdf`.
212212
See also: [`logpdf`](@ref).
213213
"""
214214
@inline function pdf(
215-
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N}
216-
) where {N}
217-
@boundscheck begin
218-
size(x) == size(d) ||
219-
throw(DimensionMismatch("inconsistent array dimensions"))
215+
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,M}
216+
) where {N,M}
217+
if M == N
218+
@boundscheck begin
219+
size(x) == size(d) ||
220+
throw(DimensionMismatch("inconsistent array dimensions"))
221+
end
222+
return _pdf(d, x)
223+
else
224+
@boundscheck begin
225+
M > N ||
226+
throw(DimensionMismatch(
227+
"number of dimensions of the variates ($M) must be greater than or equal to the dimension of the distribution ($N)"
228+
))
229+
ntuple(i -> size(x, i), Val(N)) == size(d) ||
230+
throw(DimensionMismatch("inconsistent array dimensions"))
231+
end
232+
return @inbounds map(Base.Fix1(pdf, d), eachvariate(x, variate_form(typeof(d))))
220233
end
221-
return _pdf(d, x)
222234
end
223235

224236
function _pdf(d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N}) where {N}
@@ -241,13 +253,25 @@ size of `x`.
241253
See also: [`pdf`](@ref).
242254
"""
243255
@inline function logpdf(
244-
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N}
245-
) where {N}
246-
@boundscheck begin
247-
size(x) == size(d) ||
248-
throw(DimensionMismatch("inconsistent array dimensions"))
256+
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,M}
257+
) where {N,M}
258+
if M == N
259+
@boundscheck begin
260+
size(x) == size(d) ||
261+
throw(DimensionMismatch("inconsistent array dimensions"))
262+
end
263+
return _logpdf(d, x)
264+
else
265+
@boundscheck begin
266+
M > N ||
267+
throw(DimensionMismatch(
268+
"number of dimensions of the variates ($M) must be greater than or equal to the dimension of the distribution ($N)"
269+
))
270+
ntuple(i -> size(x, i), Val(N)) == size(d) ||
271+
throw(DimensionMismatch("inconsistent array dimensions"))
272+
end
273+
return @inbounds map(Base.Fix1(logpdf, d), eachvariate(x, variate_form(typeof(d))))
249274
end
250-
return _logpdf(d, x)
251275
end
252276

253277
# `_logpdf` should be implemented and has no default definition
@@ -272,20 +296,6 @@ Base.@propagate_inbounds function pdf(
272296
return map(Base.Fix1(pdf, d), x)
273297
end
274298

275-
@inline function pdf(
276-
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,M},
277-
) where {N,M}
278-
@boundscheck begin
279-
M > N ||
280-
throw(DimensionMismatch(
281-
"number of dimensions of `x` ($M) must be greater than number of dimensions of `d` ($N)"
282-
))
283-
ntuple(i -> size(x, i), Val(N)) == size(d) ||
284-
throw(DimensionMismatch("inconsistent array dimensions"))
285-
end
286-
return @inbounds map(Base.Fix1(pdf, d), eachvariate(x, variate_form(typeof(d))))
287-
end
288-
289299
"""
290300
logpdf(d::Distribution{ArrayLikeVariate{N}}, x) where {N}
291301
@@ -305,20 +315,6 @@ Base.@propagate_inbounds function logpdf(
305315
return map(Base.Fix1(logpdf, d), x)
306316
end
307317

308-
@inline function logpdf(
309-
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,M},
310-
) where {N,M}
311-
@boundscheck begin
312-
M > N ||
313-
throw(DimensionMismatch(
314-
"number of dimensions of `x` ($M) must be greater than number of dimensions of `d` ($N)"
315-
))
316-
ntuple(i -> size(x, i), Val(N)) == size(d) ||
317-
throw(DimensionMismatch("inconsistent array dimensions"))
318-
end
319-
return @inbounds map(Base.Fix1(logpdf, d), eachvariate(x, variate_form(typeof(d))))
320-
end
321-
322318
"""
323319
pdf!(out, d::Distribution{ArrayLikeVariate{N}}, x) where {N}
324320
@@ -365,7 +361,7 @@ end
365361
@boundscheck begin
366362
M > N ||
367363
throw(DimensionMismatch(
368-
"number of dimensions of `x` ($M) must be greater than number of dimensions of `d` ($N)"
364+
"number of dimensions of the variates ($M) must be greater than the dimension of the distribution ($N)"
369365
))
370366
ntuple(i -> size(x, i), Val(N)) == size(d) ||
371367
throw(DimensionMismatch("inconsistent array dimensions"))
@@ -414,7 +410,7 @@ See also: [`pdf!`](@ref).
414410
@boundscheck begin
415411
M > N ||
416412
throw(DimensionMismatch(
417-
"number of dimensions of `x` ($M) must be greater than number of dimensions of `d` ($N)"
413+
"number of dimensions of the variates ($M) must be greater than the dimension of the distribution ($N)"
418414
))
419415
ntuple(i -> size(x, i), Val(N)) == size(d) ||
420416
throw(DimensionMismatch("inconsistent array dimensions"))
@@ -445,23 +441,22 @@ be
445441
- an array of dimension `N + 1` with `size(x)[1:N] == size(d)`, or
446442
- an array of arrays `xi` of dimension `N` with `size(xi) == size(d)`.
447443
"""
448-
Base.@propagate_inbounds function loglikelihood(
449-
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N},
450-
) where {N}
451-
return logpdf(d, x)
452-
end
453-
@inline function loglikelihood(
444+
Base.@propagate_inbounds @inline function loglikelihood(
454445
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,M},
455446
) where {N,M}
456-
@boundscheck begin
457-
M > N ||
458-
throw(DimensionMismatch(
459-
"number of dimensions of `x` ($M) must be greater than number of dimensions of `d` ($N)"
460-
))
461-
ntuple(i -> size(x, i), Val(N)) == size(d) ||
462-
throw(DimensionMismatch("inconsistent array dimensions"))
447+
if M == N
448+
return logpdf(d, x)
449+
else
450+
@boundscheck begin
451+
M > N ||
452+
throw(DimensionMismatch(
453+
"number of dimensions of the variates ($M) must be greater than or equal to the dimension of the distribution ($N)"
454+
))
455+
ntuple(i -> size(x, i), Val(N)) == size(d) ||
456+
throw(DimensionMismatch("inconsistent array dimensions"))
457+
end
458+
return @inbounds sum(Base.Fix1(logpdf, d), eachvariate(x, ArrayLikeVariate{N}))
463459
end
464-
return @inbounds sum(Base.Fix1(logpdf, d), eachvariate(x, ArrayLikeVariate{N}))
465460
end
466461
Base.@propagate_inbounds function loglikelihood(
467462
d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:AbstractArray{<:Real,N}},

src/deprecates.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ for fun in [:pdf, :logpdf,
3434
fun! = Symbol(fun, '!')
3535

3636
@eval begin
37-
@deprecate ($_fun!)(r::AbstractArray, d::UnivariateDistribution, X::AbstractArray) r .= ($fun).(d, X) false
38-
@deprecate ($fun!)(r::AbstractArray, d::UnivariateDistribution, X::AbstractArray) r .= ($fun).(d, X) false
39-
@deprecate ($fun)(d::UnivariateDistribution, X::AbstractArray) ($fun).(d, X)
37+
@deprecate ($_fun!)(r::AbstractArray{<:Real}, d::UnivariateDistribution, X::AbstractArray{<:Real}) r .= ($fun).(d, X) false
38+
@deprecate ($fun!)(r::AbstractArray{<:Real}, d::UnivariateDistribution, X::AbstractArray{<:Real}) r .= ($fun).(d, X) false
39+
@deprecate ($fun)(d::UnivariateDistribution, X::AbstractArray{<:Real}) ($fun).(d, X)
4040
end
4141
end
4242

src/mixtures/mixturemodel.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,14 +362,14 @@ end
362362
pdf(d::UnivariateMixture, x::Real) = _mixpdf1(d, x)
363363
logpdf(d::UnivariateMixture, x::Real) = _mixlogpdf1(d, x)
364364

365-
_pdf!(r::AbstractArray, d::UnivariateMixture{Discrete}, x::UnitRange) = _mixpdf!(r, d, x)
366-
_pdf!(r::AbstractArray, d::UnivariateMixture, x::AbstractArray) = _mixpdf!(r, d, x)
367-
_logpdf!(r::AbstractArray, d::UnivariateMixture, x::AbstractArray) = _mixlogpdf!(r, d, x)
368-
369-
_pdf(d::MultivariateMixture, x::AbstractVector) = _mixpdf1(d, x)
370-
_logpdf(d::MultivariateMixture, x::AbstractVector) = _mixlogpdf1(d, x)
371-
_pdf!(r::AbstractArray, d::MultivariateMixture, x::AbstractMatrix) = _mixpdf!(r, d, x)
372-
_logpdf!(r::AbstractArray, d::MultivariateMixture, x::AbstractMatrix) = _mixlogpdf!(r, d, x)
365+
_pdf!(r::AbstractArray{<:Real}, d::UnivariateMixture{Discrete}, x::UnitRange) = _mixpdf!(r, d, x)
366+
_pdf!(r::AbstractArray{<:Real}, d::UnivariateMixture, x::AbstractArray{<:Real}) = _mixpdf!(r, d, x)
367+
_logpdf!(r::AbstractArray{<:Real}, d::UnivariateMixture, x::AbstractArray{<:Real}) = _mixlogpdf!(r, d, x)
368+
369+
_pdf(d::MultivariateMixture, x::AbstractVector{<:Real}) = _mixpdf1(d, x)
370+
_logpdf(d::MultivariateMixture, x::AbstractVector{<:Real}) = _mixlogpdf1(d, x)
371+
_pdf!(r::AbstractArray{<:Real}, d::MultivariateMixture, x::AbstractMatrix{<:Real}) = _mixpdf!(r, d, x)
372+
_logpdf!(r::AbstractArray{<:Real}, d::MultivariateMixture, x::AbstractMatrix{<:Real}) = _mixlogpdf!(r, d, x)
373373

374374

375375
## component-wise pdf and logpdf

src/multivariate/mvtdist.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ function _logpdf(d::AbstractMvTDist, x::AbstractVector{T}) where T<:Real
139139
v - shdfhdim * log1p(sqmahal(d, x) / d.df)
140140
end
141141

142-
function _logpdf!(r::AbstractArray, d::AbstractMvTDist, x::AbstractMatrix)
142+
function _logpdf!(r::AbstractArray{<:Real}, d::AbstractMvTDist, x::AbstractMatrix{<:Real})
143143
sqmahal!(r, d, x)
144144
shdfhdim, v = mvtdist_consts(d)
145145
for i = 1:size(x, 2)

src/product.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ struct ProductDistribution{N,M,D,S<:ValueSupport,T} <: Distribution{ArrayLikeVar
1212
size::Dims{N}
1313

1414
function ProductDistribution{N,M,D}(dists::D) where {N,M,D}
15-
isempty(dists) && error("product distribution must consist of at least one distribution")
15+
if isempty(dists)
16+
throw(ArgumentError("a product distribution must consist of at least one distribution"))
17+
end
1618
return new{N,M,D,_product_valuesupport(dists),_product_eltype(dists)}(
1719
dists,
1820
_product_size(dists),
1921
)
2022
end
2123
end
2224

23-
function ProductDistribution(dists::AbstractArray{<:Distribution{ArrayLikeVariate{M}},N}) where {M,N}
25+
function ProductDistribution(dists::AbstractArray{<:Distribution{<:ArrayLikeVariate{M}},N}) where {M,N}
2426
return ProductDistribution{M + N,M,typeof(dists)}(dists)
2527
end
2628

27-
function ProductDistribution(dists::NTuple{N,Distribution{ArrayLikeVariate{M}}}) where {M,N}
29+
function ProductDistribution(dists::Tuple{Distribution{<:ArrayLikeVariate{M}},Vararg{Distribution{<:ArrayLikeVariate{M}}}}) where {M}
2830
return ProductDistribution{M + 1,M,typeof(dists)}(dists)
2931
end
3032

@@ -54,10 +56,10 @@ function _product_size(dists::AbstractArray{<:Distribution{<:ArrayLikeVariate{M}
5456
size_dists = size(dists)
5557
return ntuple(i -> i <= M ? size_d[i] : size_dists[i-M], Val(M + N))
5658
end
57-
function _product_size(dists::NTuple{N,Distribution{<:ArrayLikeVariate{M}}}) where {M,N}
59+
function _product_size(dists::Tuple{Distribution{<:ArrayLikeVariate{M}},Vararg{Distribution{<:ArrayLikeVariate{M}}, N}}) where {M,N}
5860
size_d = size(first(dists))
5961
all(size(d) == size_d for d in dists) || error("all distributions must be of the same size")
60-
return ntuple(i -> i <= M ? size_d[i] : N, Val(M + 1))
62+
return ntuple(i -> i <= M ? size_d[i] : N + 1, Val(M + 1))
6163
end
6264

6365
## aliases
@@ -167,7 +169,7 @@ function _rand!(
167169
end
168170

169171
# `_logpdf` for arrays of distributions
170-
# we have to fix a method ambiguity
172+
# we have to fix some method ambiguities
171173
_logpdf(d::ProductDistribution{N}, x::AbstractArray{<:Real,N}) where {N} = __logpdf(d, x)
172174
_logpdf(d::ProductDistribution{2}, x::AbstractMatrix{<:Real}) = __logpdf(d, x)
173175
function __logpdf(

src/univariate/discrete/categorical.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ function pdf(d::Categorical, x::Real)
8989
return insupport(d, x) ? ps[round(Int, x)] : zero(eltype(ps))
9090
end
9191

92-
function _pdf!(r::AbstractArray, d::Categorical{T}, rgn::UnitRange) where {T<:Real}
92+
function _pdf!(r::AbstractArray{<:Real}, d::Categorical{T}, rgn::UnitRange) where {T<:Real}
9393
vfirst = round(Int, first(rgn))
9494
vlast = round(Int, last(rgn))
9595
vl = max(vfirst, 1)

src/univariates.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ See also: [`logpdf`](@ref).
311311
pdf(d::UnivariateDistribution, x::Real) = exp(logpdf(d, x))
312312

313313
# extract value from array of zero dimension
314-
_pdf(d::UnivariateDistribution, x::AbstractArray{<:Real,0}) = pdf(d, first(x))
314+
pdf(d::UnivariateDistribution, x::AbstractArray{<:Real,0}) = pdf(d, first(x))
315315

316316
"""
317317
logpdf(d::UnivariateDistribution, x::Real)
@@ -323,7 +323,7 @@ See also: [`pdf`](@ref).
323323
logpdf(d::UnivariateDistribution, x::Real)
324324

325325
# extract value from array of zero dimension
326-
_logpdf(d::UnivariateDistribution, x::AbstractArray{<:Real,0}) = logpdf(d, first(x))
326+
logpdf(d::UnivariateDistribution, x::AbstractArray{<:Real,0}) = logpdf(d, first(x))
327327

328328
# loglikelihood for `Real`
329329
Base.@propagate_inbounds loglikelihood(d::UnivariateDistribution, x::Real) = logpdf(d, x)
@@ -452,7 +452,7 @@ function _pdf_fill_outside!(r::AbstractArray, d::DiscreteUnivariateDistribution,
452452
return vl, vr, vfirst, vlast
453453
end
454454

455-
function _pdf!(r::AbstractArray, d::DiscreteUnivariateDistribution, X::UnitRange)
455+
function _pdf!(r::AbstractArray{<:Real}, d::DiscreteUnivariateDistribution, X::UnitRange)
456456
vl,vr, vfirst, vlast = _pdf_fill_outside!(r, d, X)
457457

458458
# fill central part: with non-zero pdf

0 commit comments

Comments
 (0)