Faster core training: the per-sample k-nearest-coding-vector search now reuses the distances already computed for the quantization step instead of recomputing them and copying the active codebook on every sample. Embeddings are unchanged (bit-identical).
predict() and the codebook-graph plotting paths (plot() / autoplot()) are vectorized.
Bug fixes
autoplot() no longer errors for type = "codebook" or type = "graph" when color_by has input-point length; like plot(), it now maps the labels to coding vectors.
The UMAP dispersion step now winsorizes the embedding before building the UMAP init, so a single drifted coding vector can no longer dominate the min-max scaling and strand its points as a far outlier. This removes occasional outliers and improves cluster separation (e.g. Fashion-MNIST reproduction AMI 0.50 -> 0.55). Only the dispersion = TRUE path is affected; the core SONG embedding is unchanged.
The UMAP dispersion now uses a stronger refinement (200 epochs, learning rate 1.0, min_dist = 0.1) instead of the reference’s very gentle 11-epoch step. songR’s raw embedding is more collapsed than the reference’s on hard, multi-class data, and the gentle step left it stranded near one axis; the stronger refinement makes the embedding use the full plane and, in benchmarks, improves AMI on every tested dataset (MNIST, Fashion-MNIST, COIL-20, Samusik, Wong). Only the dispersion = TRUE visualization changes; the core SONG embedding stays frozen.
The Shiny comparison app no longer claims SONG stops training early, and its documented k and epochs defaults match the implementation.
All user-facing messages now use cli, with errors signalled at the calling function for clearer tracebacks. Messages and behavior are otherwise unchanged.
Verification
Added reference-parity tests against the original Python implementation (tests/testthat/test-reference-parity.R), covering deterministic kernels (Tier A, ≤ 1e-5) and clustering equivalence (Tier B, AMI).
songR 0.1.0
Core Features
Core SONG algorithm implemented in C++ via RcppArmadillo.