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_cmmnow returns counting-process records with columnsid,start,stop,from_state,to_state,status,X0, replacing the previousid,start,stop,status,X0,transitionframe. Subjects contribute two or three rows rather than one: while in state 1 a subject is at risk of both1 -> 2and1 -> 3, so it gets a row for each over the same interval withstatusmarking whichever occurred, and a subject reaching state 2 gets a further2 -> 3row.The
transitioncolumn is gone. It encoded the destination as an integer, and in the opposite sense to the R packageβstranscodes, which made it easy to misread.from_stateandto_statestate the transition explicitly.gen_thmmnow 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_cmmignoredrate[4],rate[5]andbeta[2]. It drew the2 -> 3sojourn 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_thmmignoredrate[2]andbeta[2]for the same reason.gen_cmmnow resolves its seed through the shared RNG helper, so it accepts anumpy.random.Generatoras well as anint, 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_cmmreturns transition intervals andgen_thmmreturns states observed at times, mirroringgenCMMandgenTHMMin 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.pywith 21 structural tests: row counts per subject, both competing transitions being at risk over a shared interval, the2 -> 3row 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_cmmsnapshot 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 toz**2 / (2 * lambda), so a requested Exponential(1) marginal was reallychi2(1) / 2with 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
+rand-ronto the same positive dependence, so a requested correlation of-0.8produced roughly+0.64. The sign is now preserved.gen_tdcmwas 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]andstatus[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_tdcmrejected 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 raisedLengthError. Two are now accepted; three still work but emit aDeprecationWarning.
Breaking Changesο
Event times, covariates and statuses differ from 1.2.0 for
gen_tdcm,sample_bivariate_distribution,gen_competing_risksandgen_competing_risks_weibull. This is the point of the release, but it does mean any stored 1.2.0 output should be regenerated.scipyis now a declared runtime dependency. It was already installed as a transitive dependency oflifelines, so this should not change resolution.The PyPI maturity classifier moves from
5 - Production/Stableto4 - 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 to5 - Production/Stableonce the multistate output schema lands.
Featuresο
Unified the RNG contract.
sample_bivariate_distribution,gen_tdcmandgen_thmmdrew from the global NumPy random state and could not be seeded;gen_thmmhad noseedparameter at all. All three now acceptseed, which may be anint, anumpy.random.Generatorfor sharing one stream across simulators, orNone. No simulator touches the global state.Censoring draws in
gen_tdcmandgen_thmmnow 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) andlifelines(>=0.30) releases, neither of which ships for 3.10.Removed the
devextra. It declaredProvides-Extra: devwith no dependencies behind it, sopip install gen-surv[dev]never actually installed anything. Usepoetry install --with devfor development, orpip install scikit-survivalfor 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
lifelinesfloor to 0.30.3. Earlier releases crash inadd_at_risk_countsunder numpy 2.x withTypeError: 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
numpyandlifelinesconstraints.Dropped the
scripts/check_version_match.pysteps and thebump-versionworkflow. 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.pydrop 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ο
Fix import (
3cdb59a)
Choresο
Documentationο
v0.7.0 (2025-04-12)ο
Choresο
Update documentation (
d34e32f)
Featuresο
docs: Document generic interface
generate()and update examples (55e22a4)
v0.6.1 (2025-04-12)ο
Bug Fixesο
Fix pyproject toml (
a06f58a)
Choresο
Fix readme (
f4897cd)
Documentationο
Docs (
75417f1)
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ο
Fix codecoverage (
16bc525)
Choresο
Featuresο
v0.3.1 (2025-04-12)ο
Bug Fixesο
Bump version (
5cc649d)
Choresο
Featuresο
Add documentation to readthedocs (
c33f666)
v0.3.0 (2025-04-12)ο
Bug Fixesο
Fix git hub actions (
c9559ba)
Choresο
Bump version (
e111826)