Internal Documentation
Documentation for ComposedDistributions's internal interface.
Contents
Index
ComposedDistributions.ParamsTableBase.randBase.showComposedDistributions._composed_paramsComposedDistributions._composer_randComposedDistributions._edit_atComposedDistributions._flat_event_namesComposedDistributions.rand_outcomeDistributions.ccdfDistributions.cdfDistributions.logpdfDistributions.pdfDistributions.probsStatistics.meanStatistics.stdStatistics.varStatsAPI.params
Internal API
ComposedDistributions.ParamsTable Type
struct ParamsTable{C<:NamedTuple}A Tables.jl column table of a composed distribution's free parameters.
The value params_table returns: a Tables.jl source (a column table) that prints as a padded edge | param | value | support | prior table. It is a thin wrapper over a NamedTuple of equal-length column vectors, forwarding the whole Tables.jl column interface and column access (tbl.edge, tbl.param, ...), so Tables.istable, Tables.columns, Tables.getcolumn, DataFrame(tbl) and build_priors all consume it unchanged; only its display is customised.
See also: params_table, build_priors.
Fields
columns::NamedTuple
ComposedDistributions._composed_params Function
_composed_params(
d::Union{Parallel, Sequential}
) -> NamedTupleNested, name-keyed parameters of a composed distribution.
Returns a NamedTuple keyed by the node names, each value the params of that child (recursing into nested composers; a leaf delegates to its standard/ extended Distributions.params). A Resolve node contributes a name-keyed NamedTuple of its outcomes plus a branch_probs entry. This nested form is for prior introspection via params_table; a composed distribution reconstructs through compose, not through Distribution(params...).
See also: params_table, event_names, event
ComposedDistributions._composer_rand Function
_composer_rand(
rng::Random.AbstractRNG,
d::Union{Parallel, Sequential}
) -> Vector_composer_rand(rng, d)The vector-valued realisation of a composer: the generic per-leaf-value draw (one value per leaf, a nested composer contributing its own sub-vector). A Resolve child collapses to its marginal time-to-resolution (its univariate rand), a Choose child to its first alternative. Composed distributions score this flat, vector-valued representation (consumed by logpdf/AD); the labelled outputs below (_named_composer_rand, mean/var/std of a Parallel) wrap it by name for users.
ComposedDistributions._edit_at Function
_edit_at(node, path::Tuple, op) -> Any_edit_at(node, path, op)The path-walk core shared by update, prune and splice: walks path from node, applying op(target) at the addressed node and rebuilding the spine on the way back up. path is a tuple of edge names, in the same forms event accepts. An empty path applies op to node itself; otherwise _edit_step dispatches on the composer type to find the named child, recurse, and rebuild with the edited child swapped in.
ComposedDistributions._flat_event_names Function
_flat_event_names(
d::Union{Parallel, Sequential}
) -> Tuple{Vararg{Symbol}}_flat_event_names(d)The internal worker behind the public event_names (flat) accessor: the tuple of event names matching the scored event vector [E_0, E_1, ..., E_k], the root origin event followed by one target event per edge in depth-first order. Built by appending into a Symbol[] and freezing to a tuple, mirroring the params_table pre-order walk; edge names are read from the parent composer's names field (a leaf edge does not store its own name), so each child is visited paired with its edge name.
Event names are derived from the composer's edge names (an edge :onset_admit gives origin :onset and target :admit); an edge with a positional default name (:step_i / :branch_i) contributes the positional event name :event_i instead. These event names key a data row (a linelist column is an event time), distinct from the edge names (component_names / the parameter inventory).
Distributions.ccdf Function
ccdf(c::Compete, t::Real) -> AnySurvival of the racing-hazard marginal any-event time at t: ∏_k S_k(t).
See also: Compete
Distributions.cdf Function
cdf(c::Resolve, x::Real) -> AnyCumulative distribution function of the one_of-outcome marginal at x.
The branch-prob-weighted mixture cdf Σ_i p_i F_i(x), summed directly so the probabilities keep their (possibly AD Dual) element type rather than being stripped by as_mixture's float.(branch_probs). This keeps the cdf AD-safe on a differentiated path (e.g. a censored-survival term), matching logpdf.
See also: as_mixture
Distributions.logpdf Function
logpdf(d::Sequential, x::AbstractVector) -> AnyLog probability density of a chain's step-value vector.
See also: Sequential
logpdf(d::Parallel, x::AbstractVector) -> AnyLog probability density of a branch-value vector, summed over branches.
See also: Parallel
logpdf(c::Resolve, x::Real) -> AnyLog probability density of the one_of-outcome marginal at x.
Routed through the AD-safe _one_of_logmix reduction rather than logpdf(as_mixture(c), x): as_mixture does float.(branch_probs), which strips an AD Dual/tracked type from the branch probabilities, breaking the gradient w.r.t. a covariate case-fatality term (logistic(Xβ)) when a Resolve is scored as a leaf of a plain (non-censored) compose(...) tree. The explicit log-sum-exp keeps the probabilities' element type, so a Dual propagates exactly as on the censored-tree scorer.
See also: as_mixture
logpdf(c::Compete, t::Real) -> AnyLog density of the racing-hazard marginal any-event time T = min_k D_k.
The marginal density is ∑_j f_j(t) ∏_{k≠j} S_k(t); this is its log via the log-sum-exp of the cause-resolved sub-densities, AD-safe (the leaf params propagate, no float stripping).
See also: Compete, Distributions.probs
logpdf(d::Choose, x::NamedTuple) -> AnyScore a self-describing Choose record (the shape a bare rand(d) returns).
A bare rand(d) draw is a NamedTuple whose selector field names the drawn alternative and whose remaining fields are that alternative's labelled draw, so logpdf(d, rand(d)) round-trips with no kind argument: the selector field is read to pick the alternative, then the rest of the record is scored under that alternative's own logpdf. A leaf alternative's value rides in the :value field; a composer alternative is scored on its own labelled record fields. A column table of such records is summed per row.
Statistics.mean Function
mean(d::Sequential) -> AnyOverall mean of a composed distribution (the simple "mean delay").
mean(d) behaves like a normal delay distribution's mean. For a univariate-collapsible composer (a Sequential chain, a Convolved, a Resolve) it returns the SCALAR mean of the overall observed delay — the mean of observed_distribution(d) (the convolved total for a chain, the marginal time-to-resolution for a Resolve). For a genuinely multivariate Parallel (several independent observed endpoints) it returns the per-ENDPOINT Vector, one overall mean per branch endpoint, NOT the origin / intermediate events. Censoring is seen through to the free delay. An uncertain leaf contributes its TEMPLATE moment (parameter uncertainty is NOT propagated); guard with has_uncertain(d) if that matters, draw the marginal with rand, or collapse the leaf to its concrete template with update(tree, params) to work with fixed parameters.
For a single event's own moment, fetch its distribution with event and take its mean directly, e.g. mean(event(d, :onset_admit)).
Examples
using ComposedDistributions, Distributions
seq = Sequential(Gamma(2.0, 1.0), LogNormal(0.5, 0.4))
mean(seq) # overall mean delay (a scalar)See also
event: fetch an edge/event's own distributionevent_names: the flat per-event labelsobserved_distribution: collapse a chain to its terminal scalar
StatsAPI.params Function
params(d::Sequential) -> NamedTupleNested, name-keyed parameters of the chain.
Returns a NamedTuple keyed by the step names, each value the params of that step (recursing into nested composers; a leaf delegates to its standard/extended Distributions.params). This nested form is for prior introspection via params_table; a composed distribution reconstructs through compose, not through Distribution(params...).
See also: params_table, event_names, event
params(d::Parallel) -> NamedTupleNested, name-keyed parameters of the branches.
Returns a NamedTuple keyed by the branch names, each value the params of that branch (recursing into nested composers; a leaf delegates to its standard/ extended Distributions.params). This nested form is for prior introspection via params_table; a composed distribution reconstructs through compose, not through Distribution(params...).
See also: params_table, event_names, event
Distributions.pdf Function
pdf(d::Sequential, x::AbstractVector) -> AnyProbability density of a chain's step-value vector.
See also: logpdf
pdf(d::Parallel, x::AbstractVector) -> AnyProbability density of a branch-value vector.
See also: logpdf
pdf(c::Resolve, x::Real) -> AnyProbability density of the one_of-outcome marginal at x.
exp of the AD-safe logpdf, so branch-prob gradients survive (see the logpdf note on why as_mixture is avoided on a differentiated path).
See also: logpdf
pdf(d::Choose, x::Real; kind)Probability density of the SELECTED alternative at x.
See also: logpdf
Distributions.probs Function
probs(c::Resolve) -> NamedTupleThe per-outcome probabilities of a fixed-probability Resolve node: its declared branch probabilities (the no-event branch's mass is the non-occurrence probability), returned as a NamedTuple keyed by the outcome names.
This is the Resolve method of Distributions.probs, the standard mixture-weight reader: a Resolve lowers to a MixtureModel (see as_mixture), so its weights ARE the declared branch probabilities. The racing-hazard Compete sibling derives the same split from the hazards instead.
Arguments
c: theResolvenode whose declared branch probabilities to read.
Examples
using ComposedDistributions, Distributions
node = resolve(:death => (Gamma(1.5, 1.0), 0.3),
:disch => (Gamma(2.0, 1.5), 0.7))
probs(node)See also: occurrence_probability
probs(c::Compete) -> NamedTupleThe DERIVED per-cause winning probabilities of a racing-hazard Compete node: P(cause = j) = ∫ f_j(t) ∏_{k≠j} S_k(t) dt, returned as a NamedTuple keyed by the outcome names.
This is the Compete method of Distributions.probs, the standard mixture-weight reader: it gives the same per-outcome split Resolve returns from its declared branch probabilities, but DERIVED here from the hazards rather than declared.
Computed by AD-safe fixed-node Gauss-Legendre quadrature of the cause-resolved sub-density over the marginal support. The probabilities are sub-stochastic-free (they sum to one for proper, eventually-certain causes); a node whose causes can leave residual survival at +∞ (a defective cause) sums to less than one, the deficit being the never-resolved mass.
Arguments
c: theCompetenode whose derived per-cause winning split to read.
Examples
using ComposedDistributions, Distributions
node = compete(:death => Gamma(2.0, 3.0), :recover => Gamma(3.0, 2.0))
probs(node)See also: Compete, occurrence_probability
Base.rand Function
rand(rng::Random.AbstractRNG, d::Sequential) -> NamedTupleSample a chain realisation as a NamedTuple keyed by the per-step value names: one entry per leaf step, a nested Sequential/Parallel step contributing its own sub-values under dotted-joined names, and a Resolve step contributing its own collapsed scalar.
See also: Sequential
rand(rng::Random.AbstractRNG, d::Parallel) -> NamedTupleSample a branch realisation as a NamedTuple keyed by the per-branch value names: one entry per leaf branch, a nested Sequential/Parallel branch contributing its own sub-values under dotted-joined names, and a Resolve branch contributing its own collapsed scalar.
See also: Parallel
rand(rng::Random.AbstractRNG, c::Resolve) -> AnySample the one_of-outcome marginal time-to-resolution.
See also: as_mixture
rand(rng::Random.AbstractRNG, c::Compete) -> AnySample the racing-hazard marginal any-event time min_k D_k.
See also: rand_outcome to retain WHICH cause won.
rand(rng::Random.AbstractRNG, d::Choose; kind) -> NamedTupleSample a Choose, returning a self-describing record tagging which alternative was drawn.
Without a kind (the forward-simulation path, where no data names the branch) an alternative is sampled uniformly and the result is a NamedTuple carrying the selector field set to the drawn alternative's name plus that alternative's own draw, so the record identifies which alternative fired and feeds straight back into logpdf with no extra arguments. A leaf alternative's value is labelled :value; a composer alternative contributes its own flat event-record fields.
With a kind (explicit selection) the draw is that alternative's own rand returned directly (a scalar for a leaf, a labelled NamedTuple for a composer), not wrapped in a selector tag: the caller already named the alternative, so this is the in-tree / committed-selection path (logpdf(d, draw; kind) scores it).
rand(rng::Random.AbstractRNG, d::Uncertain) -> AnyDraw the marginal of an uncertain distribution: draw every uncertain parameter from its spec (recursively, so a nested Uncertain spec draws via its own rand), rebuild the concrete leaf (fixed wrapper structure re-applied), then draw the value. Each call draws a fresh parameter set, so repeated draws are iid from the marginal.
ComposedDistributions.rand_outcome Function
Sample a composed-distribution outcome AND its time, returning (name, time).
rand_outcome retains WHICH outcome/cause occurred, unlike the univariate rand (the marginal time only, which discards which outcome/cause won). Dispatches on the composer:
a
Resolvenode (below): draws the resolved outcome from the branch probabilities and the time from that outcome's own delay;a
Competenode (below, inhazard_one_of.jl): draws a racing-hazard outcome, a latent time per cause with theargmincause and itsmintime returned.
rand_outcome(rng, c::Resolve)
Used by the full-path tree simulation, where a Resolve node resolves to a single named outcome, so the chosen outcome is retained rather than discarded.
Arguments
rng: random number generator (the no-rngmethod uses the global default).c: theResolvenode to sample an outcome from.
Examples
using ComposedDistributions, Distributions, Random
node = Resolve(:death => (Gamma(1.5, 1.0), 0.3),
:disch => (Gamma(2.0, 1.5), 0.7))
name, time = rand_outcome(MersenneTwister(1), node)rand_outcome(rng, c::Compete)
This is the generative dual of the logpdf (f_j ∏_{k≠j} S_k) and of the forward convolve_distributions stream: the Monte Carlo winning-cause frequencies match the derived Distributions.probs split and the forward per-outcome stream masses.
Arguments
rng: random number generator (the no-rngmethod uses the global default).c: theCompetenode to sample a winning cause from.
Examples
using ComposedDistributions, Distributions, Random
node = compete(:death => Gamma(2.0, 3.0), :recover => Gamma(3.0, 2.0))
name, time = rand_outcome(MersenneTwister(1), node)See also
sourceBase.show Function
show(io::IO, _::MIME{Symbol("text/plain")}, d::Sequential)Print a Sequential chain as a recursive indented tree, descending into any nested composer children so the whole structure is shown at once.
See also: Sequential
show(io::IO, _::MIME{Symbol("text/plain")}, d::Parallel)Print a Parallel composer as a recursive indented tree, descending into any nested composer children so the whole structure is shown at once.
See also: Parallel
show(io::IO, _::MIME{Symbol("text/plain")}, c::Resolve)Print a Resolve node as a recursive indented tree, labelling each outcome with its name and branch probability and descending into any nested composer outcome so the whole structure is shown at once.
See also: Resolve
show(io::IO, _::MIME{Symbol("text/plain")}, c::Compete)Print a Compete node as a recursive indented tree.
See also: Compete
show(io::IO, _::MIME{Symbol("text/plain")}, d::Choose)Print a Choose node as its selector and named alternatives.
See also: Choose
show(io::IO, d::Shared)Print a Shared tagged leaf as its tag and wrapped distribution.
See also: shared
show(io::IO, d::Uncertain)Print an Uncertain leaf as its constructor form: the template and the name = spec pairs.
See also: uncertain
Statistics.std Function
std(d::Sequential) -> AnyOverall standard deviation of a composed distribution.
std(d) is sqrt(var(d)) (or its elementwise form for a Parallel). For a single event's own std, use std(event(d, name)).
See also
sourceStatistics.var Function
var(d::Sequential) -> AnyOverall variance of a composed distribution.
var(d) mirrors mean: the scalar variance of the overall observed delay for a univariate-collapsible composer (the variance of observed_distribution(d)), or the per-ENDPOINT Vector for a Parallel. For a single event's own variance, use var(event(d, name)).
See also
source