/** * Optimized hierarchical agglomerative clustering using the nearest-neighbor * chain algorithm with Lance–Williams distance updates. * * NN-chain follows reciprocal nearest neighbors until it finds a reducible * merge pair, then updates distances in place. For single, complete, average, * and Ward linkage this gives guaranteed O(n²) time and O(n²) memory. * * The distance matrix is stored as a flat Float64Array of size n×n with * index-based active tracking (Uint8Array flags). This avoids the * O(n²)-per-merge cost of Array.splice and is cache-friendly. * * Lance–Williams recurrence for the updated distance D(t,k) when merging * clusters i and j into t: * * Single : min(D(i,k), D(j,k)) * Complete : max(D(i,k), D(j,k)) * Average : (n_i·D(i,k) + n_j·D(j,k)) / (n_i + n_j) * Ward : sqrt(max(((n_i+n_k)·D(i,k)² + (n_j+n_k)·D(j,k)² - n_k·D(i,j)²) * / (n_i + n_j + n_k), 0)) */ export type LinkageCriterion = 'single' | 'complete' | 'average' | 'ward'; export interface MergeRecord { /** Lower active slot index of the two merged clusters. */ cluster_a: number; /** Higher active slot index of the two merged clusters. */ cluster_b: number; distance: number; new_size: number; } /** * Emitted merges are sorted by distance before returning, matching the * scipy/fastcluster convention for NN-chain. The raw discovery order is not a * valid dendrogram order for cutting. * * @param D Flat n×n distance matrix (Float64Array). Mutated in place. */ export declare function nn_chain_cluster(D: Float64Array, n: number, linkage: LinkageCriterion): MergeRecord[];