Segment — recurrence, lag, and Laplacian structure
segment turns a feature matrix into structure: self-similarity (recurrence) and
cross-similarity graphs, the recurrence↔lag shear, temporally-constrained agglomerative
boundaries, and the full McFee-Ellis Laplacian spectral segmentation built on top of
them. It is the structural-analysis layer that the segmentation demo surfaced, and it is
where pleco-xa’s linalg and
cluster primitives earn their keep.
Recurrence, the recurrence↔lag conversions, and agglomerative boundaries are fixture-gated
in CI (dtw_segment.json, case 2): connectivity exact, affinity toleranced,
lag exact, boundary frames exact.
Key functions
Section titled “Key functions”Verified against the built barrel (segment namespace):
recurrenceMatrix(data, opts)→(t, t)self-similarity. Modes'connectivity'/'distance'/'affinity';sym: truekeeps mutual nearest neighbours.crossSimilarity(data, dataRef, opts)→(n_ref, n)graph from one sequence into a reference.recurrenceToLag(rec, opts)/lagToRecurrence(lag)— the real time-lag shear (lag[i][j] = rec[(i + j) mod H][j]) and its inverse.agglomerative(data, k, opts)→Uint32Arrayof left-boundary frame indices (always starts with 0); greedy Ward merges of adjacent segments.laplacianSegmentation(features, opts)→{ segmentIds, boundaries }; McFee-Ellis (2014) spectral clustering: recurrence → time-lag median filter → normalized Laplacian →eigh→kmeans.
Example
Section titled “Example”import { segment } from 'pleco-xa'
// features: 2D matrix, rows = feature dims, columns = frames (d×n layout)const R = segment.recurrenceMatrix(features, { mode: 'affinity', width: 3, sym: true,})
// Structural segmentation into k sections:const { segmentIds, boundaries } = segment.laplacianSegmentation(features, { k: 5 })// segmentIds[i] is frame i's section; boundaries are the internal onset frames
// Two feature streams — one for repetition, one for local continuity:const seg2 = segment.laplacianSegmentation( { recurrenceFeatures: chroma, pathFeatures: mfcc }, { k: 5, mu: 0.5 },)- Input is never shape-guessed. Pass a 2D matrix (rows = features, columns = frames) or
a flat typed array with explicit
{ nFeatures, nFrames }. Ambiguous flat input throws. widthmust satisfy1 <= width <= (n - 1) // 2— tiny sequences need an explicitwidth, since the default band can exceed the bound.symis mutual-NN, i.e. the element-wise minimum with the transpose (not union/max). The returned matrix uses a transposed orientation:rec[i][j]non-zero means frameiis a k-NN of framej.laplacianSegmentationhas two input forms: a single feature stack (the same matrix drives both the recurrence and path graphs) or the two-feature object form{ recurrenceFeatures, pathFeatures }, the CQT-for-repetition / MFCC-for-continuity split. Both matrices must share the same number of frames.boundariesfromlaplacianSegmentationare the internal label transitions (1 + where(seg[:-1] ≠ seg[1:]));agglomerativeinstead returns left edges starting at 0.
API reference
Section titled “API reference”Full signatures: segment namespace — e.g.
recurrenceMatrix,
laplacianSegmentation,
agglomerative.