Changelog
Source:NEWS.md
distspec 0.1.0
distspec 0.1.0 splits the <dist_spec> interface out of EpiNow2. The entries below are changes relative to that code as it stood in EpiNow2 1.9.0.
New features
- Distribution constructors now validate the structure of the object they build (class, parameters, and
max/cdf_cutoffattributes) and raise an informative error if it is malformed. - Added a
Beta()distribution (shape1/shape2, ormean/sd). - Added
Exponential()andWeibull()distributions. - Added
Dirichlet()and support for uncertain nonparametric distributions specified via a Dirichlet prior (NonParametric(pmf = Dirichlet(...))). - Added
sample_dist()to draw random samples from a distribution with fixed parameters. A composite distribution is sampled per component, returning annbykmatrix (rowSums()gives samples of the combined distribution). Distributions with uncertain (prior) parameters cannot be sampled and raise an error. - Added
has_uncertainty(), a predicate for whether a<dist_spec>(or a component of a composite) carries a prior, so dependent packages and internal code can test for uncertainty in one place. - Uncertainty in a distribution specified with non-natural parameters (e.g.
Gamma(mean = Normal(4, 0.5), sd = 1)) is now propagated to the natural parameters with a first-order delta-method approximation. This replaces an ad-hoc rule that understated the natural-parameter standard deviations several times over. -
discretise()gains aremove_trailing_zerosargument (defaultTRUE). - Exported the lower-level helpers
sd(),ndist(),natural_params()andlower_bounds()so that dependent packages can reuse them. -
natural_params()andlower_bounds()accept a distribution type given by name (e.g.natural_params("gamma")), as well as a<dist_spec>, so dependent packages can query type metadata without constructing an instance.
Breaking changes
- The package has been renamed from
dist.spectodistspec. - A distribution’s type is now carried in the S3 class of its
<dist_spec>(e.g.c("gamma", "dist_spec")), so per-type behaviour dispatches directly and each distribution’s methods live in one place. The internaldistributiondispatch class andnew_dist()have been removed. The internal helpersnatural_params()andlower_bounds()now take a<dist_spec>rather than a distribution-name string. -
get_parameters()is now an S3 generic. - The
cdf_cutoffargument (on the distribution constructors andbound_dist()) is the cumulative probability to keep up to:cdf_cutoff = 0.999truncates at the 99.9th percentile, and the default1keeps the full distribution. A value below0.5is rejected, as it is almost certainly the tail probability to drop (use1 - x).
Deprecations
-
Exp()is deprecated in favour ofExponential().
Bug fixes
-
NonParametric()andDirichlet(prior = )now reject a numeric PMF or weight vector that contains negative or non-finite values, or is all zero, with an informative error, instead of silently producing an invalid distribution. Un-normalised non-negative weights are still accepted and normalised, but now warn when they do not sum to one. - A distribution parameter given as a certain distribution (standard deviation 0, e.g.
Normal(x, 0), which collapses toFixed(x)) is now resolved to its point value at construction, so it behaves exactly like passing the number. Previously such a parameter left the distribution marked uncertain, somean()andsd()returnedNAfor an otherwise fully-fixed distribution (e.g.Gamma(shape = Normal(3, 0), rate = 2)). -
sd()of a nonparametric distribution now returns the standard deviation rather than the variance (a missing square root). This also affectssd()of any discretised distribution, sincediscretise()produces a nonparametric distribution. -
collapse()now correctly convolves runs of three or more consecutive nonparametric distributions, and runs that do not begin at the first component, rather than erroring or convolving the wrong component. - Convolution in
collapse()now uses a numerically stable implementation. -
bound_dist()now truncates a fixed nonparametric PMF atmaxwhen the PMF is longer thanmax + 1, renormalising the result, and leaves it untouched whenmaxreaches beyond the support. Previously the condition was inverted, so the bound never applied when requested and produced an all-NAPMF whenmaxexceeded the support. - Comparing two distributions with
==(or!=) no longer errors when a parameter is a numeric vector of length greater than one; such parameters are now compared as whole vectors. -
fix_parameters()anddiscretise()now forwardstrategyandremove_trailing_zerosto the components of a composite distribution, so these arguments are no longer silently ignored for composites. -
Fixed()distributions may now take a value of0; the lower bound for thevalueparameter has been corrected accordingly, and a value below that bound is now rejected with an informative error instead of silently producing an invalid probability mass function. - An uncertain (Dirichlet-backed) nonparametric distribution is now treated consistently as uncertain, storing its Dirichlet prior in place of a concrete PMF just as an uncertain parametric distribution stores a
dist_specfor a parameter. It has no PMF until resolved withfix_parameters():get_pmf()errors on such a distribution,mean()returnsNA(or the prior mean withignore_uncertainty = TRUE), and it prints with its prior nested like any other uncertain distribution. - Applying
maxorcdf_cutoffto an uncertain (Dirichlet-backed) nonparametric distribution now raises an informative error, since its support is fixed by the Dirichlet prior and the bound would otherwise be silently ignored. -
plot()gives an actionable error when asked to plot a distribution with no finite range (no finitemaxand nocdf_cutoff), pointing tobound_dist(), rather than a cryptic message or a silently chosen default range. -
mean()andsd()now emit an informative message when they returnNAbecause a distribution has uncertain parameters, pointing tomean(x, ignore_uncertainty = TRUE)andfix_parameters(). - Improved the error messages from
get_element()andget_parameters(): an out-of-rangeidnow reports the offending value and valid range, and the nonparametric error no longer implies that Weibull, Beta and Exponential distributions lack parameters.
Documentation
- Each distribution now has its own reference page (
Gamma(),LogNormal(), …) rather than a single combined page, so each shows only its own parameters. The reference index covers the full exported API, and thediscretise()help page documents how discretisation works, including the fixed point-mass special case. - Documentation improvements: the getting-started vignette now shows the end-to-end
get_pmf(collapse(discretise(d1 + d2)))pipeline for combining two delays into a single PMF, stale EpiNow2 and Stan references have been removed from the roxygen, and thebound_dist(),discretise(),fix_parameters()andsd()help pages have clearer descriptions and runnable examples.
Package changes
- Discretisation now uses the
primarycensoredpackage to compute double censored probability mass functions. -
natural_params()andlower_bounds()are now S3 generics, with each distribution’s behaviour defined alongside its type (in its ownR/file) rather than in scatteredswitch()/ifstatements.Gamma(),Normal(),LogNormal(),Exp(),Weibull(),Beta(),Fixed(), theDirichlet()prior and the nonparametric distribution now define their per-type behaviour (parameter metadata, andmean()/sd()/max()where applicable) this way. The internal per-distributionswitch()statements have been collapsed to direct S3 dispatch; attempting to discretise a distribution that has no CDF now reports this directly. - Internal idiomatic cleanups: switched the uncertain-parameter checks to the existing
has_uncertainty()predicate (removing a near-duplicate helper), threaded pre-computed parameter means throughto_natural()to avoid redundantlapply(x$parameters, mean)calls in every method, vectorised the attribute-copy loop indiscretise(), used%||%for null-default attribute guards, and extracted repeatedget_parameters()calls andsum(convolutions)into local variables. - Reduced dependencies: dropped
data.table,checkmateandpurrr, and movedggplot2toSuggests.plot()now prompts to installggplot2if it is missing, so it is no longer a hard dependency of the package.