All notable changes to this project are documented here. The format is loosely
based on Keep a Changelog, and the project follows
Semantic Versioning. The three published artifacts —
the nj crate (crates.io), nj_py (PyPI), and @holmrenser/nj (npm) — share a
single version, bumped together via make bump-{patch,minor,major}.
- Among-site rate-variation corrections for the distance models: a gamma
rate-heterogeneity shape parameter (
gamma_shape, Jin & Nei 1990) and a proportion of invariant sites (p_invar). For distance methods both are exact closed-form corrections to each model's−ln(...)step, so no discrete rate categories are needed; they apply to every correctable model (JukesCantor,Kimura2P,TajimaNei,Tamura,Poisson,KimuraProtein) and compose as+I+Γ. The gamma correction converges back to the uncorrected model as the shape parameter grows;PDiff(raw p-distance) is unaffected. Exposed across the CLI (-g/--gamma-shape,-i/--p-invar), Python, and WASM bindings, withNJError::InvalidGammaShape/NJError::InvalidPInvarfor out-of-range values. - Three substitution models:
TajimaNei(Tajima-Nei 1984, DNA — corrects Jukes-Cantor for unequal base frequencies),Tamura(Tamura 1992, DNA — Kimura two-parameter with a GC-content correction), andKimuraProtein(Kimura 1983, protein — empirical correction to the Poisson distance). All are closed-form and reduce to the model they extend under the appropriate conditions (Tajima-Nei → Jukes-Cantor at equal frequencies, Tamura → Kimura-2P at GC = 0.5). Exposed across the CLI, Python, and WASM bindings.
- Protein sequences are now encoded case-insensitively; lowercase residues were
previously mapped to
X, silently corrupting protein alignments. - Newick output now single-quotes identifiers containing whitespace or reserved
characters (
()[]{}',:;), producing valid Newick for names with spaces, etc. - Bootstrap replicate failures now propagate as errors instead of panicking a worker thread.
- New
simdCargo feature providing an explicitcore::simddistance kernel (~5-7x faster distance computation). It requires a nightly toolchain (unstableportable_simd); published wheels enable it, while crate/source builds fall back to the autovectorized scalar path on stable. - Duplicate sequence identifiers are rejected with
NJError::DuplicateIdentifier(they previously corrupted bootstrap clade counting). - A
Warninglog event is emitted for all-gap sequences (whose distances are 0). - Language bindings surface error kind: Python raises
ValueErrorfor usage errors andRuntimeErrorfor internal failures; WASM throws anErrorwhosenameis the stable error code. Failing user callbacks are logged rather than silently dropped. - Criterion benchmarks (
make bench) and proptest property + golden-tree tests. scripts/check-versions.shand a CI job that verify the three package versions stay in sync.SequenceObject::is_empty()companion tolen().
- The
clifeature now impliesparallel, so the installednjbinary runs bootstrap and distance computation multi-threaded by default; the bare library stays Rayon-free unlessparallelis requested. Cap workers with-t/--num-threads. - Python wheels are built once per platform as a stable-ABI (
abi3-py310) wheel covering CPython 3.10+, replacing the per-minor-version build matrix.
See the Git tag history (git tag) and the GitHub releases page for prior
versions.