getting the types right for transformed distributions


#1

I have a question about how to structure certain types. Even though the application is statistics, the question is really about types.

I’d like to build types that take a Distribution (from the Distributions package) and transform it into another Distribution. I’d like this to maintain the VariateForm of the Distribution. Below is a simplified version of what I’d like. Is there a way to do this which works?

using Distributions

type Translation{S,T<:UnivariateDistribution{S}} <: UnivariateDistribution{S}
distribution::T
translation::Float64
scale::Float64
end

Translation( distribution::UnivariateDistribution, x::Float64 ) =
Translation( distribution, x, 1/x )

t = Translation( Normal(), 2.0 )


#2

(Please quote your code with backticks).

In general, yes, this is the way to wrap some other object. In the specific example, I am not sure why you have a type parameter S, you could just have T <: UnivariateDistribution (perhaps you are using S somewhere? but that is not in the example).

Also, there is no reason to restrict to Float64, use some R <: Real, so that your code would work with eg ForwardDiff.jl at zero performance cost.


#3

I think the S parameter is necessary so that the resulting type can itself be <: UnivariateDistribution{S}.


#4

I must be missing something about the type hierarchy of Distributions.jl, but it is unclear to me how that is used. The only parametric usage of that type I could find is the definition, the rest dispatch on UnivariateDistribution, and then subtypes just use a non-parametric subtype (eg Normal).


#5

I ended up solving my problem soon after posting it. Template parameters were needed for the function:

`
using Distributions

type Translation{S,T<:UnivariateDistribution{S}} <: UnivariateDistribution{S}
distribution::T
translation::Float64
scale::Float64
end

Translation{S,T<:UnivariateDistribution{S}}( distribution::T, x::Float64 ) =
Translation{S,T}( distribution, x, 1/x )

t = Translation( Normal(), 2.0 )
`