Public Documentation
Documentation for ConvolvedDistributions's public interface.
Contents
Index
ConvolvedDistributions.AbstractConvolvedDistributionConvolvedDistributions.AbstractSolverMethodConvolvedDistributions.AnalyticalSolverConvolvedDistributions.ConvolvedConvolvedDistributions.DelayPMFConvolvedDistributions.DifferenceConvolvedDistributions.GaussLegendreConvolvedDistributions.NumericSolverConvolvedDistributions.ProductConvolvedDistributions.convolve_seriesConvolvedDistributions.convolvedConvolvedDistributions.differenceConvolvedDistributions.discretise_pmfConvolvedDistributions.gl_integrateConvolvedDistributions.integrateConvolvedDistributions.product
Public API
ConvolvedDistributions.AbstractConvolvedDistribution Type
abstract type AbstractConvolvedDistribution{F<:Distributions.VariateForm, S<:Distributions.ValueSupport} <: Distributions.Distribution{F<:Distributions.VariateForm, S<:Distributions.ValueSupport}Supertype of the distributions of X op Y for independent components — the generalised convolutions. Convolved is the classical sum, Difference the reflected form (Z = X - Y), and Product the Mellin form (Z = X * Y); further operations (order statistics) fit the same family.
Parametric on variate form and value support (Distribution{F, S}), so the univariate members keep their UnivariateDistribution{Continuous} supertype and existing dispatch is unchanged.
Required of a concrete subtype:
params(d);logpdf(d, x)finite on its support;Base.show(io, d).
Verify a subtype with ConvolvedDistributions.TestUtils.test_convolved_interface, and family membership with ConvolvedDistributions.TestUtils.test_abstract_membership.
See also
Convolved,Difference,Product: the concrete members.ConvolvedDistributions.TestUtils: the interface verifiers for a new subtype.
Fields
sourceConvolvedDistributions.AbstractSolverMethod Type
abstract type AbstractSolverMethodAbstract type for solver methods used in CDF/PDF computation.
Subtypes determine whether analytical solutions are preferred or numerical integration is forced.
See also
AnalyticalSolver: prefer closed forms, fall back to quadrature.NumericSolver: always use quadrature.
Fields
sourceConvolvedDistributions.AnalyticalSolver Type
struct AnalyticalSolver{S} <: ConvolvedDistributions.AbstractSolverMethodSolver that attempts analytical solutions when available, falling back to numerical integration.
Stores a numerical integration solver for use when no analytical solution exists for a given distribution pair.
See also
NumericSolver: force the quadrature path.GaussLegendre: the default fallback quadrature solver.
Fields
solver::Any: Fallback solver for when no analytical solution exists.
ConvolvedDistributions.Convolved Type
struct Convolved{C<:Tuple, M<:ConvolvedDistributions.AbstractSolverMethod} <: ConvolvedDistributions.AbstractConvolvedDistribution{Distributions.Univariate, Distributions.Continuous}Distribution of a sum of independent random variables (a convolution).
Convolved represents
Components may have negative support (for example a Normal capturing pre-symptomatic transmission timing); minimum and maximum are the sums of the component supports, taking the value
CDF computation
The CDF is computed by integrating one component out against the CDF of the others:
where
Where an analytical convolution is available (Distributions.convolve applies, e.g. Normal+Normal, equal-scale Gamma, equal-rate Exponential) the two-component result is taken directly from the convolved distribution unless a NumericSolver method is set. All other cases use AD-safe fixed-node Gauss-Legendre quadrature: the integral is mapped from the fixed reference domain gl_integrate), which lets every AD backend specialise on the integrand's own type so component Duals and tangents propagate.
The method field selects the CDF/PDF backend: an AnalyticalSolver (the default) uses the analytic convolution when one exists and falls back to quadrature otherwise, while a NumericSolver forces the numeric quadrature path even when an analytic convolution exists; the latter is useful for validation and debugging.
See also
convolved: Constructor function
Fields
components::Tuple: Tuple of independent component distributions to be summed.method::ConvolvedDistributions.AbstractSolverMethod: Solver method choosing the analytic vs numeric quadrature backend.
ConvolvedDistributions.DelayPMF Type
struct DelayPMF{V<:(AbstractVector), I<:Real}A precomputed discretised delay PMF, built once and reused across many vector evaluations.
DelayPMF holds the raw CDF-difference interval masses of a delay distribution on the grid [0, 1), [1, 2), ..., [m, m + 1) scaled by interval (where m is the maxlag it was built with), clamped at zero against numeric-CDF noise but never renormalised, so a single discretisation is shared across many series or lag lookups instead of being rebuilt per call.
Build it with discretise_pmf; apply it with convolve_series (the causal series convolution, unit grid only) or read masses at integer lags with pdf(pmf, lag). The object is immutable and carries no mutable cache: the masses keep the delay's parameter type, so the build and every reuse differentiate cleanly, and a parameter change is handled by building a fresh object.
See also
discretise_pmf: the build-once constructorconvolve_series: apply the PMF across a series
Fields
masses::AbstractVector: The discretised interval masses over the grid0..maxlag.interval::Real: The grid width the masses were discretised on.
ConvolvedDistributions.Difference Type
struct Difference{X<:(Distributions.UnivariateDistribution), Y<:(Distributions.UnivariateDistribution), M<:ConvolvedDistributions.AbstractSolverMethod} <: ConvolvedDistributions.AbstractConvolvedDistribution{Distributions.Univariate, Distributions.Continuous}Distribution of a difference of two independent random variables.
Difference represents X and Y are independent univariate distributions. It is the dual of Convolved (the sum X with the reflection of Y. Where a convolution gathers two delays into one longer gap, a difference is the signed gap between two events, so it arises as a derived observation (for example the offset between two independently timed measurements) rather than as a delay leaf.
Because the subtraction reflects Y, the support of Z is in general two-sided and can be negative: it runs from Z is therefore not a non-negative delay distribution; treat a Difference as an observation or derived quantity, not as a delay leaf.
Independence
The construction assumes X and Y are independent. The density, CDF, mean and variance below all rely on this; they are not correct for dependent components.
Density and CDF computation
The density is the cross-correlation of the two component densities:
and the CDF integrates X's CDF against Y's density:
For a Normal-Normal pair the closed form NumericSolver method is set. All other cases use AD-safe fixed-node Gauss-Legendre quadrature (gl_integrate), the same construction Convolved uses: the integral is mapped from the fixed reference domain Duals and tangents propagate.
The method field selects the backend: an AnalyticalSolver (the default) uses the analytic difference where one exists and falls back to quadrature otherwise, while a NumericSolver forces the numeric path even for a Normal-Normal pair (useful for validation).
See also
difference: Constructor functionConvolved: The dual sum
Fields
x::Distributions.UnivariateDistribution: The minuend component (theXinZ = X - Y).y::Distributions.UnivariateDistribution: The subtrahend component (theYinZ = X - Y).method::ConvolvedDistributions.AbstractSolverMethod: Solver method choosing the analytic vs numeric quadrature backend.
ConvolvedDistributions.GaussLegendre Type
struct GaussLegendre{R}Fixed-node Gauss-Legendre quadrature solver (the package default).
Integrates with a Gauss-Legendre rule of n nodes, evaluated as a bare weighted dot product (see gl_integrate). The constant control flow and the accumulator type being seeded from the integrand make this the AD-safe default: every supported AD backend can differentiate through it, unlike adaptive schemes whose node count depends on integrand values.
The reference nodes and weights are built once at construction and held on the solver, so the differentiated hot path is a pure weighted sum with no shared mutable state. This matters for trace-based reverse-mode backends (Enzyme, ReverseDiff): resolving the rule through a mutated global cache inside the integrand crashes Enzyme reverse, so the rule travels with the solver instead.
n = 64 is accurate to about 1e-13 on the smooth, density-weighted integrands used in this package. This is the core default and needs no heavy dependency. Load Integrals.jl and pass an Integrals.jl algorithm (e.g. QuadGKJL()) when adaptive accuracy is wanted and AD is not.
Examples
using ConvolvedDistributions
# A 64-node rule; integrate x^2 over [0, 1] (exact value 1/3)
solver = ConvolvedDistributions.GaussLegendre(; n = 64)
approx = ConvolvedDistributions.integrate(solver, x -> x^2, 0.0, 1.0)See also
gl_integrate: The underlying quadrature reduction.integrate: The pluggable entry point dispatching on a solver.
Fields
n::Int64: Number of Gauss-Legendre nodes.rule::Any: The reference Gauss-Legendre rule (nodes/weights on[-1, 1]).
ConvolvedDistributions.NumericSolver Type
struct NumericSolver{S} <: ConvolvedDistributions.AbstractSolverMethodSolver that always uses numerical integration.
Forces numerical computation even when analytical solutions are available, useful for testing and validation.
The solver field contains the numerical integration solver to use.
See also
AnalyticalSolver: the default, preferring closed forms.GaussLegendre: the default quadrature solver.
Fields
solver::Any: Numerical integration solver to use.
ConvolvedDistributions.Product Type
struct Product{X<:(Distributions.UnivariateDistribution), Y<:(Distributions.UnivariateDistribution), M<:ConvolvedDistributions.AbstractSolverMethod} <: ConvolvedDistributions.AbstractConvolvedDistribution{Distributions.Univariate, Distributions.Continuous}Distribution of a product of two independent random variables.
Product represents X and Y are independent univariate distributions with non-negative support. It is the multiplicative member of the family: where Convolved gathers two delays into one longer gap and Difference takes the signed gap between two events, a product scales one variable by another, as when a delay is stretched by an independent multiplicative factor.
Both components must satisfy minimum(d) >= 0; the constructor throws an ArgumentError otherwise. Sign-crossing supports are future work (they split the Mellin quadrature into positive and negative branches). The support of Z runs from
Independence
The construction assumes X and Y are independent. The density, CDF, mean and variance below all rely on this; they are not correct for dependent components.
Density and CDF computation
The density is the Mellin convolution of the two component densities:
and the CDF integrates X's CDF against Y's density:
evaluated numerically in the equivalent survival form Y's density diverges at zero (Gamma or Weibull shape below one).
For a LogNormal-LogNormal pair the closed form NumericSolver method is set. All other cases use AD-safe fixed-node Gauss-Legendre quadrature (gl_integrate), the same construction Convolved and Difference use: the integral is mapped from the fixed reference domain Duals and tangents propagate.
The method field selects the backend: an AnalyticalSolver (the default) uses the analytic product where one exists and falls back to quadrature otherwise, while a NumericSolver forces the numeric path even for a LogNormal-LogNormal pair (useful for validation).
See also
product: Constructor functionConvolved: The sumDifference: The signed gap
Fields
x::Distributions.UnivariateDistribution: The multiplicand component (theXinZ = X * Y).y::Distributions.UnivariateDistribution: The multiplier component (theYinZ = X * Y).method::ConvolvedDistributions.AbstractSolverMethod: Solver method choosing the analytic vs numeric quadrature backend.
ConvolvedDistributions.convolve_series Function
convolve_series(
delay::Distributions.Distribution{Distributions.Univariate, Distributions.Discrete},
series::AbstractVector{<:Real}
) -> AnyConvolve a timeseries with the PMF of a discrete delay distribution.
convolve_series(delay, series) for a DiscreteUnivariateDistribution delay reads the delay PMF directly off the integer lag grid — the lag-k mass IS pdf(delay, k) — and returns the causal discrete convolution of series with that PMF, truncated to the series window. With series the expected events at times 0, 1, ..., t (e.g. infections), the result is the expected downstream event counts at the same times (the EpiNow2-style latent / renewal observation layer).
The masses are [pdf(delay, k) for k in 0:(length(series) - 1)], used as given: no renormalisation, so any delay mass beyond the series window is truncated. pdf(delay, k) is differentiable in the delay parameters for the standard discrete families, so gradients flow under the supported AD backends.
Direct PMF evaluation, NOT a CDF difference: for an integer-support delay, pdf(delay, k) and never routes through discretise_pmf's CDF-difference masses.
Only the integer lags 0, 1, 2, ... are read. A delay with atoms off the integer grid is out of scope (a lag grid means masses at the integers), and mass at negative lags cannot enter a causal convolution, so lags below 0 are not read (consistent with the causal kernel).
For a CONTINUOUS delay there is no mass on the integer grid until it is discretised, and discretisation is an explicit modelling choice; that method throws — see below.
Unlike convolved, which combines distributions into a single Convolved distribution, this returns a numeric series; the separate verb keeps convolved strictly for distribution construction.
Arguments
delay: aDiscreteUnivariateDistribution(e.g.Poisson,DiscreteUniform, a shifted count delay).series: the input timeseries (expected events at unit-spaced times from 0).
Returns
- A numeric vector of expected downstream counts, the same length as
series.
Examples
using ConvolvedDistributions, Distributions
delay = Poisson(2.0)
infections = [0.0, 1.0, 3.0, 6.0, 8.0, 5.0, 2.0]
expected_counts = convolve_series(delay, infections)See also
convolved: the distribution-level convolutiondiscretise_pmf: discretise a continuous delay, then convolveconvolve_series(pmf, series): the PMF-vector form for caller-owned discretisation
convolve_series(
delay::Distributions.Distribution{Distributions.Univariate, Distributions.Continuous},
series::AbstractVector{<:Real}
)Reject a continuous delay: discretising it needs an explicit censoring scheme.
convolve_series(delay, series) for a ContinuousUnivariateDistribution (including a Convolved total delay) throws an ArgumentError. A continuous delay carries no mass on the integer lag grid until it is discretised, and there is more than one right way to do that: the naive CDF-difference scheme is interval-censored on the secondary event with an EXACT primary, whereas the usual epidemiological case (a primary event known only to the day) needs double interval censoring. Rather than pick one silently, the caller discretises first and passes the resulting PMF to convolve_series(pmf, series):
discretise_pmf(delay, maxlag)for interval-censored- secondary masses (exact primary), orCensoredDistributions.jl's double-interval-censored extension for day-binned primaries.
See also
discretise_pmf: the interval-censored-secondary discretisationconvolve_series(pmf, series): convolve a caller-supplied PMF
convolve_series(
pmf::AbstractVector{<:Real},
series::AbstractVector{<:Real}
) -> AnyConvolve a timeseries with a caller-supplied discretised delay PMF.
convolve_series(pmf, series) returns the causal discrete convolution of series with the probability masses pmf, truncated to the series window: out[i] = sum(pmf[k + 1] * series[i - k] for k in 0:(min(length(pmf), i) - 1)). pmf[k + 1] is read as the delay mass at integer lag k on the same unit grid as series.
The masses are used exactly as given: no renormalisation, no validation that they sum to one, and no tail correction — mass at lags beyond the series window (including any pmf entries past length(series)) is simply never used, so sub-normalised or window-truncated PMFs stay truncated. This is the decoupled form of convolve_series(delay, series): the caller owns the discretisation (e.g. double-interval-censored masses from CensoredDistributions.jl), and this method only convolves. The convolution is linear, so gradients flow through both pmf and series under the supported AD backends.
Arguments
pmf: the discretised delay probability masses at integer lags0, 1, 2, ...(used as given).series: the input timeseries (expected events at unit-spaced times from 0).
Returns
- A numeric vector of expected downstream counts, the same length as
series.
Examples
using ConvolvedDistributions
pmf = [0.5, 0.3, 0.2]
infections = [0.0, 1.0, 3.0, 6.0, 8.0, 5.0, 2.0]
expected_counts = convolve_series(pmf, infections)See also
discretise_pmf: build a reusableDelayPMFfrom a delay distribution
convolve_series(
pmf::ConvolvedDistributions.DelayPMF,
series::AbstractVector{<:Real}
) -> AnyConvolve a timeseries with a precomputed DelayPMF, reusing the build-once masses.
convolve_series(pmf, series) is the causal, window-truncated convolution of series with a PMF discretised once via discretise_pmf instead of rebuilt per call, so the result is numerically identical to discretising and convolving in one step. The series is interpreted on the PMF's own grid: entry i of series is the value at time (i - 1) * pmf.interval, and lag k shifts by k grid steps of that width. The grid width therefore comes from the discretisation the caller chose — a weekly-binned PMF convolves a weekly series — and no separate step argument exists to conflict with it.
Arguments
pmf: a precomputedDelayPMF; itsintervalis the grid the series is read on.series: the input timeseries, sampled at steps ofpmf.intervalfrom time 0.
Examples
using ConvolvedDistributions, Distributions
pmf = discretise_pmf(Gamma(2.0, 1.0), 6)
infections = [0.0, 1.0, 3.0, 6.0, 8.0, 5.0, 2.0]
expected_counts = convolve_series(pmf, infections)See also
discretise_pmf: build the PMF once
ConvolvedDistributions.convolved Function
convolved(
components::AbstractVector{<:Distributions.UnivariateDistribution};
method
) -> ConvolvedDistributions.Convolved{C, AnalyticalSolver{ConvolvedDistributions.GaussLegendre{ConvolvedDistributions._GL{Vector{Float64}, Vector{Float64}}}}} where C<:TupleCreate the distribution of a sum of independent delays (a convolution).
Accepts either two or more positional component distributions, or a single vector/tuple of components. Returns a Convolved distribution.
Arguments
components: Two or moreUnivariateDistributions, or a vector/tuple of them.
Keyword Arguments
method: The solver method, anAnalyticalSolver(the default) orNumericSolver.NumericSolverforces numeric quadrature even when an analytic convolution is available.
Returns
- A
Convolveddistribution of the sum of the components.
Examples
using ConvolvedDistributions, Distributions
# Sum of two delays
d = convolved(Gamma(2.0, 1.0), LogNormal(1.5, 0.5))
cdf_at_5 = cdf(d, 5.0)
# Sum of three delays from a vector
d3 = convolved([Gamma(2.0, 1.0), Gamma(1.0, 1.0), Normal(0.0, 1.0)])
mean_sample = rand(d3)
# Force numeric quadrature even for an analytic pair
dn = convolved(Normal(0.0, 1.0), Normal(1.0, 2.0);
method = NumericSolver())
cdf_numeric = cdf(dn, 2.0)See also
Convolved: The distribution type
ConvolvedDistributions.difference Function
difference(
x::Distributions.UnivariateDistribution,
y::Distributions.UnivariateDistribution;
method
) -> Difference{X, Y, AnalyticalSolver{ConvolvedDistributions.GaussLegendre{ConvolvedDistributions._GL{Vector{Float64}, Vector{Float64}}}}} where {X<:(Distributions.UnivariateDistribution), Y<:(Distributions.UnivariateDistribution)}Create the distribution of a difference of two independent variables.
Returns a Difference representing convolved: a convolution forms the sum of two delays, a difference the signed gap between two events. The support of Z can be negative, so Z is an observation or derived quantity rather than a non-negative delay leaf (see Difference).
X and Y are assumed independent.
Arguments
x: The minuend distribution (theXinZ = X - Y), aUnivariateDistribution.y: The subtrahend distribution (theYinZ = X - Y), aUnivariateDistribution.
Keyword Arguments
method: The solver method, anAnalyticalSolver(the default) orNumericSolver.NumericSolverforces numeric quadrature even for aNormal-Normalpair, mirroringconvolved.
Returns
- A
Differencedistribution of the signed gapZ = X - Y.
Examples
using ConvolvedDistributions, Distributions
# Difference of two delays; mean is the difference of the means (≈ 3)
d = difference(Normal(5.0, 1.0), Normal(2.0, 1.0))
mean(d)See also
Difference: The distribution typeconvolved: The dual sum
ConvolvedDistributions.discretise_pmf Function
discretise_pmf(
delay::Distributions.UnivariateDistribution,
maxlag::Integer;
interval
) -> ConvolvedDistributions.DelayPMF{V, Float64} where V<:(AbstractVector)Discretise a delay distribution to a DelayPMF once, for reuse across many series or lag lookups.
discretise_pmf(delay, maxlag; interval = 1.0) computes the raw CDF-difference interval masses of delay on the grid [0, 1), ..., [maxlag, maxlag + 1) (scaled by interval) and returns a precomputed DelayPMF to pass into convolve_series or pdf(pmf, lag). Building once and reusing avoids rediscretising the delay per series or per record.
The masses F(k + 1) - F(k) are the interval-censored-secondary scheme with an EXACT primary event: the probability the delay lands in day k given the primary happened at a precise instant. This is an explicit modelling choice, not a neutral default. When the PRIMARY is also known only to the day — the usual epidemiological case — the day-binned masses need double interval censoring, which is CensoredDistributions.jl's job (build those masses there and pass them to convolve_series(pmf, series)). Reach for discretise_pmf only when the exact-primary assumption is the one you want.
The masses are clamped at zero against numeric-CDF noise but never renormalised, so delay mass beyond maxlag stays truncated. They keep the delay's parameter type, so the discretisation differentiates w.r.t. the delay parameters; a parameter change is handled by calling discretise_pmf again (there is no stale cache).
Arguments
delay: the delay distribution to discretise (anyUnivariateDistribution, including aConvolvedtotal delay).maxlag: the largest integer lag to carry a mass for; the PMF hasmaxlag + 1entries.
Keyword Arguments
interval: the discretisation grid width (default1.0). The width travels with theDelayPMF:convolve_seriesreads the series on the PMF's own grid, andpdf(pmf, k)is the mass on[k * interval, (k + 1) * interval).
Returns
- A
DelayPMFholding themaxlag + 1interval masses and the grid width.
Examples
using ConvolvedDistributions, Distributions
delay = convolved(Gamma(2.0, 1.0), LogNormal(0.5, 0.4))
# Build the delay PMF once for a 30-step window.
pmf = discretise_pmf(delay, 30)
# Reuse it across many series without rediscretising.
infections = [0.0, 1.0, 3.0, 6.0, 8.0, 5.0, 2.0]
counts = convolve_series(pmf, infections)See also
DelayPMF: the precomputed-PMF objectconvolve_series: apply the PMF across a series
ConvolvedDistributions.gl_integrate Function
gl_integrate(f, lo, hi) -> Any
gl_integrate(
f,
lo,
hi,
rule::ConvolvedDistributions._GL
) -> AnyIntegrate a scalar function f over [lo, hi] by fixed-node Gauss-Legendre quadrature.
The reference domain [-1, 1] is mapped onto [lo, hi] inside the integrand and the result reduced as a weighted dot product, so the accumulator's element type is taken from the integrand and AD Duals and tangents propagate. Returns a typed zero when hi <= lo.
Arguments
f: The scalar integrand.lo: Lower integration bound.hi: Upper integration bound.rule: Gauss-Legendre rule to use (default: the 192-node convolution rule).
Returns
- The quadrature approximation of the integral, typed by the integrand (a typed zero when
hi <= lo).
Examples
using ConvolvedDistributions
# Integrate x^2 over [0, 1] (exact value 1/3)
approx = ConvolvedDistributions.gl_integrate(x -> x^2, 0.0, 1.0)See also
GaussLegendre: The default solver wrapping this rule.integrate: The pluggable entry point.
ConvolvedDistributions.integrate Function
integrate(
solver::ConvolvedDistributions.GaussLegendre,
f,
lower,
upper
) -> AnyIntegrate a scalar function f over [lower, upper] using solver.
This is the pluggable integration entry point: every integral in the package calls integrate, dispatching on the solver type. The default GaussLegendre solver routes to gl_integrate. Loading the optional Integrals.jl extension adds a method for Integrals.jl algorithms (e.g. QuadGKJL()), which builds an IntegralProblem and calls solve.
Arguments
solver: The integration backend.GaussLegendreby default; any Integrals.jl algorithm when that extension is loaded.f: The scalar integrand.lower: Lower integration bound.upper: Upper integration bound.
Returns
- The integral approximation computed by the chosen backend, typed by the integrand.
Examples
using ConvolvedDistributions
solver = ConvolvedDistributions.GaussLegendre(; n = 64)
approx = ConvolvedDistributions.integrate(solver, x -> x^2, 0.0, 1.0)See also
GaussLegendre: The default solver.gl_integrate: The default quadrature reduction.
ConvolvedDistributions.product Function
product(
x::Distributions.UnivariateDistribution,
y::Distributions.UnivariateDistribution;
method
) -> ConvolvedDistributions.Product{X, Y, AnalyticalSolver{ConvolvedDistributions.GaussLegendre{ConvolvedDistributions._GL{Vector{Float64}, Vector{Float64}}}}} where {X<:(Distributions.UnivariateDistribution), Y<:(Distributions.UnivariateDistribution)}Create the distribution of a product of two independent variables.
Returns a Product representing convolved sums two delays and difference takes their signed gap, a product scales one variable by an independent multiplicative factor. Both components must have non-negative support (minimum(d) >= 0); sign-crossing supports throw an ArgumentError and are future work.
X and Y are assumed independent.
Arguments
x: The multiplicand distribution (theXinZ = X * Y), aUnivariateDistributionwith non-negative support.y: The multiplier distribution (theYinZ = X * Y), aUnivariateDistributionwith non-negative support.
Keyword Arguments
method: The solver method, anAnalyticalSolver(the default) orNumericSolver.NumericSolverforces numeric quadrature even for aLogNormal-LogNormalpair, mirroringconvolved.
Returns
- A
Productdistribution of the productZ = X * Y.
Examples
using ConvolvedDistributions, Distributions
# A delay stretched by an independent multiplicative factor;
# the mean is the product of the means (≈ 3.3).
d = product(Gamma(3.0, 1.0), LogNormal(0.0, 0.3))
mean(d)See also
Product: The distribution typeconvolved: The sumdifference: The signed gap