Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New type hierarchy for ValueSupport #945

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions docs/src/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ The `ValueSupport` sub-types defined in `Distributions.jl` are:

**Type** | **Element type** | **Descriptions**
--- | --- | ---
`Discrete` | `Int` | Samples take discrete values
`Continuous` | `Float64` | Samples take continuous real values
`DiscreteSupport{T}` | `T` | Samples take any discrete values
`Discrete = DiscreteSupport{Int}` | `Int` | Samples take `Int` values
`ContinuousSupport{T <: Number}` | `T` | Samples take continuous values
`Continuous = ContinuousSupport{Float64}` | `Float64` | Samples take continuous `Float64` values
richardreeve marked this conversation as resolved.
Show resolved Hide resolved

Multiple samples are often organized into an array, depending on the variate form.

Expand All @@ -69,22 +71,28 @@ abstract type Distribution{F<:VariateForm,S<:ValueSupport} <: Sampleable{F,S} en
Distributions.Distribution
```

To simplify the use in practice, we introduce a series of type alias as follows:
To simplify the use in practice, we introduce a series of type aliases as follows:
```julia
const UnivariateDistribution{S<:ValueSupport} = Distribution{Univariate,S}
const MultivariateDistribution{S<:ValueSupport} = Distribution{Multivariate,S}
const MatrixDistribution{S<:ValueSupport} = Distribution{Matrixvariate,S}
const NonMatrixDistribution = Union{UnivariateDistribution, MultivariateDistribution}

const DiscreteDistribution{F<:VariateForm} = Distribution{F,Discrete}
const ContinuousDistribution{F<:VariateForm} = Distribution{F,Continuous}
const CountableDistribution{F<:VariateForm, C<:CountableSupport} = Distribution{F,C}
const DiscreteDistribution{F<:VariateForm} = CountableDistribution{F,Discrete}
const ContinuousDistribution{F<:VariateForm} = Distribution{F,Continuous}

const DiscreteUnivariateDistribution = Distribution{Univariate, Discrete}
const ContinuousUnivariateDistribution = Distribution{Univariate, Continuous}
const DiscreteMultivariateDistribution = Distribution{Multivariate, Discrete}
const ContinuousMultivariateDistribution = Distribution{Multivariate, Continuous}
const DiscreteMatrixDistribution = Distribution{Matrixvariate, Discrete}
const ContinuousMatrixDistribution = Distribution{Matrixvariate, Continuous}
const CountableUnivariateDistribution{C<:CountableSupport} = UnivariateDistribution{C}
const DiscreteUnivariateDistribution = CountableUnivariateDistribution{Discrete}
const ContinuousUnivariateDistribution = UnivariateDistribution{Continuous}

const CountableMultivariateDistribution{C<:CountableSupport} = MultivariateDistribution{C}
const DiscreteMultivariateDistribution = CountableMultivariateDistribution{Discrete}
const ContinuousMultivariateDistribution = MultivariateDistribution{Continuous}

const CountableMatrixDistribution{C<:CountableSupport} = MatrixDistribution{C}
const DiscreteMatrixDistribution = CountableMatrixDistribution{Discrete}
const ContinuousMatrixDistribution = MatrixDistribution{Continuous}
```

All methods applicable to `Sampleable` also applies to `Distribution`. The API for distributions of different variate forms are different (refer to [univariates](@ref univariates), [multivariates](@ref multivariates), and [matrix](@ref matrix-variates) for details).
10 changes: 9 additions & 1 deletion src/Distributions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,28 @@ export
# generic types
VariateForm,
ValueSupport,
CountableSupport,
ContiguousSupport,
ContinuousSupport,
DiscontinuousSupport,
UnionSupport,
Univariate,
Multivariate,
Matrixvariate,
Discrete,
Continuous,
Discontinuous,
Sampleable,
Distribution,
UnivariateDistribution,
MultivariateDistribution,
MatrixDistribution,
NoncentralHypergeometric,
NonMatrixDistribution,
DiscreteDistribution,
ContinuousDistribution,
CountableUnivariateDistribution,
CountableMultivariateDistribution,
CountableMatrixDistribution,
DiscreteUnivariateDistribution,
DiscreteMultivariateDistribution,
DiscreteMatrixDistribution,
Expand Down
62 changes: 42 additions & 20 deletions src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,21 @@ struct Matrixvariate <: VariateForm end
`S <: ValueSupport` specifies the support of sample elements,
either discrete or continuous.
"""
abstract type ValueSupport end
struct Discrete <: ValueSupport end
struct Continuous <: ValueSupport end
abstract type ValueSupport{N} end
struct ContinuousSupport{N <: Number} <: ValueSupport{N} end
abstract type CountableSupport{C} <: ValueSupport{C} end
struct ContiguousSupport{C <: Integer} <: CountableSupport{C} end
struct UnionSupport{N1, N2,
S1 <: ValueSupport{N1},
S2 <: ValueSupport{N2}} <:
ValueSupport{Union{N1, N2}} end

const Discrete = ContiguousSupport{Int}
const Continuous = ContinuousSupport{Float64}
const DiscontinuousSupport{I, F} =
UnionSupport{I, F, <: CountableSupport{I},
ContinuousSupport{F}} where {I <: Number, F <: Number}
const Discontinuous = DiscontinuousSupport{Int, Float64}

## Sampleable

Expand Down Expand Up @@ -50,13 +62,14 @@ Base.size(s::Sampleable{Multivariate}) = (length(s),)

"""
eltype(s::Sampleable)
eltype(::ValueSupport)

The default element type of a sample. This is the type of elements of the samples generated
by the `rand` method. However, one can provide an array of different element types to
store the samples using `rand!`.
"""
Base.eltype(s::Sampleable{F,Discrete}) where {F} = Int
Base.eltype(s::Sampleable{F,Continuous}) where {F} = Float64
Base.eltype(::Sampleable{F, <: ValueSupport{N}}) where {F, N} = N
Base.eltype(::ValueSupport{N}) where {N} = N

"""
nsamples(s::Sampleable)
Expand All @@ -67,10 +80,11 @@ into an array, depending on the variate form.
nsamples(t::Type{Sampleable}, x::Any)
nsamples(::Type{D}, x::Number) where {D<:Sampleable{Univariate}} = 1
nsamples(::Type{D}, x::AbstractArray) where {D<:Sampleable{Univariate}} = length(x)
nsamples(::Type{D}, x::AbstractVector) where {D<:Sampleable{Multivariate}} = 1
nsamples(::Type{D}, x::AbstractArray{<:AbstractVector}) where {D<:Sampleable{Multivariate}} = length(x)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an unrelated change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was fixing the handling of numbers throughout the code and I spotted that multivariate was missing this function - this isn't a deletion... the edited code is in the next line:

nsamples(::Type{D}, x::AbstractVector{<:Number}) where {D<:Sampleable{Multivariate}} = 1

nsamples(::Type{D}, x::AbstractVector{<:Number}) where {D<:Sampleable{Multivariate}} = 1
nsamples(::Type{D}, x::AbstractMatrix) where {D<:Sampleable{Multivariate}} = size(x, 2)
nsamples(::Type{D}, x::Number) where {D<:Sampleable{Matrixvariate}} = 1
nsamples(::Type{D}, x::Array{Matrix{T}}) where {D<:Sampleable{Matrixvariate},T<:Number} = length(x)
nsamples(::Type{D}, x::AbstractMatrix{<:Number}) where {D<:Sampleable{Matrixvariate}} = 1
nsamples(::Type{D}, x::AbstractArray{<:AbstractMatrix{T}}) where {D<:Sampleable{Matrixvariate},T<:Number} = length(x)

"""
Distribution{F<:VariateForm,S<:ValueSupport} <: Sampleable{F,S}
Expand All @@ -85,23 +99,31 @@ abstract type Distribution{F<:VariateForm,S<:ValueSupport} <: Sampleable{F,S} en
const UnivariateDistribution{S<:ValueSupport} = Distribution{Univariate,S}
const MultivariateDistribution{S<:ValueSupport} = Distribution{Multivariate,S}
const MatrixDistribution{S<:ValueSupport} = Distribution{Matrixvariate,S}
const NonMatrixDistribution = Union{UnivariateDistribution, MultivariateDistribution}

const DiscreteDistribution{F<:VariateForm} = Distribution{F,Discrete}
const CountableDistribution{F<:VariateForm,
C<:CountableSupport} = Distribution{F,C}
const DiscreteDistribution{F<:VariateForm} = CountableDistribution{F,Discrete}
const ContinuousDistribution{F<:VariateForm} = Distribution{F,Continuous}

const DiscreteUnivariateDistribution = Distribution{Univariate, Discrete}
const ContinuousUnivariateDistribution = Distribution{Univariate, Continuous}
const DiscreteMultivariateDistribution = Distribution{Multivariate, Discrete}
const ContinuousMultivariateDistribution = Distribution{Multivariate, Continuous}
const DiscreteMatrixDistribution = Distribution{Matrixvariate, Discrete}
const ContinuousMatrixDistribution = Distribution{Matrixvariate, Continuous}
const CountableUnivariateDistribution{C<:CountableSupport} =
UnivariateDistribution{C}
const DiscreteUnivariateDistribution =
CountableUnivariateDistribution{Discrete}
const ContinuousUnivariateDistribution = UnivariateDistribution{Continuous}

variate_form(::Type{Distribution{VF,VS}}) where {VF<:VariateForm,VS<:ValueSupport} = VF
variate_form(::Type{T}) where {T<:Distribution} = variate_form(supertype(T))
const CountableMultivariateDistribution{C<:CountableSupport} =
MultivariateDistribution{C}
const DiscreteMultivariateDistribution =
CountableMultivariateDistribution{Discrete}
const ContinuousMultivariateDistribution = MultivariateDistribution{Continuous}

value_support(::Type{Distribution{VF,VS}}) where {VF<:VariateForm,VS<:ValueSupport} = VS
value_support(::Type{T}) where {T<:Distribution} = value_support(supertype(T))
const CountableMatrixDistribution{C<:CountableSupport} = MatrixDistribution{C}
const DiscreteMatrixDistribution = CountableMatrixDistribution{Discrete}
const ContinuousMatrixDistribution = MatrixDistribution{Continuous}


variate_form(::Type{<:Sampleable{VF, <:ValueSupport}}) where {VF<:VariateForm} = VF
value_support(::Type{<:Sampleable{<:VariateForm,VS}}) where {VS<:ValueSupport} = VS

# allow broadcasting over distribution objects
# to be decided: how to handle multivariate/matrixvariate distributions?
Expand Down
6 changes: 6 additions & 0 deletions src/functionals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ function expectation(distr::DiscreteUnivariateDistribution, g::Function, epsilon
sum(x -> f(x)*g(x), leftEnd:rightEnd)
end

function expectation(distr::CountableUnivariateDistribution,
g::Function, epsilon::Real)
f = x->pdf(distr,x)
sum(x -> f(x)*g(x), support(distr))
richardreeve marked this conversation as resolved.
Show resolved Hide resolved
end

function expectation(distr::UnivariateDistribution, g::Function)
expectation(distr, g, 1e-10)
end
Expand Down
4 changes: 2 additions & 2 deletions src/mixtures/mixturemodel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ the components given by ``params``, and a prior probability vector.
If no `prior` is provided then all components will have the same prior probabilities.
"""
function MixtureModel(::Type{C}, params::AbstractArray) where C<:Distribution
components = C[_construct_component(C, a) for a in params]
components = [_construct_component(C, a) for a in params]
richardreeve marked this conversation as resolved.
Show resolved Hide resolved
MixtureModel(components)
end

Expand All @@ -142,7 +142,7 @@ _construct_component(::Type{C}, arg) where {C<:Distribution} = C(arg)
_construct_component(::Type{C}, args::Tuple) where {C<:Distribution} = C(args...)

function MixtureModel(::Type{C}, params::AbstractArray, p::Vector{T}) where {C<:Distribution,T<:Real}
components = C[_construct_component(C, a) for a in params]
components = [_construct_component(C, a) for a in params]
MixtureModel(components, p)
end

Expand Down
3 changes: 1 addition & 2 deletions src/multivariate/dirichlet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Dirichlet(alpha) # Dirichlet distribution with parameter vector alpha
Dirichlet(k, a) # Dirichlet distribution with parameter a * ones(k)
```
"""
struct Dirichlet{T<:Real} <: ContinuousMultivariateDistribution
struct Dirichlet{T<:Real} <: MultivariateDistribution{ContinuousSupport{T}}
alpha::Vector{T}
alpha0::T
lmnB::T
Expand Down Expand Up @@ -57,7 +57,6 @@ end

length(d::DirichletCanon) = length(d.alpha)

eltype(::Dirichlet{T}) where {T} = T
#### Conversions
convert(::Type{Dirichlet{Float64}}, cf::DirichletCanon) = Dirichlet(cf.alpha)
convert(::Type{Dirichlet{T}}, alpha::Vector{S}) where {T<:Real, S<:Real} =
Expand Down
5 changes: 2 additions & 3 deletions src/multivariate/mvlognormal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#
###########################################################

abstract type AbstractMvLogNormal <: ContinuousMultivariateDistribution end
abstract type AbstractMvLogNormal{T} <: MultivariateDistribution{ContinuousSupport{T}} end

function insupport(::Type{D},x::AbstractVector{T}) where {T<:Real,D<:AbstractMvLogNormal}
for i=1:length(x)
Expand Down Expand Up @@ -161,7 +161,7 @@ Mean vector ``\\boldsymbol{\\mu}`` and covariance matrix ``\\boldsymbol{\\Sigma}
underlying normal distribution are known as the *location* and *scale*
parameters of the corresponding lognormal distribution.
"""
struct MvLogNormal{T<:Real,Cov<:AbstractPDMat,Mean<:AbstractVector} <: AbstractMvLogNormal
struct MvLogNormal{T<:Real,Cov<:AbstractPDMat,Mean<:AbstractVector} <: AbstractMvLogNormal{T}
normal::MvNormal{T,Cov,Mean}
end

Expand All @@ -176,7 +176,6 @@ MvLogNormal(σ::AbstractVector) = MvLogNormal(MvNormal(σ))
MvLogNormal(d::Int,s::Real) = MvLogNormal(MvNormal(d,s))


eltype(::MvLogNormal{T}) where {T} = T
### Conversion
function convert(::Type{MvLogNormal{T}}, d::MvLogNormal) where T<:Real
MvLogNormal(convert(MvNormal{T}, d.normal))
Expand Down
6 changes: 2 additions & 4 deletions src/multivariate/mvnormal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const ZeroMeanDiagNormal = MvNormal{PDiagMat, ZeroVector{Float64}}
const ZeroMeanFullNormal = MvNormal{PDMat, ZeroVector{Float64}}
```
"""
abstract type AbstractMvNormal <: ContinuousMultivariateDistribution end
abstract type AbstractMvNormal{T<:Real} <: MultivariateDistribution{ContinuousSupport{T}} end

### Generic methods (for all AbstractMvNormal subtypes)

Expand Down Expand Up @@ -170,7 +170,7 @@ isotropic covariance as `abs2(sig) * eye(d)`.
**Note:** The constructor will choose an appropriate covariance form internally, so that
special structure of the covariance can be exploited.
"""
struct MvNormal{T<:Real,Cov<:AbstractPDMat,Mean<:AbstractVector} <: AbstractMvNormal
struct MvNormal{T<:Real,Cov<:AbstractPDMat,Mean<:AbstractVector} <: AbstractMvNormal{T}
μ::Mean
Σ::Cov
end
Expand Down Expand Up @@ -219,8 +219,6 @@ MvNormal(Σ::Matrix{<:Real}) = MvNormal(PDMat(Σ))
MvNormal(σ::Vector{<:Real}) = MvNormal(PDiagMat(abs2.(σ)))
MvNormal(d::Int, σ::Real) = MvNormal(ScalMat(d, abs2(σ)))


eltype(::MvNormal{T}) where {T} = T
### Conversion
function convert(::Type{MvNormal{T}}, d::MvNormal) where T<:Real
MvNormal(convert(AbstractArray{T}, d.μ), convert(AbstractArray{T}, d.Σ))
Expand Down
3 changes: 1 addition & 2 deletions src/multivariate/mvnormalcanon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Construct a multivariate normal distribution of dimension `d`, with zero mean an

**Note:** `MvNormalCanon` share the same set of methods as `MvNormal`.
"""
struct MvNormalCanon{T<:Real,P<:AbstractPDMat,V<:AbstractVector} <: AbstractMvNormal
struct MvNormalCanon{T<:Real,P<:AbstractPDMat,V<:AbstractVector} <: AbstractMvNormal{T}
μ::V # the mean vector
h::V # potential vector, i.e. inv(Σ) * μ
J::P # precision matrix, i.e. inv(Σ)
Expand Down Expand Up @@ -156,7 +156,6 @@ length(d::MvNormalCanon) = length(d.μ)
mean(d::MvNormalCanon) = convert(Vector{eltype(d.μ)}, d.μ)
params(d::MvNormalCanon) = (d.μ, d.h, d.J)
@inline partype(d::MvNormalCanon{T}) where {T<:Real} = T
eltype(::MvNormalCanon{T}) where {T} = T

var(d::MvNormalCanon) = diag(inv(d.J))
cov(d::MvNormalCanon) = Matrix(inv(d.J))
Expand Down
5 changes: 2 additions & 3 deletions src/multivariate/mvtdist.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Generic multivariate t-distribution class

abstract type AbstractMvTDist <: ContinuousMultivariateDistribution end
abstract type AbstractMvTDist{T} <: MultivariateDistribution{ContinuousSupport{T}} end

struct GenericMvTDist{T<:Real, Cov<:AbstractPDMat, Mean<:AbstractVector} <: AbstractMvTDist
struct GenericMvTDist{T<:Real, Cov<:AbstractPDMat, Mean<:AbstractVector} <: AbstractMvTDist{T}
df::T # non-integer degrees of freedom allowed
dim::Int
zeromean::Bool
Expand Down Expand Up @@ -103,7 +103,6 @@ logdet_cov(d::GenericMvTDist) = d.df>2 ? logdet((d.df/(d.df-2))*d.Σ) : NaN

params(d::GenericMvTDist) = (d.df, d.μ, d.Σ)
@inline partype(d::GenericMvTDist{T}) where {T} = T
eltype(::GenericMvTDist{T}) where {T} = T
matbesancon marked this conversation as resolved.
Show resolved Hide resolved

# For entropy calculations see "Multivariate t Distributions and their Applications", S. Kotz & S. Nadarajah
function entropy(d::GenericMvTDist)
Expand Down
2 changes: 1 addition & 1 deletion src/truncate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ isupperbounded(d::Truncated) = isupperbounded(d.untruncated) || isfinite(d.upper
minimum(d::Truncated) = max(minimum(d.untruncated), d.lower)
maximum(d::Truncated) = min(maximum(d.untruncated), d.upper)

insupport(d::Truncated{D,Union{Discrete,Continuous}}, x::Real) where {D<:UnivariateDistribution} =
insupport(d::Truncated{D,VS}, x::Real) where {VS<:ValueSupport, D<:UnivariateDistribution{VS}} =
d.lower <= x <= d.upper && insupport(d.untruncated, x)


Expand Down
4 changes: 1 addition & 3 deletions src/univariate/continuous/normal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ External links
* [Normal distribution on Wikipedia](http://en.wikipedia.org/wiki/Normal_distribution)

"""
struct Normal{T<:Real} <: ContinuousUnivariateDistribution
struct Normal{T<:Real} <: UnivariateDistribution{ContinuousSupport{T}}
μ::T
σ::T
Normal{T}(µ::T, σ::T) where {T<:Real} = new{T}(µ, σ)
Expand Down Expand Up @@ -61,8 +61,6 @@ params(d::Normal) = (d.μ, d.σ)
location(d::Normal) = d.μ
scale(d::Normal) = d.σ

eltype(::Normal{T}) where {T} = T

#### Statistics

mean(d::Normal) = d.μ
Expand Down
6 changes: 4 additions & 2 deletions src/univariate/discrete/discretenonparametric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ External links

* [Probability mass function on Wikipedia](http://en.wikipedia.org/wiki/Probability_mass_function)
"""
struct DiscreteNonParametric{T<:Real,P<:Real,Ts<:AbstractVector{T},Ps<:AbstractVector{P}} <: DiscreteUnivariateDistribution
struct DiscreteNonParametric{T<:Real,P<:Real,Ts<:AbstractVector{T},Ps<:AbstractVector{P}} <: CountableUnivariateDistribution{CountableSupport{T}}
support::Ts
p::Ps

Expand Down Expand Up @@ -156,8 +156,10 @@ end

minimum(d::DiscreteNonParametric) = first(support(d))
maximum(d::DiscreteNonParametric) = last(support(d))
insupport(d::DiscreteNonParametric, x::Real) =
insupport(d::DiscreteNonParametric{T}, x::T) where {T} =
length(searchsorted(support(d), x)) > 0
insupport(d::DiscreteNonParametric{T}, x::Number) where {T<:Number} =
length(searchsorted(support(d), convert(T, x))) > 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer support to do the right thing here and not insupport to second guess the needed transformation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you expect support to do here? It's just returning the support, and then we're checking for presence of the value in that set.


mean(d::DiscreteNonParametric) = dot(probs(d), support(d))

Expand Down
5 changes: 3 additions & 2 deletions src/univariates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,11 @@ end
insupport(d::Union{D,Type{D}}, X::AbstractArray) where {D<:UnivariateDistribution} =
insupport!(BitArray(undef, size(X)), d, X)

insupport(d::Union{D,Type{D}},x::Real) where {D<:ContinuousUnivariateDistribution} = minimum(d) <= x <= maximum(d)
insupport(d::Union{D,Type{D}},x::Real) where {D<:UnivariateDistribution{ContinuousSupport{T}}} where {T} = minimum(d) <= x <= maximum(d)
insupport(d::D,x::T) where {T, D<:UnivariateDistribution{CountableSupport{T}}} = x ∈ support(d)
insupport(d::Union{D,Type{D}},x::Real) where {D<:DiscreteUnivariateDistribution} = isinteger(x) && minimum(d) <= x <= maximum(d)

support(d::Union{D,Type{D}}) where {D<:ContinuousUnivariateDistribution} = RealInterval(minimum(d), maximum(d))
support(d::Union{D,Type{D}}) where {D<:UnivariateDistribution{ContinuousSupport{T}}} where {T} = RealInterval(minimum(d), maximum(d))
support(d::Union{D,Type{D}}) where {D<:DiscreteUnivariateDistribution} = round(Int, minimum(d)):round(Int, maximum(d))

# Type used for dispatch on finite support
Expand Down
1 change: 1 addition & 0 deletions test/locationscale.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function test_location_scale_normal(μ::Real, σ::Real, μD::Real, σD::Real,
#### Evaluation & Sampling

insupport(d,0.4) == insupport(dref,0.4)
insupport(d,0.4) == insupport(dref,Dual(0.4))
@test pdf(d,0.1) ≈ pdf(dref,0.1)
@test pdf.(d,2:4) ≈ pdf.(dref,2:4)
@test logpdf(d,0.4) ≈ logpdf(dref,0.4)
Expand Down
Loading