Skip to content

Finally remove anonymous functions in bounds #551

Description

@odunbar

Issue

The following construction of bounds is neat but leads to the primary instability of reconstructing EKP priors with JLD2

function bounded_above(upper_bound::FT) where {FT <: Real}
if isinf(upper_bound)
return no_constraint()
end
c_to_u = (x -> log(upper_bound - x))
jacobian = (x -> 1.0 / (upper_bound - x))
u_to_c = (x -> upper_bound - exp(x))
bounds = Dict("upper_bound" => upper_bound)
return Constraint{BoundedAbove}(c_to_u, jacobian, u_to_c, bounds)
end

The reason this arises is a long time ago - there was an un-julia-like decision, which somehow lead to an avoidance of clear dispatch

A possible solution (Dispatch)

Create the structs

struct BoundedAbove{FT} <: ConstraintType
    upper_bound::FT
end

Create the methods

function c_to_u(c::BoundedAbove, x)
    log(c.upper_bound - x)
end

function jacobian(c::BoundedAbove, x)
    1.0 / (c.upper_bound - x)
end

function u_to_c(c::BoundedAbove, x)
    c.upper_bound - exp(x)
end

This would need to be changed in just a few places (exclusively in ParameterDistributions.jl, and FunctionParameterDistributions.jl) where we explicitly call c.c_to_u e.g.,

function transform_constrained_to_unconstrained(
d::PDT,
constraints::AbstractVector,
x::AbstractArray{FT},
) where {FT <: Real, PDT <: ParameterDistributionType}
x_out = similar(x)
for (out, in, c) in zip(eachrow(x_out), eachrow(x), constraints)
out .= c.constrained_to_unconstrained.(in)
end

It may also mean that Constraint will not be a parameterized type, but rather the abstract type

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions