Package interoperability showcases

Picking up on our discussion on nice packages of the Julia ecosystem, What packages are state of the art… I argued that naming isolated packages does the ecosystem disregard because things julia-magically work together and therefore packages do not only add to the ecosystem but multiply. For example you model a trebuchet with RigidBodyDynamics on one day and find the optimal proportions on the next day with ForwardDiff . I still (2020) owe you to do that actually.

What kind of short and nice examples with maybe surprising and creative use of package combinations can we come up?



  • ForwardDiff with anything, Zygote with a lot of things
  • various <: AbstractArray implementations with anything that uses, well, arrays
  • various packages implementing operations on numbers, eg Unitful.jl, with anything involving these operations

For reasonably complex projects, it is more or less inevitable to have examples of the unreasonable effectiveness of multiple dispatch.

But as for showcasing, especially to people who do not yet use Julia, I am not sure these things are useful. If someone has not used multiple dispatch before, it is difficult to imagine how nice it is.


An example by Luca Ferranti what illustrates very well what I am looking for. Context is the question, how to prove that a function is convex.

Since a 1D-function is convex/concave over an interval if it has positive/negative second derivative, you can use interval arithmetic to get a certificate of the convexity of the function. Here is a MWE

using ForwardDiff, IntervalArithmetic
df = x -> ForwardDiff.derivative(exp, x)
ddf = x -> ForwardDiff.derivative(df, x)
julia> ddf(0..1)
[1, 2.71829]

the last result tells you that the second derivative is always above zero and hence the function is convex over that interval.


Via @Keno’s Twitter



One more via @dlfivefifty 's Twitter:

# InfiniteLinearAlgebra.jl+IntervalArithmetic.jl

julia> J̃ = z -> (SymTridiagonal(-2*(0:∞)/z, ones(∞)) \ [1; zeros(∞)])[1];

julia> roots(J̃, 2.4..2.405)[1].interval
[2.40482, 2.40483]

We have a few long-form examples under the “Ecosystem Integration” section of the Agents.jl documentation.


Four-way :slight_smile:

using Turing, Distributions, IntervalArithmetic, ForwardDiff
@model model() = begin
    X ~ Normal()

v = Turing.VarInfo(model())
sampler = Turing.SampleFromPrior()
ctx = DynamicPPL.DefaultContext()

function ℓ(θ)
    new_vi = Turing.VarInfo(v, sampler, [θ])
    model()(new_vi, sampler, ctx)
    logp = Turing.getlogp(new_vi)
    return logp

C = sup(ForwardDiff.derivative(ℓ, -1..2))

(This computes the upper bound of a gradient of a probability density generated by Turing model, relevant for sampling this posterior with PDMP methods )

1 Like

Question on slack: wonder if any symbolic package can perform the completing the square in the Gaussian density f(x,F,Γ) = exp(((-x^2) /2)*(Γ)+ x*F)


using Mitosis
using Symbolics
@variables F,Γ
p = convert(Mitosis.Gaussian{(:μ,:Σ)}, Mitosis.Gaussian{(:F,:Γ)}(F, Γ))

There it is

julia> p
Gaussian{(:μ, :Σ)}((μ = F*(Γ^-1), Σ = Γ^-1))