umap-web 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +98 -0
- package/LICENSE +29 -0
- package/NOTICE +19 -0
- package/README.md +205 -0
- package/dist/chunk-Bp6m_JJh.js +13 -0
- package/dist/core-BPpH5_PW.js +2816 -0
- package/dist/core-BPpH5_PW.js.map +1 -0
- package/dist/core-IHdw-3yY.d.ts +373 -0
- package/dist/core.d.ts +3 -0
- package/dist/core.js +4 -0
- package/dist/index.d.ts +261 -0
- package/dist/index.js +2991 -0
- package/dist/index.js.map +1 -0
- package/dist/init-DLiEtGpx.js +802 -0
- package/dist/init-DLiEtGpx.js.map +1 -0
- package/dist/sparse-BxSeVhO4.d.ts +150 -0
- package/dist/webgpu.d.ts +111 -0
- package/dist/webgpu.js +955 -0
- package/dist/webgpu.js.map +1 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +1095 -0
- package/dist/worker.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-BPpH5_PW.js","names":["cost","tmpCols: number[]","tmpVals: number[]","col: number","out: Csr","val: number","distGraph: Csr | null","SPECS: Record<string, MetricSpec>","NAMED_METRICS: readonly string[]","identity: CorrectionFn","v","i","iSwap: number","swap","forest: FlatTree[]","rows: Int32Array[]","side: number","s: number","top: number[]","topDeg: number[]","best: HubSplitResult | null","retained: number[]","col: number","v: number","cols: number[]","vals: number[]","graph: CsrF32","rX: Matrix","norm","out: number[]","outI: number[]","hyperplane: SparseVec","leaves: Int32Array[]","treeStates: Int32Array[]","knnInternal: KnnGraph","knn: KnnGraph","knn","timer: ReturnType<typeof setTimeout> | undefined","rows","cols","data"],"sources":["../src/graph/ab.ts","../src/sparse.ts","../src/graph/epochs.ts","../src/graph/smooth.ts","../src/graph/fuzzy.ts","../src/metrics.ts","../src/knn/internal-metrics.ts","../src/knn/exact.ts","../src/rng.ts","../src/knn/heap.ts","../src/knn/nndescent.ts","../src/knn/rpforest.ts","../src/knn/search.ts","../src/knn/sparse-forest.ts","../src/knn/index.ts","../src/util.ts"],"sourcesContent":["/**\n * find_ab_params (umap_.py:1393-1408): least-squares fit of\n * curve(x) = 1 / (1 + a·x^(2b)) to the fuzzy-membership target built from\n * (spread, minDist), via Levenberg–Marquardt from p0 = (1, 1) — mirroring\n * scipy.optimize.curve_fit's default solver on the same 300-point grid.\n */\n\nexport interface ABParams {\n a: number;\n b: number;\n}\n\nexport function findABParams(spread: number, minDist: number): ABParams {\n const N = 300;\n const xv = new Float64Array(N);\n const yv = new Float64Array(N);\n const step = (spread * 3) / (N - 1); // np.linspace(0, 3*spread, 300) inclusive\n for (let i = 0; i < N; i++) {\n const x = i * step;\n xv[i] = x;\n yv[i] = x < minDist ? 1.0 : Math.exp(-(x - minDist) / spread);\n }\n\n let a = 1.0;\n let b = 1.0;\n let lambda = 1e-3;\n\n const residuals = (pa: number, pb: number): number => {\n let cost = 0;\n for (let i = 0; i < N; i++) {\n const r = 1.0 / (1.0 + pa * xv[i]! ** (2 * pb)) - yv[i]!;\n cost += r * r;\n }\n return cost;\n };\n\n let cost = residuals(a, b);\n for (let iter = 0; iter < 300; iter++) {\n // Build JtJ (2x2) and Jtr (2)\n let jaa = 0;\n let jab = 0;\n let jbb = 0;\n let ga = 0;\n let gb = 0;\n for (let i = 0; i < N; i++) {\n const x = xv[i]!;\n const xp = x > 0 ? x ** (2 * b) : 0;\n const denom = 1.0 + a * xp;\n const f = 1.0 / denom;\n const r = f - yv[i]!;\n const dfda = -xp / (denom * denom);\n const dfdb = x > 0 ? (-a * xp * 2 * Math.log(x)) / (denom * denom) : 0;\n jaa += dfda * dfda;\n jab += dfda * dfdb;\n jbb += dfdb * dfdb;\n ga += dfda * r;\n gb += dfdb * r;\n }\n // solve (JtJ + λ diag(JtJ)) δ = -g\n const m00 = jaa * (1 + lambda);\n const m11 = jbb * (1 + lambda);\n const m01 = jab;\n const det = m00 * m11 - m01 * m01;\n if (det === 0 || !Number.isFinite(det)) break;\n const da = (-ga * m11 + gb * m01) / det;\n const db = (ga * m01 - gb * m00) / det;\n const na = a + da;\n const nb = b + db;\n const newCost = residuals(na, nb);\n if (newCost < cost) {\n a = na;\n b = nb;\n const improvement = cost - newCost;\n cost = newCost;\n lambda = Math.max(lambda / 3, 1e-12);\n if (improvement < 1e-15 && Math.abs(da) + Math.abs(db) < 1e-12) break;\n } else {\n lambda *= 3;\n if (lambda > 1e12) break;\n }\n }\n return { a, b };\n}\n","/**\n * CSR sparse matrix utilities. Canonical form: sorted column indices per row,\n * duplicates summed, explicit zeros eliminated — matching scipy's behavior after\n * `tocsr()` + `sum_duplicates()` + `eliminate_zeros()`.\n */\n\nexport interface Csr {\n data: Float64Array;\n indices: Int32Array;\n indptr: Int32Array;\n rows: number;\n cols: number;\n}\n\nexport function csrNnz(m: Csr): number {\n return m.indptr[m.rows]!;\n}\n\n/**\n * Build canonical CSR from COO triplets: duplicates summed, zeros eliminated,\n * columns sorted per row.\n */\nexport function csrFromCoo(\n rows: number,\n cols: number,\n rowIdx: Int32Array,\n colIdx: Int32Array,\n values: Float64Array | Float32Array,\n): Csr {\n const nnzIn = rowIdx.length;\n // counting sort by row\n const counts = new Int32Array(rows + 1);\n for (let t = 0; t < nnzIn; t++) counts[rowIdx[t]! + 1]!++;\n for (let r = 0; r < rows; r++) counts[r + 1]! += counts[r]!;\n const order = new Int32Array(nnzIn);\n const cursor = counts.slice(0, rows);\n for (let t = 0; t < nnzIn; t++) {\n const r = rowIdx[t]!;\n order[cursor[r]!++] = t;\n }\n const indptr = new Int32Array(rows + 1);\n const outIdx = new Int32Array(nnzIn);\n const outVal = new Float64Array(nnzIn);\n let nnz = 0;\n // per-row: gather, sort by col, sum duplicates, drop zeros\n const tmpCols: number[] = [];\n const tmpVals: number[] = [];\n for (let r = 0; r < rows; r++) {\n tmpCols.length = 0;\n tmpVals.length = 0;\n for (let p = counts[r]!; p < counts[r + 1]!; p++) {\n const t = order[p]!;\n tmpCols.push(colIdx[t]!);\n tmpVals.push(values[t]!);\n }\n const n = tmpCols.length;\n if (n > 0) {\n const perm = Array.from({ length: n }, (_, i) => i).sort((a, b) => tmpCols[a]! - tmpCols[b]!);\n let lastCol = -1;\n let acc = 0;\n for (let i = 0; i <= n; i++) {\n const c = i < n ? tmpCols[perm[i]!]! : -2;\n if (c !== lastCol) {\n if (lastCol >= 0 && acc !== 0) {\n outIdx[nnz] = lastCol;\n outVal[nnz] = acc;\n nnz++;\n }\n lastCol = c;\n acc = 0;\n }\n if (i < n) acc += tmpVals[perm[i]!]!;\n }\n }\n indptr[r + 1] = nnz;\n }\n return {\n data: outVal.slice(0, nnz),\n indices: outIdx.slice(0, nnz),\n indptr,\n rows,\n cols,\n };\n}\n\nexport function csrTranspose(m: Csr): Csr {\n const nnz = csrNnz(m);\n const counts = new Int32Array(m.cols + 1);\n for (let t = 0; t < nnz; t++) counts[m.indices[t]! + 1]!++;\n for (let c = 0; c < m.cols; c++) counts[c + 1]! += counts[c]!;\n const indptr = counts.slice();\n const indices = new Int32Array(nnz);\n const data = new Float64Array(nnz);\n const cursor = counts.slice(0, m.cols);\n for (let r = 0; r < m.rows; r++) {\n for (let p = m.indptr[r]!; p < m.indptr[r + 1]!; p++) {\n const c = m.indices[p]!;\n const dst = cursor[c]!++;\n indices[dst] = r;\n data[dst] = m.data[p]!;\n }\n }\n // rows were visited in order, so each transposed row is already column-sorted\n return { data, indices, indptr, rows: m.cols, cols: m.rows };\n}\n\n/**\n * Elementwise combine over the UNION sparsity of two canonical CSRs.\n * `f(a, b)` receives 0 for absent entries; results equal to 0 are eliminated.\n */\nexport function csrBinaryOp(A: Csr, B: Csr, f: (a: number, b: number) => number): Csr {\n const rows = A.rows;\n const cols = A.cols;\n const indptr = new Int32Array(rows + 1);\n const cap = csrNnz(A) + csrNnz(B);\n const indices = new Int32Array(cap);\n const data = new Float64Array(cap);\n let nnz = 0;\n for (let r = 0; r < rows; r++) {\n let pa = A.indptr[r]!;\n let pb = B.indptr[r]!;\n const ea = A.indptr[r + 1]!;\n const eb = B.indptr[r + 1]!;\n while (pa < ea || pb < eb) {\n const ca = pa < ea ? A.indices[pa]! : Infinity;\n const cb = pb < eb ? B.indices[pb]! : Infinity;\n let col: number;\n let va = 0;\n let vb = 0;\n if (ca < cb) {\n col = ca;\n va = A.data[pa]!;\n pa++;\n } else if (cb < ca) {\n col = cb;\n vb = B.data[pb]!;\n pb++;\n } else {\n col = ca;\n va = A.data[pa]!;\n vb = B.data[pb]!;\n pa++;\n pb++;\n }\n const v = f(va, vb);\n if (v !== 0) {\n indices[nnz] = col;\n data[nnz] = v;\n nnz++;\n }\n }\n indptr[r + 1] = nnz;\n }\n return { data: data.slice(0, nnz), indices: indices.slice(0, nnz), indptr, rows, cols };\n}\n\n/** Drop explicit zeros (canonicalize). */\nexport function csrEliminateZeros(m: Csr): Csr {\n const nnz = csrNnz(m);\n let out = 0;\n for (let t = 0; t < nnz; t++) if (m.data[t] !== 0) out++;\n if (out === nnz) return m;\n const indptr = new Int32Array(m.rows + 1);\n const indices = new Int32Array(out);\n const data = new Float64Array(out);\n let k = 0;\n for (let r = 0; r < m.rows; r++) {\n for (let p = m.indptr[r]!; p < m.indptr[r + 1]!; p++) {\n if (m.data[p] !== 0) {\n indices[k] = m.indices[p]!;\n data[k] = m.data[p]!;\n k++;\n }\n }\n indptr[r + 1] = k;\n }\n return { data, indices, indptr, rows: m.rows, cols: m.cols };\n}\n\n/** Map values in place. */\nexport function csrMapValues(m: Csr, f: (v: number) => number): Csr {\n for (let t = 0; t < csrNnz(m); t++) m.data[t] = f(m.data[t]!);\n return m;\n}\n\n/** Max of |A - B| over union sparsity, for tests. */\nexport function csrMaxAbsDiff(A: Csr, B: Csr): number {\n let worst = 0;\n const d = csrBinaryOp(A, B, (a, b) => {\n const v = Math.abs(a - b);\n if (v > worst) worst = v;\n return v;\n });\n void d;\n return worst;\n}\n\n/** Row-normalize by max (scipy normalize(norm='max')): divide each row by its max value. */\nexport function csrRowNormalizeMax(m: Csr): Csr {\n for (let r = 0; r < m.rows; r++) {\n let mx = 0;\n for (let p = m.indptr[r]!; p < m.indptr[r + 1]!; p++) {\n const v = m.data[p]!;\n if (v > mx) mx = v; // scipy uses max of |values|; graph weights are >= 0\n }\n if (mx > 0) {\n for (let p = m.indptr[r]!; p < m.indptr[r + 1]!; p++) {\n m.data[p] = m.data[p]! / mx;\n }\n }\n }\n return m;\n}\n\n/** COO iteration helper. */\nexport function csrForEach(m: Csr, cb: (row: number, col: number, val: number) => void): void {\n for (let r = 0; r < m.rows; r++) {\n for (let p = m.indptr[r]!; p < m.indptr[r + 1]!; p++) {\n cb(r, m.indices[p]!, m.data[p]!);\n }\n }\n}\n\n/** Deep copy. */\nexport function csrCopy(m: Csr): Csr {\n return {\n data: m.data.slice(),\n indices: m.indices.slice(),\n indptr: m.indptr.slice(),\n rows: m.rows,\n cols: m.cols,\n };\n}\n","/**\n * make_epochs_per_sample + graph pre-pruning + n_epochs defaults\n * (umap_.py:906-925, 1072-1093; notes §6).\n */\n\nimport { type Csr, csrEliminateZeros } from '../sparse.js';\n\nexport function makeEpochsPerSample(\n weights: Float64Array | Float32Array,\n nEpochs: number,\n): Float64Array {\n const result = new Float64Array(weights.length).fill(-1.0);\n let wMax = -Infinity;\n for (let i = 0; i < weights.length; i++) if (weights[i]! > wMax) wMax = weights[i]!;\n for (let i = 0; i < weights.length; i++) {\n const nSamples = nEpochs * (weights[i]! / wMax);\n if (nSamples > 0) result[i] = nEpochs / nSamples;\n }\n return result;\n}\n\n/** Default epoch rule: 500 for n<=10000 else 200; +200 when densMAP (notes §6.2). */\nexport function defaultNEpochs(nVertices: number, densmap: boolean): number {\n let d = nVertices <= 10000 ? 500 : 200;\n if (densmap) d += 200;\n return d;\n}\n\n/**\n * Prune graph weights below max/n_epochs (in place on a copy) exactly like\n * simplicial_set_embedding, returning the pruned graph.\n */\nexport function pruneGraphForEpochs(graph: Csr, nEpochsMax: number, defaultEpochs: number): Csr {\n const out: Csr = {\n data: graph.data.slice(),\n indices: graph.indices,\n indptr: graph.indptr,\n rows: graph.rows,\n cols: graph.cols,\n };\n let mx = -Infinity;\n for (let i = 0; i < out.data.length; i++) if (out.data[i]! > mx) mx = out.data[i]!;\n const divisor = nEpochsMax > 10 ? nEpochsMax : defaultEpochs;\n const thresh = mx / divisor;\n for (let i = 0; i < out.data.length; i++) {\n if (out.data[i]! < thresh) out.data[i] = 0.0;\n }\n return csrEliminateZeros(out);\n}\n","/**\n * smooth_knn_dist — sigma/rho computation (umap_.py:143-253; notes §1).\n *\n * Python runs this in float32 fastmath; we compute in float64 (matches to ~1e-6,\n * within the §3.3 tolerance policy).\n */\n\nexport const SMOOTH_K_TOLERANCE = 1e-5;\nexport const MIN_K_DIST_SCALE = 1e-3;\n\nexport interface SmoothKnnResult {\n sigmas: Float32Array;\n rhos: Float32Array;\n}\n\nexport interface SmoothKnnOptions {\n nIter?: number;\n localConnectivity?: number;\n bandwidth?: number;\n}\n\n/**\n * @param distances (nSamples × nNeighbors) row-major, each row sorted ascending\n * (includes self at column 0 for standard kNN).\n * @param k the float number of neighbors (callers pass the integer k).\n */\nexport function smoothKnnDist(\n distances: Float32Array,\n nNeighbors: number,\n k: number,\n { nIter = 64, localConnectivity = 1.0, bandwidth = 1.0 }: SmoothKnnOptions = {},\n): SmoothKnnResult {\n const nSamples = distances.length / nNeighbors;\n const target = Math.log2(k) * bandwidth;\n const rhos = new Float32Array(nSamples);\n const sigmas = new Float32Array(nSamples);\n\n // global mean over ALL entries (incl. zeros)\n let meanDistances = 0;\n for (let t = 0; t < distances.length; t++) meanDistances += distances[t]!;\n meanDistances /= distances.length;\n\n const nonZero = new Float64Array(nNeighbors);\n\n for (let i = 0; i < nSamples; i++) {\n const base = i * nNeighbors;\n let lo = 0.0;\n let hi = Infinity;\n let mid = 1.0;\n\n // ---- rho via localConnectivity ----\n let nz = 0;\n for (let j = 0; j < nNeighbors; j++) {\n const d = distances[base + j]!;\n if (d > 0) nonZero[nz++] = d;\n }\n let rho = 0.0;\n if (nz >= localConnectivity) {\n const index = Math.floor(localConnectivity);\n const interpolation = localConnectivity - index;\n if (index > 0) {\n rho = nonZero[index - 1]!;\n if (interpolation > SMOOTH_K_TOLERANCE) {\n rho += interpolation * (nonZero[index]! - nonZero[index - 1]!);\n }\n } else {\n rho = interpolation * nonZero[0]!;\n }\n } else if (nz > 0) {\n let mx = -Infinity;\n for (let j = 0; j < nz; j++) if (nonZero[j]! > mx) mx = nonZero[j]!;\n rho = mx;\n }\n rhos[i] = rho;\n\n // ---- binary search for sigma ----\n // NOTE (DECISIONS.md D-006): the pinned wheel compiles this loop with numba\n // fastmath=True, which folds the source's `if hi == inf: mid *= 2` branch to\n // false (fastmath assumes no infinities). The executed semantics are therefore\n // `mid = (lo + hi) / 2` in BOTH branches — so when psum(mid=1) <= target, mid\n // becomes (1 + inf)/2 = inf and sigma is inf (membership weight 1.0 for all\n // neighbors). We reproduce the executed oracle, not the source text.\n for (let n = 0; n < nIter; n++) {\n let psum = 0.0;\n for (let j = 1; j < nNeighbors; j++) {\n const d = distances[base + j]! - rho;\n psum += d > 0 ? Math.exp(-(d / mid)) : 1.0;\n }\n if (Math.abs(psum - target) < SMOOTH_K_TOLERANCE) break;\n if (psum > target) {\n hi = mid;\n } else {\n lo = mid;\n }\n mid = (lo + hi) / 2.0; // == Infinity while hi is still Infinity (fastmath fold)\n }\n let sigma = mid;\n\n // ---- floors ----\n if (rho > 0.0) {\n let meanIth = 0;\n for (let j = 0; j < nNeighbors; j++) meanIth += distances[base + j]!;\n meanIth /= nNeighbors;\n if (sigma < MIN_K_DIST_SCALE * meanIth) sigma = MIN_K_DIST_SCALE * meanIth;\n } else if (sigma < MIN_K_DIST_SCALE * meanDistances) {\n sigma = MIN_K_DIST_SCALE * meanDistances;\n }\n sigmas[i] = sigma;\n }\n return { sigmas, rhos };\n}\n","/**\n * compute_membership_strengths + fuzzy_simplicial_set (umap_.py:351-617; notes §3-4).\n */\n\nimport { type Csr, csrBinaryOp, csrEliminateZeros, csrFromCoo, csrTranspose } from '../sparse.js';\nimport { smoothKnnDist } from './smooth.js';\n\nexport interface MembershipStrengths {\n rows: Int32Array;\n cols: Int32Array;\n vals: Float32Array;\n dists: Float32Array | null;\n}\n\nexport function computeMembershipStrengths(\n knnIndices: Int32Array,\n knnDists: Float32Array,\n sigmas: Float32Array,\n rhos: Float32Array,\n nNeighbors: number,\n returnDists = false,\n bipartite = false,\n): MembershipStrengths {\n const nSamples = knnIndices.length / nNeighbors;\n const size = nSamples * nNeighbors;\n const rows = new Int32Array(size);\n const cols = new Int32Array(size);\n const vals = new Float32Array(size);\n const dists = returnDists ? new Float32Array(size) : null;\n\n for (let i = 0; i < nSamples; i++) {\n const base = i * nNeighbors;\n for (let j = 0; j < nNeighbors; j++) {\n const idx = knnIndices[base + j]!;\n if (idx === -1) continue; // leave (0,0,0.0) triplet — eliminated later\n let val: number;\n if (!bipartite && idx === i) {\n val = 0.0;\n } else if (knnDists[base + j]! - rhos[i]! <= 0.0 || sigmas[i]! === 0.0) {\n val = 1.0;\n } else {\n val = Math.fround(Math.exp(-((knnDists[base + j]! - rhos[i]!) / sigmas[i]!)));\n }\n rows[base + j] = i;\n cols[base + j] = idx;\n vals[base + j] = val;\n if (dists) dists[base + j] = knnDists[base + j]!;\n }\n }\n return { rows, cols, vals, dists };\n}\n\nexport interface FuzzySimplicialSetResult {\n graph: Csr;\n sigmas: Float32Array;\n rhos: Float32Array;\n /** symmetrized (max) distances, only when returnDists */\n dists: Csr | null;\n}\n\nexport interface FuzzySimplicialSetOptions {\n setOpMixRatio?: number;\n localConnectivity?: number;\n applySetOperations?: boolean;\n returnDists?: boolean;\n bipartite?: boolean;\n}\n\n/**\n * Build the fuzzy simplicial set from a kNN graph (knn indices+distances required;\n * the estimator computes them per §5.2 backends).\n */\nexport function fuzzySimplicialSet(\n nSamples: number,\n nNeighbors: number,\n knnIndices: Int32Array,\n knnDists: Float32Array,\n {\n setOpMixRatio = 1.0,\n localConnectivity = 1.0,\n applySetOperations = true,\n returnDists = false,\n }: FuzzySimplicialSetOptions = {},\n): FuzzySimplicialSetResult {\n const { sigmas, rhos } = smoothKnnDist(knnDists, nNeighbors, nNeighbors, {\n localConnectivity,\n });\n const { rows, cols, vals, dists } = computeMembershipStrengths(\n knnIndices,\n knnDists,\n sigmas,\n rhos,\n nNeighbors,\n returnDists,\n );\n let graph = csrFromCoo(nSamples, nSamples, rows, cols, vals);\n\n if (applySetOperations) {\n const transpose = csrTranspose(graph);\n // set_op_mix_ratio * (A + At − A∘At) + (1−set_op_mix_ratio) * (A∘At)\n graph = csrBinaryOp(graph, transpose, (a, b) => {\n const prod = a * b;\n return setOpMixRatio * (a + b - prod) + (1.0 - setOpMixRatio) * prod;\n });\n }\n graph = csrEliminateZeros(graph);\n\n let distGraph: Csr | null = null;\n if (returnDists && dists) {\n const dmat = csrFromCoo(nSamples, nSamples, rows, cols, dists);\n const dmatT = csrTranspose(dmat);\n distGraph = csrEliminateZeros(csrBinaryOp(dmat, dmatT, (a, b) => Math.max(a, b)));\n }\n return { graph, sigmas, rhos, dists: distGraph };\n}\n","/**\n * Named distance metrics — faithful ports of `umap.distances` (vendored 0.5.9.post2).\n * Every formula, branch, and edge case mirrors the Python source (see\n * reference/notes/umap-internals.md and DECISIONS.md D-004 for the requirement set).\n *\n * Computation is float64 (JS Number); inputs are typically Float32Array views.\n */\n\nimport { UmapValidationError } from './types.js';\n\nexport type Vec = Float32Array | Float64Array;\nexport type MetricImpl = (x: Vec, y: Vec) => number;\n\nexport interface MetricOptions {\n /** minkowski / wminkowski exponent */\n p?: number;\n /** seuclidean variance vector */\n V?: ArrayLike<number>;\n /** wminkowski weight vector */\n w?: ArrayLike<number>;\n /** mahalanobis inverse covariance (row-major cols×cols) */\n VInv?: ArrayLike<number>;\n}\n\nexport function euclidean(x: Vec, y: Vec): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n const d = x[i]! - y[i]!;\n result += d * d;\n }\n return Math.sqrt(result);\n}\n\n/** Squared euclidean — used internally by the optimizer (rdist). */\nexport function sqeuclidean(x: Vec, y: Vec): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n const d = x[i]! - y[i]!;\n result += d * d;\n }\n return result;\n}\n\nexport function standardisedEuclidean(x: Vec, y: Vec, sigma: ArrayLike<number>): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n const d = x[i]! - y[i]!;\n result += (d * d) / (sigma[i] as number);\n }\n return Math.sqrt(result);\n}\n\nexport function manhattan(x: Vec, y: Vec): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n result += Math.abs(x[i]! - y[i]!);\n }\n return result;\n}\n\nexport function chebyshev(x: Vec, y: Vec): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n const v = Math.abs(x[i]! - y[i]!);\n if (v > result) result = v;\n }\n return result;\n}\n\nexport function minkowski(x: Vec, y: Vec, p: number): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n result += Math.abs(x[i]! - y[i]!) ** p;\n }\n return result ** (1.0 / p);\n}\n\nexport function weightedMinkowski(x: Vec, y: Vec, w: ArrayLike<number>, p: number): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n result += (w[i] as number) * Math.abs(x[i]! - y[i]!) ** p;\n }\n return result ** (1.0 / p);\n}\n\nexport function mahalanobis(x: Vec, y: Vec, vinv: ArrayLike<number>): number {\n const n = x.length;\n let result = 0;\n const diff = new Float64Array(n);\n for (let i = 0; i < n; i++) diff[i] = x[i]! - y[i]!;\n for (let i = 0; i < n; i++) {\n let tmp = 0;\n for (let j = 0; j < n; j++) {\n tmp += (vinv[i * n + j] as number) * diff[j]!;\n }\n result += tmp * diff[i]!;\n }\n return Math.sqrt(result);\n}\n\nexport function hamming(x: Vec, y: Vec): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n if (x[i] !== y[i]) result += 1;\n }\n return result / x.length;\n}\n\nexport function canberra(x: Vec, y: Vec): number {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n const denominator = Math.abs(x[i]!) + Math.abs(y[i]!);\n if (denominator > 0) result += Math.abs(x[i]! - y[i]!) / denominator;\n }\n return result;\n}\n\nexport function brayCurtis(x: Vec, y: Vec): number {\n let numerator = 0;\n let denominator = 0;\n for (let i = 0; i < x.length; i++) {\n numerator += Math.abs(x[i]! - y[i]!);\n denominator += Math.abs(x[i]! + y[i]!);\n }\n return denominator > 0 ? numerator / denominator : 0;\n}\n\nexport function jaccard(x: Vec, y: Vec): number {\n let numNonZero = 0;\n let numEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n numNonZero += xt || yt ? 1 : 0;\n numEqual += xt && yt ? 1 : 0;\n }\n return numNonZero === 0 ? 0 : (numNonZero - numEqual) / numNonZero;\n}\n\nexport function matching(x: Vec, y: Vec): number {\n let numNotEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n if (xt !== yt) numNotEqual += 1;\n }\n return numNotEqual / x.length;\n}\n\nexport function dice(x: Vec, y: Vec): number {\n let numTrueTrue = 0;\n let numNotEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n numTrueTrue += xt && yt ? 1 : 0;\n numNotEqual += xt !== yt ? 1 : 0;\n }\n return numNotEqual === 0 ? 0 : numNotEqual / (2.0 * numTrueTrue + numNotEqual);\n}\n\nexport function kulsinski(x: Vec, y: Vec): number {\n let numTrueTrue = 0;\n let numNotEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n numTrueTrue += xt && yt ? 1 : 0;\n numNotEqual += xt !== yt ? 1 : 0;\n }\n return numNotEqual === 0 ? 0 : (numNotEqual - numTrueTrue + x.length) / (numNotEqual + x.length);\n}\n\nexport function rogersTanimoto(x: Vec, y: Vec): number {\n let numNotEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n if (xt !== yt) numNotEqual += 1;\n }\n return (2.0 * numNotEqual) / (x.length + numNotEqual);\n}\n\nexport function russellrao(x: Vec, y: Vec): number {\n let numTrueTrue = 0;\n let xNonZero = 0;\n let yNonZero = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n numTrueTrue += xt && yt ? 1 : 0;\n xNonZero += xt ? 1 : 0;\n yNonZero += yt ? 1 : 0;\n }\n if (numTrueTrue === xNonZero && numTrueTrue === yNonZero) return 0;\n return (x.length - numTrueTrue) / x.length;\n}\n\nexport function sokalMichener(x: Vec, y: Vec): number {\n return rogersTanimoto(x, y); // identical formula in source\n}\n\nexport function sokalSneath(x: Vec, y: Vec): number {\n let numTrueTrue = 0;\n let numNotEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n numTrueTrue += xt && yt ? 1 : 0;\n numNotEqual += xt !== yt ? 1 : 0;\n }\n return numNotEqual === 0 ? 0 : numNotEqual / (0.5 * numTrueTrue + numNotEqual);\n}\n\nexport function yule(x: Vec, y: Vec): number {\n let tt = 0;\n let tf = 0;\n let ft = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n tt += xt && yt ? 1 : 0;\n tf += xt && !yt ? 1 : 0;\n ft += !xt && yt ? 1 : 0;\n }\n const ff = x.length - tt - tf - ft;\n if (tf === 0 || ft === 0) return 0;\n return (2.0 * tf * ft) / (tt * ff + tf * ft);\n}\n\nexport function cosine(x: Vec, y: Vec): number {\n let result = 0;\n let normX = 0;\n let normY = 0;\n for (let i = 0; i < x.length; i++) {\n result += x[i]! * y[i]!;\n normX += x[i]! * x[i]!;\n normY += y[i]! * y[i]!;\n }\n if (normX === 0 && normY === 0) return 0;\n if (normX === 0 || normY === 0) return 1;\n return 1.0 - result / Math.sqrt(normX * normY);\n}\n\nexport function correlation(x: Vec, y: Vec): number {\n let muX = 0;\n let muY = 0;\n let normX = 0;\n let normY = 0;\n let dot = 0;\n const n = x.length;\n for (let i = 0; i < n; i++) {\n muX += x[i]!;\n muY += y[i]!;\n }\n muX /= n;\n muY /= n;\n for (let i = 0; i < n; i++) {\n const sx = x[i]! - muX;\n const sy = y[i]! - muY;\n normX += sx * sx;\n normY += sy * sy;\n dot += sx * sy;\n }\n if (normX === 0 && normY === 0) return 0;\n if (dot === 0) return 1;\n return 1.0 - dot / Math.sqrt(normX * normY);\n}\n\nexport function hellinger(x: Vec, y: Vec): number {\n let result = 0;\n let l1x = 0;\n let l1y = 0;\n for (let i = 0; i < x.length; i++) {\n result += Math.sqrt(x[i]! * y[i]!);\n l1x += x[i]!;\n l1y += y[i]!;\n }\n if (l1x === 0 && l1y === 0) return 0;\n if (l1x === 0 || l1y === 0) return 1;\n return Math.sqrt(1 - result / Math.sqrt(l1x * l1y));\n}\n\n// --- ll_dirichlet helpers (distances.py:678-712), exact truncated Stirling forms ---\n\nfunction approxLogGamma(x: number): number {\n if (x === 1) return 0;\n return x * Math.log(x) - x + 0.5 * Math.log((2.0 * Math.PI) / x) + 1.0 / (x * 12.0);\n}\n\nfunction logBeta(x: number, y: number): number {\n const a = Math.min(x, y);\n const b = Math.max(x, y);\n if (b < 5) {\n let value = -Math.log(b);\n for (let i = 1; i < Math.trunc(a); i++) {\n value += Math.log(i) - Math.log(b + i);\n }\n return value;\n }\n return approxLogGamma(x) + approxLogGamma(y) - approxLogGamma(x + y);\n}\n\nfunction logSingleBeta(x: number): number {\n return Math.log(2.0) * (-2.0 * x + 0.5) + 0.5 * Math.log((2.0 * Math.PI) / x) + 0.125 / x;\n}\n\nexport function llDirichlet(data1: Vec, data2: Vec): number {\n let n1 = 0;\n let n2 = 0;\n for (let i = 0; i < data1.length; i++) n1 += data1[i]!;\n for (let i = 0; i < data2.length; i++) n2 += data2[i]!;\n let logB = 0;\n let selfDenom1 = 0;\n let selfDenom2 = 0;\n for (let i = 0; i < data1.length; i++) {\n const d1 = data1[i]!;\n const d2 = data2[i]!;\n if (d1 * d2 > 0.9) {\n logB += logBeta(d1, d2);\n selfDenom1 += logSingleBeta(d1);\n selfDenom2 += logSingleBeta(d2);\n } else {\n if (d1 > 0.9) selfDenom1 += logSingleBeta(d1);\n if (d2 > 0.9) selfDenom2 += logSingleBeta(d2);\n }\n }\n return Math.sqrt(\n (1.0 / n2) * (logB - logBeta(n1, n2) - (selfDenom2 - logSingleBeta(n2))) +\n (1.0 / n1) * (logB - logBeta(n2, n1) - (selfDenom1 - logSingleBeta(n1))),\n );\n}\n\n/**\n * Symmetrized KL divergence. NOTE: the Python source mutates its inputs (adds z,\n * normalizes in place); we copy to preserve the same numerics without side effects.\n */\nexport function symmetricKl(x: Vec, y: Vec, z = 1e-11): number {\n const n = x.length;\n let xSum = 0;\n let ySum = 0;\n const xs = new Float64Array(n);\n const ys = new Float64Array(n);\n for (let i = 0; i < n; i++) {\n xs[i] = x[i]! + z;\n xSum += xs[i]!;\n ys[i] = y[i]! + z;\n ySum += ys[i]!;\n }\n for (let i = 0; i < n; i++) {\n xs[i] = xs[i]! / xSum;\n ys[i] = ys[i]! / ySum;\n }\n let kl1 = 0;\n let kl2 = 0;\n for (let i = 0; i < n; i++) {\n kl1 += xs[i]! * Math.log(xs[i]! / ys[i]!);\n kl2 += ys[i]! * Math.log(ys[i]! / xs[i]!);\n }\n return (kl1 + kl2) / 2;\n}\n\nexport function haversine(x: Vec, y: Vec): number {\n if (x.length !== 2) {\n throw new UmapValidationError('haversine is only defined for 2 dimensional data');\n }\n const sinLat = Math.sin(0.5 * (x[0]! - y[0]!));\n const sinLong = Math.sin(0.5 * (x[1]! - y[1]!));\n const result = Math.sqrt(sinLat * sinLat + Math.cos(x[0]!) * Math.cos(y[0]!) * sinLong * sinLong);\n return 2.0 * Math.asin(result);\n}\n\n// ---------------------------------------------------------------------------\n// registry\n// ---------------------------------------------------------------------------\n\ninterface MetricSpec {\n /** canonical name */\n canonical: string;\n /** which options it requires */\n needs?: ('p' | 'V' | 'w' | 'VInv')[];\n resolve: (opts: MetricOptions) => MetricImpl;\n}\n\nfunction simple(fn: MetricImpl, canonical: string): MetricSpec {\n return { canonical, resolve: () => fn };\n}\n\nconst SPECS: Record<string, MetricSpec> = {\n euclidean: simple(euclidean, 'euclidean'),\n l2: simple(euclidean, 'euclidean'),\n sqeuclidean: simple(sqeuclidean, 'sqeuclidean'),\n manhattan: simple(manhattan, 'manhattan'),\n taxicab: simple(manhattan, 'manhattan'),\n l1: simple(manhattan, 'manhattan'),\n chebyshev: simple(chebyshev, 'chebyshev'),\n linfinity: simple(chebyshev, 'chebyshev'),\n linfty: simple(chebyshev, 'chebyshev'),\n linf: simple(chebyshev, 'chebyshev'),\n minkowski: {\n canonical: 'minkowski',\n needs: ['p'],\n resolve: (o) => {\n const p = o.p ?? 2;\n return (x, y) => minkowski(x, y, p);\n },\n },\n seuclidean: {\n canonical: 'seuclidean',\n needs: ['V'],\n resolve: (o) => {\n if (!o.V) throw new UmapValidationError(\"metric 'seuclidean' requires metricOptions.V\");\n const V = o.V;\n return (x, y) => standardisedEuclidean(x, y, V);\n },\n },\n standardised_euclidean: {\n canonical: 'seuclidean',\n needs: ['V'],\n resolve: (o) => {\n if (!o.V) {\n throw new UmapValidationError(\"metric 'standardised_euclidean' requires metricOptions.V\");\n }\n const V = o.V;\n return (x, y) => standardisedEuclidean(x, y, V);\n },\n },\n wminkowski: {\n canonical: 'wminkowski',\n needs: ['w', 'p'],\n resolve: (o) => {\n if (!o.w) throw new UmapValidationError(\"metric 'wminkowski' requires metricOptions.w\");\n const w = o.w;\n const p = o.p ?? 2;\n return (x, y) => weightedMinkowski(x, y, w, p);\n },\n },\n weighted_minkowski: {\n canonical: 'wminkowski',\n needs: ['w', 'p'],\n resolve: (o) => {\n if (!o.w) {\n throw new UmapValidationError(\"metric 'weighted_minkowski' requires metricOptions.w\");\n }\n const w = o.w;\n const p = o.p ?? 2;\n return (x, y) => weightedMinkowski(x, y, w, p);\n },\n },\n mahalanobis: {\n canonical: 'mahalanobis',\n needs: ['VInv'],\n resolve: (o) => {\n if (!o.VInv) {\n throw new UmapValidationError(\"metric 'mahalanobis' requires metricOptions.VInv\");\n }\n const VInv = o.VInv;\n return (x, y) => mahalanobis(x, y, VInv);\n },\n },\n canberra: simple(canberra, 'canberra'),\n braycurtis: simple(brayCurtis, 'braycurtis'),\n cosine: simple(cosine, 'cosine'),\n correlation: simple(correlation, 'correlation'),\n haversine: simple(haversine, 'haversine'),\n hamming: simple(hamming, 'hamming'),\n jaccard: simple(jaccard, 'jaccard'),\n dice: simple(dice, 'dice'),\n matching: simple(matching, 'matching'),\n kulsinski: simple(kulsinski, 'kulsinski'),\n rogerstanimoto: simple(rogersTanimoto, 'rogerstanimoto'),\n russellrao: simple(russellrao, 'russellrao'),\n sokalmichener: simple(sokalMichener, 'sokalmichener'),\n sokalsneath: simple(sokalSneath, 'sokalsneath'),\n yule: simple(yule, 'yule'),\n hellinger: simple(hellinger, 'hellinger'),\n ll_dirichlet: simple(llDirichlet, 'll_dirichlet'),\n symmetric_kl: simple(symmetricKl, 'symmetric_kl'),\n};\n\nexport const NAMED_METRICS: readonly string[] = Object.keys(SPECS);\n\n/** Metrics that auto-enable angular RP-forest (umap_.py:1938-1946). */\nexport const ANGULAR_METRICS = new Set([\n 'cosine',\n 'correlation',\n 'dice',\n 'jaccard',\n 'll_dirichlet',\n 'hellinger',\n]);\n\nexport function isNamedMetric(name: string): boolean {\n return name in SPECS;\n}\n\nexport function canonicalMetricName(name: string): string {\n const spec = SPECS[name];\n if (!spec) throw new UmapValidationError(`unknown metric '${name}'`);\n return spec.canonical;\n}\n\nexport function resolveMetric(name: string, options: MetricOptions = {}): MetricImpl {\n const spec = SPECS[name];\n if (!spec) {\n throw new UmapValidationError(\n `unknown metric '${name}' — named metrics: ${NAMED_METRICS.join(', ')}`,\n );\n }\n return spec.resolve(options);\n}\n\n/**\n * Size/positivity checks for metricOptions once the data dimension is known —\n * a wrong-sized V/w/VInv would otherwise read undefined and silently poison\n * every distance with NaN.\n */\nexport function validateMetricOptionSizes(name: string, options: MetricOptions, dim: number): void {\n const spec = SPECS[name];\n if (!spec) return; // unknown names throw in resolveMetric with a clearer message\n const canonical = spec.canonical;\n if ((canonical === 'minkowski' || canonical === 'wminkowski') && options.p !== undefined) {\n if (!Number.isFinite(options.p) || options.p <= 0) {\n throw new UmapValidationError('metricOptions.p must be a finite number > 0');\n }\n }\n if (canonical === 'seuclidean' && options.V) {\n if (options.V.length !== dim) {\n throw new UmapValidationError(\n `metricOptions.V has ${options.V.length} entries; the data has ${dim} features`,\n );\n }\n for (let i = 0; i < dim; i++) {\n const v = options.V[i] as number;\n if (!Number.isFinite(v) || v <= 0) {\n throw new UmapValidationError(`metricOptions.V must be positive (index ${i} is ${v})`);\n }\n }\n }\n if (canonical === 'wminkowski' && options.w) {\n if (options.w.length !== dim) {\n throw new UmapValidationError(\n `metricOptions.w has ${options.w.length} entries; the data has ${dim} features`,\n );\n }\n }\n if (canonical === 'mahalanobis' && options.VInv) {\n if (options.VInv.length !== dim * dim) {\n throw new UmapValidationError(\n `metricOptions.VInv has ${options.VInv.length} entries; expected ${dim}×${dim} = ${dim * dim}`,\n );\n }\n }\n}\n","/**\n * pynndescent internal (\"alternative\") distance spaces + corrections (notes §8).\n * All build/search ranking happens in these spaces; corrections are applied only to\n * final outputs (neighbor_graph, query).\n */\n\nimport { type MetricImpl, type MetricOptions, resolveMetric } from '../metrics.js';\n\nexport const FLOAT32_MAX = 3.4028234663852886e38;\nexport const FLOAT32_EPS = 1.1920928955078125e-7;\n\nexport function squaredEuclidean(x: Float32Array, y: Float32Array): number {\n let r = 0;\n const n = x.length;\n let i = 0;\n // 4-way unroll (hot path of NN-descent)\n const n4 = n - (n % 4);\n for (; i < n4; i += 4) {\n const d0 = x[i]! - y[i]!;\n const d1 = x[i + 1]! - y[i + 1]!;\n const d2 = x[i + 2]! - y[i + 2]!;\n const d3 = x[i + 3]! - y[i + 3]!;\n r += d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3;\n }\n for (; i < n; i++) {\n const d = x[i]! - y[i]!;\n r += d * d;\n }\n return r;\n}\n\n/** alternative_cosine (distances.py:583-630). */\nexport function alternativeCosine(x: Float32Array, y: Float32Array): number {\n let dot = 0;\n let nx = 0;\n let ny = 0;\n for (let i = 0; i < x.length; i++) {\n dot += x[i]! * y[i]!;\n nx += x[i]! * x[i]!;\n ny += y[i]! * y[i]!;\n }\n if (nx === 0 && ny === 0) return 0;\n if (nx === 0 || ny === 0) return FLOAT32_MAX;\n if (dot <= 0) return FLOAT32_MAX;\n return Math.log2(Math.sqrt(nx * ny) / dot);\n}\n\n/** alternative_hellinger (distances.py:1387-1416). */\nexport function alternativeHellinger(x: Float32Array, y: Float32Array): number {\n let result = 0;\n let l1x = 0;\n let l1y = 0;\n for (let i = 0; i < x.length; i++) {\n result += Math.sqrt(x[i]! * y[i]!);\n l1x += x[i]!;\n l1y += y[i]!;\n }\n if (l1x === 0 && l1y === 0) return 0;\n if (l1x === 0 || l1y === 0) return FLOAT32_MAX;\n if (result <= 0) return FLOAT32_MAX;\n return Math.log2(Math.sqrt(l1x * l1y) / result);\n}\n\n/** alternative_jaccard (distances.py:259-336 family). */\nexport function alternativeJaccard(x: Float32Array, y: Float32Array): number {\n let numNonZero = 0;\n let numEqual = 0;\n for (let i = 0; i < x.length; i++) {\n const xt = x[i] !== 0;\n const yt = y[i] !== 0;\n numNonZero += xt || yt ? 1 : 0;\n numEqual += xt && yt ? 1 : 0;\n }\n if (numNonZero === 0) return 0;\n if (numEqual === 0) return FLOAT32_MAX;\n return -Math.log2(numEqual / numNonZero);\n}\n\nexport type CorrectionFn = (d: number) => number;\n\nexport interface InternalMetric {\n /** distance used for ALL internal ranking/thresholds */\n dist: MetricImpl;\n /** correction applied to final output distances (identity if none) */\n correction: CorrectionFn;\n /** whether angular RP trees are used (pynndescent decides by metric name) */\n angularTrees: boolean;\n}\n\nconst identity: CorrectionFn = (d) => d;\n\n/** Metric names that switch NNDescent to angular trees (pynndescent_.py:1059-1077). */\nconst ANGULAR_TREE_METRICS = new Set([\n 'cosine',\n 'dot',\n 'correlation',\n 'dice',\n 'jaccard',\n 'hellinger',\n 'hamming',\n]);\n\n/**\n * Resolve the internal metric + correction for NN-descent\n * (fast_distance_alternatives, distances.py:2170-2188).\n */\nexport function resolveInternalMetric(name: string, options: MetricOptions): InternalMetric {\n const angularTrees = ANGULAR_TREE_METRICS.has(name);\n switch (name) {\n case 'euclidean':\n case 'l2':\n return {\n dist: squaredEuclidean as MetricImpl,\n correction: (d) => Math.sqrt(d),\n angularTrees,\n };\n case 'cosine':\n return {\n dist: alternativeCosine as MetricImpl,\n correction: (d) => 1.0 - 2.0 ** -d,\n angularTrees,\n };\n case 'hellinger':\n return {\n dist: alternativeHellinger as MetricImpl,\n correction: (d) => Math.sqrt(1.0 - 2.0 ** -d),\n angularTrees,\n };\n case 'jaccard':\n return {\n dist: alternativeJaccard as MetricImpl,\n correction: (d) => 1.0 - 2.0 ** -d,\n angularTrees,\n };\n default:\n return { dist: resolveMetric(name, options), correction: identity, angularTrees };\n }\n}\n\n// ---------------------------------------------------------------------------\n// sparse (CSR row) variants — used by sparse NN-descent (notes §9)\n// ---------------------------------------------------------------------------\n\nexport type SparseMetricImpl = (\n ind1: Int32Array,\n data1: Float32Array,\n ind2: Int32Array,\n data2: Float32Array,\n) => number;\n\n/** sparse_squared_euclidean (sparse.py:383-408). */\nexport function sparseSquaredEuclidean(\n ind1: Int32Array,\n data1: Float32Array,\n ind2: Int32Array,\n data2: Float32Array,\n): number {\n let r = 0;\n let i1 = 0;\n let i2 = 0;\n while (i1 < ind1.length && i2 < ind2.length) {\n const c1 = ind1[i1]!;\n const c2 = ind2[i2]!;\n if (c1 === c2) {\n const d = data1[i1]! - data2[i2]!;\n r += d * d;\n i1++;\n i2++;\n } else if (c1 < c2) {\n r += data1[i1]! * data1[i1]!;\n i1++;\n } else {\n r += data2[i2]! * data2[i2]!;\n i2++;\n }\n }\n while (i1 < ind1.length) {\n r += data1[i1]! * data1[i1]!;\n i1++;\n }\n while (i2 < ind2.length) {\n r += data2[i2]! * data2[i2]!;\n i2++;\n }\n return r;\n}\n\n/** sparse_alternative_cosine (sparse.py:632-659). */\nexport function sparseAlternativeCosine(\n ind1: Int32Array,\n data1: Float32Array,\n ind2: Int32Array,\n data2: Float32Array,\n): number {\n let dot = 0;\n let i1 = 0;\n let i2 = 0;\n while (i1 < ind1.length && i2 < ind2.length) {\n const c1 = ind1[i1]!;\n const c2 = ind2[i2]!;\n if (c1 === c2) {\n dot += data1[i1]! * data2[i2]!;\n i1++;\n i2++;\n } else if (c1 < c2) i1++;\n else i2++;\n }\n let nx = 0;\n for (let i = 0; i < data1.length; i++) nx += data1[i]! * data1[i]!;\n let ny = 0;\n for (let i = 0; i < data2.length; i++) ny += data2[i]! * data2[i]!;\n if (nx === 0 && ny === 0) return 0;\n if (nx === 0 || ny === 0) return FLOAT32_MAX;\n if (dot <= 0) return FLOAT32_MAX;\n return Math.log2(Math.sqrt(nx * ny) / dot);\n}\n\n/** sparse_correct_alternative_cosine clamps near-zero/negative to 0 (sparse.py:662-667). */\nexport function sparseCorrectAlternativeCosine(d: number): number {\n if (Math.abs(d) < 1e-7 || d < 0) return 0.0;\n return 1.0 - 2.0 ** -d;\n}\n\nexport interface SparseInternalMetric {\n dist: SparseMetricImpl;\n correction: CorrectionFn;\n angularTrees: boolean;\n}\n\nexport function resolveSparseInternalMetric(name: string): SparseInternalMetric {\n switch (name) {\n case 'euclidean':\n case 'l2':\n return {\n dist: sparseSquaredEuclidean,\n correction: (d) => Math.sqrt(d),\n angularTrees: false,\n };\n case 'cosine':\n return {\n dist: sparseAlternativeCosine,\n correction: sparseCorrectAlternativeCosine,\n angularTrees: true,\n };\n default:\n throw new Error(`sparse metric '${name}' is not supported (euclidean, cosine)`);\n }\n}\n","/**\n * Exact brute-force kNN (incl. self), matching umap's small-data semantics:\n * fit computes a full pairwise distance matrix and per-row argsorts the first k\n * (umap_.py:2550-2607, utils.py fast_knn_indices). We never materialize n×n —\n * distances are computed per row (§5.6).\n */\n\nimport type { MetricImpl, MetricOptions } from '../metrics.js';\nimport { resolveMetric } from '../metrics.js';\nimport type { CSRInput, KnnGraph, Matrix } from '../types.js';\nimport { UmapValidationError } from '../types.js';\nimport { resolveSparseInternalMetric } from './internal-metrics.js';\n\nexport interface ExactKnnOptions {\n metricOptions?: MetricOptions;\n /** distances >= this become inf / index -1 (disconnection pruning) */\n disconnectionDistance?: number;\n}\n\n/** Row-wise exact kNN for dense data. Accepts a named metric or a custom MetricFn. */\nexport function exactKnnDense(\n X: Matrix,\n k: number,\n metricName: string | ((a: Float32Array, b: Float32Array) => number),\n { metricOptions = {}, disconnectionDistance = Infinity }: ExactKnnOptions = {},\n): KnnGraph {\n const { rows: n, cols: d, data } = X;\n // Custom fns take Float32Array (the only dtype we pass); MetricImpl is the wider shape.\n const metric =\n typeof metricName === 'function'\n ? (metricName as MetricImpl)\n : resolveMetric(metricName, metricOptions);\n const fastEuclidean = metricName === 'euclidean' || metricName === 'l2';\n const indices = new Int32Array(n * k);\n const distances = new Float32Array(n * k);\n const rowDist = new Float64Array(n);\n const order = new Int32Array(n);\n\n const heapIdx = new Int32Array(k);\n const heapDst = new Float64Array(k);\n\n for (let i = 0; i < n; i++) {\n const xi = data.subarray(i * d, (i + 1) * d);\n if (fastEuclidean) {\n // direct-indexed hot loop — no per-pair subarray allocation; strictly\n // sequential accumulation (bit-exact vs the reference summation order)\n const base = i * d;\n for (let j = 0; j < n; j++) {\n const jb = j * d;\n let r = 0;\n for (let c = 0; c < d; c++) {\n const dd = data[base + c]! - data[jb + c]!;\n r += dd * dd;\n }\n rowDist[j] = r;\n }\n } else {\n for (let j = 0; j < n; j++) {\n rowDist[j] = metric(xi, data.subarray(j * d, (j + 1) * d));\n }\n }\n // partial selection of k smallest (max-heap of size k), then sort ascending\n selectKSmallest(rowDist, n, k, heapIdx, heapDst, order);\n for (let j = 0; j < k; j++) {\n let dist = heapDst[j]!;\n if (fastEuclidean) dist = Math.sqrt(dist);\n if (dist >= disconnectionDistance) {\n indices[i * k + j] = -1;\n distances[i * k + j] = Infinity;\n } else {\n indices[i * k + j] = heapIdx[j]!;\n distances[i * k + j] = dist;\n }\n }\n }\n return { indices, distances, k };\n}\n\n/**\n * Select k smallest of rowDist[0..n) with ties broken by smaller index (matching\n * a stable argsort); outputs sorted ascending into heapIdx/heapDst.\n */\nfunction selectKSmallest(\n rowDist: Float64Array,\n n: number,\n k: number,\n outIdx: Int32Array,\n outDst: Float64Array,\n scratchOrder: Int32Array,\n): void {\n // max-heap over (dist, idx) of size k; ties: larger idx counts as \"greater\"\n let count = 0;\n const gt = (d1: number, i1: number, d2: number, i2: number) => d1 > d2 || (d1 === d2 && i1 > i2);\n for (let j = 0; j < n; j++) {\n const dj = rowDist[j]!;\n if (count < k) {\n // push\n let c = count++;\n outDst[c] = dj;\n outIdx[c] = j;\n while (c > 0) {\n const parent = (c - 1) >> 1;\n if (gt(outDst[c]!, outIdx[c]!, outDst[parent]!, outIdx[parent]!)) {\n swap(outDst, outIdx, c, parent);\n c = parent;\n } else break;\n }\n } else if (gt(outDst[0]!, outIdx[0]!, dj, j)) {\n outDst[0] = dj;\n outIdx[0] = j;\n let c = 0;\n for (;;) {\n const l = 2 * c + 1;\n const r = l + 1;\n let m = c;\n if (l < k && gt(outDst[l]!, outIdx[l]!, outDst[m]!, outIdx[m]!)) m = l;\n if (r < k && gt(outDst[r]!, outIdx[r]!, outDst[m]!, outIdx[m]!)) m = r;\n if (m === c) break;\n swap(outDst, outIdx, c, m);\n c = m;\n }\n }\n }\n // k > n: pad the never-written slots (they hold garbage from prior rows)\n for (let j = count; j < k; j++) {\n outDst[j] = Infinity;\n outIdx[j] = -1;\n }\n // sort the k ascending by (dist, idx)\n for (let j = 0; j < k; j++) scratchOrder[j] = j;\n const idxArr = Array.from({ length: k }, (_, j) => j);\n idxArr.sort((a, b) => outDst[a]! - outDst[b]! || outIdx[a]! - outIdx[b]!);\n const tmpD = new Float64Array(k);\n const tmpI = new Int32Array(k);\n for (let j = 0; j < k; j++) {\n tmpD[j] = outDst[idxArr[j]!]!;\n tmpI[j] = outIdx[idxArr[j]!]!;\n }\n outDst.set(tmpD);\n outIdx.set(tmpI);\n}\n\nfunction swap(d: Float64Array, i: Int32Array, a: number, b: number): void {\n const td = d[a]!;\n d[a] = d[b]!;\n d[b] = td;\n const ti = i[a]!;\n i[a] = i[b]!;\n i[b] = ti;\n}\n\n/** Exact kNN for CSR input (euclidean or cosine). */\nexport function exactKnnSparse(X: CSRInput, k: number, metricName: string): KnnGraph {\n const n = X.rows;\n const internal = resolveSparseInternalMetric(metricName);\n const indices = new Int32Array(n * k);\n const distances = new Float32Array(n * k);\n const rowDist = new Float64Array(n);\n const heapIdx = new Int32Array(k);\n const heapDst = new Float64Array(k);\n const order = new Int32Array(n);\n\n const rowInd = (i: number) => X.indices.subarray(X.indptr[i]!, X.indptr[i + 1]!);\n const rowDat = (i: number) => X.data.subarray(X.indptr[i]!, X.indptr[i + 1]!);\n\n for (let i = 0; i < n; i++) {\n const ii = rowInd(i);\n const di = rowDat(i);\n for (let j = 0; j < n; j++) {\n rowDist[j] = internal.dist(ii, di, rowInd(j), rowDat(j));\n }\n selectKSmallest(rowDist, n, k, heapIdx, heapDst, order);\n for (let j = 0; j < k; j++) {\n indices[i * k + j] = heapIdx[j]!;\n distances[i * k + j] = internal.correction(heapDst[j]!);\n }\n }\n return { indices, distances, k };\n}\n\n/**\n * metric='precomputed': X is a dense n×n distance matrix; per-row argsort prefix\n * (umap_.py:312-324); infinite distances → index -1.\n */\nexport function knnFromPrecomputed(X: Matrix, k: number): KnnGraph {\n const n = X.rows;\n if (X.cols !== n) {\n throw new UmapValidationError(`precomputed distance matrix must be square, got ${n}x${X.cols}`);\n }\n const indices = new Int32Array(n * k);\n const distances = new Float32Array(n * k);\n const heapIdx = new Int32Array(k);\n const heapDst = new Float64Array(k);\n const order = new Int32Array(n);\n const rowDist = new Float64Array(n);\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) rowDist[j] = X.data[i * n + j]!;\n selectKSmallest(rowDist, n, k, heapIdx, heapDst, order);\n for (let j = 0; j < k; j++) {\n const dist = heapDst[j]!;\n if (dist === Infinity) {\n indices[i * k + j] = -1;\n distances[i * k + j] = Infinity;\n } else {\n indices[i * k + j] = heapIdx[j]!;\n distances[i * k + j] = dist;\n }\n }\n }\n return { indices, distances, k };\n}\n","/**\n * Seeded PRNG — PCG32 (O'Neill, pcg-random.org), the reproducible generator of §5.5.\n *\n * Test vectors in test/unit/rng.test.ts were generated from the canonical C reference\n * (pcg_basic.c) compiled locally; the first draw for seed(42, 54) is 0xa15c02b7,\n * matching the published pcg32-demo output.\n *\n * 64-bit state is held as two u32 words; the LCG multiply uses exact 16-bit limb\n * arithmetic (all intermediates < 2^53).\n */\n\nconst MULT_HI = 0x5851f42d >>> 0;\nconst MULT_LO = 0x4c957f2d >>> 0;\n\nexport class Pcg32 {\n private sHi = 0;\n private sLo = 0;\n private iHi = 0;\n private iLo = 0;\n private spareNormal: number | null = null;\n\n constructor(seedHi: number, seedLo: number, seqHi: number, seqLo: number) {\n // inc = (initseq << 1) | 1 (64-bit)\n this.iHi = ((seqHi << 1) | (seqLo >>> 31)) >>> 0;\n this.iLo = ((seqLo << 1) | 1) >>> 0;\n this.sHi = 0;\n this.sLo = 0;\n this.nextU32();\n // state += initstate\n const lo = this.sLo + (seedLo >>> 0);\n this.sLo = lo >>> 0;\n this.sHi = (this.sHi + (seedHi >>> 0) + (lo > 0xffffffff ? 1 : 0)) >>> 0;\n this.nextU32();\n }\n\n /** Derive from a JS number seed (integer-valued; uses full 53-bit range). */\n static fromSeed(seed: number, stream = 54): Pcg32 {\n const s = Math.abs(Math.floor(seed));\n const hi = Math.floor(s / 0x100000000) >>> 0;\n const lo = s >>> 0;\n return new Pcg32(hi, lo, 0, stream >>> 0);\n }\n\n nextU32(): number {\n const oHi = this.sHi;\n const oLo = this.sLo;\n\n // state = oldstate * MULT + inc (mod 2^64), 16-bit limbs\n const a0 = oLo & 0xffff;\n const a1 = oLo >>> 16;\n const a2 = oHi & 0xffff;\n const a3 = oHi >>> 16;\n const b0 = MULT_LO & 0xffff;\n const b1 = MULT_LO >>> 16;\n const b2 = MULT_HI & 0xffff;\n const b3 = MULT_HI >>> 16;\n\n const p0 = a0 * b0;\n const p1 = a1 * b0 + a0 * b1;\n const p2 = a2 * b0 + a1 * b1 + a0 * b2;\n const p3 = a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3;\n // Assemble 64-bit result limb-by-limb (16-bit limbs l0..l3), then add inc.\n let l0 = p0 & 0xffff;\n let acc = Math.floor(p0 / 0x10000) + p1;\n let l1 = acc & 0xffff;\n acc = Math.floor(acc / 0x10000) + p2;\n let l2 = acc & 0xffff;\n acc = Math.floor(acc / 0x10000) + p3;\n let l3 = acc & 0xffff;\n // + inc (64-bit add)\n let s = l0 + (this.iLo & 0xffff);\n l0 = s & 0xffff;\n s = l1 + (this.iLo >>> 16) + (s >>> 16);\n l1 = s & 0xffff;\n s = l2 + (this.iHi & 0xffff) + (s >>> 16);\n l2 = s & 0xffff;\n s = l3 + (this.iHi >>> 16) + (s >>> 16);\n l3 = s & 0xffff;\n\n this.sLo = ((l1 << 16) | l0) >>> 0;\n this.sHi = ((l3 << 16) | l2) >>> 0;\n\n // xorshifted = ((old >> 18) ^ old) >> 27 (u32); rot = old >> 59\n const xHi = (oHi ^ (oHi >>> 18)) >>> 0;\n const xLo = (oLo ^ ((oHi << 14) | (oLo >>> 18))) >>> 0;\n const xorshifted = ((xHi << 5) | (xLo >>> 27)) >>> 0;\n const rot = oHi >>> 27;\n return ((xorshifted >>> rot) | (xorshifted << (-rot & 31))) >>> 0;\n }\n\n /** Uniform float in [0, 1). */\n nextFloat(): number {\n return this.nextU32() * 2.3283064365386963e-10; // 2^-32\n }\n\n /** Uniform float in [lo, hi). */\n uniform(lo: number, hi: number): number {\n return lo + (hi - lo) * this.nextFloat();\n }\n\n /** Integer in [0, n) — modulo method (matches umap's structural usage). */\n randint(n: number): number {\n return this.nextU32() % n;\n }\n\n /** Integer in [lo, hi) like numpy randint. */\n randintRange(lo: number, hi: number): number {\n return lo + (this.nextU32() % (hi - lo));\n }\n\n /** Standard normal via Box–Muller (cached spare). */\n normal(): number {\n if (this.spareNormal !== null) {\n const v = this.spareNormal;\n this.spareNormal = null;\n return v;\n }\n let u = 0;\n let v = 0;\n do {\n u = this.nextFloat();\n } while (u <= 1e-12);\n v = this.nextFloat();\n const r = Math.sqrt(-2.0 * Math.log(u));\n const theta = 2.0 * Math.PI * v;\n this.spareNormal = r * Math.sin(theta);\n return r * Math.cos(theta);\n }\n\n /** In-place Fisher–Yates shuffle. */\n shuffle(arr: Int32Array | Uint32Array | Float32Array): void {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = this.randint(i + 1);\n const t = arr[i]!;\n arr[i] = arr[j]!;\n arr[j] = t;\n }\n }\n\n /**\n * Seed a 3-word tau state like Python's\n * `random_state.randint(INT32_MIN, INT32_MAX, 3)` (values in int32 range).\n */\n tauState(): Int32Array {\n const st = new Int32Array(3);\n for (let i = 0; i < 3; i++) st[i] = this.nextU32() | 0;\n return st;\n }\n\n /** Snapshot the full generator state (backend-fallback rng restoration). */\n clone(): Pcg32 {\n const c = new Pcg32(0, 0, 0, 0);\n c.sHi = this.sHi;\n c.sLo = this.sLo;\n c.iHi = this.iHi;\n c.iLo = this.iLo;\n c.spareNormal = this.spareNormal;\n return c;\n }\n\n /** Restore state from a clone() snapshot (un-consumes draws after the snapshot). */\n restoreFrom(snapshot: Pcg32): void {\n this.sHi = snapshot.sHi;\n this.sLo = snapshot.sLo;\n this.iHi = snapshot.iHi;\n this.iLo = snapshot.iLo;\n this.spareNormal = snapshot.spareNormal;\n }\n}\n\n/**\n * taus88 combined Tausworthe step, structurally identical to umap's `tau_rand_int`\n * but on u32 words (Python runs it on int64 with 32-bit truncations). Used for the\n * SGD negative-sampling stream; parity with Python is statistical, not bitwise (§5.5).\n * Returns a signed int32.\n */\nexport function tauRandInt(state: Int32Array): number {\n const s0 = state[0]! >>> 0;\n const s1 = state[1]! >>> 0;\n const s2 = state[2]! >>> 0;\n state[0] = (((s0 & 0xfffffffe) << 12) ^ ((((s0 << 13) >>> 0) ^ s0) >>> 19)) | 0;\n state[1] = (((s1 & 0xfffffff8) << 4) ^ ((((s1 << 2) >>> 0) ^ s1) >>> 25)) | 0;\n state[2] = (((s2 & 0xfffffff0) << 17) ^ ((((s2 << 3) >>> 0) ^ s2) >>> 11)) | 0;\n return (state[0]! ^ state[1]! ^ state[2]!) | 0;\n}\n\n/** Floor-mod (Python `%` semantics) of a signed int by a positive int. */\nexport function floorMod(a: number, n: number): number {\n const r = a % n;\n return r < 0 ? r + n : r;\n}\n\n/** tau_rand: uniform in [0,1] from tauRandInt (umap utils.py:66-80). */\nexport function tauRand(state: Int32Array): number {\n return Math.abs(tauRandInt(state) / 0x7fffffff);\n}\n","/**\n * pynndescent heap structure (utils.py:130-218, 352-533): per-row max-heap on\n * distance rooted at column 0 (root = current worst). Rows: indices int32 (-1 empty),\n * distances float32 (+inf empty), flags uint8.\n */\n\nexport interface NeighborHeap {\n indices: Int32Array; // n * size\n distances: Float32Array; // n * size\n flags: Uint8Array; // n * size\n n: number;\n size: number;\n}\n\nexport function makeHeap(n: number, size: number): NeighborHeap {\n const indices = new Int32Array(n * size).fill(-1);\n const distances = new Float32Array(n * size).fill(Infinity);\n const flags = new Uint8Array(n * size);\n return { indices, distances, flags, n, size };\n}\n\n/**\n * checked_flagged_heap_push (utils.py:471-533). Operates on one row given by base\n * offset. Rejects p >= root (ties dropped) and duplicates. Returns 1 if pushed.\n */\nexport function checkedFlaggedHeapPush(\n heap: NeighborHeap,\n row: number,\n p: number,\n n: number,\n f: number,\n): number {\n const size = heap.size;\n const base = row * size;\n const priorities = heap.distances;\n const indices = heap.indices;\n const flags = heap.flags;\n if (p >= priorities[base]!) return 0;\n for (let i = 0; i < size; i++) {\n if (indices[base + i] === n) return 0;\n }\n // sift down from root\n let i = 0;\n for (;;) {\n const ic1 = 2 * i + 1;\n const ic2 = ic1 + 1;\n let iSwap: number;\n if (ic1 >= size) break;\n if (ic2 >= size) {\n if (priorities[base + ic1]! > p) iSwap = ic1;\n else break;\n } else if (priorities[base + ic1]! >= priorities[base + ic2]!) {\n if (p < priorities[base + ic1]!) iSwap = ic1;\n else break;\n } else {\n if (p < priorities[base + ic2]!) iSwap = ic2;\n else break;\n }\n priorities[base + i] = priorities[base + iSwap]!;\n indices[base + i] = indices[base + iSwap]!;\n flags[base + i] = flags[base + iSwap]!;\n i = iSwap;\n }\n priorities[base + i] = p;\n indices[base + i] = n;\n flags[base + i] = f;\n return 1;\n}\n\n/** checked_heap_push (utils.py:409-468) — no flags. */\nexport function checkedHeapPush(\n priorities: Float32Array,\n indices: Int32Array,\n base: number,\n size: number,\n p: number,\n n: number,\n): number {\n if (p >= priorities[base]!) return 0;\n for (let i = 0; i < size; i++) {\n if (indices[base + i] === n) return 0;\n }\n let i = 0;\n for (;;) {\n const ic1 = 2 * i + 1;\n const ic2 = ic1 + 1;\n let iSwap: number;\n if (ic1 >= size) break;\n if (ic2 >= size) {\n if (priorities[base + ic1]! > p) iSwap = ic1;\n else break;\n } else if (priorities[base + ic1]! >= priorities[base + ic2]!) {\n if (p < priorities[base + ic1]!) iSwap = ic1;\n else break;\n } else {\n if (p < priorities[base + ic2]!) iSwap = ic2;\n else break;\n }\n priorities[base + i] = priorities[base + iSwap]!;\n indices[base + i] = indices[base + iSwap]!;\n i = iSwap;\n }\n priorities[base + i] = p;\n indices[base + i] = n;\n return 1;\n}\n\n/** simple_heap_push (utils.py:352-406) — no duplicate scan (query uses visited mask). */\nexport function simpleHeapPush(\n priorities: Float32Array,\n indices: Int32Array,\n size: number,\n p: number,\n n: number,\n): number {\n if (p >= priorities[0]!) return 0;\n let i = 0;\n for (;;) {\n const ic1 = 2 * i + 1;\n const ic2 = ic1 + 1;\n let iSwap: number;\n if (ic1 >= size) break;\n if (ic2 >= size) {\n if (priorities[ic1]! > p) iSwap = ic1;\n else break;\n } else if (priorities[ic1]! >= priorities[ic2]!) {\n if (p < priorities[ic1]!) iSwap = ic1;\n else break;\n } else {\n if (p < priorities[ic2]!) iSwap = ic2;\n else break;\n }\n priorities[i] = priorities[iSwap]!;\n indices[i] = indices[iSwap]!;\n i = iSwap;\n }\n priorities[i] = p;\n indices[i] = n;\n return 1;\n}\n\nfunction siftdownRange(\n distances: Float32Array,\n indices: Int32Array,\n base: number,\n len: number,\n elt: number,\n): void {\n // utils.py:165-186 — restore max-heap over [base, base+len)\n let e = elt;\n while (e * 2 + 1 < len) {\n const leftChild = e * 2 + 1;\n const rightChild = leftChild + 1;\n let swap = e;\n if (distances[base + swap]! < distances[base + leftChild]!) swap = leftChild;\n if (rightChild < len && distances[base + swap]! < distances[base + rightChild]!) {\n swap = rightChild;\n }\n if (swap === e) break;\n const td = distances[base + e]!;\n distances[base + e] = distances[base + swap]!;\n distances[base + swap] = td;\n const ti = indices[base + e]!;\n indices[base + e] = indices[base + swap]!;\n indices[base + swap] = ti;\n e = swap;\n }\n}\n\n/** deheap_sort (utils.py:189-218): per-row heapsort → ascending, (-1, inf) tail. */\nexport function deheapSort(heap: NeighborHeap): void {\n const { indices, distances, n, size } = heap;\n for (let r = 0; r < n; r++) {\n const base = r * size;\n for (let j = size - 1; j > 0; j--) {\n const td = distances[base]!;\n distances[base] = distances[base + j]!;\n distances[base + j] = td;\n const ti = indices[base]!;\n indices[base] = indices[base + j]!;\n indices[base + j] = ti;\n siftdownRange(distances, indices, base, j, 0);\n }\n }\n}\n","/**\n * NN-descent (pynndescent_.py @ 0.6.0, notes §3-4). Single-threaded deterministic\n * structure (seeded umap forces n_jobs=1). Updates are applied directly rather than\n * via per-thread buffers — same candidate sets and acceptance rules, so the result\n * quality is equivalent (recall-gated, not bitwise; §5.5).\n */\n\nimport { floorMod, tauRand, tauRandInt } from '../rng.js';\nimport {\n checkedFlaggedHeapPush,\n checkedHeapPush,\n deheapSort,\n makeHeap,\n type NeighborHeap,\n} from './heap.js';\n\nexport type DistFn = (i: number, j: number) => number;\n\nexport interface NnDescentOptions {\n maxCandidates?: number;\n nIters?: number;\n delta?: number;\n /** dense leaf init: d < max(tp,tq); sparse: d < tp or d < tq (notes §9) */\n leafAcceptance?: 'max' | 'either';\n /** per-iteration progress hook (the library never writes to the console) */\n onIteration?: (iter: number, c: number) => void;\n}\n\n/** init_rp_tree: all pairs within each leaf. */\nexport function initRpTree(\n nLeaves: number,\n leafCols: number,\n leafArray: Int32Array,\n heap: NeighborHeap,\n dist: DistFn,\n leafAcceptance: 'max' | 'either' = 'max',\n): void {\n const k = heap.size;\n const distances = heap.distances;\n const either = leafAcceptance === 'either';\n for (let leaf = 0; leaf < nLeaves; leaf++) {\n const base = leaf * leafCols;\n for (let a = 0; a < leafCols; a++) {\n const p = leafArray[base + a]!;\n if (p < 0) break;\n for (let b = a + 1; b < leafCols; b++) {\n const q = leafArray[base + b]!;\n if (q < 0) break;\n const d = dist(p, q);\n // dense: d < max(th_p, th_q) (pynndescent_.py:103-104); sparse: either (sparse_nndescent.py:67)\n const accept = either\n ? d < distances[p * k]! || d < distances[q * k]!\n : d < Math.max(distances[p * k]!, distances[q * k]!);\n if (accept) {\n checkedFlaggedHeapPush(heap, p, d, q, 1);\n checkedFlaggedHeapPush(heap, q, d, p, 1);\n }\n }\n }\n }\n}\n\n/** init_random: one attempt per missing slot (pynndescent_.py:188-203). */\nexport function initRandom(\n n: number,\n heap: NeighborHeap,\n dist: DistFn,\n rngState: Int32Array,\n): void {\n const k = heap.size;\n for (let i = 0; i < n; i++) {\n if (heap.indices[i * k]! < 0) {\n let filled = 0;\n for (let j = 0; j < k; j++) if (heap.indices[i * k + j]! >= 0) filled++;\n const missing = k - filled;\n for (let j = 0; j < missing; j++) {\n const idx = Math.abs(tauRandInt(rngState)) % n;\n const d = dist(idx, i);\n checkedFlaggedHeapPush(heap, i, d, idx, 1);\n }\n }\n }\n}\n\n/**\n * new_build_candidates (utils.py:221-320): sample up to maxCandidates new/old\n * candidates per vertex via random priorities; clear \"new\" flags for sampled entries.\n * The master rng state is NOT advanced (per-thread copies in Python; thread 0 here).\n */\nfunction buildCandidates(\n heap: NeighborHeap,\n maxCandidates: number,\n masterRng: Int32Array,\n): { newIdx: Int32Array; oldIdx: Int32Array } {\n const n = heap.n;\n const k = heap.size;\n const newIdx = new Int32Array(n * maxCandidates).fill(-1);\n const newPri = new Float32Array(n * maxCandidates).fill(Infinity);\n const oldIdx = new Int32Array(n * maxCandidates).fill(-1);\n const oldPri = new Float32Array(n * maxCandidates).fill(Infinity);\n\n const localRng = Int32Array.from(masterRng); // copy — master not advanced\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < k; j++) {\n const idx = heap.indices[i * k + j]!;\n if (idx < 0) continue;\n const d = tauRand(localRng);\n const isNew = heap.flags[i * k + j]! === 1;\n if (isNew) {\n checkedHeapPush(newPri, newIdx, i * maxCandidates, maxCandidates, d, idx);\n checkedHeapPush(newPri, newIdx, idx * maxCandidates, maxCandidates, d, i);\n } else {\n checkedHeapPush(oldPri, oldIdx, i * maxCandidates, maxCandidates, d, idx);\n checkedHeapPush(oldPri, oldIdx, idx * maxCandidates, maxCandidates, d, i);\n }\n }\n }\n // flag reset pass: sampled \"new\" entries become old\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < k; j++) {\n const idx = heap.indices[i * k + j]!;\n if (idx < 0 || heap.flags[i * k + j] !== 1) continue;\n const cbase = i * maxCandidates;\n for (let c = 0; c < maxCandidates; c++) {\n if (newIdx[cbase + c] === idx) {\n heap.flags[i * k + j] = 0;\n break;\n }\n }\n }\n }\n return { newIdx, oldIdx };\n}\n\n/** Local joins over candidate lists; returns number of successful pushes. */\nfunction processCandidates(\n heap: NeighborHeap,\n newIdx: Int32Array,\n oldIdx: Int32Array,\n maxCandidates: number,\n dist: DistFn,\n): number {\n const n = heap.n;\n const k = heap.size;\n const distances = heap.distances;\n let c = 0;\n for (let i = 0; i < n; i++) {\n const base = i * maxCandidates;\n for (let j = 0; j < maxCandidates; j++) {\n const p = newIdx[base + j]!;\n if (p < 0) continue;\n // new-new pairs, k from j (INCLUDES k == j ⇒ (p,p,0) self-edge; umap depends on it)\n for (let t = j; t < maxCandidates; t++) {\n const q = newIdx[base + t]!;\n if (q < 0) continue;\n const d = dist(p, q);\n if (d <= Math.max(distances[p * k]!, distances[q * k]!)) {\n c += checkedFlaggedHeapPush(heap, p, d, q, 1);\n c += checkedFlaggedHeapPush(heap, q, d, p, 1);\n }\n }\n // new-old pairs\n for (let t = 0; t < maxCandidates; t++) {\n const q = oldIdx[base + t]!;\n if (q < 0) continue;\n const d = dist(p, q);\n if (d <= Math.max(distances[p * k]!, distances[q * k]!)) {\n c += checkedFlaggedHeapPush(heap, p, d, q, 1);\n c += checkedFlaggedHeapPush(heap, q, d, p, 1);\n }\n }\n }\n }\n return c;\n}\n\n/**\n * Full NN-descent. `leafArray` from the RP forest (or null to skip tree init).\n * Returns the heap AFTER deheap_sort: ascending distances, (-1, inf) tails.\n * Distances are in the INTERNAL metric space (corrections applied by the caller).\n */\nexport function nnDescent(\n n: number,\n nNeighbors: number,\n dist: DistFn,\n rngState: Int32Array,\n leafArray: { data: Int32Array; rows: number; cols: number } | null,\n {\n maxCandidates = 60,\n nIters = 10,\n delta = 0.001,\n leafAcceptance = 'max',\n onIteration,\n }: NnDescentOptions = {},\n): NeighborHeap {\n const heap = makeHeap(n, nNeighbors);\n if (leafArray) {\n initRpTree(leafArray.rows, leafArray.cols, leafArray.data, heap, dist, leafAcceptance);\n }\n initRandom(n, heap, dist, rngState);\n\n for (let iter = 0; iter < nIters; iter++) {\n const { newIdx, oldIdx } = buildCandidates(heap, maxCandidates, rngState);\n const c = processCandidates(heap, newIdx, oldIdx, maxCandidates, dist);\n onIteration?.(iter, c);\n if (c <= delta * nNeighbors * n) break;\n }\n deheapSort(heap);\n return heap;\n}\n\n/** umap's NNDescent parameter rules (umap_.py:327-328). */\nexport function umapNnDescentParams(n: number): { nTrees: number; nIters: number } {\n return {\n nTrees: Math.min(64, 5 + Math.round(Math.sqrt(n) / 20.0)),\n nIters: Math.max(5, Math.round(Math.log2(n))),\n };\n}\n\n/** Random-fill count used by query init. */\nexport function missingSlots(heap: NeighborHeap, row: number): number {\n let filled = 0;\n for (let j = 0; j < heap.size; j++) if (heap.indices[row * heap.size + j]! >= 0) filled++;\n return heap.size - filled;\n}\n\nexport { floorMod };\n","/**\n * Random-projection forest (pynndescent rp_trees.py @ 0.6.0; notes §2).\n * Dense euclidean + angular splits, flat preorder trees, leaf arrays for descent\n * init, and the 0.6.0 graph-informed hub tree used as the search tree.\n */\n\nimport { floorMod, tauRandInt } from '../rng.js';\nimport type { Matrix } from '../types.js';\n\nexport const RP_EPS = 1e-8;\nexport const MIN_SPLIT_BALANCE = 0.1;\n\nexport interface FlatTree {\n /** nNodes × dim hyperplane vectors (dense) */\n hyperplanes: Float32Array;\n offsets: Float32Array;\n /** nNodes × 2; internal: child node ids (>0); leaf: (-leafStart, -leafEnd) */\n children: Int32Array;\n /** concatenated leaf point indices (a permutation of all points) */\n indices: Int32Array;\n leafSize: number;\n nNodes: number;\n dim: number;\n}\n\ninterface BuildNode {\n left: BuildNode | null;\n right: BuildNode | null;\n hyperplane: Float32Array | null;\n offset: number;\n points: Int32Array | null;\n}\n\nexport function defaultLeafSize(nNeighbors: number): number {\n return Math.max(60, Math.min(256, 5 * nNeighbors));\n}\n\ninterface SplitResult {\n left: Int32Array;\n right: Int32Array;\n hyperplane: Float32Array;\n offset: number;\n}\n\nfunction partition(indices: Int32Array, side: Uint8Array, nLeft: number, nRight: number) {\n const left = new Int32Array(nLeft);\n const right = new Int32Array(nRight);\n let il = 0;\n let ir = 0;\n for (let i = 0; i < indices.length; i++) {\n if (side[i] === 0) left[il++] = indices[i]!;\n else right[ir++] = indices[i]!;\n }\n return { left, right };\n}\n\nfunction euclideanSplit(\n data: Float32Array,\n dim: number,\n indices: Int32Array,\n rngState: Int32Array,\n): SplitResult {\n const n = indices.length;\n const leftIndex = floorMod(tauRandInt(rngState), n);\n let rightIndex = floorMod(tauRandInt(rngState), n);\n if (leftIndex === rightIndex) rightIndex += 1;\n rightIndex = floorMod(rightIndex, n);\n const l = indices[leftIndex]!;\n const r = indices[rightIndex]!;\n\n const hyperplane = new Float32Array(dim);\n let offset = 0;\n for (let d = 0; d < dim; d++) {\n const hv = data[l * dim + d]! - data[r * dim + d]!;\n hyperplane[d] = hv;\n offset -= (hv * (data[l * dim + d]! + data[r * dim + d]!)) / 2.0;\n }\n\n const side = new Uint8Array(n);\n let nLeft = 0;\n let nRight = 0;\n for (let i = 0; i < n; i++) {\n let margin = offset;\n const p = indices[i]!;\n for (let d = 0; d < dim; d++) margin += hyperplane[d]! * data[p * dim + d]!;\n if (Math.abs(margin) < RP_EPS) {\n side[i] = Math.abs(tauRandInt(rngState)) % 2;\n } else if (margin > 0) {\n side[i] = 0;\n } else {\n side[i] = 1;\n }\n if (side[i] === 0) nLeft++;\n else nRight++;\n }\n if (nLeft === 0 || nRight === 0) {\n nLeft = 0;\n nRight = 0;\n for (let i = 0; i < n; i++) {\n side[i] = floorMod(tauRandInt(rngState), 2);\n if (side[i] === 0) nLeft++;\n else nRight++;\n }\n }\n const { left, right } = partition(indices, side, nLeft, nRight);\n return { left, right, hyperplane, offset };\n}\n\nfunction angularSplit(\n data: Float32Array,\n dim: number,\n indices: Int32Array,\n rngState: Int32Array,\n): SplitResult {\n const n = indices.length;\n const leftIndex = floorMod(tauRandInt(rngState), n);\n let rightIndex = floorMod(tauRandInt(rngState), n);\n if (leftIndex === rightIndex) rightIndex += 1;\n rightIndex = floorMod(rightIndex, n);\n const l = indices[leftIndex]!;\n const r = indices[rightIndex]!;\n\n let leftNorm = 0;\n let rightNorm = 0;\n for (let d = 0; d < dim; d++) {\n leftNorm += data[l * dim + d]! * data[l * dim + d]!;\n rightNorm += data[r * dim + d]! * data[r * dim + d]!;\n }\n leftNorm = Math.sqrt(leftNorm);\n rightNorm = Math.sqrt(rightNorm);\n if (Math.abs(leftNorm) < RP_EPS) leftNorm = 1.0;\n if (Math.abs(rightNorm) < RP_EPS) rightNorm = 1.0;\n\n const hyperplane = new Float32Array(dim);\n let hnorm = 0;\n for (let d = 0; d < dim; d++) {\n const hv = data[l * dim + d]! / leftNorm - data[r * dim + d]! / rightNorm;\n hyperplane[d] = hv;\n hnorm += hv * hv;\n }\n hnorm = Math.sqrt(hnorm);\n if (Math.abs(hnorm) < RP_EPS) hnorm = 1.0;\n for (let d = 0; d < dim; d++) hyperplane[d] = hyperplane[d]! / hnorm;\n\n const side = new Uint8Array(n);\n let nLeft = 0;\n let nRight = 0;\n for (let i = 0; i < n; i++) {\n let margin = 0;\n const p = indices[i]!;\n for (let d = 0; d < dim; d++) margin += hyperplane[d]! * data[p * dim + d]!;\n if (Math.abs(margin) < RP_EPS) {\n side[i] = floorMod(tauRandInt(rngState), 2);\n } else if (margin > 0) {\n side[i] = 0;\n } else {\n side[i] = 1;\n }\n if (side[i] === 0) nLeft++;\n else nRight++;\n }\n if (nLeft === 0 || nRight === 0) {\n nLeft = 0;\n nRight = 0;\n for (let i = 0; i < n; i++) {\n side[i] = floorMod(tauRandInt(rngState), 2);\n if (side[i] === 0) nLeft++;\n else nRight++;\n }\n }\n const { left, right } = partition(indices, side, nLeft, nRight);\n return { left, right, hyperplane, offset: 0.0 };\n}\n\nfunction buildTree(\n data: Float32Array,\n dim: number,\n indices: Int32Array,\n leafSize: number,\n maxDepth: number,\n angular: boolean,\n rngState: Int32Array,\n): BuildNode {\n if (indices.length > leafSize && maxDepth > 0) {\n const { left, right, hyperplane, offset } = angular\n ? angularSplit(data, dim, indices, rngState)\n : euclideanSplit(data, dim, indices, rngState);\n return {\n left: buildTree(data, dim, left, leafSize, maxDepth - 1, angular, rngState),\n right: buildTree(data, dim, right, leafSize, maxDepth - 1, angular, rngState),\n hyperplane,\n offset,\n points: null,\n };\n }\n return { left: null, right: null, hyperplane: null, offset: 0, points: indices };\n}\n\n/** Flatten to preorder (convert_tree_format, rp_trees.py:3019-3049). */\nexport function flattenTree(root: BuildNode, nPoints: number, dim: number): FlatTree {\n let nNodes = 0;\n let maxLeaf = 0;\n const count = (node: BuildNode): void => {\n nNodes++;\n if (node.points) {\n if (node.points.length > maxLeaf) maxLeaf = node.points.length;\n } else {\n count(node.left!);\n count(node.right!);\n }\n };\n count(root);\n const hyperplanes = new Float32Array(nNodes * dim);\n const offsets = new Float32Array(nNodes);\n const children = new Int32Array(nNodes * 2).fill(-1);\n const indices = new Int32Array(nPoints).fill(-1);\n let nodeNum = 0;\n let leafStart = 0;\n const walk = (node: BuildNode): void => {\n const my = nodeNum;\n if (node.points) {\n children[my * 2] = -leafStart;\n children[my * 2 + 1] = -(leafStart + node.points.length);\n indices.set(node.points, leafStart);\n leafStart += node.points.length;\n return;\n }\n hyperplanes.set(node.hyperplane!, my * dim);\n offsets[my] = node.offset;\n nodeNum++;\n children[my * 2] = nodeNum;\n walk(node.left!);\n nodeNum++;\n children[my * 2 + 1] = nodeNum;\n walk(node.right!);\n };\n walk(root);\n return { hyperplanes, offsets, children, indices, leafSize: maxLeaf, nNodes, dim };\n}\n\nexport interface MakeForestOptions {\n leafSize?: number;\n angular?: boolean;\n maxDepth?: number;\n}\n\n/** make_forest: per-tree tau states drawn from the master PRNG. */\nexport function makeForest(\n X: Matrix,\n nNeighbors: number,\n nTrees: number,\n treeStates: Int32Array[], // one Int32Array(3) per tree\n { leafSize, angular = false, maxDepth = 200 }: MakeForestOptions = {},\n): FlatTree[] {\n const ls = leafSize ?? defaultLeafSize(nNeighbors);\n const all = new Int32Array(X.rows);\n for (let i = 0; i < X.rows; i++) all[i] = i;\n const forest: FlatTree[] = [];\n for (let t = 0; t < nTrees; t++) {\n const root = buildTree(X.data, X.cols, all.slice(), ls, maxDepth, angular, treeStates[t]!);\n forest.push(flattenTree(root, X.rows, X.cols));\n }\n return forest;\n}\n\n/** rptree_leaf_array: rows = leaves, padded with -1 to the forest-wide max leaf size. */\nexport function leafArrayFromForest(forest: FlatTree[]): {\n data: Int32Array;\n rows: number;\n cols: number;\n} {\n if (forest.length === 0) return { data: new Int32Array([-1]), rows: 1, cols: 1 };\n let maxLeafSize = 0;\n for (const t of forest) maxLeafSize = Math.max(maxLeafSize, t.leafSize);\n const rows: Int32Array[] = [];\n for (const t of forest) {\n for (let node = 0; node < t.nNodes; node++) {\n const c0 = t.children[node * 2]!;\n if (c0 <= 0) {\n const start = -c0;\n const end = -t.children[node * 2 + 1]!;\n const row = new Int32Array(maxLeafSize).fill(-1);\n row.set(t.indices.subarray(start, end));\n rows.push(row);\n }\n }\n }\n const out = new Int32Array(rows.length * maxLeafSize);\n rows.forEach((r, i) => {\n out.set(r, i * maxLeafSize);\n });\n return { data: out, rows: rows.length, cols: maxLeafSize };\n}\n\n/** search_flat_tree descent → [leafStart, leafEnd) into tree.indices. */\nexport function searchFlatTree(\n tree: FlatTree,\n point: Float32Array,\n rngState: Int32Array,\n): [number, number] {\n let node = 0;\n while (tree.children[node * 2]! > 0) {\n // select_side (rp_trees.py:2662-2677)\n let margin = tree.offsets[node]!;\n const base = node * tree.dim;\n for (let d = 0; d < tree.dim; d++) margin += tree.hyperplanes[base + d]! * point[d]!;\n let side: number;\n if (Math.abs(margin) < RP_EPS) side = Math.abs(tauRandInt(rngState)) % 2;\n else side = margin > 0 ? 0 : 1;\n node = tree.children[node * 2 + side]!;\n }\n return [-tree.children[node * 2]!, -tree.children[node * 2 + 1]!];\n}\n\n// ---------------------------------------------------------------------------\n// 0.6.0 hub tree (search tree built from the finished kNN graph; notes §6.1)\n// ---------------------------------------------------------------------------\n\ninterface HubSplitResult {\n hyperplane: Float32Array;\n offset: number;\n side: Uint8Array;\n nLeft: number;\n nRight: number;\n}\n\nfunction hubSplit(\n data: Float32Array,\n dim: number,\n indices: Int32Array,\n hubA: number,\n hubB: number,\n angular: boolean,\n): HubSplitResult {\n const n = indices.length;\n const hyperplane = new Float32Array(dim);\n let offset = 0;\n if (angular) {\n let an = 0;\n let bn = 0;\n for (let d = 0; d < dim; d++) {\n an += data[hubA * dim + d]! * data[hubA * dim + d]!;\n bn += data[hubB * dim + d]! * data[hubB * dim + d]!;\n }\n an = Math.sqrt(an);\n bn = Math.sqrt(bn);\n if (Math.abs(an) < RP_EPS) an = 1;\n if (Math.abs(bn) < RP_EPS) bn = 1;\n let hn = 0;\n for (let d = 0; d < dim; d++) {\n const hv = data[hubA * dim + d]! / an - data[hubB * dim + d]! / bn;\n hyperplane[d] = hv;\n hn += hv * hv;\n }\n hn = Math.sqrt(hn);\n if (Math.abs(hn) < RP_EPS) hn = 1;\n for (let d = 0; d < dim; d++) hyperplane[d] = hyperplane[d]! / hn;\n } else {\n for (let d = 0; d < dim; d++) {\n const hv = data[hubA * dim + d]! - data[hubB * dim + d]!;\n hyperplane[d] = hv;\n offset -= (hv * (data[hubA * dim + d]! + data[hubB * dim + d]!)) / 2.0;\n }\n }\n const side = new Uint8Array(n);\n let nLeft = 0;\n let nRight = 0;\n for (let i = 0; i < n; i++) {\n let margin = offset;\n const p = indices[i]!;\n for (let d = 0; d < dim; d++) margin += hyperplane[d]! * data[p * dim + d]!;\n let s: number;\n if (margin > RP_EPS) s = 0;\n else if (margin < -RP_EPS) s = 1;\n else s = i % 2; // deterministic alternation on ties — no rng in hub splits\n side[i] = s;\n if (s === 0) nLeft++;\n else nRight++;\n }\n return { hyperplane, offset, side, nLeft, nRight };\n}\n\n/** make_hub_tree (rp_trees.py:1232-1312) — top-3-degree hub pairs, best balance. */\nexport function makeHubTree(\n X: Matrix,\n knnIndices: Int32Array,\n leafSize = 30,\n angular = false,\n maxDepth = 200,\n): FlatTree {\n const n = X.rows;\n const degrees = new Int32Array(n);\n for (let t = 0; t < knnIndices.length; t++) {\n const j = knnIndices[t]!;\n if (j >= 0) degrees[j]!++;\n }\n\n const topHubs = (indices: Int32Array): number[] => {\n // top-3 by in-degree, strict > so earlier-seen wins ties\n const top: number[] = [];\n const topDeg: number[] = [];\n for (let i = 0; i < indices.length; i++) {\n const p = indices[i]!;\n const dg = degrees[p]!;\n let ins = -1;\n for (let s = 0; s < Math.min(3, top.length + 1); s++) {\n if (s >= top.length || dg > topDeg[s]!) {\n ins = s;\n break;\n }\n }\n if (ins >= 0) {\n top.splice(ins, 0, p);\n topDeg.splice(ins, 0, dg);\n if (top.length > 3) {\n top.pop();\n topDeg.pop();\n }\n }\n }\n return top;\n };\n\n const build = (indices: Int32Array, depth: number): BuildNode => {\n if (indices.length <= leafSize || depth <= 0) {\n return { left: null, right: null, hyperplane: null, offset: 0, points: indices };\n }\n const hubs = topHubs(indices);\n let best: HubSplitResult | null = null;\n let bestBalance = -1;\n for (let a = 0; a < hubs.length; a++) {\n for (let b = a + 1; b < hubs.length; b++) {\n const res = hubSplit(X.data, X.cols, indices, hubs[a]!, hubs[b]!, angular);\n if (res.nLeft === 0 || res.nRight === 0) continue;\n const balance = Math.min(res.nLeft, res.nRight) / indices.length;\n if (balance > bestBalance) {\n bestBalance = balance;\n best = res;\n }\n }\n }\n if (best === null || bestBalance < MIN_SPLIT_BALANCE) {\n return { left: null, right: null, hyperplane: null, offset: 0, points: indices };\n }\n const { left, right } = partition(indices, best.side, best.nLeft, best.nRight);\n return {\n left: build(left, depth - 1),\n right: build(right, depth - 1),\n hyperplane: best.hyperplane,\n offset: best.offset,\n points: null,\n };\n };\n\n const all = new Int32Array(n);\n for (let i = 0; i < n; i++) all[i] = i;\n return flattenTree(build(all, maxDepth), n, X.cols);\n}\n","/**\n * Search-graph preparation + query (pynndescent prepare()/query() @ 0.6.0, notes §6-7).\n * Dense data only (umap transform paths are dense; sparse fit needs no query).\n */\n\nimport { floorMod, tauRandInt } from '../rng.js';\nimport type { KnnGraph, Matrix } from '../types.js';\nimport { simpleHeapPush } from './heap.js';\nimport { FLOAT32_EPS } from './internal-metrics.js';\nimport { type FlatTree, makeHubTree, searchFlatTree } from './rpforest.js';\n\nexport type PairDist = (a: Float32Array, b: Float32Array) => number;\n\nexport interface SearchIndex {\n /** reordered connectivity graph (uint8 semantics: indices only) */\n indptr: Int32Array;\n indices: Int32Array;\n tree: FlatTree;\n /** reordered row idx → original idx */\n vertexOrder: Int32Array;\n /** reordered data rows */\n data: Matrix;\n dist: PairDist;\n correction: (d: number) => number;\n angular: boolean;\n minDistance: number;\n searchRngState: Int32Array;\n nNeighbors: number;\n}\n\ninterface CsrF32 {\n indptr: Int32Array;\n indices: Int32Array;\n data: Float32Array;\n n: number;\n}\n\n/** Forward diversify (pynndescent_.py:369-403) on sorted rows; prob = 1.0. */\nfunction diversifyRows(\n X: Matrix,\n dist: PairDist,\n knnIndices: Int32Array,\n knnDistances: Float32Array,\n k: number,\n): void {\n const n = X.rows;\n const d = X.cols;\n for (let i = 0; i < n; i++) {\n const base = i * k;\n let retained = 1; // slot 0 unconditionally kept\n for (let j = 1; j < k; j++) {\n const idxJ = knnIndices[base + j]!;\n if (idxJ < 0) break;\n let prune = false;\n for (let c = 0; c < retained; c++) {\n const idxC = knnIndices[base + c]!;\n if (knnDistances[base + c]! > FLOAT32_EPS) {\n const dd = dist(\n X.data.subarray(idxJ * d, (idxJ + 1) * d),\n X.data.subarray(idxC * d, (idxC + 1) * d),\n );\n if (dd < knnDistances[base + j]!) {\n prune = true;\n break;\n }\n }\n }\n if (!prune) {\n knnIndices[base + retained] = idxJ;\n knnDistances[base + retained] = knnDistances[base + j]!;\n retained++;\n }\n }\n for (let j = retained; j < k; j++) {\n knnIndices[base + j] = -1;\n knnDistances[base + j] = Infinity;\n }\n }\n}\n\nfunction csrTransposeF32(m: CsrF32): CsrF32 {\n const nnz = m.indptr[m.n]!;\n const counts = new Int32Array(m.n + 1);\n for (let t = 0; t < nnz; t++) counts[m.indices[t]! + 1]!++;\n for (let c = 0; c < m.n; c++) counts[c + 1]! += counts[c]!;\n const indptr = counts.slice();\n const indices = new Int32Array(nnz);\n const data = new Float32Array(nnz);\n const cursor = counts.slice(0, m.n);\n for (let r = 0; r < m.n; r++) {\n for (let p = m.indptr[r]!; p < m.indptr[r + 1]!; p++) {\n const c = m.indices[p]!;\n const dst = cursor[c]!++;\n indices[dst] = r;\n data[dst] = m.data[p]!;\n }\n }\n return { indptr, indices, data, n: m.n };\n}\n\n/** Reverse diversify (diversify_csr): per row in ascending-distance order. */\nfunction diversifyCsr(g: CsrF32, X: Matrix, dist: PairDist): void {\n const d = X.cols;\n for (let r = 0; r < g.n; r++) {\n const start = g.indptr[r]!;\n const end = g.indptr[r + 1]!;\n const len = end - start;\n if (len <= 1) continue;\n const order = Array.from({ length: len }, (_, i) => i).sort(\n (a, b) => g.data[start + a]! - g.data[start + b]!,\n );\n const retained: number[] = [];\n for (const oi of order) {\n const p = start + oi;\n const colJ = g.indices[p]!;\n const dj = g.data[p]!;\n let prune = false;\n for (const rp of retained) {\n if (g.data[rp]! > FLOAT32_EPS) {\n const dd = dist(\n X.data.subarray(colJ * d, (colJ + 1) * d),\n X.data.subarray(g.indices[rp]! * d, (g.indices[rp]! + 1) * d),\n );\n if (dd < dj) {\n prune = true;\n break;\n }\n }\n }\n if (prune) g.data[p] = 0;\n else retained.push(p);\n }\n }\n}\n\nfunction eliminateZerosF32(g: CsrF32): CsrF32 {\n const indptr = new Int32Array(g.n + 1);\n let nnz = 0;\n for (let t = 0; t < g.indptr[g.n]!; t++) if (g.data[t] !== 0) nnz++;\n const indices = new Int32Array(nnz);\n const data = new Float32Array(nnz);\n let w = 0;\n for (let r = 0; r < g.n; r++) {\n for (let p = g.indptr[r]!; p < g.indptr[r + 1]!; p++) {\n if (g.data[p] !== 0) {\n indices[w] = g.indices[p]!;\n data[w] = g.data[p]!;\n w++;\n }\n }\n indptr[r + 1] = w;\n }\n return { indptr, indices, data, n: g.n };\n}\n\n/** Elementwise maximum over union sparsity (rows sorted). */\nfunction csrMaximumF32(A: CsrF32, B: CsrF32): CsrF32 {\n const n = A.n;\n const indptr = new Int32Array(n + 1);\n const cap = A.indptr[n]! + B.indptr[n]!;\n const indices = new Int32Array(cap);\n const data = new Float32Array(cap);\n let nnz = 0;\n for (let r = 0; r < n; r++) {\n let pa = A.indptr[r]!;\n let pb = B.indptr[r]!;\n const ea = A.indptr[r + 1]!;\n const eb = B.indptr[r + 1]!;\n while (pa < ea || pb < eb) {\n const ca = pa < ea ? A.indices[pa]! : Infinity;\n const cb = pb < eb ? B.indices[pb]! : Infinity;\n let col: number;\n let v: number;\n if (ca < cb) {\n col = ca as number;\n v = A.data[pa]!;\n pa++;\n } else if (cb < ca) {\n col = cb as number;\n v = B.data[pb]!;\n pb++;\n } else {\n col = ca as number;\n v = Math.max(A.data[pa]!, B.data[pb]!);\n pa++;\n pb++;\n }\n if (col !== r) {\n // setdiag(0) folded in\n indices[nnz] = col;\n data[nnz] = v;\n nnz++;\n }\n }\n indptr[r + 1] = nnz;\n }\n return { indptr, indices: indices.slice(0, nnz), data: data.slice(0, nnz), n };\n}\n\n/** degree_prune: rows longer than maxDegree cut at the (maxDegree+1)-th smallest. */\nfunction degreePrune(g: CsrF32, maxDegree: number): CsrF32 {\n for (let r = 0; r < g.n; r++) {\n const start = g.indptr[r]!;\n const end = g.indptr[r + 1]!;\n if (end - start > maxDegree) {\n const vals = Array.from(g.data.subarray(start, end)).sort((a, b) => a - b);\n const cut = vals[maxDegree]!;\n for (let p = start; p < end; p++) {\n if (g.data[p]! > cut) g.data[p] = 0;\n }\n }\n }\n return eliminateZerosF32(g);\n}\n\nexport interface PrepareOptions {\n pruningDegreeMultiplier?: number; // 1.5\n searchLeafSize?: number; // 30\n maxDepth?: number; // 200\n}\n\n/**\n * Build the prepared search index from the finished kNN graph (notes §6).\n * `knn` must be the deheap-sorted neighbor graph in INTERNAL distance space.\n */\nexport function prepareSearchIndex(\n X: Matrix,\n knn: KnnGraph,\n dist: PairDist,\n correction: (d: number) => number,\n angular: boolean,\n nNeighbors: number,\n searchRngState: Int32Array,\n { pruningDegreeMultiplier = 1.5, searchLeafSize = 30, maxDepth = 200 }: PrepareOptions = {},\n): SearchIndex {\n const n = X.rows;\n const k = knn.k;\n // hub tree from the raw kNN indices (before diversification)\n const tree = makeHubTree(X, knn.indices, searchLeafSize, angular, maxDepth);\n\n // forward diversify on copies\n const divIdx = knn.indices.slice();\n const divDst = knn.distances.slice();\n diversifyRows(X, dist, divIdx, divDst, k);\n\n // CSR build: zeros → FLOAT32_EPS; -1 dropped\n let nnz = 0;\n for (let t = 0; t < divIdx.length; t++) if (divIdx[t]! >= 0) nnz++;\n const indptr = new Int32Array(n + 1);\n const indices = new Int32Array(nnz);\n const data = new Float32Array(nnz);\n let w = 0;\n for (let i = 0; i < n; i++) {\n // collect + sort columns for canonical CSR\n const cols: number[] = [];\n const vals: number[] = [];\n for (let j = 0; j < k; j++) {\n const idx = divIdx[i * k + j]!;\n if (idx < 0) continue;\n let v = divDst[i * k + j]!;\n if (v === 0) v = FLOAT32_EPS;\n cols.push(idx);\n vals.push(v);\n }\n const ord = cols.map((_, x) => x).sort((a, b) => cols[a]! - cols[b]!);\n for (const o of ord) {\n indices[w] = cols[o]!;\n data[w] = Math.fround(vals[o]!);\n w++;\n }\n indptr[i + 1] = w;\n }\n let graph: CsrF32 = { indptr, indices, data, n };\n let minDistance = Infinity;\n for (let t = 0; t < w; t++) if (data[t]! < minDistance) minDistance = data[t]!;\n\n // reverse diversify\n const reverse = csrTransposeF32(graph);\n diversifyCsr(reverse, X, dist);\n const reverseClean = eliminateZerosF32(reverse);\n\n // combine (max), setdiag 0 folded, eliminate, degree prune\n graph = csrMaximumF32(graph, reverseClean);\n graph = degreePrune(graph, Math.round(pruningDegreeMultiplier * nNeighbors));\n\n // vertex reorder into tree-leaf order\n const vertexOrder = tree.indices.slice(); // reordered idx -> original idx\n const inverse = new Int32Array(n);\n for (let i = 0; i < n; i++) inverse[vertexOrder[i]!] = i;\n\n // permute data rows\n const rdata = new Float32Array(X.data.length);\n const dcols = X.cols;\n for (let i = 0; i < n; i++) {\n rdata.set(X.data.subarray(vertexOrder[i]! * dcols, (vertexOrder[i]! + 1) * dcols), i * dcols);\n }\n const rX: Matrix = { data: rdata, rows: n, cols: dcols };\n\n // permute graph rows + remap cols (connectivity only from here)\n const rIndptr = new Int32Array(n + 1);\n for (let i = 0; i < n; i++) {\n const src = vertexOrder[i]!;\n rIndptr[i + 1] = rIndptr[i]! + (graph.indptr[src + 1]! - graph.indptr[src]!);\n }\n const rIndices = new Int32Array(rIndptr[n]!);\n for (let i = 0; i < n; i++) {\n const src = vertexOrder[i]!;\n let dst = rIndptr[i]!;\n for (let p = graph.indptr[src]!; p < graph.indptr[src + 1]!; p++) {\n rIndices[dst++] = inverse[graph.indices[p]!]!;\n }\n }\n\n // remap tree indices to reordered coordinates: leaves now list reordered ids 0..n-1\n const rTreeIndices = new Int32Array(n);\n for (let i = 0; i < n; i++) rTreeIndices[i] = inverse[tree.indices[i]!]!;\n const rTree: FlatTree = { ...tree, indices: rTreeIndices };\n\n return {\n indptr: rIndptr,\n indices: rIndices,\n tree: rTree,\n vertexOrder,\n data: rX,\n dist,\n correction,\n angular,\n minDistance,\n searchRngState,\n nNeighbors,\n };\n}\n\n/** Binary min-heap of (d, idx) pairs for the seed set (ties break on push order). */\nclass SeedHeap {\n d: number[] = [];\n v: number[] = [];\n get size(): number {\n return this.d.length;\n }\n push(dist: number, idx: number): void {\n const d = this.d;\n const v = this.v;\n d.push(dist);\n v.push(idx);\n let i = d.length - 1;\n while (i > 0) {\n const parent = (i - 1) >> 1;\n if (d[i]! < d[parent]! || (d[i]! === d[parent]! && v[i]! < v[parent]!)) {\n [d[i], d[parent]] = [d[parent]!, d[i]!];\n [v[i], v[parent]] = [v[parent]!, v[i]!];\n i = parent;\n } else break;\n }\n }\n pop(): [number, number] {\n const d = this.d;\n const v = this.v;\n const outD = d[0]!;\n const outV = v[0]!;\n const lastD = d.pop()!;\n const lastV = v.pop()!;\n if (d.length > 0) {\n d[0] = lastD;\n v[0] = lastV;\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n if (l < d.length && (d[l]! < d[m]! || (d[l]! === d[m]! && v[l]! < v[m]!))) m = l;\n if (r < d.length && (d[r]! < d[m]! || (d[r]! === d[m]! && v[r]! < v[m]!))) m = r;\n if (m === i) break;\n [d[i], d[m]] = [d[m]!, d[i]!];\n [v[i], v[m]] = [v[m]!, v[i]!];\n i = m;\n }\n }\n return [outD, outV];\n }\n}\n\n/**\n * Dense query (notes §7): tree init + random top-up + best-first expansion with\n * bound d_k + ε(d_k − minDistance). Returns ORIGINAL indices and CORRECTED distances.\n */\nexport function searchKnn(index: SearchIndex, Q: Matrix, k: number, epsilon: number): KnnGraph {\n const n = index.data.rows;\n const dim = index.data.cols;\n const nq = Q.rows;\n const outIdx = new Int32Array(nq * k).fill(-1);\n const outDst = new Float32Array(nq * k).fill(Infinity);\n const visited = new Uint8Array((n >> 3) + 1);\n const pri = new Float32Array(k);\n const idx = new Int32Array(k);\n const qbuf = new Float32Array(dim);\n\n for (let qi = 0; qi < nq; qi++) {\n visited.fill(0);\n pri.fill(Infinity);\n idx.fill(-1);\n let query = Q.data.subarray(qi * dim, (qi + 1) * dim);\n if (index.angular) {\n let norm = 0;\n for (let d = 0; d < dim; d++) norm += query[d]! * query[d]!;\n norm = Math.sqrt(norm);\n if (norm > 0) {\n for (let d = 0; d < dim; d++) qbuf[d] = query[d]! / norm;\n query = qbuf;\n }\n }\n const rng = Int32Array.from(index.searchRngState); // copied; master never advances\n const seeds = new SeedHeap();\n\n const [ls, le] = searchFlatTree(index.tree, query, rng);\n for (let p = ls; p < le; p++) {\n const cand = index.tree.indices[p]!;\n const d = index.dist(query, index.data.data.subarray(cand * dim, (cand + 1) * dim));\n simpleHeapPush(pri, idx, k, d, cand);\n seeds.push(d, cand);\n visited[cand >> 3] = visited[cand >> 3]! | (1 << (cand & 7));\n }\n const nRandom = Math.min(k, index.nNeighbors) - (le - ls);\n for (let j = 0; j < nRandom; j++) {\n const cand = Math.abs(tauRandInt(rng)) % n;\n if ((visited[cand >> 3]! & (1 << (cand & 7))) === 0) {\n visited[cand >> 3] = visited[cand >> 3]! | (1 << (cand & 7));\n const d = index.dist(query, index.data.data.subarray(cand * dim, (cand + 1) * dim));\n simpleHeapPush(pri, idx, k, d, cand);\n seeds.push(d, cand);\n }\n }\n\n let bound = pri[0]! + epsilon * (pri[0]! - index.minDistance);\n while (seeds.size > 0) {\n const [dv, vertex] = seeds.pop();\n if (dv >= bound) break;\n for (let p = index.indptr[vertex]!; p < index.indptr[vertex + 1]!; p++) {\n const cand = index.indices[p]!;\n if ((visited[cand >> 3]! & (1 << (cand & 7))) !== 0) continue;\n visited[cand >> 3] = visited[cand >> 3]! | (1 << (cand & 7));\n const d = index.dist(query, index.data.data.subarray(cand * dim, (cand + 1) * dim));\n if (d < bound) {\n simpleHeapPush(pri, idx, k, d, cand);\n seeds.push(d, cand);\n bound = pri[0]! + epsilon * (pri[0]! - index.minDistance);\n }\n }\n }\n\n // deheap-sort this row (ascending) into the output, mapping to original ids\n const rowIdx = idx.slice();\n const rowPri = pri.slice();\n const ord = Array.from({ length: k }, (_, x) => x).sort((a, b) => rowPri[a]! - rowPri[b]!);\n for (let j = 0; j < k; j++) {\n const o = ord[j]!;\n if (rowIdx[o]! >= 0) {\n outIdx[qi * k + j] = index.vertexOrder[rowIdx[o]!]!;\n outDst[qi * k + j] = index.correction(rowPri[o]!);\n }\n }\n }\n return { indices: outIdx, distances: outDst, k };\n}\n\nexport { floorMod };\n","/**\n * Sparse (CSR) RP-tree splits for NN-descent tree init (rp_trees.py:434-677).\n * Only the leaf array is needed for the descent (search trees are dense-only here).\n */\n\nimport { floorMod, tauRandInt } from '../rng.js';\nimport type { CSRInput } from '../types.js';\nimport { RP_EPS } from './rpforest.js';\n\ninterface SparseVec {\n inds: Int32Array;\n data: Float64Array;\n}\n\nfunction sparseRow(X: CSRInput, i: number): { inds: Int32Array; data: Float32Array } {\n return {\n inds: X.indices.subarray(X.indptr[i]!, X.indptr[i + 1]!),\n data: X.data.subarray(X.indptr[i]!, X.indptr[i + 1]!),\n };\n}\n\n/** merged a*sa + b*sb over union of sparse supports */\nfunction sparseCombine(\n aInds: Int32Array,\n aData: ArrayLike<number>,\n sa: number,\n bInds: Int32Array,\n bData: ArrayLike<number>,\n sb: number,\n): SparseVec {\n const out: number[] = [];\n const outI: number[] = [];\n let i = 0;\n let j = 0;\n while (i < aInds.length && j < bInds.length) {\n const ca = aInds[i]!;\n const cb = bInds[j]!;\n if (ca === cb) {\n const v = sa * (aData[i] as number) + sb * (bData[j] as number);\n if (v !== 0) {\n outI.push(ca);\n out.push(v);\n }\n i++;\n j++;\n } else if (ca < cb) {\n const v = sa * (aData[i] as number);\n if (v !== 0) {\n outI.push(ca);\n out.push(v);\n }\n i++;\n } else {\n const v = sb * (bData[j] as number);\n if (v !== 0) {\n outI.push(cb);\n out.push(v);\n }\n j++;\n }\n }\n for (; i < aInds.length; i++) {\n const v = sa * (aData[i] as number);\n if (v !== 0) {\n outI.push(aInds[i]!);\n out.push(v);\n }\n }\n for (; j < bInds.length; j++) {\n const v = sb * (bData[j] as number);\n if (v !== 0) {\n outI.push(bInds[j]!);\n out.push(v);\n }\n }\n return { inds: Int32Array.from(outI), data: Float64Array.from(out) };\n}\n\nfunction sparseDot(\n aInds: Int32Array,\n aData: ArrayLike<number>,\n bInds: Int32Array,\n bData: ArrayLike<number>,\n): number {\n let r = 0;\n let i = 0;\n let j = 0;\n while (i < aInds.length && j < bInds.length) {\n const ca = aInds[i]!;\n const cb = bInds[j]!;\n if (ca === cb) {\n r += (aData[i] as number) * (bData[j] as number);\n i++;\n j++;\n } else if (ca < cb) i++;\n else j++;\n }\n return r;\n}\n\nfunction norm(v: ArrayLike<number>): number {\n let s = 0;\n for (let i = 0; i < v.length; i++) s += (v[i] as number) * (v[i] as number);\n return Math.sqrt(s);\n}\n\nfunction sparseSplit(\n X: CSRInput,\n indices: Int32Array,\n rngState: Int32Array,\n angular: boolean,\n): { left: Int32Array; right: Int32Array } {\n const n = indices.length;\n const leftIndex = floorMod(Math.abs(tauRandInt(rngState)), n);\n let rightIndex = floorMod(Math.abs(tauRandInt(rngState)), n);\n if (leftIndex === rightIndex) rightIndex += 1;\n rightIndex = floorMod(rightIndex, n);\n const l = indices[leftIndex]!;\n const r = indices[rightIndex]!;\n const rowL = sparseRow(X, l);\n const rowR = sparseRow(X, r);\n\n let hyperplane: SparseVec;\n let offset = 0;\n if (angular) {\n let ln = norm(rowL.data);\n let rn = norm(rowR.data);\n if (Math.abs(ln) < RP_EPS) ln = 1;\n if (Math.abs(rn) < RP_EPS) rn = 1;\n hyperplane = sparseCombine(rowL.inds, rowL.data, 1 / ln, rowR.inds, rowR.data, -1 / rn);\n let hn = norm(hyperplane.data);\n if (Math.abs(hn) < RP_EPS) hn = 1;\n for (let t = 0; t < hyperplane.data.length; t++) {\n hyperplane.data[t] = hyperplane.data[t]! / hn;\n }\n } else {\n hyperplane = sparseCombine(rowL.inds, rowL.data, 1, rowR.inds, rowR.data, -1);\n const mid = sparseCombine(rowL.inds, rowL.data, 0.5, rowR.inds, rowR.data, 0.5);\n offset = -sparseDot(hyperplane.inds, hyperplane.data, mid.inds, mid.data);\n }\n\n const side = new Uint8Array(n);\n let nLeft = 0;\n let nRight = 0;\n for (let i = 0; i < n; i++) {\n const p = indices[i]!;\n const row = sparseRow(X, p);\n const margin = offset + sparseDot(hyperplane.inds, hyperplane.data, row.inds, row.data);\n if (Math.abs(margin) < RP_EPS) {\n side[i] = floorMod(tauRandInt(rngState), 2);\n } else if (margin > 0) {\n side[i] = 0;\n } else {\n side[i] = 1;\n }\n if (side[i] === 0) nLeft++;\n else nRight++;\n }\n if (nLeft === 0 || nRight === 0) {\n nLeft = 0;\n nRight = 0;\n for (let i = 0; i < n; i++) {\n side[i] = floorMod(tauRandInt(rngState), 2);\n if (side[i] === 0) nLeft++;\n else nRight++;\n }\n }\n const left = new Int32Array(nLeft);\n const right = new Int32Array(nRight);\n let il = 0;\n let ir = 0;\n for (let i = 0; i < n; i++) {\n if (side[i] === 0) left[il++] = indices[i]!;\n else right[ir++] = indices[i]!;\n }\n return { left, right };\n}\n\n/**\n * Build only the leaf arrays of a sparse RP forest (descent init needs nothing else).\n */\nexport function sparseForestLeafArray(\n X: CSRInput,\n nNeighbors: number,\n nTrees: number,\n treeStates: Int32Array[],\n angular: boolean,\n maxDepth = 200,\n): { data: Int32Array; rows: number; cols: number } {\n const leafSize = Math.max(60, Math.min(256, 5 * nNeighbors));\n const leaves: Int32Array[] = [];\n let maxLeaf = 0;\n\n const build = (indices: Int32Array, depth: number, rngState: Int32Array): void => {\n if (indices.length > leafSize && depth > 0) {\n const { left, right } = sparseSplit(X, indices, rngState, angular);\n build(left, depth - 1, rngState);\n build(right, depth - 1, rngState);\n } else {\n leaves.push(indices);\n if (indices.length > maxLeaf) maxLeaf = indices.length;\n }\n };\n\n const all = new Int32Array(X.rows);\n for (let i = 0; i < X.rows; i++) all[i] = i;\n for (let t = 0; t < nTrees; t++) {\n build(all.slice(), maxDepth, treeStates[t]!);\n }\n const out = new Int32Array(leaves.length * maxLeaf).fill(-1);\n leaves.forEach((leaf, i) => {\n out.set(leaf, i * maxLeaf);\n });\n return { data: out, rows: leaves.length, cols: maxLeaf };\n}\n","/**\n * nearestNeighbors orchestration matching umap-learn semantics (notes §12):\n * exact below the 4096 cutoff (unless forceApproximation), NNDescent otherwise;\n * 'precomputed' handled by the caller via knnFromPrecomputed.\n */\n\nimport type { MetricOptions } from '../metrics.js';\nimport { type Pcg32, tauRandInt } from '../rng.js';\nimport type { CSRInput, KnnGraph, Matrix } from '../types.js';\nimport { exactKnnDense, exactKnnSparse } from './exact.js';\nimport { resolveInternalMetric, resolveSparseInternalMetric } from './internal-metrics.js';\nimport { nnDescent, umapNnDescentParams } from './nndescent.js';\nimport { defaultLeafSize, leafArrayFromForest, makeForest } from './rpforest.js';\nimport { prepareSearchIndex, type SearchIndex } from './search.js';\nimport { sparseForestLeafArray } from './sparse-forest.js';\n\nexport const SMALL_DATA_CUTOFF = 4096;\n\nexport interface NearestNeighborsResult {\n knn: KnnGraph;\n /** present only for the approximate (NNDescent) dense path */\n searchIndex: SearchIndex | null;\n /** which path ran */\n method: 'exact' | 'nndescent';\n}\n\nexport interface NearestNeighborsOptions {\n metricOptions?: MetricOptions;\n forceApproximation?: boolean;\n /** accepted and ignored, matching the pinned pynndescent 0.6.0 (D-007) */\n lowMemory?: boolean;\n /** force angular RP-tree splits; ORed with the metric family like Python */\n angularRpForest?: boolean;\n disconnectionDistance?: number;\n}\n\nexport function nearestNeighborsDense(\n X: Matrix,\n nNeighbors: number,\n metricName: string,\n rng: Pcg32,\n {\n metricOptions = {},\n forceApproximation = false,\n angularRpForest = false,\n disconnectionDistance = Infinity,\n }: NearestNeighborsOptions = {},\n): NearestNeighborsResult {\n if (X.rows < SMALL_DATA_CUTOFF && !forceApproximation) {\n const knn = exactKnnDense(X, nNeighbors, metricName, {\n metricOptions,\n disconnectionDistance,\n });\n return { knn, searchIndex: null, method: 'exact' };\n }\n const internal = resolveInternalMetric(metricName, metricOptions);\n const angular = internal.angularTrees || angularRpForest;\n const { nTrees, nIters } = umapNnDescentParams(X.rows);\n\n // rng consumption order mirrors pynndescent __init__ (notes §10)\n const rngState = rng.tauState();\n const searchRngState = rng.tauState();\n for (let i = 0; i < 10; i++) tauRandInt(searchRngState); // warm-up draws\n\n const treeStates: Int32Array[] = [];\n for (let t = 0; t < nTrees; t++) treeStates.push(rng.tauState());\n\n const forest = makeForest(X, nNeighbors, nTrees, treeStates, {\n leafSize: defaultLeafSize(nNeighbors),\n angular,\n });\n const leafArray = leafArrayFromForest(forest);\n\n const dim = X.cols;\n const data = X.data;\n const dist = (i: number, j: number) =>\n internal.dist(data.subarray(i * dim, (i + 1) * dim), data.subarray(j * dim, (j + 1) * dim));\n\n const heap = nnDescent(X.rows, nNeighbors, dist, rngState, leafArray, {\n maxCandidates: 60,\n nIters,\n delta: 0.001,\n });\n\n // build the search index from internal-space results, then correct output copies\n const knnInternal: KnnGraph = { indices: heap.indices, distances: heap.distances, k: nNeighbors };\n const pairDist = (a: Float32Array, b: Float32Array) => internal.dist(a, b);\n const searchIndex = prepareSearchIndex(\n X,\n knnInternal,\n pairDist,\n internal.correction,\n angular,\n nNeighbors,\n searchRngState,\n );\n\n const outDst = new Float32Array(heap.distances.length);\n for (let t = 0; t < outDst.length; t++) {\n const d = heap.distances[t]!;\n outDst[t] = d === Infinity ? Infinity : internal.correction(d);\n }\n const knn: KnnGraph = { indices: heap.indices.slice(), distances: outDst, k: nNeighbors };\n applyDisconnection(knn, disconnectionDistance);\n return { knn, searchIndex, method: 'nndescent' };\n}\n\nexport function nearestNeighborsSparse(\n X: CSRInput,\n nNeighbors: number,\n metricName: string,\n rng: Pcg32,\n {\n forceApproximation = false,\n angularRpForest = false,\n disconnectionDistance = Infinity,\n }: NearestNeighborsOptions = {},\n): NearestNeighborsResult {\n if (X.rows < SMALL_DATA_CUTOFF && !forceApproximation) {\n const knn = exactKnnSparse(X, nNeighbors, metricName);\n applyDisconnection(knn, disconnectionDistance);\n return { knn, searchIndex: null, method: 'exact' };\n }\n const internal = resolveSparseInternalMetric(metricName);\n const angular = internal.angularTrees || angularRpForest;\n const { nTrees, nIters } = umapNnDescentParams(X.rows);\n const rngState = rng.tauState();\n const searchRngState = rng.tauState();\n for (let i = 0; i < 10; i++) tauRandInt(searchRngState);\n const treeStates: Int32Array[] = [];\n for (let t = 0; t < nTrees; t++) treeStates.push(rng.tauState());\n\n const leafArray = sparseForestLeafArray(X, nNeighbors, nTrees, treeStates, angular);\n\n const rowInd = (i: number) => X.indices.subarray(X.indptr[i]!, X.indptr[i + 1]!);\n const rowDat = (i: number) => X.data.subarray(X.indptr[i]!, X.indptr[i + 1]!);\n const dist = (i: number, j: number) => internal.dist(rowInd(i), rowDat(i), rowInd(j), rowDat(j));\n\n const heap = nnDescent(X.rows, nNeighbors, dist, rngState, leafArray, {\n maxCandidates: 60,\n nIters,\n delta: 0.001,\n leafAcceptance: 'either',\n });\n\n const outDst = new Float32Array(heap.distances.length);\n for (let t = 0; t < outDst.length; t++) {\n const d = heap.distances[t]!;\n outDst[t] = d === Infinity ? Infinity : internal.correction(d);\n }\n const knn: KnnGraph = { indices: heap.indices, distances: outDst, k: nNeighbors };\n applyDisconnection(knn, disconnectionDistance);\n return { knn, searchIndex: null, method: 'nndescent' };\n}\n\nfunction applyDisconnection(knn: KnnGraph, dc: number): void {\n if (dc === Infinity) return;\n for (let t = 0; t < knn.distances.length; t++) {\n if (knn.distances[t]! >= dc) {\n knn.distances[t] = Infinity;\n knn.indices[t] = -1;\n }\n }\n}\n","/**\n * Input normalization and shared helpers.\n */\n\nimport {\n type CSRInput,\n type DenseInput,\n type Matrix,\n UmapBackendError,\n UmapValidationError,\n} from './types.js';\n\n/**\n * Bound an async backend acquisition/init: broken environments (a stalled GPU\n * service, a worker that never loads) must degrade or fail typed — never hang.\n */\nexport async function raceTimeout<T>(p: Promise<T>, ms: number, what: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new UmapBackendError(`${what} timed out after ${ms}ms`)), ms);\n });\n try {\n return await Promise.race([p, timeout]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** Convert any DenseInput to a canonical float32 Matrix, validating finiteness (§4.1). */\nexport function toMatrix(input: DenseInput, what = 'X'): Matrix {\n if (Array.isArray(input)) {\n const rows = input.length;\n if (rows === 0) throw new UmapValidationError(`${what} has no rows`);\n const first = input[0];\n if (!Array.isArray(first)) throw new UmapValidationError(`${what} must be number[][]`);\n const cols = first.length;\n if (cols === 0) throw new UmapValidationError(`${what} has no columns`);\n const data = new Float32Array(rows * cols);\n for (let r = 0; r < rows; r++) {\n const row = input[r];\n if (!Array.isArray(row) || row.length !== cols) {\n throw new UmapValidationError(`${what} row ${r} has inconsistent length`);\n }\n for (let c = 0; c < cols; c++) {\n const v = row[c];\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n throw new UmapValidationError(\n `${what} contains a non-finite value at (${r}, ${c}); NaN/Infinity are rejected`,\n );\n }\n data[r * cols + c] = v;\n }\n }\n return { data, rows, cols };\n }\n const { data, rows, cols } = input;\n if (data.length !== rows * cols) {\n throw new UmapValidationError(\n `${what}: data length ${data.length} != rows*cols = ${rows * cols}`,\n );\n }\n for (let i = 0; i < data.length; i++) {\n if (!Number.isFinite(data[i]!)) {\n throw new UmapValidationError(\n `${what} contains a non-finite value at flat index ${i}; NaN/Infinity are rejected`,\n );\n }\n }\n const f32 = data instanceof Float32Array ? data.slice() : Float32Array.from(data);\n return { data: f32, rows, cols };\n}\n\nexport function isCsrInput(x: unknown): x is CSRInput {\n return (\n typeof x === 'object' &&\n x !== null &&\n 'indptr' in x &&\n 'indices' in x &&\n 'data' in x &&\n 'rows' in x &&\n 'cols' in x\n );\n}\n\nexport function validateCsr(input: CSRInput, what = 'X'): CSRInput {\n const { data, indices, indptr, rows, cols } = input;\n if (indptr.length !== rows + 1) {\n throw new UmapValidationError(`${what}: indptr length must be rows+1`);\n }\n if (indptr[0] !== 0 || indptr[rows] !== data.length || indices.length !== data.length) {\n throw new UmapValidationError(`${what}: malformed CSR structure`);\n }\n for (let i = 0; i < data.length; i++) {\n if (!Number.isFinite(data[i]!)) {\n throw new UmapValidationError(`${what} contains a non-finite value; NaN/Infinity rejected`);\n }\n const c = indices[i]!;\n if (c < 0 || c >= cols) throw new UmapValidationError(`${what}: column index out of range`);\n }\n // the sparse metrics are merge walks: column indices must be strictly\n // increasing within each row (sorted, duplicate-free) or every distance is\n // silently wrong\n for (let r = 0; r < rows; r++) {\n if (indptr[r + 1]! < indptr[r]!) {\n throw new UmapValidationError(`${what}: indptr must be non-decreasing`);\n }\n for (let p = indptr[r]! + 1; p < indptr[r + 1]!; p++) {\n if (indices[p]! <= indices[p - 1]!) {\n throw new UmapValidationError(\n `${what}: row ${r} has unsorted or duplicate column indices ` +\n '(CSR rows must be strictly increasing)',\n );\n }\n }\n }\n return input;\n}\n\n/** Row view without copy. */\nexport function rowView(m: Matrix, r: number): Float32Array {\n return m.data.subarray(r * m.cols, (r + 1) * m.cols);\n}\n\nexport function mean(a: ArrayLike<number>): number {\n let s = 0;\n for (let i = 0; i < a.length; i++) s += a[i] as number;\n return s / a.length;\n}\n\n/** argsort ascending (stable) of a numeric array. */\nexport function argsort(a: ArrayLike<number>): Int32Array {\n const idx = new Int32Array(a.length);\n for (let i = 0; i < idx.length; i++) idx[i] = i;\n const arr = Array.from(idx);\n arr.sort((i, j) => (a[i] as number) - (a[j] as number) || i - j);\n return Int32Array.from(arr);\n}\n"],"mappings":"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"}
|