Skip to content

Commit

Permalink
Fix inconsistency of pdf/cdf of Uniform (#1682)
Browse files Browse the repository at this point in the history
* Fix inconsistency of `pdf`/`cdf` of `Uniform`

* Fix existing tests

* Fixes

* Fix
  • Loading branch information
devmotion authored Feb 23, 2023
1 parent e761040 commit 610bc12
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 27 deletions.
10 changes: 7 additions & 3 deletions src/univariate/continuous/uniform.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,16 @@ entropy(d::Uniform) = log(d.b - d.a)
#### Evaluation

function pdf(d::Uniform, x::Real)
val = inv(d.b - d.a)
# include dependency on `x` for return type to be consistent with `cdf`
a, b, _ = promote(d.a, d.b, x)
val = inv(b - a)
return insupport(d, x) ? val : zero(val)
end
function logpdf(d::Uniform, x::Real)
diff = d.b - d.a
return insupport(d, x) ? -log(diff) : log(zero(diff))
# include dependency on `x` for return type to be consistent with `logcdf`
a, b, _ = promote(d.a, d.b, x)
val = - log(b - a)
return insupport(d, x) ? val : oftype(val, -Inf)
end
gradlogpdf(d::Uniform, x::Real) = zero(partype(d)) / oneunit(x)

Expand Down
34 changes: 34 additions & 0 deletions test/univariate/continuous/uniform.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Distributions
using ChainRulesTestUtils
using OffsetArrays
using StatsFuns

using Random
using Test
Expand Down Expand Up @@ -80,4 +81,37 @@ using Test
end
end
end
# issue #1677
@testset "consistency of pdf and cdf" begin
for T in (Int, Float32, Float64)
d = Uniform{T}(T(2), T(4))
for S in (Int, Float32, Float64)
TS = float(promote_type(T, S))

@test @inferred(pdf(d, S(1))) === TS(0)
@test @inferred(pdf(d, S(3))) === TS(1//2)
@test @inferred(pdf(d, S(5))) === TS(0)

@test @inferred(logpdf(d, S(1))) === TS(-Inf)
@test @inferred(logpdf(d, S(3))) === -TS(logtwo)
@test @inferred(logpdf(d, S(5))) === TS(-Inf)

@test @inferred(cdf(d, S(1))) === TS(0)
@test @inferred(cdf(d, S(3))) === TS(1//2)
@test @inferred(cdf(d, S(5))) === TS(1)

@test @inferred(logcdf(d, S(1))) === TS(-Inf)
@test @inferred(logcdf(d, S(3))) === -TS(logtwo)
@test @inferred(logcdf(d, S(5))) === TS(0)

@test @inferred(ccdf(d, S(1))) === TS(1)
@test @inferred(ccdf(d, S(3))) === TS(1//2)
@test @inferred(ccdf(d, S(5))) === TS(0)

@test @inferred(logccdf(d, S(1))) === TS(0)
@test @inferred(logccdf(d, S(3))) === -TS(logtwo)
@test @inferred(logccdf(d, S(5))) === TS(-Inf)
end
end
end
end
24 changes: 0 additions & 24 deletions test/univariates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,30 +177,6 @@ end
@test invlogccdf(d, log(0.6)) isa Int
end

@testset "Uniform type inference" begin
for T in (Int, Float32)
d = Uniform{T}(T(2), T(3))
FT = float(T)
XFT = promote_type(FT, Float64)

@test @inferred(pdf(d, 1.5)) === zero(FT)
@test @inferred(pdf(d, 2.5)) === one(FT)
@test @inferred(pdf(d, 3.5)) === zero(FT)

@test @inferred(logpdf(d, 1.5)) === FT(-Inf)
@test @inferred(logpdf(d, 2.5)) === -zero(FT) # negative zero
@test @inferred(logpdf(d, 3.5)) === FT(-Inf)

@test @inferred(cdf(d, 1.5)) === zero(XFT)
@test @inferred(cdf(d, 2.5)) === XFT(1//2)
@test @inferred(cdf(d, 3.5)) === one(XFT)

@test @inferred(ccdf(d, 1.5)) === one(XFT)
@test @inferred(ccdf(d, 2.5)) === XFT(1//2)
@test @inferred(ccdf(d, 3.5)) === zero(XFT)
end
end

# #1471
@testset "InverseGamma constructor (#1471)" begin
@test_throws DomainError InverseGamma(-1, 2)
Expand Down

0 comments on commit 610bc12

Please sign in to comment.