This minor release extends the L (lower truncation) parameter to accept negative and -Inf values in both the R and Stan code, letting delay distributions with support below zero (e.g. normal, logistic, Cauchy, Gumbel) be used with primary censoring and fitted via fitdistdoublecens() and pcd_cmdstan_model(). The default value of L has changed from 0 to -Inf, which leaves results unchanged for distributions with non-negative support (e.g. lognormal, gamma, Weibull). It also fixes a normalisation bug in the exponential growth primary distribution and rewrites the analytical CDFs in a CDF-direct form, dropping the pracma dependency.
L in pprimarycensored(), dprimarycensored(), qprimarycensored(), rprimarycensored(), and pcens_quantile() has changed from 0 to -Inf. fitdistdoublecens() now treats a missing L column as L = -Inf to match. For delay distributions with support on the non-negative reals (e.g. lognormal, gamma, Weibull) F_cens(0) = 0, so the new default leaves results unchanged. Callers that relied on the implicit left truncation at 0 (for example to truncate signed-support delays such as pnorm) must now pass L = 0 explicitly (or add an L column in fitdistdoublecens()). (#267)L may now be negative or -Inf in pprimarycensored(), dprimarycensored(), qprimarycensored(), and rprimarycensored(). This lets delay distributions with support below zero (e.g. normal, logistic, Cauchy) be used with primary censoring. L = -Inf is the sentinel for "no left truncation"; any finite L left-truncates the distribution at L. (#267)pcd_as_stan_data() mirror the R-side handling of L: negative and -Inf values are accepted, and a missing start_relative_obs_time column defaults to -Inf. pcd_cmdstan_model() now accepts negative observed delays and fully-negative truncation windows, letting distributions with support on the reals (e.g. logistic, Cauchy, Gumbel) be fitted. (#313)dist_id upper bound in pcens_model.stan has been raised from 17 to 25, exposing every delay distribution that dist_lcdf already dispatches (Normal, Double Exponential, Pareto, scaled inverse chi-square, Student's t, Uniform, von Mises) through pcd_cmdstan_model(). (#314)fitdistdoublecens() and pcd_cmdstan_model() from doubly-censored, right-truncated samples that include negative observed delays.dexpgrowth(), pexpgrowth(), and their Stan equivalents (expgrowth_pdf, expgrowth_lpdf, expgrowth_cdf, expgrowth_rng) when min is non-zero.
The PDF and CDF formulas contained a stray exp(-r * min) factor from using exp(r * (x - min)) instead of exp(r * x).
The Stan RNG had a compensating xmin + offset.
The bug did not affect results when min = 0 (the default and only value used within the package's primary censoring functions).
Thanks to @TimTaylor for reporting (#290).q = 0 and q > 0 code paths (single algebraic expression, better for NUTS), the outer log_diff_exp ordering is now mathematically guaranteed, and the Gamma case uses the incomplete-gamma recursion $P(k{+}1, y) = P(k, y) - y^k e^{-y}/\Gamma(k{+}1)$ to halve gamma_lcdf evaluations. Behaviour and tests are unchanged.pracma::gammainc with stats::pgamma in the Weibull g() helper, dropping the pracma dependency. The previous pwindow > 3 fallback to numeric integration (and the internal overflow guard) is no longer needed — the base R implementation is stable across the full parameter range. Closes #127.This major release adds left-truncation support via the L parameter, enabling distributions to be truncated over [L, D] rather than just [0, D]. It also removes deprecated functionality that was soft-deprecated in version 1.1.0 and removes the lifecycle and rlang packages from dependencies.
pdist_name and dprimary_name arguments from pprimarycensored(), dprimarycensored(), new_pcens(), and fitdistdoublecens(). Use add_name_attribute() on the pdist and dprimary functions instead to enable analytical solutions.pwindow and D arguments in fitdistdoublecens(). These must now be column names in censdata.lifecycle and rlang packages from dependencies.L parameter before D in their signatures. If you were using positional arguments for D (e.g., pprimarycensored(x, pdist, pwindow, 10)), you must now use named arguments (e.g., pprimarycensored(x, pdist, pwindow, D = 10)). The affected functions are dprimarycensored(), pprimarycensored(), rprimarycensored(), and qprimarycensored(). (#63)L parameter for lower truncation, placed before D. This affects primarycensored_lpmf, primarycensored_lcdf, primarycensored_cdf, primarycensored_pmf, and all vectorized variants. Update your Stan code to include the new parameter: primarycensored_lpmf(d | dist_id, params, pwindow, d_upper, L, D, primary_id, primary_params). (#63)dependencies argument to pcd_load_stan_functions() that automatically resolves and includes all functions that the requested functions depend on. When TRUE, dependencies are included in topological order (dependencies before functions that use them). (#171)pcd_stan_function_deps() to query the dependency graph of Stan functions, returning all dependencies for a given function in topological order. (#171)pcd_distributions that were previously only available in Stan: normal, inverse chi-square, double exponential, pareto, scaled inverse chi-square, student t, uniform, and von Mises (IDs 18–25). These are now accessible via pcd_stan_dist_id(). (#277)L parameter to all primary censored distribution functions (dprimarycensored(), pprimarycensored(), rprimarycensored(), qprimarycensored()) and Stan functions. The L parameter specifies the minimum delay (lower truncation point), enabling distributions to be truncated over [L, D] rather than just [0, D]. This is useful for generation intervals and other settings where delays below a threshold cannot occur. Defaults to L = 0 for backward compatibility. (#63)expgrowth_lpdf Stan function to support negative growth rates. Previously, log(r) returned NaN for r < 0. Now uses log(abs(r)) and log(abs(...)) for the denominator. (#276)dist_lcdf distribution ID mapping to match R's pcd_distributions table. Previously, most distribution IDs were mismatched between R and Stan (e.g. pcd_stan_dist_id("weibull") returned 3 but Stan's dist_lcdf used ID 3 for the Normal distribution). Only lognormal (1), gamma (2), and exponential (4) were correct. This affected the ODE numerical integration path for all mismatched distributions. (#277)min and max parameters to xmin and xmax in Stan functions (expgrowth_pdf, expgrowth_lpdf, expgrowth_cdf, expgrowth_lcdf, expgrowth_rng, primary_lpdf) to avoid conflicts with Stan built-in functions. CmdStan 2.38.0 now strictly enforces reserved keyword restrictions when exposing Stan functions to R. (#258)This minor release improves documentation for fitdistdoublecens() and adds learning objective sections to vignettes. It also fixes floating-point precision issues in dprimarycensored() and adds bounds checking to CDF methods.
fitdistdoublecens():
@details sections explaining how distribution names are resolved (e.g., "gamma" uses dgamma() and pgamma()), and what the function does internally.distr parameter documentation with examples and guidance on custom distributions.pcd_as_stan_data() and fitdistdoublecens() correctly handle data frames with additional columns beyond those required. (#213)dprimarycensored() could return very small negative values (e.g., -2.2e-16) due to floating-point precision when computing PMF as CDF differences. PMF values are now clamped to be non-negative. (#238)pcens_cdf() methods to ensure CDF values are always in [0, 1], complementing the existing upper bound check with a lower bound check.This minor release adds quantile functions for primary censored distributions and enhances the fitdistdoublecens() function to support varying primary censoring windows and truncation times. The release also improves documentation, particularly the Stan reference, making it easier for users to navigate and work with the Stan code.
pcens_quantile(): Core implementation using numerical optimisation to find
quantiles by inverting the CDF. The implementation allows for analytical
solutions to be added in future versions using the same interface as pcens_cdf().qpcens() and qprimarycensored(): Convenient wrapper functions that provide
alternative interfaces to pcens_quantile().fitdistdoublecens() to allow for varying primary censoring windows and truncation times. As part of this refactor the interface has also been improved to allow for more flexible data input.fitdistrplus vignette to use more complex data where the relative observation time is not constant. Also removed the note that the fitdistdoublecens() function is limited to a single primary censoring windows and truncation time as this is no longer the case.This minor release improves the documentation and the internal system used to automatically discover analytical solutions. It also adds lookups for supported supported distributions and tooling for working with these lookups. This makes it easier for package developers using primarycensored and also makes it easier to work with the Stan likelihood functions by improving the discoverability of the distribution functions. Minor bugs were also fixed.
epidist.pdist_name and dprimary_name arguments throughout. Users wishing to pass distribution names (i.e. to potentially leverage analytical solutions) are advised to use the newly introduced add_name_attribute() function. Adds transient dependency on lifecycle and rlang packages. See #188 by @pearsonca.pcd_stan_dist_id() to allow for discovery of distribution IDs for Stan models.pcd_dist_name() to allow for discovery of distribution names for R functions as needed for add_name_attribute().methods(pcens_cdf) to find analytical solutions.pcd_distributions and pcd_primary_distributions to document the distributions supported by primarycensored.primarycensored_lcdf().@family tag to the pcens functions. This omission resulted in the Weibull analytical solution not being visible in the package documentation.primarycensored_cdf() stan function, avoiding errors on some platforms due to narrowing conversions in aggregate initialisation.D to be of type real in pcens_model.stan in order to support infinite relative_obs_time.num_elements() over size() in all stan code to resolve compilation issues on some platforms as reported by @sbfnk.This is the first major release of primarycensored and has been submitted to CRAN.
primary_lpdf.rhub checks to the Github Actions workflow.dependencies: "hard" to the R-CMD-check workflow to ensure checks pass without optional dependencies.This release renames the package to primarycensored from primarycensoredist and also renames many of the functions to remove the dist in their name. This was done to make the package name and the functions more consistent and to remove the need to use the dist suffix. It also aligns it with the new PrimaryCensored.jl package in our Julia ecosystem.
Aside from name changes, this release also adds an analytical solution for the weibull distribution with uniform primary censoring, removes the need to assign functions to the global environment for fitdistdoublecens() by using withr, and adds a check_truncation() function to check if the truncation time is larger than the maximum observed delay. This is used in fitdistdoublecens() and pcd_as_stan_data() to ensure that the truncation time is appropriate to maximise computational efficiency.
fitdistdoublecens() by using withr.check_truncation() function to check if the truncation time is larger than the maximum observed delay. This is used in fitdistdoublecens() and pcd_as_stan_data() to ensure that the truncation time is appropriate to maximise computational efficiency.pcd_as_cmdstan_data() has been renamed to pcd_as_stan_data() to better reflect that it is used for Stan models in general rather than just the CmdStan models.stan folder and the stan model has been moved into the stan folder. All paths to the stan code have been updated to reflect this.primarycensored as have all functions that use "dist" in their name.pdist, dprimary, rdist, and rprimary arguments in the getting started vignette to make it easier to link to mathematical details.This release adds a new {touchstone} based benchmark suite to the package. It also adds a new "How it works" vignette which aims to give the reader more details into how the primary censored distributions work.
As part of the "How it works" we (@SamuelBrand1) found analytical solutions for the gamma, lognormal, and weibull distributions with uniform primary censoring. These are now implemented for the lognormal and gamma distributions in the R and stan code providing significant speedups to the fitting process (~10-20 times faster). The Weibull will be added in the next release.
{touchstone} based benchmarks for benchmarking R utility functions, and fitting the stan and fitdistplus models.primarycensored S3 class.R and stan code.In this release, we have added a new package stan model for fitting distributions using the cmdstanr package. We have also added a new function fitdistdoublecens() to allow for fitting of double censored and truncated data using the fitdistrplus package. As well as these functionality improvements this release focuses on improving the stability of the stan model and improving the speed of the primarycensored_ode function.
fitdistdoublecens() to allow for fitting of double censored and truncated data using the fitdistrplus package.primarycensored_ode function.CmdStan model for fitting distributions using the cmdstanr package.CmdStan model and added an example to the vignette.CmdStan model which tests the primarycensored_lpmf function when used with NUTS based fitting.This release fixes and improves truncation handling across the code base. It also adds a new vignette showcasing how to use the primarycensored and fitdistrplus packages together to fit distributions.
primarycensored_lpmf when used for NUTS based fitting (i.e. in Stan).primarycensored and fitdistrplus packages together to fit distributions.This release puts in place initial documentation and vignettes. It also includes a new primary censored distribution interface to allow for non-secondary event censored distributions. Development of this release as identified some numerical issues in the
gradient evaluations for the primary censored distributions which may lead to breaking
interface changes in 0.3.0 for the Stan code.
swindow = 0 to rprimarycensored to allow for non-secondary event censored distributions.rprimarycensored so that truncation is based on the primary censored distribution before secondary events are censored. This better matches the generative process.cmdstanr.cmdstanr package.This is the initial primarycensored release and includes R and stan tools for dealing with potentially truncated primary event censored delay distributions. We expect all current features to work but the UI may change as the package matures over the next few versions.
0.2.0 release.