Internal Documentation
Documentation for ConvolvedDistributions's internal interface.
Contents
Index
ConvolvedDistributions._collapse_analytic_pairConvolvedDistributions._convolved_analytic_armConvolvedDistributions._difference_analytic_armConvolvedDistributions._product_analytic_armConvolvedDistributions._ratio_analytic_armConvolvedDistributions._repeat_combinationConvolvedDistributions._validate_repeat_countDistributions.cdfDistributions.componentsDistributions.logcdfDistributions.logcdfDistributions.logcdfDistributions.logcdfDistributions.logpdfDistributions.pdfStatistics.meanStatistics.meanStatistics.meanStatistics.meanStatistics.quantileStatistics.stdStatistics.stdStatistics.stdStatistics.stdStatistics.varStatistics.varStatistics.varStatistics.var
Internal API
ConvolvedDistributions._collapse_analytic_pair Function
_collapse_analytic_pair(_::Tuple{})_collapse_analytic_pair(components::Tuple)Scan every component pair (not just adjacent ones, so a non-analytic component sitting between two collapsible ones does not block them) for one where convolve_pair succeeds; replace that pair with the resulting distribution and return the reduced tuple, or nothing when no pair collapses. Written as head/tail Tuple recursion (dispatching on the empty- and single-element base cases below), rather than building the result through a mutable Vector, so it stays @inferred-stable for the common small-n case instead of widening to Any.
ConvolvedDistributions._convolved_analytic_arm Function
_convolved_analytic_arm(
generic,
direct,
d::ConvolvedDistributions.Convolved,
components::Tuple,
x,
method::AnalyticalSolver
) -> AnyShared AnalyticalSolver arm for a convolved_* quantity generic (review A): a single remaining component evaluates directly (direct); otherwise collapse one analytic pair (_collapse_analytic_pair) and recurse generic on the reduced Convolved, or – when no pair collapses – fall through to generic's NumericSolver arm. No step is restricted to exactly two components: this same arm handles a two-component pair (collapsing it in one step) and a three-or-more fold (collapsing repeatedly, taking whichever pair resolves first) uniformly.
ConvolvedDistributions._difference_analytic_arm Function
_difference_analytic_arm(
generic,
direct,
d::Difference,
components::Tuple,
x,
method::AnalyticalSolver
) -> AnyShared AnalyticalSolver arm for a difference_* quantity generic: when (x, y) resolves via difference_pair, evaluate direct on the result; otherwise fall through to generic's NumericSolver arm.
ConvolvedDistributions._product_analytic_arm Function
_product_analytic_arm(
generic,
direct,
d::ConvolvedDistributions.Product,
components::Tuple,
x,
method::AnalyticalSolver
) -> AnyShared AnalyticalSolver arm for a product_* quantity generic: when (x, y) resolves via product_pair, evaluate direct on the result; otherwise fall through to generic's NumericSolver arm.
ConvolvedDistributions._ratio_analytic_arm Function
_ratio_analytic_arm(
generic,
direct,
d::Ratio,
components::Tuple,
x,
method::AnalyticalSolver
) -> AnyShared AnalyticalSolver arm for a ratio_* quantity generic: when (x, y) resolves via ratio_pair, evaluate direct on the result; otherwise fall through to generic's NumericSolver arm.
ConvolvedDistributions._repeat_combination Function
_repeat_combination(
analytic,
build,
d::Distributions.UnivariateDistribution,
k
) -> AnyShared mechanism behind convolved(d, k) and product(d, k): validate k, return d unchanged for k == 1, try the closed form for k iid copies of d via analytic(d, k), and only when that returns nothing build the k-fold combination via build(d, k). k is either a plain Integer or a Val{K}; build receives it unchanged so it can offer an inference-stable path for the Val case.
ConvolvedDistributions._validate_repeat_count Function
_validate_repeat_count(k::Integer)Validate a repeat count for convolved(d, k) / product(d, k): must be a positive integer, else throw an ArgumentError.
Distributions.cdf Function
cdf(d::UnivariateDistribution, x::Real)Evaluate the cumulative probability at x.
See also ccdf, logcdf, and logccdf.
cdf(d::ConvolvedDistributions.Convolved, x::Real) -> AnyCompute the cumulative distribution function.
Routes through convolved_cdf (S1, review A): an analytical fast path where a component pair collapses (d1 + d2 names a distribution) or a component-specific method exists, otherwise AD-safe numeric quadrature. Any number of components is handled uniformly – there is no separate two-component-only path.
See also: logcdf
cdf(
d::ConvolvedDistributions.Convolved,
x::AbstractVector{<:Real}
) -> AnyCompute the CDF for a vector of evaluation points, analytically where convolved_cdf has an exact route, otherwise in one batched composite-quadrature pass.
Each numeric point is integrated over the same window the scalar path picks, on a shared panel grid whose nodes and integration-component density are evaluated once and reused across points, plus small per-point end-correction integrals. Batched and scalar numeric results therefore agree to well within ~1e-8 (typically near machine precision) for batches spanning up to ~40x point ranges; extreme spans (100x and beyond) stay within ~1e-6. See the FAQ.
See also: cdf
cdf(d::Difference, z::Real) -> AnyCompute the cumulative distribution function.
Uses the analytic Normal-Normal difference where it applies, otherwise AD-safe numeric quadrature of
See also: logcdf
cdf(d::ConvolvedDistributions.Product, z::Real) -> AnyCompute the cumulative distribution function.
Uses the analytic LogNormal-LogNormal product where it applies, otherwise AD-safe numeric quadrature of Y's density diverges at zero (shape below one).
See also: logcdf
cdf(d::Ratio, z::Real) -> AnyCompute the cumulative distribution function.
Uses the analytic ratio where one applies, otherwise AD-safe numeric quadrature split into the Y > 0 / Y < 0 branches (see the Ratio docstring's Density and CDF computation section).
See also: logcdf
Distributions.components Method
components(d::ConvolvedDistributions.Convolved) -> Tuplecomponents(d::Convolved)The independent delay distributions whose sum d represents, returned as the component tuple. The public accessor for peeling a Convolved apart without reaching into its fields — a downstream lower bridge, for one, folds them into a series phase-type chain. Extends Distributions.components (the standard composite-distribution accessor), so it composes with using Distributions rather than clashing with it.
Distributions.logcdf Method
logcdf(d::ConvolvedDistributions.Convolved, x::Real) -> AnyCompute the log cumulative distribution function.
See also: cdf
Distributions.logcdf Method
logcdf(d::Difference, z::Real) -> AnyCompute the log cumulative distribution function.
See also: cdf
Distributions.logcdf Method
logcdf(d::ConvolvedDistributions.Product, z::Real) -> AnyCompute the log cumulative distribution function.
See also: cdf
Distributions.logcdf Method
logcdf(d::Ratio, z::Real) -> AnyCompute the log cumulative distribution function.
See also: cdf
Distributions.logpdf Function
logpdf(d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N}) where {N}Evaluate the logarithm of the probability density function of d at x.
This function checks if the size of x is compatible with distribution d. This check can be disabled by using @inbounds.
Implementation
Instead of logpdf one should implement _logpdf(d, x) which does not have to check the size of x.
See also: pdf, gradlogpdf.
logpdf(d::Distribution{ArrayLikeVariate{N}}, x) where {N}Evaluate the logarithm of the probability density function of d at every element in a collection x.
This function checks for every element of x if its size is compatible with distribution d. This check can be disabled by using @inbounds.
Here, x can be
an array of dimension
> Nwithsize(x)[1:N] == size(d), oran array of arrays
xiof dimensionNwithsize(xi) == size(d).
logpdf(d::UnivariateDistribution, x::Real)Evaluate the logarithm of probability density (mass) at x.
See also: pdf.
logpdf(d::Union{UnivariateMixture, MultivariateMixture}, x)Evaluate the logarithm of the (mixed) probability density function over x. Here, x can be a single sample or an array of multiple samples.
logpdf(d::ConvolvedDistributions.Convolved, x::Real) -> AnyCompute the log probability density function.
sourcelogpdf(
d::ConvolvedDistributions.Convolved,
x::AbstractVector{<:Real}
) -> AnyCompute log densities for a vector of points, analytically where convolved_logpdf has an exact route, otherwise as the log of the batched PDF solve.
Each numeric point is integrated over the same window the scalar path picks (shared composite panels plus per-point end corrections), so batched and scalar numeric log densities agree to well within ~1e-8 even for wide batches (typically near machine precision; extreme 100x-plus point spans stay within ~1e-6).
sourcelogpdf(d::Difference, z::Real) -> AnyCompute the log probability density function.
sourcelogpdf(d::ConvolvedDistributions.Product, z::Real) -> AnyCompute the log probability density function.
sourcelogpdf(d::Ratio, z::Real) -> AnyCompute the log probability density function.
sourceStatistics.mean Method
mean(d::ConvolvedDistributions.Convolved) -> AnyMean of the convolution: the exact sum of the component means.
A Convolved is a sum of independent components, so the mean is mean; a component without one errors (there is no numeric fallback).
Statistics.mean Method
mean(d::Difference) -> AnyMean of the difference: the difference of the component means,
Statistics.mean Method
mean(d::ConvolvedDistributions.Product) -> AnyMean of the product: the product of the component means,
Statistics.mean Method
mean(d::Ratio) -> AnyMean of the ratio, delegating to the analytic ratio distribution's own mean (NaN for the zero-mean Normal/Normal pair, since its ratio is Cauchy). Throws an ArgumentError naming the component families when no analytic ratio exists: E[X / Y] = E[X] E[1/Y] needs an inverse moment of the denominator, which is not generally available.
Distributions.pdf Function
pdf(d::Distribution{ArrayLikeVariate{N}}, x::AbstractArray{<:Real,N}) where {N}Evaluate the probability density function of d at x.
This function checks if the size of x is compatible with distribution d. This check can be disabled by using @inbounds.
Implementation
Instead of pdf one should implement _pdf(d, x) which does not have to check the size of x. However, since the default definition of pdf(d, x) falls back to logpdf(d, x) usually it is sufficient to implement logpdf.
See also: logpdf.
pdf(d::Distribution{ArrayLikeVariate{N}}, x) where {N}Evaluate the probability density function of d at every element in a collection x.
This function checks for every element of x if its size is compatible with distribution d. This check can be disabled by using @inbounds.
Here, x can be
an array of dimension
> Nwithsize(x)[1:N] == size(d), oran array of arrays
xiof dimensionNwithsize(xi) == size(d).
pdf(d::UnivariateDistribution, x::Real)Evaluate the probability density (mass) at x.
See also: logpdf.
pdf(d::Union{UnivariateMixture, MultivariateMixture}, x)Evaluate the (mixed) probability density function over x. Here, x can be a single sample or an array of multiple samples.
pdf(d::ConvolvedDistributions.Convolved, x::Real) -> AnyCompute the probability density function.
Routes through convolved_pdf (S1, review A): an analytical fast path where one applies, otherwise the AD-safe numeric density convolution
See also: logpdf
pdf(
d::ConvolvedDistributions.Convolved,
x::AbstractVector{<:Real}
) -> AnyCompute densities for a vector of points (see the batched cdf method for the analytic-vs-numeric routing).
See also: pdf
pdf(d::Difference, z::Real) -> AnyCompute the probability density function.
Uses the exact analytic Normal-Normal density where it applies, otherwise the AD-safe numeric cross-correlation
See also: logpdf
pdf(d::ConvolvedDistributions.Product, z::Real) -> AnyCompute the probability density function.
Uses the exact analytic LogNormal-LogNormal density where it applies, otherwise the AD-safe numeric Mellin convolution
See also: logpdf
pdf(d::Ratio, z::Real) -> AnyCompute the probability density function.
Uses the exact analytic ratio density where one applies, otherwise the AD-safe numeric quadrature
See also: logpdf
Statistics.quantile Function
quantile(d::UnivariateDistribution, q::Real)Evaluate the (generalized) inverse cumulative distribution function at q.
For a given 0 ≤ q ≤ 1, quantile(d, q) is the smallest value x in the support of d for which cdf(d, x) ≥ q.
See also: cquantile, invlogcdf, and invlogccdf.
quantile(
d::ConvolvedDistributions.Convolved,
p::Real
) -> AnyCompute the quantile (inverse CDF) of the convolution.
Routes through convolved_quantile (S1/S2.4, review A): exact where the components collapse to a named distribution (e.g. Normal+Normal, equal-scale Gamma, equal-rate Exponential), with no dependency on Optimization.jl. A fold that gets stuck falls back to the numeric quantile in the ConvolvedDistributionsOptimizationExt extension, for any number of components. A Discrete-typed convolution instead returns an exact lattice point from an upward summation scan, also with no Optimization.jl dependency.
See also: cdf
quantile(
d::Difference{<:Distributions.UnivariateDistribution, <:Distributions.UnivariateDistribution, <:ConvolvedDistributions.AbstractSolverMethod, Distributions.Discrete},
p::Real
) -> AnyCompute the quantile (inverse CDF) of the difference.
For a Discrete-typed difference, returns an exact integer lattice point, with p == 0/p == 1 always returning the bounds exactly. Any other case needs the ConvolvedDistributionsOptimizationExt extension loaded.
See also: cdf
quantile(
d::ConvolvedDistributions.Product{<:Distributions.UnivariateDistribution, <:Distributions.UnivariateDistribution, <:ConvolvedDistributions.AbstractSolverMethod, Distributions.Discrete},
p::Real
) -> AnyCompute the quantile (inverse CDF) of the product.
For a Discrete-typed product, returns an exact integer lattice point, with p == 0/p == 1 always returning the bounds exactly. Any other case needs the ConvolvedDistributionsOptimizationExt extension loaded.
See also: cdf
quantile(itr, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)Compute the quantile(s) of a collection itr at a specified probability or vector or tuple of probabilities p on the interval [0,1]. The keyword argument sorted indicates whether itr can be assumed to be sorted.
Samples quantile are defined by Q(p) = (1-γ)*x[j] + γ*x[j+1], where x[j] is the j-th order statistic of itr, j = floor(n*p + m), m = alpha + p*(1 - alpha - beta) and γ = n*p + m - j.
By default (alpha = beta = 1), quantiles are computed via linear interpolation between the points ((k-1)/(n-1), x[k]), for k = 1:n where n = length(itr). This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R and NumPy default.
The keyword arguments alpha and beta correspond to the same parameters in Hyndman and Fan, setting them to different values allows to calculate quantiles with any of the methods 4-9 defined in this paper:
Def. 4:
alpha=0,beta=1Def. 5:
alpha=0.5,beta=0.5(MATLAB default)Def. 6:
alpha=0,beta=0(ExcelPERCENTILE.EXC, Python default, Stataaltdef)Def. 7:
alpha=1,beta=1(Julia, R and NumPy default, ExcelPERCENTILEandPERCENTILE.INC, Python'inclusive')Def. 8:
alpha=1/3,beta=1/3Def. 9:
alpha=3/8,beta=3/8
Note
An ArgumentError is thrown if v contains NaN or missing values. Use the skipmissing function to omit missing entries and compute the quantiles of non-missing values.
References
Hyndman, R.J and Fan, Y. (1996) "Sample Quantiles in Statistical Packages", The American Statistician, Vol. 50, No. 4, pp. 361-365
Quantile on Wikipedia details the different quantile definitions
Examples
julia> using Statistics
julia> quantile(0:20, 0.5)
10.0
julia> quantile(0:20, [0.1, 0.5, 0.9])
3-element Vector{Float64}:
2.0
10.0
18.000000000000004
julia> quantile(skipmissing([1, 10, missing]), 0.5)
5.5Statistics.std Method
std(d::ConvolvedDistributions.Convolved) -> AnyStandard deviation of the convolution,
Statistics.std Method
std(d::ConvolvedDistributions.Product) -> AnyStandard deviation of the product,
Statistics.std Method
std(d::Ratio) -> AnyStandard deviation of the ratio, delegating to the analytic ratio distribution's own standard deviation. See mean for when this throws.
Statistics.var Method
var(d::ConvolvedDistributions.Convolved) -> AnyVariance of the convolution: the exact sum of the component variances.
Independence makes the variance additive, mean, each component must provide an analytic var or the call errors.
Statistics.var Method
var(d::Difference) -> AnyVariance of the difference: the sum of the component variances,
Statistics.var Method
var(d::ConvolvedDistributions.Product) -> AnyVariance of the product:
Statistics.var Method
var(d::Ratio) -> AnyVariance of the ratio, delegating to the analytic ratio distribution's own variance. See mean for when this throws.