Changelog

CHANGELOG

v2.0.0 (2026-08-10)

Completes the illness-death models. gen_cmm and gen_thmm previously reported only a subject’s first transition, which left the 2 -> 3 transition entirely absent from their output and several declared parameters with no effect. Both now emit the full trajectory, so their returned shape changes and the major version is incremented.

Breaking Changes

  • gen_cmm now returns counting-process records with columns id, start, stop, from_state, to_state, status, X0, replacing the previous id, start, stop, status, X0, transition frame. Subjects contribute two or three rows rather than one: while in state 1 a subject is at risk of both 1 -> 2 and 1 -> 3, so it gets a row for each over the same interval with status marking whichever occurred, and a subject reaching state 2 gets a further 2 -> 3 row.

  • The transition column is gone. It encoded the destination as an integer, and in the opposite sense to the R package’s trans codes, which made it easy to misread. from_state and to_state state the transition explicitly.

  • gen_thmm now returns the full state trajectory. Columns are unchanged (id, time, state, X0) but subjects contribute two or three rows instead of one: an entry observation in state 1 at time 0, then one observation per transition, or an observation in the occupied state at the censoring time.

  • Any code that assumed one row per subject from either generator needs to group by id.

Bug Fixes

  • gen_cmm ignored rate[4], rate[5] and beta[2]. It drew the 2 -> 3 sojourn time and discarded it, so a third of its declared parameters could be changed with no effect on the output whatsoever. All six rates and all three coefficients now reach the result.

  • gen_thmm ignored rate[2] and beta[2] for the same reason.

  • gen_cmm now resolves its seed through the shared RNG helper, so it accepts a numpy.random.Generator as well as an int, consistent with the other generators.

  • Tie handling in both generators now matches the R implementation, which treats a censoring time equal to the first transition time as an event.

Documentation

  • The CMM and THMM sections of the algorithms and theory pages now describe the emitted layouts, including why the two differ: gen_cmm returns transition intervals and gen_thmm returns states observed at times, mirroring genCMM and genTHMM in the R package. The 1.3.0 note recording the missing trajectory as a known limitation has been removed, since it is now fixed.

Testing

  • Added tests/test_multistate_schema.py with 21 structural tests: row counts per subject, both competing transitions being at risk over a shared interval, the 2 -> 3 row appearing exactly when illness was observed, the reset clock on entry to state 2, monotone trajectories, death being terminal, and direct guards that every rate and coefficient influences the output. The parameter-influence tests were confirmed to fail against the 1.3.0 code.

  • Replaced the two gen_cmm snapshot tests, which asserted exact values of the old one-row-per-subject frame, with reproducibility and schema tests.

v1.3.0 (2026-08-10)

A scientific-correctness release. Three of the fixes below change the numbers the simulators produce, so results generated with 1.2.0 or earlier are not comparable with results from this release.

Bug Fixes

  • The bivariate sampler produced the wrong distribution entirely. It mapped correlated normals to uniforms with u = 1 - exp(-z**2 / 2), which is the chi-squared(2) CDF applied to a chi-squared(1) variable. The composed transform reduced to z**2 / (2 * lambda), so a requested Exponential(1) marginal was really chi2(1) / 2 with mean 0.5 instead of 1.0. Replaced with the normal CDF, making this a correctly specified Gaussian copula with exact marginals.

  • Negative dependence was unreachable in the bivariate sampler. Squaring the normals mapped +r and -r onto the same positive dependence, so a requested correlation of -0.8 produced roughly +0.64. The sign is now preserved.

  • gen_tdcm was affected by both of the above, since it draws its covariates from that sampler.

  • The competing-risks generators fabricated events. When fewer than two distinct statuses appeared in a sample, both generators overwrote status[0] and status[1] with event labels, attaching events to subjects whose event times had not occurred. A cause that is absent from a finite sample is a valid stochastic outcome, so this post-processing has been removed.

  • gen_tdcm rejected its own documented signature. The docstring specified two coefficients and the model uses two, but validation required three and silently ignored the third, so the documented call raised LengthError. Two are now accepted; three still work but emit a DeprecationWarning.

Breaking Changes

  • Event times, covariates and statuses differ from 1.2.0 for gen_tdcm, sample_bivariate_distribution, gen_competing_risks and gen_competing_risks_weibull. This is the point of the release, but it does mean any stored 1.2.0 output should be regenerated.

  • scipy is now a declared runtime dependency. It was already installed as a transitive dependency of lifelines, so this should not change resolution.

  • The PyPI maturity classifier moves from 5 - Production/Stable to 4 - Beta. A package that has just corrected the marginal distribution and the dependence sign of one of its core samplers is not accurately described as production-stable, and known correctness gaps remain: CMM and THMM report only the first transition rather than a full trajectory, and the CLI cannot drive every registered generator. The classifier is intended to return to 5 - Production/Stable once the multistate output schema lands.

Features

  • Unified the RNG contract. sample_bivariate_distribution, gen_tdcm and gen_thmm drew from the global NumPy random state and could not be seeded; gen_thmm had no seed parameter at all. All three now accept seed, which may be an int, a numpy.random.Generator for sharing one stream across simulators, or None. No simulator touches the global state.

  • Censoring draws in gen_tdcm and gen_thmm now share the caller’s generator rather than creating an unseeded one, so a single seed reproduces a whole dataset.

Documentation

  • THMM was documented as a Hidden Markov Model, which it is not. The name means Time-Homogeneous Markov Model. The docs additionally described latent states with Gaussian emissions, none of which exists in the implementation. Rewritten to describe the three-state model with constant transition intensities that the code actually simulates, and re-cited to Andersen et al. instead of an HMM textbook. The known limitation that only the first transition is emitted is now stated explicitly.

Testing

  • Added tests/test_statistical_correctness.py: Kolmogorov-Smirnov tests for the exponential and Weibull marginals, moment checks, a dependence-sign test, a monotonicity test, a Spearman check against the Gaussian copula identity, no-fabrication tests for competing risks, and seed-reproducibility plus global-state-independence tests for every affected generator. Each was confirmed to fail against the 1.2.0 code.

  • Replaced two tests that asserted the fabricated competing-risks statuses as required behaviour, and removed a property-based assertion that every sample must contain at least two distinct statuses, which is not a property the model guarantees.

v1.2.0 (2026-08-10)

Breaking Changes

  • Python 3.10 is no longer supported; the minimum supported version is now 3.11. This is required by the current numpy (>=2.3) and lifelines (>=0.30) releases, neither of which ships for 3.10.

  • Removed the dev extra. It declared Provides-Extra: dev with no dependencies behind it, so pip install gen-surv[dev] never actually installed anything. Use poetry install --with dev for development, or pip install scikit-survival for the optional scikit-survival integration.

Features

  • Added official support for Python 3.13; CI now tests 3.11, 3.12 and 3.13.

Bug Fixes

  • Raised the lifelines floor to 0.30.3. Earlier releases crash in add_at_risk_counts under numpy 2.x with TypeError: only 0-dimensional arrays can be converted to Python scalars, which broke every survival-curve and covariate-effect plot.

  • Made optional dependencies lazy, normalized identifier handling and stabilized the test suite (#116).

Continuous Integration

  • Fixed dependency resolution, which failed for every job because the declared Python floor (3.10) was incompatible with the pinned numpy and lifelines constraints.

  • Dropped the scripts/check_version_match.py steps and the bump-version workflow. The script had been deleted in #86/#90, so all three workflows referencing it failed. Release tags are now created manually.

Misc

  • Added Zenodo metadata.

  • Updated dependency constraints (numpy, pandas, matplotlib, pyarrow, typer, click) and refreshed pinned GitHub Actions.

v1.0.9 (2025-08-02)

Features

  • export datasets to RDS files

  • test workflow runs on a Python version matrix

  • scikit-learn compatible data generator

  • compatibility helpers for lifelines and scikit-survival

Documentation

  • updated usage examples and tutorials

  • document optional scikit-survival dependency throughout the docs

Continuous Integration

  • auto-tag releases using the version check script

Misc

  • README quick example uses covariate_range

v1.0.8 (2025-07-30)

Documentation

  • ensure absolute path resolution in conf.py

  • drop unsupported theme option

  • define bibliography anchors and headings

  • fix tutorial links to non-existing docs

  • add additional references to the bibliography

Testing

  • add CLI integration test

  • expand piecewise generator test coverage

Misc

  • remove fix_recommendations.md

v1.0.0 (2025-06-06)

Misc

  • Align pyproject version with GitHub tag

  • Add project Code of Conduct

v0.7.1 (2025-04-13)

Bug Fixes

Chores

Documentation

  • Add mathematical foundations page for all survival models (8472ff1)

  • Add roadmap for advanced survival models and extend TODO (1990109)

  • Add usage examples for all models in index.md (57c5fb0)

  • Fix version number in pyproject (6cff868)

v0.7.0 (2025-04-12)

Chores

Features

  • docs: Document generic interface generate() and update examples (55e22a4)

v0.6.1 (2025-04-12)

Bug Fixes

Chores

Documentation

v0.6.0 (2025-04-12)

v0.5.0 (2025-04-12)

Features

  • Add documentation to readthedocs (1b00d74)

v0.4.0 (2025-04-12)

Bug Fixes

Chores

Features

  • Add documentation to readthedocs (d1a0d29)

  • Add documentation to readthedocs (78eb448)

v0.3.1 (2025-04-12)

Bug Fixes

Chores

Features

  • Add documentation to readthedocs (c33f666)

v0.3.0 (2025-04-12)

Bug Fixes

Chores

v0.2.1 (2025-04-12)

v0.2.0 (2025-04-12)

v0.1.0 (2025-04-12)

Bug Fixes

Chores

Continuous Integration

  • Add GitHub Actions workflow for test automation (0d57884)

  • Add GitHub Actions workflow for test automation (33e1e40)

Documentation

  • Add Sphinx configuration with Markdown support and index.md setup (75d4653)

  • Add Sphinx documentation with MyST and autodoc integration (f58feea)

Features

  • Add changelog automation (055c209)

  • Add changelog automation (f22aba7)

  • Implement core CPHM data simulation with validation and censoring models (f5ef282)

  • Implement THMM data generator and finalize full model suite (1e667ba)