Leiden 0.7.0 - #7
Merged
Merged
Conversation
publish.yml fired on every push to main as well as on tags, with no test job in front of it — so any commit bumping the version published it. crates.io versions can be yanked but never replaced. Now tags only, behind fmt/clippy/tests, a tag-vs-Cargo.toml version check and a cargo package dry run. The publish step sits in a `crates-io` environment so a required reviewer can be added for a manual confirm. ci.yml runs the core with --no-default-features (fmt, clippy, tests in debug and release), the kNN feature separately so an hnsw breakage doesn't take the core red, and cargo-semver-checks. Also gitignore /data, which holds downloaded h5ad fixtures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0.6.1 produced wrong, irreproducible clusterings, quadratically slowly. Six distinct bugs, each now with a regression test: - aggregate() halved the degree sum, because a self-loop added its weight once instead of twice to strength — the null model was off above level 0 - the RB null term divided by 2m instead of 4m, so resolution meant 2x what it does in scanpy/leidenalg - candidates were iterated out of a HashSet, so seed: Some(42) still drifted - the "only singletons may merge" guard in refinement hung off the wrong statement, losing the internal-connectivity guarantee - diff_move was O(n) per call rather than O(degree) - n_iterations and tolerance were dead config fields Rewritten: Partition keeps every aggregate incrementally in O(1) per move; NeighborWeights replaces the per-call HashSet and get_group_members allocation; Objective is a trait over RB and CPM; local moving is queue-based remove-then-insert; refinement matches libleidenalg's semantics with the randomised selection from the paper. Storage went to u32 ids and f32 weights (16 bytes per undirected edge), plus a zero-copy from_csr_parts that takes a connectivity matrix without a copy. 20k nodes: 44.1s -> 18ms. 1M: 1.75s. 8M: 20.1s. 1.33x faster than igraph native on synthetic graphs, 2.5-3x on pbmc3k. Modularity is within noise of leidenalg (-0.09% mean single-seed over 160 committed fixtures) and on pbmc3k matches the author cell types as well as scanpy does (ARI 0.8599 vs 0.8609). Verification is five independent layers: invariants, known answers, differential fixtures generated from leidenalg and committed, exhaustive brute-force optimality on small graphs, and randomised property tests. 90 tests. Drops the petgraph dependency and puts the kNN stack behind a default-on feature so the core builds where hnsw does not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
some old performance improvements i had lying around