Skip to content

Truncated distributions not compatible with autodiff #745

@clint-leach

Description

@clint-leach

This came up in a project I am working on:

using ForwardDiff
using Distributions

Truncated(Normal(ForwardDiff.Dual(0.0), ForwardDiff.Dual(1.0)), 0.0, Inf)

which produces a "cannot convert object of type ForwardDiff.Dual to Float64" error. The error seems to result from trying to store the cdf calculations in the Truncated struct. Locally, I fixed this with:

struct Truncated{D<:UnivariateDistribution, S<:ValueSupport, T<:Real} <: UnivariateDistribution{S}
    untruncated::D      # the original distribution (untruncated)
    lower::Float64      # lower bound
    upper::Float64      # upper bound
    lcdf::T             # cdf of lower bound
    ucdf::T             # cdf of upper bound

    tp::T               # the probability of the truncated part, i.e. ucdf - lcdf
    logtp::T            # log(tp), i.e. log(ucdf - lcdf)
end

### Constructors

function Truncated(d::UnivariateDistribution, l::Float64, u::Float64)
    l < u || error("lower bound should be less than upper bound.")
    lcdf = isinf(l) ? 0.0 : cdf(d, l)
    ucdf = isinf(u) ? 1.0 : cdf(d, u)
    tp = ucdf - lcdf
    Truncated{typeof(d), value_support(typeof(d)), eltype(params(d))}(d, l, u, lcdf, ucdf, tp, log(tp))
end

which I can put in a pull request if it's useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions