Extending LoweredDistributions
There are two different ways to extend the package: giving a distribution family its own exact lowering, and adding a new backend. The lowering type hierarchy itself — AbstractLowering, AbstractChainTrick, and the four concrete representations (ErlangChain, Coxian, PhaseType, CTMC) — is locked; every lowering is one of these four, so neither extension point adds a new representation type.
Giving a distribution an exact lowering
lower dispatches on the Distribution's type, with a moment-matched phase_type fit as the fallback (lower(d::Distribution) = phase_type(d) in src/lower.jl). A distribution with a known exact chain representation gets its own method, following lower(d::Gamma) and lower(d::Exponential):
LoweredDistributions.lower(d::MyDistribution) = ErlangChain(d; kwargs...)This is ordinary Julia dispatch on your own type, so it needs no extension mechanism — add the method wherever MyDistribution is defined.
Adding a new backend
The four built-in backends (Catalyst, SciMLBase, AlgebraicPetri, JumpProcesses) each follow the same shape: 2. A stub function with no method, declared and exported in the core package — e.g. function ode_problem end in src/ode.jl — so it is part of the public API even before the backend package is loaded.
A package extension
ext/LoweredDistributions<Backend>Ext.jl, gated on the backend as a weak dependency, adding the concrete method dispatching onAbstractLowering(or a narrower type, if the backend only applies to one branch of the hierarchy).The extension builds on the internal numeric core every backend shares:
_generator(m)(src/generator.jl) returns the full state-space generatorQand a default initial condition for ANYAbstractLoweringuniformly, whether it came from a phase-type fit or a bareCTMC.
ext/LoweredDistributionsSciMLBaseExt.jl is the shortest of the four and the best template to start from — it wraps _generator's Q/u0 as an ODEProblem in about a dozen lines.
To add a fifth backend: 2. Add the target package as a [weakdeps] entry and register the extension in [extensions] in Project.toml.
Declare and export a stub function with a docstring in
src/.Write
ext/LoweredDistributions<Backend>Ext.jlfollowing the pattern above, building on_generator(or onPhaseType/CTMCdirectly, if the backend needs the phase-type view rather than the full generator).Add a tutorial under
docs/src/getting-started/tutorials/, mirroring the existing four backend tutorials, and register it indocs/pages.jl.Check the new backend's output against the source distribution on the same delay every other backend tutorial uses.