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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["densReSum: Float32Array | null","densPhiSum: Float32Array | null","info: EpochCallbackInfo","gradCoeff: number","repCoeff: number","gradD: number","wLNeg: number","w","Worker","pool: WorkerPool | null","initArgs: WorkerInitArgs","failures: string[]","out: Array<[number, number]>","treeStates: Int32Array[]","shared: Float32Array | null","info: { epoch: number; nEpochs: number; phase: string; embedding?: Float32Array }","out: Csr","OUTPUT_METRIC_GRADS: Record<string, OutputMetricGradFn>","DISCONNECTION_DISTANCES: Record<string, number>","BYTES_PER: Record<SectionMeta['dtype'], number>","m: SerializedModelFields","sections: Array<{ name: string; arr: TypedArray }>","sectionMeta: SectionMeta[]","header: any","tree: FlatTree","yieldToLoop: () => Promise<void>","denseFull: Matrix | null","sparse: CSRInput | null","knn: KnnGraph","gpuKnnResult: KnnGraph | null","emb: Float32Array","gpuInit: { embedding: Float32Array } | null","embMatrix: Matrix","qKnn: KnnGraph","nEpochs: number","knnInternal: KnnGraph","X: Matrix","index: number[]","out: Int32Array[]","out: Float32Array[]","slices: Matrix[]","heads: Int32Array[]","tails: Int32Array[]","epochsPerSamples: Float64Array[]","embeddings: Float32Array[]","anchorsPrev: number[]","anchorsSelf: number[]"],"sources":["../src/layout/sgd.ts","../src/backends/cpu/pool.ts","../src/backends/cpu/workers.ts","../src/graph/supervised.ts","../src/layout/densmap.ts","../src/layout/outputMetrics.ts","../src/estimator/options.ts","../src/estimator/serialize.ts","../src/estimator/transform-init.ts","../src/estimator/umap.ts","../src/estimator/aligned.ts","../src/index.ts"],"sourcesContent":["/**\n * SGD layout optimization — faithful port of layouts.py (notes §9-11):\n * optimize_layout_euclidean (+ densMAP terms) and optimize_layout_generic.\n * Single-thread reference implementation; the worker backend shards the same\n * epoch kernels (Hogwild) at M6.\n */\n\nimport { tauRandInt } from '../rng.js';\nimport { throwIfAborted } from '../types.js';\nimport type { OutputMetricGradFn } from './outputMetrics.js';\n\nexport interface EpochCallbackInfo {\n epoch: number;\n nEpochs: number;\n phase: 'layout';\n embedding?: Float32Array;\n}\n\nexport interface DensmapParams {\n lambda: number;\n frac: number;\n varShift: number;\n /** per-edge membership weights (graph.data), aligned with head/tail */\n mu: Float32Array;\n /** per-vertex membership sums */\n muSum: Float32Array;\n /** standardized log original radii */\n R: Float32Array;\n}\n\nexport interface OptimizeLayoutOptions {\n gamma?: number; // repulsion_strength\n initialAlpha?: number;\n negativeSampleRate?: number;\n moveOther?: boolean;\n densmap?: DensmapParams | null;\n onEpoch?: (info: EpochCallbackInfo) => void;\n signal?: AbortSignal;\n /** snapshot embedding into onEpoch every k epochs (0 = never) */\n snapshotEvery?: number;\n}\n\nexport function clip(val: number): number {\n if (val > 4.0) return 4.0;\n if (val < -4.0) return -4.0;\n return val;\n}\n\n/** Per-vertex tau streams: base rng_state + bit-pattern of the vertex's first coord. */\nexport function perVertexRngStates(\n n: number,\n rngState: Int32Array,\n embedding: Float32Array,\n dim: number,\n): Int32Array {\n const states = new Int32Array(n * 3);\n const buf = new DataView(new ArrayBuffer(8));\n for (let j = 0; j < n; j++) {\n buf.setFloat64(0, embedding[j * dim]!, true);\n const lo = buf.getInt32(0, true);\n const hi = buf.getInt32(4, true);\n // int64 add of the bit pattern folds into 32-bit words (statistical equivalence)\n states[j * 3] = (rngState[0]! + lo) | 0;\n states[j * 3 + 1] = (rngState[1]! + hi) | 0;\n states[j * 3 + 2] = (rngState[2]! + (lo ^ hi)) | 0;\n }\n return states;\n}\n\n/**\n * optimize_layout_euclidean. Mutates headEmbedding (and tailEmbedding when\n * moveOther and they alias). Returns the final embedding.\n */\nexport function optimizeLayoutEuclidean(\n headEmbedding: Float32Array,\n tailEmbedding: Float32Array,\n dim: number,\n head: Int32Array,\n tail: Int32Array,\n nEpochs: number,\n nVertices: number,\n epochsPerSample: Float64Array,\n a: number,\n b: number,\n rngState: Int32Array,\n {\n gamma = 1.0,\n initialAlpha = 1.0,\n negativeSampleRate = 5,\n moveOther = true,\n densmap = null,\n onEpoch,\n signal,\n snapshotEvery = 0,\n }: OptimizeLayoutOptions = {},\n): Float32Array {\n const nEdges = epochsPerSample.length;\n let alpha = initialAlpha;\n\n const epochsPerNegativeSample = new Float64Array(nEdges);\n for (let i = 0; i < nEdges; i++) {\n epochsPerNegativeSample[i] = epochsPerSample[i]! / negativeSampleRate;\n }\n const epochOfNextNegativeSample = epochsPerNegativeSample.slice();\n const epochOfNextSample = epochsPerSample.slice();\n\n const nHead = headEmbedding.length / dim;\n const vertexRng = perVertexRngStates(nHead, rngState, headEmbedding, dim);\n\n // densMAP state\n let densReSum: Float32Array | null = null;\n let densPhiSum: Float32Array | null = null;\n let densMuTot = 0;\n if (densmap) {\n densReSum = new Float32Array(nVertices);\n densPhiSum = new Float32Array(nVertices);\n for (let i = 0; i < densmap.muSum.length; i++) densMuTot += densmap.muSum[i]!;\n densMuTot /= 2;\n }\n\n const rngRow = new Int32Array(3);\n\n for (let n = 0; n < nEpochs; n++) {\n throwIfAborted(signal);\n\n let densmapFlag = false;\n let densReStd = 0;\n let densReMean = 0;\n let densReCov = 0;\n if (densmap && densmap.lambda > 0 && (n + 1) / nEpochs > 1 - densmap.frac) {\n densmapFlag = true;\n // epoch init: recompute embedding local radii\n densReSum!.fill(0);\n densPhiSum!.fill(0);\n for (let i = 0; i < nEdges; i++) {\n const j = head[i]!;\n const k = tail[i]!;\n let d2 = 0;\n for (let d = 0; d < dim; d++) {\n const diff = headEmbedding[j * dim + d]! - tailEmbedding[k * dim + d]!;\n d2 += diff * diff;\n }\n const phi = 1.0 / (1.0 + a * d2 ** b);\n densReSum![j] = densReSum![j]! + phi * d2;\n densReSum![k] = densReSum![k]! + phi * d2;\n densPhiSum![j] = densPhiSum![j]! + phi;\n densPhiSum![k] = densPhiSum![k]! + phi;\n }\n let mean = 0;\n for (let i = 0; i < nVertices; i++) {\n densReSum![i] = Math.log(1e-8 + densReSum![i]! / densPhiSum![i]!);\n mean += densReSum![i]!;\n }\n mean /= nVertices;\n let variance = 0;\n let cov = 0;\n for (let i = 0; i < nVertices; i++) {\n variance += (densReSum![i]! - mean) ** 2;\n cov += densReSum![i]! * densmap.R[i]!;\n }\n variance /= nVertices;\n densReStd = Math.sqrt(variance + densmap.varShift);\n densReMean = mean;\n densReCov = cov / (nVertices - 1);\n }\n\n if (dim === 2 && !densmap) {\n // hot-path specialization (identical arithmetic, unrolled). Vertex j's\n // coords live in f32-rounded locals across the edge iteration —\n // Math.fround after every update reproduces the per-step Float32Array\n // rounding bit-exactly while avoiding the load/store traffic.\n const fround = Math.fround;\n const bm1 = b - 1.0;\n for (let i = 0; i < nEdges; i++) {\n if (epochOfNextSample[i]! > n) continue;\n const j = head[i]!;\n let k = tail[i]!;\n const jBase = j * 2;\n let kBase = k * 2;\n let cj0 = headEmbedding[jBase]!;\n let cj1 = headEmbedding[jBase + 1]!;\n let dx = cj0 - tailEmbedding[kBase]!;\n let dy = cj1 - tailEmbedding[kBase + 1]!;\n const d2 = dx * dx + dy * dy;\n if (d2 > 0) {\n // pow(d2, b-1) kept separate from pow(d2, b): numba op order, bit-exact\n const gc = (-2.0 * a * b * d2 ** bm1) / (a * d2 ** b + 1.0);\n const g0 = clip(gc * dx);\n const g1 = clip(gc * dy);\n cj0 = fround(cj0 + g0 * alpha);\n cj1 = fround(cj1 + g1 * alpha);\n if (moveOther) {\n tailEmbedding[kBase] = tailEmbedding[kBase]! - g0 * alpha;\n tailEmbedding[kBase + 1] = tailEmbedding[kBase + 1]! - g1 * alpha;\n }\n }\n epochOfNextSample[i] = epochOfNextSample[i]! + epochsPerSample[i]!;\n const nNegSamples = Math.trunc(\n (n - epochOfNextNegativeSample[i]!) / epochsPerNegativeSample[i]!,\n );\n // taus88 inlined on integer locals (bit-identical to tauRandInt)\n let s0 = vertexRng[j * 3]! | 0;\n let s1 = vertexRng[j * 3 + 1]! | 0;\n let s2 = vertexRng[j * 3 + 2]! | 0;\n for (let s = 0; s < nNegSamples; s++) {\n const u0 = s0 >>> 0;\n const u1 = s1 >>> 0;\n const u2 = s2 >>> 0;\n s0 = (((u0 & 0xfffffffe) << 12) ^ ((((u0 << 13) >>> 0) ^ u0) >>> 19)) | 0;\n s1 = (((u1 & 0xfffffff8) << 4) ^ ((((u1 << 2) >>> 0) ^ u1) >>> 25)) | 0;\n s2 = (((u2 & 0xfffffff0) << 17) ^ ((((u2 << 3) >>> 0) ^ u2) >>> 11)) | 0;\n const r = (s0 ^ s1 ^ s2) | 0;\n const rm = r % nVertices;\n k = rm + (rm < 0 ? nVertices : 0);\n if (j === k) continue;\n kBase = k * 2;\n dx = cj0 - tailEmbedding[kBase]!;\n dy = cj1 - tailEmbedding[kBase + 1]!;\n const dn = dx * dx + dy * dy;\n if (dn > 0) {\n const rc = (2.0 * gamma * b) / ((0.001 + dn) * (a * dn ** b + 1));\n cj0 = fround(cj0 + clip(rc * dx) * alpha);\n cj1 = fround(cj1 + clip(rc * dy) * alpha);\n }\n }\n headEmbedding[jBase] = cj0;\n headEmbedding[jBase + 1] = cj1;\n vertexRng[j * 3] = s0;\n vertexRng[j * 3 + 1] = s1;\n vertexRng[j * 3 + 2] = s2;\n epochOfNextNegativeSample[i] =\n epochOfNextNegativeSample[i]! + nNegSamples * epochsPerNegativeSample[i]!;\n }\n alpha = initialAlpha * (1.0 - n / nEpochs);\n if (onEpoch) {\n const info: EpochCallbackInfo = { epoch: n, nEpochs, phase: 'layout' };\n if (snapshotEvery > 0 && (n % snapshotEvery === 0 || n === nEpochs - 1)) {\n info.embedding = headEmbedding;\n }\n onEpoch(info);\n }\n continue;\n }\n\n for (let i = 0; i < nEdges; i++) {\n if (epochOfNextSample[i]! > n) continue;\n const j = head[i]!;\n let k = tail[i]!;\n const jBase = j * dim;\n let kBase = k * dim;\n\n let distSquared = 0;\n for (let d = 0; d < dim; d++) {\n const diff = headEmbedding[jBase + d]! - tailEmbedding[kBase + d]!;\n distSquared += diff * diff;\n }\n\n let gradCorCoeff = 0;\n if (densmapFlag) {\n const phi = 1.0 / (1.0 + a * distSquared ** b);\n const dphiTerm = (a * b * distSquared ** (b - 1)) / (1.0 + a * distSquared ** b);\n const qjk = phi / densPhiSum![k]!;\n const qkj = phi / densPhiSum![j]!;\n const drk = qjk * ((1.0 - b * (1 - phi)) / Math.exp(densReSum![k]!) + dphiTerm);\n const drj = qkj * ((1.0 - b * (1 - phi)) / Math.exp(densReSum![j]!) + dphiTerm);\n const reStdSq = densReStd * densReStd;\n const weightK = densmap!.R[k]! - (densReCov * (densReSum![k]! - densReMean)) / reStdSq;\n const weightJ = densmap!.R[j]! - (densReCov * (densReSum![j]! - densReMean)) / reStdSq;\n gradCorCoeff =\n (((densmap!.lambda * densMuTot) / (densmap!.mu[i]! * densReStd)) *\n (weightK * drk + weightJ * drj)) /\n nVertices;\n }\n\n let gradCoeff: number;\n if (distSquared > 0) {\n // pow(d2, b-1) kept separate from pow(d2, b): numba op order, bit-exact\n gradCoeff = (-2.0 * a * b * distSquared ** (b - 1.0)) / (a * distSquared ** b + 1.0);\n } else {\n gradCoeff = 0;\n }\n for (let d = 0; d < dim; d++) {\n const diff = headEmbedding[jBase + d]! - tailEmbedding[kBase + d]!;\n let gradD = clip(gradCoeff * diff);\n if (densmapFlag) gradD += clip(2 * gradCorCoeff * diff);\n headEmbedding[jBase + d] = headEmbedding[jBase + d]! + gradD * alpha;\n if (moveOther) {\n tailEmbedding[kBase + d] = tailEmbedding[kBase + d]! - gradD * alpha;\n }\n }\n\n epochOfNextSample[i] = epochOfNextSample[i]! + epochsPerSample[i]!;\n\n const nNegSamples = Math.trunc(\n (n - epochOfNextNegativeSample[i]!) / epochsPerNegativeSample[i]!,\n );\n\n rngRow[0] = vertexRng[j * 3]!;\n rngRow[1] = vertexRng[j * 3 + 1]!;\n rngRow[2] = vertexRng[j * 3 + 2]!;\n for (let p = 0; p < nNegSamples; p++) {\n const r = tauRandInt(rngRow);\n k = (r % nVertices) + (r % nVertices < 0 ? nVertices : 0);\n kBase = k * dim;\n distSquared = 0;\n for (let d = 0; d < dim; d++) {\n const diff = headEmbedding[jBase + d]! - tailEmbedding[kBase + d]!;\n distSquared += diff * diff;\n }\n let repCoeff: number;\n if (distSquared > 0) {\n repCoeff = (2.0 * gamma * b) / ((0.001 + distSquared) * (a * distSquared ** b + 1));\n } else if (j === k) {\n continue;\n } else {\n repCoeff = 0;\n }\n for (let d = 0; d < dim; d++) {\n let gradD: number;\n if (repCoeff > 0) {\n const diff = headEmbedding[jBase + d]! - tailEmbedding[kBase + d]!;\n gradD = clip(repCoeff * diff);\n } else {\n gradD = 0; // 0.5.9 semantics: no push at coincident points (notes §9.4)\n }\n headEmbedding[jBase + d] = headEmbedding[jBase + d]! + gradD * alpha;\n }\n }\n vertexRng[j * 3] = rngRow[0]!;\n vertexRng[j * 3 + 1] = rngRow[1]!;\n vertexRng[j * 3 + 2] = rngRow[2]!;\n\n epochOfNextNegativeSample[i] =\n epochOfNextNegativeSample[i]! + nNegSamples * epochsPerNegativeSample[i]!;\n }\n\n alpha = initialAlpha * (1.0 - n / nEpochs);\n if (onEpoch) {\n const info: EpochCallbackInfo = { epoch: n, nEpochs, phase: 'layout' };\n if (snapshotEvery > 0 && (n % snapshotEvery === 0 || n === nEpochs - 1)) {\n info.embedding = headEmbedding;\n }\n onEpoch(info);\n }\n }\n return headEmbedding;\n}\n\n/**\n * optimize_layout_inverse (layouts.py:663-732; notes §13): optimizes DATA-space\n * positions of inverse-transformed points against the raw training data.\n * Negative samples use the SHARED rng state (not per-vertex).\n */\nexport function optimizeLayoutInverse(\n headEmbedding: Float32Array, // query points in DATA space (mutated)\n tailEmbedding: Float32Array, // raw training data (fixed)\n dim: number,\n head: Int32Array,\n tail: Int32Array,\n weight: Float32Array,\n sigmas: Float32Array,\n rhos: Float32Array,\n nEpochs: number,\n nVertices: number,\n epochsPerSample: Float64Array,\n rngState: Int32Array,\n outputMetric: OutputMetricGradFn,\n { gamma = 1.0, initialAlpha = 1.0, negativeSampleRate = 5, signal }: OptimizeLayoutOptions = {},\n): Float32Array {\n const nEdges = epochsPerSample.length;\n let alpha = initialAlpha;\n const epochsPerNegativeSample = new Float64Array(nEdges);\n for (let i = 0; i < nEdges; i++) {\n epochsPerNegativeSample[i] = epochsPerSample[i]! / negativeSampleRate;\n }\n const epochOfNextNegativeSample = epochsPerNegativeSample.slice();\n const epochOfNextSample = epochsPerSample.slice();\n const grad = new Float64Array(dim);\n const cur = new Float32Array(dim);\n const oth = new Float32Array(dim);\n\n for (let n = 0; n < nEpochs; n++) {\n throwIfAborted(signal);\n for (let i = 0; i < nEdges; i++) {\n if (epochOfNextSample[i]! > n) continue;\n const j = head[i]!;\n let k = tail[i]!;\n const jBase = j * dim;\n let kBase = k * dim;\n for (let d = 0; d < dim; d++) {\n cur[d] = headEmbedding[jBase + d]!;\n oth[d] = tailEmbedding[kBase + d]!;\n }\n outputMetric(cur, oth, grad);\n const wL = weight[i]!;\n const gradCoeff = -(1 / (wL * sigmas[k]! + 1e-6));\n for (let d = 0; d < dim; d++) {\n const gradD = clip(gradCoeff * grad[d]!);\n headEmbedding[jBase + d] = headEmbedding[jBase + d]! + gradD * alpha;\n }\n epochOfNextSample[i] = epochOfNextSample[i]! + epochsPerSample[i]!;\n const nNegSamples = Math.trunc(\n (n - epochOfNextNegativeSample[i]!) / epochsPerNegativeSample[i]!,\n );\n for (let p = 0; p < nNegSamples; p++) {\n const r = tauRandInt(rngState);\n k = (r % nVertices) + (r % nVertices < 0 ? nVertices : 0);\n kBase = k * dim;\n for (let d = 0; d < dim; d++) {\n cur[d] = headEmbedding[jBase + d]!;\n oth[d] = tailEmbedding[kBase + d]!;\n }\n const distOutput = outputMetric(cur, oth, grad);\n const wH = Math.exp(-Math.max(distOutput - rhos[k]!, 1e-6) / (sigmas[k]! + 1e-6));\n // sigma=inf (fastmath fold, D-006) makes (1−wH)·σ ill-defined (0·∞). The pinned\n // wheel produces huge finite coefficients that the ±4 clip saturates; we take\n // the same clip-saturating limit (denominator → 1e-6). See DECISIONS D-010.\n let denom = (1 - wH) * sigmas[k]! + 1e-6;\n if (!Number.isFinite(denom)) denom = 1e-6;\n const gradCoeffNeg = -gamma * ((0 - wH) / denom);\n for (let d = 0; d < dim; d++) {\n const gradD = clip(gradCoeffNeg * grad[d]!);\n headEmbedding[jBase + d] = headEmbedding[jBase + d]! + gradD * alpha;\n }\n }\n epochOfNextNegativeSample[i] =\n epochOfNextNegativeSample[i]! + nNegSamples * epochsPerNegativeSample[i]!;\n }\n alpha = initialAlpha * (1.0 - n / nEpochs);\n }\n return headEmbedding;\n}\n\n/** optimize_layout_generic — non-euclidean output metrics (notes §10). */\nexport function optimizeLayoutGeneric(\n headEmbedding: Float32Array,\n tailEmbedding: Float32Array,\n dim: number,\n head: Int32Array,\n tail: Int32Array,\n nEpochs: number,\n nVertices: number,\n epochsPerSample: Float64Array,\n a: number,\n b: number,\n rngState: Int32Array,\n outputMetric: OutputMetricGradFn,\n {\n gamma = 1.0,\n initialAlpha = 1.0,\n negativeSampleRate = 5,\n moveOther = true,\n onEpoch,\n signal,\n snapshotEvery = 0,\n }: OptimizeLayoutOptions = {},\n): Float32Array {\n const nEdges = epochsPerSample.length;\n let alpha = initialAlpha;\n\n const epochsPerNegativeSample = new Float64Array(nEdges);\n for (let i = 0; i < nEdges; i++) {\n epochsPerNegativeSample[i] = epochsPerSample[i]! / negativeSampleRate;\n }\n const epochOfNextNegativeSample = epochsPerNegativeSample.slice();\n const epochOfNextSample = epochsPerSample.slice();\n\n const nHead = headEmbedding.length / dim;\n const vertexRng = perVertexRngStates(nHead, rngState, headEmbedding, dim);\n const grad = new Float64Array(dim);\n const revGrad = new Float64Array(dim);\n const rngRow = new Int32Array(3);\n const cur = new Float32Array(dim);\n const oth = new Float32Array(dim);\n\n for (let n = 0; n < nEpochs; n++) {\n throwIfAborted(signal);\n for (let i = 0; i < nEdges; i++) {\n if (epochOfNextSample[i]! > n) continue;\n const j = head[i]!;\n let k = tail[i]!;\n const jBase = j * dim;\n let kBase = k * dim;\n\n for (let d = 0; d < dim; d++) {\n cur[d] = headEmbedding[jBase + d]!;\n oth[d] = tailEmbedding[kBase + d]!;\n }\n const distOutput = outputMetric(cur, oth, grad);\n outputMetric(oth, cur, revGrad);\n\n const wL = distOutput > 0 ? (1 + a * distOutput ** (2 * b)) ** -1 : 1.0;\n const gradCoeff = (2 * b * (wL - 1)) / (distOutput + 1e-6);\n\n for (let d = 0; d < dim; d++) {\n const gradD = clip(gradCoeff * grad[d]!);\n headEmbedding[jBase + d] = headEmbedding[jBase + d]! + gradD * alpha;\n if (moveOther) {\n const revD = clip(gradCoeff * revGrad[d]!);\n tailEmbedding[kBase + d] = tailEmbedding[kBase + d]! + revD * alpha;\n }\n }\n\n epochOfNextSample[i] = epochOfNextSample[i]! + epochsPerSample[i]!;\n const nNegSamples = Math.trunc(\n (n - epochOfNextNegativeSample[i]!) / epochsPerNegativeSample[i]!,\n );\n\n rngRow[0] = vertexRng[j * 3]!;\n rngRow[1] = vertexRng[j * 3 + 1]!;\n rngRow[2] = vertexRng[j * 3 + 2]!;\n for (let p = 0; p < nNegSamples; p++) {\n const r = tauRandInt(rngRow);\n k = (r % nVertices) + (r % nVertices < 0 ? nVertices : 0);\n kBase = k * dim;\n for (let d = 0; d < dim; d++) {\n cur[d] = headEmbedding[jBase + d]!;\n oth[d] = tailEmbedding[kBase + d]!;\n }\n const dNeg = outputMetric(cur, oth, grad);\n let wLNeg: number;\n if (dNeg > 0) {\n wLNeg = (1 + a * dNeg ** (2 * b)) ** -1;\n } else if (j === k) {\n continue;\n } else {\n wLNeg = 1.0;\n }\n const repCoeff = (gamma * 2 * b * wLNeg) / (dNeg + 1e-6);\n for (let d = 0; d < dim; d++) {\n const gradD = clip(repCoeff * grad[d]!);\n headEmbedding[jBase + d] = headEmbedding[jBase + d]! + gradD * alpha;\n }\n }\n vertexRng[j * 3] = rngRow[0]!;\n vertexRng[j * 3 + 1] = rngRow[1]!;\n vertexRng[j * 3 + 2] = rngRow[2]!;\n\n epochOfNextNegativeSample[i] =\n epochOfNextNegativeSample[i]! + nNegSamples * epochsPerNegativeSample[i]!;\n }\n alpha = initialAlpha * (1.0 - n / nEpochs);\n if (onEpoch) {\n const info: EpochCallbackInfo = { epoch: n, nEpochs, phase: 'layout' };\n if (snapshotEvery > 0 && (n % snapshotEvery === 0 || n === nEpochs - 1)) {\n info.embedding = headEmbedding;\n }\n onEpoch(info);\n }\n }\n return headEmbedding;\n}\n","/**\n * Worker pool over Node worker_threads and browser Worker (§5.3).\n * SharedArrayBuffer is used when available (Node, or crossOriginIsolated\n * browsers); otherwise falls back to ownership transfer of chunked buffers —\n * GitHub Pages cannot set COOP/COEP, so the no-SAB path is first-class.\n *\n * Failure model: any worker error/exit/messageerror marks the pool dead and\n * rejects every in-flight call with a typed UmapBackendError — a broken worker\n * must never hang (browser) or crash the host on an unhandled 'error' (Node).\n */\n\nimport { UmapBackendError } from '../../types.js';\n\nexport interface RpcWorker {\n post(msg: unknown, transfers?: Transferable[]): void;\n onMessage(cb: (msg: unknown) => void): void;\n onFailure(cb: (err: Error) => void): void;\n terminate(): Promise<void> | void;\n}\n\nexport const IS_NODE = typeof process !== 'undefined' && !!process.versions?.node;\n\n/**\n * Runtime-only import of node builtins. The variable specifier plus the ignore\n * comments keep browser bundlers (esbuild/Vite/webpack) from trying to resolve\n * `node:*` modules they cannot ship; every call site is behind an IS_NODE\n * guard so the import never evaluates in a browser.\n */\nfunction nodeImport<T>(specifier: string): Promise<T> {\n return import(/* @vite-ignore */ /* webpackIgnore: true */ specifier) as Promise<T>;\n}\n\nexport function sabAvailable(): boolean {\n if (typeof SharedArrayBuffer === 'undefined') return false;\n if (IS_NODE) return true;\n // browsers expose SAB only when crossOriginIsolated\n return (globalThis as { crossOriginIsolated?: boolean }).crossOriginIsolated === true;\n}\n\nexport function hardwareConcurrency(): number {\n // navigator.hardwareConcurrency exists in browsers and Node ≥ 21\n return Math.max(\n 1,\n (globalThis as { navigator?: { hardwareConcurrency?: number } }).navigator\n ?.hardwareConcurrency ?? 4,\n );\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: dynamic platform imports\ntype AnyRec = Record<string, any>;\n\n/**\n * Bundler-visible browser worker factory. webpack 5 and Vite (build) statically\n * detect the exact inline `new Worker(new URL('./worker.js', import.meta.url),\n * {type:'module'})` expression — including inside node_modules — and emit the\n * worker as an asset of the consumer's build. Do NOT extract the URL into a\n * variable or helper: detection depends on the literal shape of this\n * expression (guarded by scripts/check-bundlers.mjs).\n */\nfunction defaultBrowserWorker(): Worker {\n return new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });\n}\n\n/**\n * Cross-origin retry (CDN / import-map consumers): fetch the sibling worker\n * source and spawn it from a blob: URL. Valid only because dist/worker.js is\n * built fully self-contained (no sibling-chunk imports; enforced by\n * scripts/check-worker-selfcontained.mjs). Requires `worker-src blob:` under\n * a strict CSP (documented in README).\n */\nexport async function blobWorkerUrl(): Promise<string | null> {\n try {\n const res = await fetch(new URL('./worker.js', import.meta.url));\n if (!res.ok) return null;\n const text = await res.text();\n return URL.createObjectURL(new Blob([text], { type: 'text/javascript' }));\n } catch {\n return null;\n }\n}\n\nasync function spawnWorker(source: URL | string | undefined): Promise<RpcWorker> {\n if (IS_NODE) {\n const { Worker } =\n await nodeImport<typeof import('node:worker_threads')>('node:worker_threads');\n const resolved = source ?? (await workerEntryUrl());\n // node accepts a URL object or a filesystem path, not a 'file://…' string\n const target =\n typeof resolved === 'string' && resolved.startsWith('file:') ? new URL(resolved) : resolved;\n const w = new Worker(target);\n return {\n post: (msg, transfers) => w.postMessage(msg, (transfers ?? []) as never),\n onMessage: (cb) => {\n w.on('message', cb);\n },\n onFailure: (cb) => {\n w.on('error', (e) => cb(e instanceof Error ? e : new Error(String(e))));\n w.on('messageerror', (e) => cb(new Error(`worker messageerror: ${e}`)));\n w.on('exit', (code) => {\n if (code !== 0) cb(new Error(`worker exited with code ${code}`));\n });\n },\n terminate: async () => {\n await w.terminate();\n },\n };\n }\n const w = source === undefined ? defaultBrowserWorker() : new Worker(source, { type: 'module' });\n return {\n post: (msg, transfers) => w.postMessage(msg, { transfer: transfers ?? [] }),\n onMessage: (cb) => {\n w.onmessage = (e) => cb(e.data);\n },\n onFailure: (cb) => {\n w.onerror = (e) =>\n cb(new Error(`worker error: ${(e as ErrorEvent).message || 'failed to load worker.js'}`));\n w.onmessageerror = () => cb(new Error('worker messageerror (unserializable message)'));\n },\n terminate: () => w.terminate(),\n };\n}\n\ninterface Pending {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n}\n\nexport class WorkerPool {\n private workers: RpcWorker[] = [];\n private pending = new Map<number, Pending>();\n private nextId = 1;\n private failure: Error | null = null;\n private terminating = false;\n private cleanup: (() => void) | null = null;\n readonly size: number;\n\n private constructor(size: number) {\n this.size = size;\n }\n\n /**\n * Spawn `size` workers from `source` (undefined → platform default resolution).\n * `cleanup` runs once at terminate() (e.g. revoking a blob: URL). Partial\n * spawn failures terminate the already-spawned workers before rethrowing.\n */\n static async create(\n size: number,\n source?: URL | string,\n cleanup?: () => void,\n ): Promise<WorkerPool> {\n const pool = new WorkerPool(size);\n pool.cleanup = cleanup ?? null;\n try {\n for (let i = 0; i < size; i++) {\n const w = await spawnWorker(source);\n w.onMessage((msg) => pool.dispatch(msg));\n w.onFailure((err) => pool.markFailed(err));\n pool.workers.push(w);\n }\n } catch (e) {\n await pool.terminate();\n throw e;\n }\n return pool;\n }\n\n /** A worker died: poison the pool and reject everything in flight. */\n private markFailed(err: Error): void {\n if (this.terminating || this.failure) return;\n this.failure = err;\n const inflight = [...this.pending.values()];\n this.pending.clear();\n const wrapped = new UmapBackendError(`worker failed: ${err.message}`);\n for (const p of inflight) p.reject(wrapped);\n }\n\n private dispatch(msg: unknown): void {\n const m = msg as { id?: number; error?: string; result?: unknown };\n if (typeof m?.id !== 'number') return;\n const p = this.pending.get(m.id);\n if (!p) return;\n this.pending.delete(m.id);\n if (m.error) p.reject(new UmapBackendError(`worker error: ${m.error}`));\n else p.resolve(m.result);\n }\n\n call<T>(worker: number, method: string, args: AnyRec, transfers?: Transferable[]): Promise<T> {\n if (this.failure) {\n return Promise.reject(new UmapBackendError(`worker pool is dead: ${this.failure.message}`));\n }\n if (this.terminating) {\n return Promise.reject(new UmapBackendError('worker pool has been terminated'));\n }\n const id = this.nextId++;\n const promise = new Promise<T>((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject });\n });\n this.workers[worker]!.post({ id, method, args }, transfers);\n return promise;\n }\n\n /** Run `method` on every worker with per-worker args; await all. */\n mapAll<T>(\n method: string,\n argsFor: (w: number) => AnyRec,\n transfersFor?: (w: number) => Transferable[],\n ): Promise<T[]> {\n return Promise.all(\n this.workers.map((_, w) => this.call<T>(w, method, argsFor(w), transfersFor?.(w))),\n );\n }\n\n async terminate(): Promise<void> {\n if (this.terminating) return;\n this.terminating = true;\n const inflight = [...this.pending.values()];\n this.pending.clear();\n for (const p of inflight) {\n p.reject(new UmapBackendError('worker pool terminated with calls in flight'));\n }\n await Promise.all(this.workers.map((w) => w.terminate()));\n this.workers = [];\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = null;\n }\n }\n}\n\n/**\n * Node-only resolution of the worker entry: the bundled sibling (dist layout),\n * then the package export (bundled-consumer deploys that keep node_modules),\n * then the package's dist for the src/test context. Browser resolution happens\n * in defaultBrowserWorker/blobWorkerUrl instead.\n */\nexport async function workerEntryUrl(): Promise<URL> {\n const local = new URL('./worker.js', import.meta.url);\n if (IS_NODE && local.protocol === 'file:') {\n const { existsSync } = await nodeImport<typeof import('node:fs')>('node:fs');\n const { fileURLToPath } = await nodeImport<typeof import('node:url')>('node:url');\n if (!existsSync(fileURLToPath(local))) {\n try {\n const meta = import.meta as ImportMeta & { resolve?: (specifier: string) => string };\n const viaExport = meta.resolve?.('umap-web/worker');\n if (viaExport?.startsWith('file:') && existsSync(fileURLToPath(new URL(viaExport)))) {\n return new URL(viaExport);\n }\n } catch {\n // not resolvable from here (e.g. running from src) — fall through\n }\n // src context: packages/umap-web/src/backends/cpu/pool.ts → ../../../dist/worker.js\n return new URL('../../../dist/worker.js', import.meta.url);\n }\n }\n return local;\n}\n","/**\n * Parallel CPU driver (§5.3): NN-descent with worker distance passes (blockwise,\n * threshold-snapshot pruning like Python's per-block buffers) and Hogwild-style\n * epoch-sharded SGD. SAB shares data zero-copy; the transfer fallback copies the\n * data once per worker and moves snapshots/deltas per epoch (first-class path —\n * GitHub Pages has no COOP/COEP).\n */\n\nimport {\n checkedFlaggedHeapPush,\n checkedHeapPush,\n deheapSort,\n makeHeap,\n type NeighborHeap,\n} from '../../knn/heap.js';\nimport { resolveInternalMetric } from '../../knn/internal-metrics.js';\nimport type { NnDescentOptions } from '../../knn/nndescent.js';\nimport { umapNnDescentParams } from '../../knn/nndescent.js';\nimport { prepareSearchIndex, type SearchIndex } from '../../knn/search.js';\nimport type { MetricOptions } from '../../metrics.js';\nimport { type Pcg32, tauRand, tauRandInt } from '../../rng.js';\nimport type { KnnGraph, Logger, Matrix } from '../../types.js';\nimport { raceTimeout } from '../../util.js';\nimport { blobWorkerUrl, hardwareConcurrency, IS_NODE, sabAvailable, WorkerPool } from './pool.js';\n\nexport interface ParallelContext {\n pool: WorkerPool;\n sab: boolean;\n data: Float32Array; // SAB-backed when sab\n rows: number;\n cols: number;\n dist: (a: Float32Array, b: Float32Array) => number; // internal-space metric (main thread)\n}\n\n/** Copy data into a SAB-backed view when available. */\nfunction shareData(X: Matrix, sab: boolean): Float32Array {\n if (!sab) return X.data;\n const shared = new Float32Array(new SharedArrayBuffer(X.data.length * 4));\n shared.set(X.data);\n return shared;\n}\n\n/** Cap on worker spawn + init; a stuck worker must degrade, never hang fit(). */\nconst WORKER_INIT_TIMEOUT_MS = 10_000;\n\ninterface WorkerInitArgs {\n data: Float32Array;\n rows: number;\n cols: number;\n metricName: string;\n metricOptions: MetricOptions;\n}\n\nasync function tryCreatePool(\n size: number,\n source: URL | string | undefined,\n cleanup: (() => void) | undefined,\n initArgs: WorkerInitArgs,\n failures: string[],\n): Promise<WorkerPool | null> {\n let pool: WorkerPool | null = null;\n try {\n pool = await WorkerPool.create(size, source, cleanup);\n const init = pool.mapAll('init', () => initArgs);\n init.catch(() => {}); // handled via the race; avoid an unhandled late rejection\n await raceTimeout(init, WORKER_INIT_TIMEOUT_MS, 'worker init');\n return pool;\n } catch (e) {\n failures.push(e instanceof Error ? e.message : String(e));\n if (pool) await pool.terminate();\n return null;\n }\n}\n\nexport async function createParallelContext(\n X: Matrix,\n metricName: string,\n metricOptions: MetricOptions,\n requested: number | 'auto',\n workerUrl?: URL | string,\n logger?: Logger,\n): Promise<ParallelContext | null> {\n const hw = hardwareConcurrency();\n const size = requested === 'auto' ? Math.max(1, Math.min(hw - 1, 16)) : requested;\n if (size <= 1) return null;\n const sab = sabAvailable();\n const data = shareData(X, sab);\n const initArgs: WorkerInitArgs = { data, rows: X.rows, cols: X.cols, metricName, metricOptions };\n const failures: string[] = [];\n\n let pool: WorkerPool | null = null;\n if (workerUrl !== undefined) {\n // the caller pinned the source — fail loudly rather than trying other origins\n pool = await tryCreatePool(size, workerUrl, undefined, initArgs, failures);\n } else {\n pool = await tryCreatePool(size, undefined, undefined, initArgs, failures);\n if (!pool && !IS_NODE) {\n // cross-origin (CDN/import-map) retry: self-contained worker via blob: URL\n const blob = await blobWorkerUrl();\n if (blob) {\n pool = await tryCreatePool(size, blob, () => URL.revokeObjectURL(blob), initArgs, failures);\n } else {\n failures.push('worker source fetch for blob retry failed');\n }\n }\n }\n if (!pool) {\n logger?.warn(\n `worker pool unavailable (${failures.join('; ')}) — continuing single-threaded. ` +\n 'Bundled apps: see the README section \"Workers & bundlers\" or pass options.workerUrl.',\n );\n return null;\n }\n const internal = resolveInternalMetric(metricName, metricOptions);\n return {\n pool,\n sab,\n data,\n rows: X.rows,\n cols: X.cols,\n dist: (a, b) => internal.dist(a, b),\n };\n}\n\nfunction splitRange(total: number, parts: number): Array<[number, number]> {\n const out: Array<[number, number]> = [];\n const step = Math.ceil(total / parts);\n for (let i = 0; i < parts; i++) {\n out.push([Math.min(i * step, total), Math.min((i + 1) * step, total)]);\n }\n return out;\n}\n\nfunction applyTriples(heap: NeighborHeap, buffers: Float64Array[]): number {\n let c = 0;\n for (const buf of buffers) {\n for (let t = 0; t < buf.length; t += 3) {\n const p = buf[t]!;\n const q = buf[t + 1]!;\n const d = buf[t + 2]!;\n c += checkedFlaggedHeapPush(heap, p, d, q, 1);\n c += checkedFlaggedHeapPush(heap, q, d, p, 1);\n }\n }\n return c;\n}\n\nfunction thresholdSnapshot(heap: NeighborHeap, out: Float32Array): Float32Array {\n const k = heap.size;\n for (let i = 0; i < heap.n; i++) out[i] = heap.distances[i * k]!;\n return out;\n}\n\n/**\n * Parallel NN-descent (same candidate scheme/acceptance as the single-thread\n * port; distance passes fan out to workers per block).\n */\nexport async function parallelNnDescent(\n ctx: ParallelContext,\n nNeighbors: number,\n rng: Pcg32,\n angular: boolean,\n { maxCandidates = 60, delta = 0.001 }: NnDescentOptions = {},\n): Promise<{ knnInternal: KnnGraph; searchRngState: Int32Array }> {\n const n = ctx.rows;\n const { nTrees, nIters } = umapNnDescentParams(n);\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 // --- forest build across workers\n const perWorker = splitRange(nTrees, ctx.pool.size);\n const leafParts = await ctx.pool.mapAll<{ data: Int32Array; rows: number; cols: number }>(\n 'buildTrees',\n (w) => ({\n treeStates: treeStates.slice(perWorker[w]![0], perWorker[w]![1]),\n nNeighbors,\n angular,\n }),\n );\n const parts = leafParts.filter((p) => p.rows > 0 && p.cols > 0);\n const maxCols = Math.max(1, ...parts.map((p) => p.cols));\n const totalRows = parts.reduce((s, p) => s + p.rows, 0);\n const leafArray = new Int32Array(totalRows * maxCols).fill(-1);\n {\n let r = 0;\n for (const p of parts) {\n for (let i = 0; i < p.rows; i++) {\n leafArray.set(p.data.subarray(i * p.cols, (i + 1) * p.cols), r * maxCols);\n r++;\n }\n }\n }\n\n const heap = makeHeap(n, nNeighbors);\n const thresholds = new Float32Array(n);\n\n // --- leaf init, blockwise with refreshed thresholds\n const LEAF_BLOCK = 4096;\n for (let start = 0; start < totalRows; start += LEAF_BLOCK) {\n const end = Math.min(totalRows, start + LEAF_BLOCK);\n thresholdSnapshot(heap, thresholds);\n const shards = splitRange(end - start, ctx.pool.size);\n const results = await ctx.pool.mapAll<Float64Array>('leafUpdates', (w) => ({\n leafArray,\n cols: maxCols,\n rowStart: start + shards[w]![0],\n rowEnd: start + shards[w]![1],\n thresholds,\n }));\n applyTriples(heap, results);\n }\n\n // --- random fill for under-full rows (sequential, cheap)\n {\n const d = ctx.cols;\n const dist = (i: number, j: number) =>\n ctx.dist(ctx.data.subarray(i * d, (i + 1) * d), ctx.data.subarray(j * d, (j + 1) * d));\n const k = nNeighbors;\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 for (let j = 0; j < k - filled; j++) {\n const idx = Math.abs(tauRandInt(rngState)) % n;\n checkedFlaggedHeapPush(heap, i, dist(idx, i), idx, 1);\n }\n }\n }\n }\n\n // --- descent iterations\n const VBLOCK = 16384;\n for (let iter = 0; iter < nIters; iter++) {\n const { newIdx, oldIdx } = buildCandidatesMain(heap, maxCandidates, rngState);\n let c = 0;\n for (let vs = 0; vs < n; vs += VBLOCK) {\n const ve = Math.min(n, vs + VBLOCK);\n thresholdSnapshot(heap, thresholds);\n const shards = splitRange(ve - vs, ctx.pool.size);\n const results = await ctx.pool.mapAll<Float64Array>('joinUpdates', (w) => ({\n newIdx: newIdx.subarray(\n (vs + shards[w]![0]) * maxCandidates,\n (vs + shards[w]![1]) * maxCandidates,\n ),\n oldIdx: oldIdx.subarray(\n (vs + shards[w]![0]) * maxCandidates,\n (vs + shards[w]![1]) * maxCandidates,\n ),\n maxCandidates,\n vStart: 0,\n vEnd: shards[w]![1] - shards[w]![0],\n thresholds,\n }));\n c += applyTriples(heap, results);\n }\n if (c <= delta * nNeighbors * n) break;\n }\n deheapSort(heap);\n return {\n knnInternal: { indices: heap.indices, distances: heap.distances, k: nNeighbors },\n searchRngState,\n };\n}\n\n/** new_build_candidates on the main thread (heap pushes are cheap). */\nfunction buildCandidatesMain(\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 const localRng = Int32Array.from(masterRng);\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 if (heap.flags[i * k + j] === 1) {\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 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// ---------------------------------------------------------------------------\n// parallel layout\n// ---------------------------------------------------------------------------\n\nexport interface ParallelLayoutOptions {\n gamma: number;\n initialAlpha: number;\n negativeSampleRate: number;\n moveOther: boolean;\n onEpoch?: (info: {\n epoch: number;\n nEpochs: number;\n phase: string;\n embedding?: Float32Array;\n }) => void;\n signal?: AbortSignal;\n snapshotEvery?: number;\n}\n\n/**\n * Hogwild epoch-sharded SGD across the pool. SAB mode writes concurrently into\n * the shared embedding (races tolerated, like umap's parallel=True); transfer\n * mode applies per-worker deltas at each epoch barrier (stale-by-one-epoch reads).\n */\nexport async function parallelOptimizeLayout(\n ctx: ParallelContext,\n embedding: Float32Array,\n dim: number,\n head: Int32Array,\n tail: Int32Array,\n nEpochs: number,\n nVertices: number,\n epochsPerSample: Float64Array,\n a: number,\n b: number,\n rngState: Int32Array,\n opts: ParallelLayoutOptions,\n): Promise<Float32Array> {\n const nEdges = epochsPerSample.length;\n const shards = splitRange(nEdges, ctx.pool.size);\n\n let shared: Float32Array | null = null;\n if (ctx.sab) {\n shared = new Float32Array(new SharedArrayBuffer(embedding.length * 4));\n shared.set(embedding);\n }\n const embForWorkers = shared ?? embedding;\n\n await ctx.pool.mapAll('layoutInit', (w) => ({\n embedding: embForWorkers,\n tailEmbedding: null,\n head,\n tail,\n epochsPerSample,\n rngState,\n params: {\n a,\n b,\n gamma: opts.gamma,\n initialAlpha: opts.initialAlpha,\n negativeSampleRate: opts.negativeSampleRate,\n dim,\n nVertices,\n moveOther: opts.moveOther,\n edgeStart: shards[w]![0],\n edgeEnd: shards[w]![1],\n sharedEmbedding: ctx.sab,\n },\n }));\n\n let alpha = opts.initialAlpha;\n for (let epoch = 0; epoch < nEpochs; epoch++) {\n if (opts.signal?.aborted) {\n throw (\n (opts.signal.reason as Error | undefined) ??\n new DOMException('The operation was aborted.', 'AbortError')\n );\n }\n if (ctx.sab) {\n await ctx.pool.mapAll('layoutEpoch', () => ({ epoch, alpha }));\n } else {\n const deltas = await ctx.pool.mapAll<Float32Array>('layoutEpoch', () => ({\n epoch,\n alpha,\n embedding,\n }));\n for (const d of deltas) {\n for (let i = 0; i < embedding.length; i++) embedding[i] = embedding[i]! + d[i]!;\n }\n }\n alpha = opts.initialAlpha * (1.0 - epoch / nEpochs);\n if (opts.onEpoch) {\n const info: { epoch: number; nEpochs: number; phase: string; embedding?: Float32Array } = {\n epoch,\n nEpochs,\n phase: 'layout',\n };\n if (opts.snapshotEvery && (epoch % opts.snapshotEvery === 0 || epoch === nEpochs - 1)) {\n if (shared) embedding.set(shared);\n info.embedding = embedding;\n }\n opts.onEpoch(info);\n }\n }\n if (shared) embedding.set(shared);\n return embedding;\n}\n\n/** Build the prepared search index from a parallel kNN result (main thread). */\nexport function prepareIndexFromParallel(\n X: Matrix,\n knnInternal: KnnGraph,\n metricName: string,\n metricOptions: MetricOptions,\n nNeighbors: number,\n searchRngState: Int32Array,\n angular?: boolean,\n): { searchIndex: SearchIndex; knn: KnnGraph } {\n const internal = resolveInternalMetric(metricName, metricOptions);\n const pairDist = (x: Float32Array, y: Float32Array) => internal.dist(x, y);\n const searchIndex = prepareSearchIndex(\n X,\n knnInternal,\n pairDist,\n internal.correction,\n angular ?? internal.angularTrees,\n nNeighbors,\n searchRngState,\n );\n const outDst = new Float32Array(knnInternal.distances.length);\n for (let t = 0; t < outDst.length; t++) {\n const d = knnInternal.distances[t]!;\n outDst[t] = d === Infinity ? Infinity : internal.correction(d);\n }\n return {\n searchIndex,\n knn: { indices: knnInternal.indices.slice(), distances: outDst, k: knnInternal.k },\n };\n}\n","/**\n * Supervised simplicial-set intersections (umap_.py:620-903; notes §5):\n * categorical (fast_intersection, -1 = unlabeled), general (continuous target),\n * and reset_local_connectivity.\n */\n\nimport {\n type Csr,\n csrBinaryOp,\n csrEliminateZeros,\n csrRowNormalizeMax,\n csrTranspose,\n} from '../sparse.js';\n\n/**\n * fast_intersection semantics in-place over a COPY of the graph:\n * unknown (−1) edges ×= e^{−unknown_dist}; mismatched labels ×= e^{−far_dist}.\n */\nexport function fastIntersection(\n graph: Csr,\n target: ArrayLike<number>,\n unknownDist = 1.0,\n farDist = 5.0,\n): 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 const eUnknown = Math.exp(-unknownDist);\n const eFar = Math.exp(-farDist);\n for (let i = 0; i < out.rows; i++) {\n const ti = target[i] as number;\n for (let p = out.indptr[i]!; p < out.indptr[i + 1]!; p++) {\n const tj = target[out.indices[p]!] as number;\n if (ti === -1 || tj === -1) {\n out.data[p] = out.data[p]! * eUnknown;\n } else if (ti !== tj) {\n out.data[p] = out.data[p]! * eFar;\n }\n }\n }\n return out;\n}\n\n/** reset_local_connectivity (umap_.py:749-777): row-max normalize + fuzzy union. */\nexport function resetLocalConnectivity(graph: Csr): Csr {\n const normed = csrRowNormalizeMax({\n data: graph.data.slice(),\n indices: graph.indices,\n indptr: graph.indptr,\n rows: graph.rows,\n cols: graph.cols,\n });\n const t = csrTranspose(normed);\n const unioned = csrBinaryOp(normed, t, (a, b) => a + b - a * b);\n return csrEliminateZeros(unioned);\n}\n\n/**\n * discrete_metric_simplicial_set_intersection with metric=None (categorical path):\n * fast_intersection then reset_local_connectivity (umap_.py:780-855).\n */\nexport function categoricalSimplicialSetIntersection(\n graph: Csr,\n target: ArrayLike<number>,\n { unknownDist = 1.0, farDist = 5.0 }: { unknownDist?: number; farDist?: number } = {},\n): Csr {\n const intersected = csrEliminateZeros(fastIntersection(graph, target, unknownDist, farDist));\n return resetLocalConnectivity(intersected);\n}\n\n/**\n * general_simplicial_set_intersection (umap_.py:858-883 + sparse.py:146-197):\n * result sparsity = union (A + B); values re-mixed by weight where either side\n * exceeds its floor.\n */\nexport function generalSimplicialSetIntersection(A: Csr, B: Csr, weight: number): Csr {\n let leftMin = Infinity;\n for (let t = 0; t < A.data.length; t++) if (A.data[t]! < leftMin) leftMin = A.data[t]!;\n leftMin = Math.max(leftMin / 2.0, 1.0e-8);\n let rightMin = Infinity;\n for (let t = 0; t < B.data.length; t++) if (B.data[t]! < rightMin) rightMin = B.data[t]!;\n rightMin = Math.min(Math.max(rightMin / 2.0, 1.0e-8), 1e-4);\n\n return csrBinaryOp(A, B, (a, b) => {\n const leftVal = a !== 0 ? a : leftMin;\n const rightVal = b !== 0 ? b : rightMin;\n if (leftVal > leftMin || rightVal > rightMin) {\n if (weight < 0.5) {\n return leftVal * rightVal ** (weight / (1.0 - weight));\n }\n return leftVal ** ((1.0 - weight) / weight) * rightVal;\n }\n // untouched entries keep the (A + B) sum value\n return a + b;\n });\n}\n\n/** far_dist rule from target_weight (umap_.py:2706-2713). */\nexport function farDistFromWeight(targetWeight: number): number {\n return targetWeight < 1.0 ? 2.5 * (1.0 / (1.0 - targetWeight)) : 1.0e12;\n}\n","/**\n * densMAP original-space radii (umap_.py:1156-1186; notes §11.1) and the\n * embedding-space radii for outputDens (umap_.py:1242-1299; notes §11.4).\n */\n\nimport type { Csr } from '../sparse.js';\n\n/** Binary-search lookup in a canonical CSR row; absent → 0 (DOK semantics). */\nexport function csrLookup(m: Csr, row: number, col: number): number {\n let lo = m.indptr[row]!;\n let hi = m.indptr[row + 1]! - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const c = m.indices[mid]!;\n if (c === col) return m.data[mid]!;\n if (c < col) lo = mid + 1;\n else hi = mid - 1;\n }\n return 0;\n}\n\nexport interface OrigRadiiResult {\n /** log local radii (aux rad_orig) */\n ro: Float32Array;\n /** per-vertex membership sums */\n muSum: Float32Array;\n /** standardized R (densmap only) */\n R: Float32Array;\n}\n\n/**\n * Original radii over the PRUNED graph edges, using the symmetrized kNN distance\n * matrix `dists`. `head`/`tail`/`mu` are the pruned COO arrays.\n */\nexport function computeOrigRadii(\n head: Int32Array,\n tail: Int32Array,\n mu: Float32Array,\n dists: Csr,\n nVertices: number,\n): OrigRadiiResult {\n const ro = new Float32Array(nVertices);\n const muSum = new Float32Array(nVertices);\n for (let i = 0; i < head.length; i++) {\n const j = head[i]!;\n const k = tail[i]!;\n const dRaw = csrLookup(dists, j, k);\n const D = dRaw * dRaw; // squared — matches sq-euclidean used for embedding\n const m = mu[i]!;\n ro[j] = ro[j]! + m * D;\n ro[k] = ro[k]! + m * D;\n muSum[j] = muSum[j]! + m;\n muSum[k] = muSum[k]! + m;\n }\n const R = new Float32Array(nVertices);\n let mean = 0;\n for (let i = 0; i < nVertices; i++) {\n ro[i] = Math.log(1e-8 + ro[i]! / muSum[i]!);\n mean += ro[i]!;\n }\n mean /= nVertices;\n let variance = 0;\n for (let i = 0; i < nVertices; i++) variance += (ro[i]! - mean) ** 2;\n variance /= nVertices; // np.std default ddof=0\n const std = Math.sqrt(variance);\n for (let i = 0; i < nVertices; i++) R[i] = (ro[i]! - mean) / std;\n return { ro, muSum, R };\n}\n\n/**\n * Embedding radii for outputDens: mu-weighted mean of UNsquared embedding kNN\n * distances over a fresh fuzzy set built on the embedding (asymmetric with\n * rad_orig, which squares — pinned quirk).\n */\nexport function computeEmbRadii(graph: Csr, dists: Csr, nVertices: number): Float32Array {\n const re = new Float32Array(nVertices);\n const muSum = new Float32Array(nVertices);\n for (let j = 0; j < nVertices; j++) {\n for (let p = graph.indptr[j]!; p < graph.indptr[j + 1]!; p++) {\n const k = graph.indices[p]!;\n const m = graph.data[p]!;\n const D = csrLookup(dists, j, k); // NOT squared\n re[j] = re[j]! + m * D;\n re[k] = re[k]! + m * D;\n muSum[j] = muSum[j]! + m;\n muSum[k] = muSum[k]! + m;\n }\n }\n for (let i = 0; i < nVertices; i++) {\n re[i] = Math.log(1e-8 + re[i]! / muSum[i]!);\n }\n return re;\n}\n","/**\n * Output-metric distance-and-gradient pairs (named_distances_with_gradients subset;\n * distances.py; notes §10.2-10.4): euclidean, haversine, hyperboloid.\n */\n\nimport { UmapValidationError } from '../types.js';\n\n/** writes grad into `grad`, returns distance */\nexport type OutputMetricGradFn = (x: Float32Array, y: Float32Array, grad: Float64Array) => number;\n\nexport function euclideanGrad(x: Float32Array, y: Float32Array, grad: Float64Array): number {\n let s = 0;\n for (let i = 0; i < x.length; i++) {\n const d = x[i]! - y[i]!;\n s += d * d;\n }\n const dist = Math.sqrt(s);\n for (let i = 0; i < x.length; i++) grad[i] = (x[i]! - y[i]!) / (1e-6 + dist);\n return dist;\n}\n\n/** haversine_grad (distances.py:504-531) — 2-D only, latitudes offset by π/2. */\nexport function haversineGrad(x: Float32Array, y: Float32Array, grad: Float64Array): 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 cosLat = Math.cos(0.5 * (x[0]! - y[0]!));\n const sinLong = Math.sin(0.5 * (x[1]! - y[1]!));\n const cosLong = Math.cos(0.5 * (x[1]! - y[1]!));\n const a0 = Math.cos(x[0]! + Math.PI / 2) * Math.cos(y[0]! + Math.PI / 2) * sinLong * sinLong;\n const a1 = a0 + sinLat * sinLat;\n const d = 2.0 * Math.asin(Math.sqrt(Math.min(Math.max(Math.abs(a1), 0), 1)));\n const denom = Math.sqrt(Math.abs(a1 - 1.0)) * Math.sqrt(Math.abs(a1));\n grad[0] =\n (sinLat * cosLat -\n Math.sin(x[0]! + Math.PI / 2) * Math.cos(y[0]! + Math.PI / 2) * sinLong * sinLong) /\n (denom + 1e-6);\n grad[1] =\n (Math.cos(x[0]! + Math.PI / 2) * Math.cos(y[0]! + Math.PI / 2) * sinLong * cosLong) /\n (denom + 1e-6);\n return d;\n}\n\n/** hyperboloid_grad (distances.py:205-225) — reduced hyperboloid coordinates. */\nexport function hyperboloidGrad(x: Float32Array, y: Float32Array, grad: Float64Array): number {\n let sx = 1;\n let sy = 1;\n let dot = 0;\n for (let i = 0; i < x.length; i++) {\n sx += x[i]! * x[i]!;\n sy += y[i]! * y[i]!;\n dot += x[i]! * y[i]!;\n }\n const s = Math.sqrt(sx);\n const t = Math.sqrt(sy);\n let B = s * t - dot;\n if (B <= 1) B = 1.0 + 1e-8;\n const gradCoeff = 1.0 / (Math.sqrt(B - 1) * Math.sqrt(B + 1));\n for (let i = 0; i < x.length; i++) {\n grad[i] = gradCoeff * ((x[i]! * t) / s - y[i]!);\n }\n return Math.acosh(B);\n}\n\nconst OUTPUT_METRIC_GRADS: Record<string, OutputMetricGradFn> = {\n euclidean: euclideanGrad,\n l2: euclideanGrad,\n haversine: haversineGrad,\n hyperboloid: hyperboloidGrad,\n};\n\nexport function resolveOutputMetricGrad(name: string): OutputMetricGradFn {\n const fn = OUTPUT_METRIC_GRADS[name];\n if (!fn) {\n throw new UmapValidationError(\n `gradient function is not implemented for output metric '${name}' (supported: ${Object.keys(OUTPUT_METRIC_GRADS).join(', ')})`,\n );\n }\n return fn;\n}\n\nexport function isEuclideanOutput(name: string): boolean {\n return name === 'euclidean' || name === 'l2';\n}\n","/**\n * Public options (BRIEF §4.3) — defaults match umap-learn 0.5.9.post2 exactly.\n */\n\nimport type { InitMethod } from '../init/index.js';\nimport type { MetricOptions } from '../metrics.js';\nimport type { Embedding, Logger, MetricFn } from '../types.js';\n\nexport interface UmapOptions {\n nNeighbors?: number; // 15\n nComponents?: number; // 2\n metric?: string | MetricFn; // 'euclidean' | 'precomputed' | custom fn (CPU only)\n metricOptions?: MetricOptions;\n outputMetric?: string; // 'euclidean' | 'haversine' | 'hyperboloid' (CPU)\n outputMetricOptions?: Record<string, number>;\n nEpochs?: number; // auto: 500 small / 200 large (+200 densmap)\n learningRate?: number; // 1.0\n init?: InitMethod; // 'spectral'\n minDist?: number; // 0.1\n spread?: number; // 1.0\n lowMemory?: boolean; // true (accepted; no-op in the pinned pynndescent 0.6.0 — D-007)\n concurrency?: number | 'auto'; // worker count; 1 = single-thread deterministic\n setOpMixRatio?: number; // 1.0\n localConnectivity?: number; // 1.0\n repulsionStrength?: number; // 1.0\n negativeSampleRate?: number; // 5\n transformQueueSize?: number; // 4.0 (legacy; unused by the pinned pynndescent query)\n a?: number;\n b?: number;\n seed?: number; // random_state\n angularRpForest?: boolean; // false (auto-enabled for angular metric family)\n targetNNeighbors?: number; // -1\n targetMetric?: string; // 'categorical'\n targetMetricOptions?: MetricOptions;\n targetWeight?: number; // 0.5\n transformSeed?: number; // 42\n transformMode?: 'embedding' | 'graph';\n forceApproximation?: boolean; // false\n verbose?: boolean | Logger;\n unique?: boolean; // false\n densMap?: boolean; // false\n densLambda?: number; // 2.0\n densFrac?: number; // 0.3\n densVarShift?: number; // 0.1\n outputDens?: boolean; // false\n disconnectionDistance?: number; // per-metric default\n precomputedKnn?: { indices: Int32Array; distances: Float32Array; k: number };\n backend?: 'auto' | 'cpu' | 'webgpu';\n device?: unknown; // GPUDevice or async provider\n /**\n * Explicit worker entry for the parallel CPU backend, for bundlers that do\n * not detect the library's inline `new Worker(new URL(...))` pattern.\n * Browser: an absolute URL/string (e.g. Vite's `'umap-web/worker?worker&url'`\n * import). Node: a file:// URL or absolute path. When spawning from this URL\n * fails, fit() warns and continues single-threaded. See README\n * \"Workers & bundlers\".\n */\n workerUrl?: URL | string;\n deterministic?: boolean; // false\n /** GPU SGD accumulation strategy (§A2, D-011); default from measurements */\n gpuLayoutStrategy?: 'vertexGather' | 'edgeAtomic';\n onEpoch?: (e: {\n epoch: number;\n nEpochs: number;\n phase: string;\n embedding?: Float32Array;\n }) => void;\n}\n\n/** DISCONNECTION_DISTANCES (umap_.py:61-68). */\nexport const DISCONNECTION_DISTANCES: Record<string, number> = {\n correlation: 2,\n cosine: 2,\n hellinger: 1,\n jaccard: 1,\n bit_jaccard: 1,\n dice: 1,\n};\n\nexport interface FitCallOptions {\n signal?: AbortSignal;\n}\n\nexport type { Embedding };\n","/**\n * Model serialization (BRIEF §4.7): single JSON header + concatenated binary\n * sections, versioned. Captures everything transform/inverseTransform need.\n *\n * deserializeModel treats the blob as untrusted: every section is bounds- and\n * dtype-checked, and cross-array invariants (shapes, index ranges, search-tree\n * traversal order) are validated so a corrupt or crafted blob throws a typed\n * UmapValidationError instead of producing silent garbage, out-of-bounds\n * indexing, or non-terminating tree walks.\n */\n\nimport { resolveInternalMetric } from '../knn/internal-metrics.js';\nimport type { FlatTree } from '../knn/rpforest.js';\nimport type { SearchIndex } from '../knn/search.js';\nimport type { Csr } from '../sparse.js';\nimport type { CSRInput, Embedding, KnnGraph, Matrix } from '../types.js';\nimport { UmapError, UmapValidationError } from '../types.js';\nimport type { UmapOptions } from './options.js';\nimport type { UMAP } from './umap.js';\n\nconst MAGIC = 'UMAPWEB1';\n\ntype TypedArray = Float32Array | Float64Array | Int32Array | Uint8Array;\n\ninterface SectionMeta {\n name: string;\n dtype: 'f32' | 'f64' | 'i32' | 'u8';\n offset: number;\n length: number;\n}\n\nconst BYTES_PER: Record<SectionMeta['dtype'], number> = { f32: 4, f64: 8, i32: 4, u8: 1 };\n\nfunction dtypeOf(arr: TypedArray): SectionMeta['dtype'] {\n if (arr instanceof Float32Array) return 'f32';\n if (arr instanceof Float64Array) return 'f64';\n if (arr instanceof Int32Array) return 'i32';\n return 'u8';\n}\n\n/**\n * The fitted fields the (de)serializer walks. UMAP structurally implements\n * this, so renaming a field breaks compilation here instead of silently\n * breaking round-trips.\n */\ninterface SerializedModelFields {\n _embedding: Embedding | null;\n _embeddingUnique: Float32Array | null;\n _graph: Csr | null;\n _sigmas: Float32Array | null;\n _rhos: Float32Array | null;\n _knn: KnnGraph | null;\n _searchIndex: SearchIndex | null;\n _rawData: Matrix | null;\n _rawCsr: CSRInput | null;\n _uniqueIndex: Int32Array | null;\n _uniqueInverse: Int32Array | null;\n _a: number;\n _b: number;\n _nNeighborsUsed: number;\n _smallData: boolean;\n _disconnection: number;\n _supervised: boolean;\n _inputHash: string | null;\n _radOrig: Float32Array | null;\n _radEmb: Float32Array | null;\n}\n\nexport function serializeModel(model: UMAP): Uint8Array {\n const m: SerializedModelFields = model;\n if (!m._embedding) throw new UmapError('cannot serialize an unfitted model');\n if (typeof model.options.metric === 'function') {\n throw new UmapValidationError('models with custom metric functions cannot be serialized');\n }\n if (m._rawCsr) {\n throw new UmapValidationError('sparse-fitted model serialization is not supported');\n }\n if (!m._graph || !m._sigmas || !m._rhos) {\n throw new UmapError('cannot serialize a partially fitted model');\n }\n\n const sections: Array<{ name: string; arr: TypedArray }> = [];\n const push = (name: string, arr: TypedArray | null | undefined) => {\n if (arr) sections.push({ name, arr });\n };\n\n push('embedding', m._embedding.data);\n push('embeddingUnique', m._embeddingUnique);\n push('graph.data', m._graph.data);\n push('graph.indices', m._graph.indices);\n push('graph.indptr', m._graph.indptr);\n push('sigmas', m._sigmas);\n push('rhos', m._rhos);\n push('knn.indices', m._knn?.indices);\n push('knn.distances', m._knn?.distances);\n push('rawData', m._rawData?.data);\n push('uniqueIndex', m._uniqueIndex);\n push('uniqueInverse', m._uniqueInverse);\n push('radOrig', m._radOrig);\n push('radEmb', m._radEmb);\n const si = m._searchIndex;\n if (si) {\n push('si.indptr', si.indptr);\n push('si.indices', si.indices);\n push('si.vertexOrder', si.vertexOrder);\n push('si.data', si.data.data);\n push('si.tree.hyperplanes', si.tree.hyperplanes);\n push('si.tree.offsets', si.tree.offsets);\n push('si.tree.children', si.tree.children);\n push('si.tree.indices', si.tree.indices);\n push('si.searchRngState', si.searchRngState);\n }\n\n let offset = 0;\n const sectionMeta: SectionMeta[] = [];\n for (const s of sections) {\n // 8-byte alignment for f64 views\n offset = Math.ceil(offset / 8) * 8;\n sectionMeta.push({ name: s.name, dtype: dtypeOf(s.arr), offset, length: s.arr.length });\n offset += s.arr.length * BYTES_PER[dtypeOf(s.arr)];\n }\n\n const {\n onEpoch: _onEpoch,\n verbose: _verbose,\n device: _device,\n precomputedKnn: _precomputedKnn, // typed arrays do not survive JSON\n ...serializableOptions\n } = model.options;\n const header = {\n magic: MAGIC,\n version: 1,\n options: serializableOptions,\n scalars: {\n a: m._a,\n b: m._b,\n nNeighborsUsed: m._nNeighborsUsed,\n smallData: m._smallData,\n disconnection: m._disconnection === Infinity ? 'inf' : m._disconnection,\n supervised: m._supervised,\n inputHash: m._inputHash,\n embedding: { rows: m._embedding.rows, cols: m._embedding.cols },\n graph: { rows: m._graph.rows, cols: m._graph.cols },\n knnK: m._knn?.k ?? null,\n rawData: m._rawData ? { rows: m._rawData.rows, cols: m._rawData.cols } : null,\n searchIndex: si\n ? {\n angular: si.angular,\n minDistance: si.minDistance,\n nNeighbors: si.nNeighbors,\n metricName: (model.options.metric as string) ?? 'euclidean',\n tree: { leafSize: si.tree.leafSize, nNodes: si.tree.nNodes, dim: si.tree.dim },\n dataRows: si.data.rows,\n dataCols: si.data.cols,\n }\n : null,\n },\n sections: sectionMeta,\n };\n const headerBytes = new TextEncoder().encode(JSON.stringify(header));\n const base = Math.ceil((12 + headerBytes.length) / 8) * 8; // 8-aligned data start\n const total = base + offset;\n const out = new Uint8Array(total);\n const dv = new DataView(out.buffer);\n out.set(new TextEncoder().encode(MAGIC), 0);\n dv.setUint32(8, headerBytes.length, true);\n out.set(headerBytes, 12);\n for (let i = 0; i < sections.length; i++) {\n const s = sections[i]!;\n const metaS = sectionMeta[i]!;\n const bytes = new Uint8Array(s.arr.buffer, s.arr.byteOffset, s.arr.byteLength);\n out.set(bytes, base + metaS.offset);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// deserialization (untrusted input)\n// ---------------------------------------------------------------------------\n\nfunction fail(why: string): never {\n throw new UmapValidationError(`invalid serialized model: ${why}`);\n}\n\nfunction reqInt(v: unknown, name: string, min: number): number {\n if (typeof v !== 'number' || !Number.isInteger(v) || v < min) {\n fail(`${name} must be an integer >= ${min}`);\n }\n return v;\n}\n\nfunction reqFinite(v: unknown, name: string): number {\n if (typeof v !== 'number' || !Number.isFinite(v)) fail(`${name} must be a finite number`);\n return v;\n}\n\nfunction reqBool(v: unknown, name: string): boolean {\n if (typeof v !== 'boolean') fail(`${name} must be a boolean`);\n return v;\n}\n\n/** indptr shape: length n+1, starts at 0, monotone, ends at nnz. */\nfunction checkIndptr(indptr: Int32Array, n: number, nnz: number, name: string): void {\n if (indptr.length !== n + 1) fail(`${name} length must be ${n + 1}`);\n if (indptr[0] !== 0) fail(`${name} must start at 0`);\n for (let i = 0; i < n; i++) {\n if (indptr[i + 1]! < indptr[i]!) fail(`${name} must be non-decreasing`);\n }\n if (indptr[n] !== nnz) fail(`${name} end (${indptr[n]}) must equal nnz (${nnz})`);\n}\n\nfunction checkIndexRange(arr: Int32Array, lo: number, hi: number, name: string): void {\n for (let i = 0; i < arr.length; i++) {\n const v = arr[i]!;\n if (v < lo || v >= hi) fail(`${name} contains out-of-range index ${v}`);\n }\n}\n\nexport function deserializeModel(\n blob: Uint8Array,\n UMAPClass: new (options?: UmapOptions) => UMAP,\n): UMAP {\n if (!(blob instanceof Uint8Array)) fail('expected a Uint8Array');\n if (blob.byteLength < 12) fail('blob too short for a header');\n const magic = new TextDecoder().decode(blob.subarray(0, 8));\n if (magic !== MAGIC) fail('bad magic (not a umap-web serialized model)');\n const dv = new DataView(blob.buffer, blob.byteOffset, blob.byteLength);\n const headerLen = dv.getUint32(8, true);\n if (12 + headerLen > blob.byteLength) fail('declared header length exceeds the blob');\n // biome-ignore lint/suspicious/noExplicitAny: raw JSON before validation\n let header: any;\n try {\n header = JSON.parse(new TextDecoder().decode(blob.subarray(12, 12 + headerLen)));\n } catch {\n fail('corrupt JSON header');\n }\n if (header?.version !== 1) {\n throw new UmapValidationError(`unsupported serialization version ${header?.version}`);\n }\n const sc = header.scalars;\n if (typeof sc !== 'object' || sc === null || !Array.isArray(header.sections)) {\n fail('malformed header');\n }\n\n // --- section table: shape + bounds (a truncated blob must throw, not clamp)\n const base = Math.ceil((12 + headerLen) / 8) * 8;\n const metas = new Map<string, SectionMeta>();\n for (const s of header.sections as SectionMeta[]) {\n if (typeof s?.name !== 'string' || !(s?.dtype in BYTES_PER)) fail('malformed section entry');\n reqInt(s.offset, `section ${s.name} offset`, 0);\n reqInt(s.length, `section ${s.name} length`, 0);\n if (base + s.offset + s.length * BYTES_PER[s.dtype] > blob.byteLength) {\n fail(`section ${s.name} exceeds the blob bounds`);\n }\n if (metas.has(s.name)) fail(`duplicate section ${s.name}`);\n metas.set(s.name, s);\n }\n const view = (s: SectionMeta): TypedArray => {\n const start = blob.byteOffset + base + s.offset;\n switch (s.dtype) {\n case 'f32':\n return new Float32Array(blob.buffer.slice(start, start + s.length * 4));\n case 'f64':\n return new Float64Array(blob.buffer.slice(start, start + s.length * 8));\n case 'i32':\n return new Int32Array(blob.buffer.slice(start, start + s.length * 4));\n default:\n return new Uint8Array(blob.buffer.slice(start, start + s.length));\n }\n };\n const arrays = new Map<string, TypedArray>();\n for (const s of metas.values()) arrays.set(s.name, view(s));\n /** Fetch a section, enforcing its declared dtype (a lying header must not type-pun). */\n const need = <T extends TypedArray>(name: string, dtype: SectionMeta['dtype']): T => {\n const meta = metas.get(name);\n const a = arrays.get(name);\n if (!meta || !a) fail(`missing section ${name}`);\n if (meta.dtype !== dtype) fail(`section ${name} has dtype ${meta.dtype}, expected ${dtype}`);\n return a as T;\n };\n const optional = <T extends TypedArray>(name: string, dtype: SectionMeta['dtype']): T | null =>\n metas.has(name) ? need<T>(name, dtype) : null;\n\n // --- options: strip non-data keys a crafted header could smuggle in\n const rawOptions = typeof header.options === 'object' && header.options !== null;\n const {\n onEpoch: _onEpoch,\n verbose: _verbose,\n device: _device,\n precomputedKnn: _precomputedKnn,\n ...options\n } = (rawOptions ? header.options : {}) as UmapOptions;\n const model = new UMAPClass(options as UmapOptions);\n const m: SerializedModelFields = model;\n\n // --- scalars + cross-array consistency\n m._a = reqFinite(sc.a, 'scalars.a');\n m._b = reqFinite(sc.b, 'scalars.b');\n if (sc.disconnection !== 'inf') reqFinite(sc.disconnection, 'scalars.disconnection');\n m._disconnection = sc.disconnection === 'inf' ? Infinity : (sc.disconnection as number);\n m._smallData = reqBool(sc.smallData, 'scalars.smallData');\n m._supervised = reqBool(sc.supervised, 'scalars.supervised');\n if (sc.inputHash !== null && typeof sc.inputHash !== 'string') {\n fail('scalars.inputHash must be a string or null');\n }\n m._inputHash = sc.inputHash;\n\n const embRows = reqInt(sc.embedding?.rows, 'embedding.rows', 1);\n const embCols = reqInt(sc.embedding?.cols, 'embedding.cols', 1);\n const embData = need<Float32Array>('embedding', 'f32');\n if (embData.length !== embRows * embCols) fail('embedding data does not match rows*cols');\n m._embedding = { data: embData, rows: embRows, cols: embCols };\n\n const gRows = reqInt(sc.graph?.rows, 'graph.rows', 1);\n const gCols = reqInt(sc.graph?.cols, 'graph.cols', 1);\n if (gRows !== gCols) fail('graph must be square');\n const gData = need<Float64Array>('graph.data', 'f64');\n const gIndices = need<Int32Array>('graph.indices', 'i32');\n const gIndptr = need<Int32Array>('graph.indptr', 'i32');\n if (gIndices.length !== gData.length) fail('graph indices/data length mismatch');\n checkIndptr(gIndptr, gRows, gData.length, 'graph.indptr');\n checkIndexRange(gIndices, 0, gCols, 'graph.indices');\n m._graph = { data: gData, indices: gIndices, indptr: gIndptr, rows: gRows, cols: gCols };\n\n m._nNeighborsUsed = reqInt(sc.nNeighborsUsed, 'scalars.nNeighborsUsed', 1);\n if (m._nNeighborsUsed > gRows) fail('nNeighborsUsed exceeds the number of training rows');\n\n m._sigmas = need<Float32Array>('sigmas', 'f32');\n m._rhos = need<Float32Array>('rhos', 'f32');\n if (m._sigmas.length !== gRows || m._rhos.length !== gRows) {\n fail('sigmas/rhos length must equal graph.rows');\n }\n\n const embUnique = optional<Float32Array>('embeddingUnique', 'f32');\n if (embUnique && embUnique.length !== gRows * embCols) {\n fail('embeddingUnique length must equal graph.rows * embedding.cols');\n }\n m._embeddingUnique = embUnique ?? m._embedding.data;\n\n if (sc.knnK != null) {\n const k = reqInt(sc.knnK, 'scalars.knnK', 1);\n const ki = need<Int32Array>('knn.indices', 'i32');\n const kd = need<Float32Array>('knn.distances', 'f32');\n if (ki.length !== gRows * k || kd.length !== gRows * k) {\n fail('knn arrays must have graph.rows * k entries');\n }\n checkIndexRange(ki, -1, gRows, 'knn.indices');\n m._knn = { indices: ki, distances: kd, k };\n }\n\n if (sc.rawData != null) {\n const rRows = reqInt(sc.rawData.rows, 'rawData.rows', 1);\n const rCols = reqInt(sc.rawData.cols, 'rawData.cols', 1);\n const rData = need<Float32Array>('rawData', 'f32');\n if (rData.length !== rRows * rCols) fail('rawData does not match rows*cols');\n if (rRows !== embRows) fail('rawData.rows must equal embedding.rows');\n m._rawData = { data: rData, rows: rRows, cols: rCols };\n }\n\n const uniqueIndex = optional<Int32Array>('uniqueIndex', 'i32');\n const uniqueInverse = optional<Int32Array>('uniqueInverse', 'i32');\n if ((uniqueIndex === null) !== (uniqueInverse === null)) {\n fail('uniqueIndex/uniqueInverse must be present together');\n }\n if (uniqueIndex && uniqueInverse) {\n if (uniqueIndex.length !== gRows) fail('uniqueIndex length must equal graph.rows');\n if (uniqueInverse.length !== embRows) fail('uniqueInverse length must equal embedding.rows');\n if (m._rawData) checkIndexRange(uniqueIndex, 0, m._rawData.rows, 'uniqueIndex');\n checkIndexRange(uniqueInverse, 0, gRows, 'uniqueInverse');\n }\n m._uniqueIndex = uniqueIndex;\n m._uniqueInverse = uniqueInverse;\n\n const radOrig = optional<Float32Array>('radOrig', 'f32');\n const radEmb = optional<Float32Array>('radEmb', 'f32');\n if (radOrig && radOrig.length !== embRows) fail('radOrig length must equal embedding.rows');\n if (radEmb && radEmb.length !== embRows) fail('radEmb length must equal embedding.rows');\n m._radOrig = radOrig;\n m._radEmb = radEmb;\n\n if (sc.searchIndex != null) {\n const s = sc.searchIndex;\n if (typeof s.metricName !== 'string') fail('searchIndex.metricName must be a string');\n const angular = reqBool(s.angular, 'searchIndex.angular');\n if (typeof s.minDistance !== 'number' || Number.isNaN(s.minDistance)) {\n fail('searchIndex.minDistance must be a number');\n }\n const siNeighbors = reqInt(s.nNeighbors, 'searchIndex.nNeighbors', 1);\n const dataRows = reqInt(s.dataRows, 'searchIndex.dataRows', 1);\n const dataCols = reqInt(s.dataCols, 'searchIndex.dataCols', 1);\n if (dataRows !== gRows) fail('searchIndex.dataRows must equal graph.rows');\n if (m._rawData && dataCols !== m._rawData.cols) {\n fail('searchIndex.dataCols must equal rawData.cols');\n }\n const siData = need<Float32Array>('si.data', 'f32');\n if (siData.length !== dataRows * dataCols) fail('si.data does not match rows*cols');\n\n const leafSize = reqInt(s.tree?.leafSize, 'searchIndex.tree.leafSize', 1);\n const nNodes = reqInt(s.tree?.nNodes, 'searchIndex.tree.nNodes', 1);\n const dim = reqInt(s.tree?.dim, 'searchIndex.tree.dim', 1);\n if (dim !== dataCols) fail('searchIndex.tree.dim must equal dataCols');\n const hyperplanes = need<Float32Array>('si.tree.hyperplanes', 'f32');\n const offsets = need<Float32Array>('si.tree.offsets', 'f32');\n const children = need<Int32Array>('si.tree.children', 'i32');\n const treeIndices = need<Int32Array>('si.tree.indices', 'i32');\n if (hyperplanes.length !== nNodes * dim) fail('si.tree.hyperplanes size mismatch');\n if (offsets.length !== nNodes) fail('si.tree.offsets size mismatch');\n if (children.length !== nNodes * 2) fail('si.tree.children size mismatch');\n if (treeIndices.length !== dataRows) fail('si.tree.indices size mismatch');\n checkIndexRange(treeIndices, 0, dataRows, 'si.tree.indices');\n // traversal safety: internal children strictly descend (preorder ⇒ child > parent,\n // guaranteeing searchFlatTree terminates); leaf ranges stay within indices\n for (let i = 0; i < nNodes; i++) {\n const c0 = children[i * 2]!;\n const c1 = children[i * 2 + 1]!;\n if (c0 > 0) {\n if (c0 <= i || c0 >= nNodes || c1 <= i || c1 >= nNodes) {\n fail(`si.tree.children node ${i} violates preorder traversal`);\n }\n } else {\n const ls = -c0;\n const le = -c1;\n if (ls < 0 || le < ls || le > treeIndices.length) {\n fail(`si.tree.children node ${i} has an invalid leaf range`);\n }\n }\n }\n const tree: FlatTree = {\n hyperplanes,\n offsets,\n children,\n indices: treeIndices,\n leafSize,\n nNodes,\n dim,\n };\n const siIndptr = need<Int32Array>('si.indptr', 'i32');\n const siIndices = need<Int32Array>('si.indices', 'i32');\n checkIndptr(siIndptr, dataRows, siIndices.length, 'si.indptr');\n checkIndexRange(siIndices, 0, dataRows, 'si.indices');\n const vertexOrder = need<Int32Array>('si.vertexOrder', 'i32');\n if (vertexOrder.length !== dataRows) fail('si.vertexOrder size mismatch');\n checkIndexRange(vertexOrder, 0, dataRows, 'si.vertexOrder');\n const searchRngState = need<Int32Array>('si.searchRngState', 'i32');\n if (searchRngState.length !== 3) fail('si.searchRngState must have 3 words');\n\n const internal = resolveInternalMetric(s.metricName, model.options.metricOptions ?? {});\n m._searchIndex = {\n indptr: siIndptr,\n indices: siIndices,\n tree,\n vertexOrder,\n data: { data: siData, rows: dataRows, cols: dataCols },\n dist: (a: Float32Array, b: Float32Array) => internal.dist(a, b),\n correction: internal.correction,\n angular,\n minDistance: s.minDistance,\n searchRngState,\n nNeighbors: siNeighbors,\n };\n }\n return model;\n}\n","/**\n * Transform/inverse initialization helpers (umap_.py:1304-1390; notes §12-14).\n */\n\nimport type { Csr } from '../sparse.js';\n\n/**\n * init_graph_transform (umap_.py:1337-1375): weighted mean of train embedding rows.\n * Rows with no nonzeros → NaN; a weight == 1.0 copies that train row exactly.\n */\nexport function initGraphTransform(\n graph: Csr, // (nNew × nTrain) bipartite membership CSR\n embedding: Float32Array, // train embedding\n dim: number,\n): Float32Array {\n const nNew = graph.rows;\n const out = new Float32Array(nNew * dim);\n for (let row = 0; row < nNew; row++) {\n const start = graph.indptr[row]!;\n const end = graph.indptr[row + 1]!;\n if (start === end) {\n for (let d = 0; d < dim; d++) out[row * dim + d] = Number.NaN;\n continue;\n }\n let rowSum = 0;\n let exactCol = -1;\n for (let p = start; p < end; p++) {\n rowSum += graph.data[p]!;\n if (graph.data[p]! === 1.0 && exactCol === -1) exactCol = graph.indices[p]!;\n }\n if (exactCol !== -1) {\n // Python checks `graph[row, col] == 1` first and copies exactly\n for (let d = 0; d < dim; d++) out[row * dim + d] = embedding[exactCol * dim + d]!;\n continue;\n }\n for (let p = start; p < end; p++) {\n const w = graph.data[p]! / rowSum;\n const col = graph.indices[p]!;\n for (let d = 0; d < dim; d++) {\n out[row * dim + d] = out[row * dim + d]! + w * embedding[col * dim + d]!;\n }\n }\n }\n return out;\n}\n\n/**\n * init_transform (umap_.py:1304-1334): constant-degree weighted mean of raw data\n * rows (used by inverseTransform).\n */\nexport function initTransform(\n indices: Int32Array, // (nNew × degree)\n weights: Float32Array, // (nNew × degree), row-l1-normalized\n degree: number,\n data: Float32Array, // train raw data\n dim: number,\n): Float32Array {\n const nNew = indices.length / degree;\n const out = new Float32Array(nNew * dim);\n for (let i = 0; i < nNew; i++) {\n for (let j = 0; j < degree; j++) {\n const w = weights[i * degree + j]!;\n const col = indices[i * degree + j]!;\n for (let d = 0; d < dim; d++) {\n out[i * dim + d] = out[i * dim + d]! + w * data[col * dim + d]!;\n }\n }\n }\n return out;\n}\n\n/**\n * init_update (umap_.py:1378-1390) for update(): each new point gets the summed\n * coordinates of its OLD-point neighbors divided by (count × dim) — the pinned\n * quirk divides by the extra dim factor.\n */\nexport function initUpdate(\n embedding: Float32Array,\n dim: number,\n originalSize: number,\n knnIndices: Int32Array,\n k: number,\n): void {\n const nTotal = embedding.length / dim;\n for (let i = originalSize; i < nTotal; i++) {\n let count = 0;\n for (let j = 0; j < k; j++) {\n const nb = knnIndices[i * k + j]!;\n if (nb >= 0 && nb < originalSize) {\n count += dim; // Python counts once per (neighbor, dimension) pair\n for (let d = 0; d < dim; d++) {\n embedding[i * dim + d] = embedding[i * dim + d]! + embedding[nb * dim + d]!;\n }\n }\n }\n if (count > 0) {\n for (let d = 0; d < dim; d++) {\n embedding[i * dim + d] = embedding[i * dim + d]! / count;\n }\n }\n }\n}\n","/**\n * The UMAP estimator (BRIEF §4.4) — async-first, typed-array native.\n * fit/fitTransform (dense/CSR, supervised, unique), transform (+ 'graph' mode),\n * inverseTransform, update(), serialization. CPU backends; workers/WebGPU at M6.\n */\n\nimport {\n createParallelContext,\n type ParallelContext,\n parallelNnDescent,\n parallelOptimizeLayout,\n prepareIndexFromParallel,\n} from '../backends/cpu/workers.js';\nimport { findABParams } from '../graph/ab.js';\nimport { defaultNEpochs, makeEpochsPerSample, pruneGraphForEpochs } from '../graph/epochs.js';\nimport { computeMembershipStrengths, fuzzySimplicialSet } from '../graph/fuzzy.js';\nimport { smoothKnnDist } from '../graph/smooth.js';\nimport {\n categoricalSimplicialSetIntersection,\n farDistFromWeight,\n generalSimplicialSetIntersection,\n resetLocalConnectivity,\n} from '../graph/supervised.js';\nimport { initializeEmbedding } from '../init/index.js';\nimport { exactKnnDense, knnFromPrecomputed } from '../knn/exact.js';\nimport { nearestNeighborsDense, nearestNeighborsSparse, SMALL_DATA_CUTOFF } from '../knn/index.js';\nimport { resolveInternalMetric } from '../knn/internal-metrics.js';\nimport type { SearchIndex } from '../knn/search.js';\nimport { prepareSearchIndex, searchKnn } from '../knn/search.js';\nimport { computeEmbRadii, computeOrigRadii } from '../layout/densmap.js';\nimport { isEuclideanOutput, resolveOutputMetricGrad } from '../layout/outputMetrics.js';\nimport {\n optimizeLayoutEuclidean,\n optimizeLayoutGeneric,\n optimizeLayoutInverse,\n} from '../layout/sgd.js';\nimport { isNamedMetric, resolveMetric, validateMetricOptionSizes } from '../metrics.js';\nimport { Pcg32 } from '../rng.js';\nimport { type Csr, csrEliminateZeros, csrFromCoo } from '../sparse.js';\nimport {\n type CSRInput,\n consoleLogger,\n type DenseInput,\n type Embedding,\n type KnnGraph,\n type Labels,\n type Logger,\n type Matrix,\n silentLogger,\n type Target,\n throwIfAborted,\n UmapBackendError,\n UmapError,\n UmapValidationError,\n} from '../types.js';\nimport { isCsrInput, raceTimeout, toMatrix, validateCsr } from '../util.js';\nimport { DISCONNECTION_DISTANCES, type FitCallOptions, type UmapOptions } from './options.js';\nimport { deserializeModel, serializeModel } from './serialize.js';\nimport { initGraphTransform, initTransform, initUpdate } from './transform-init.js';\n\ninterface ResolvedBackendInfo {\n knn: string;\n layout: string;\n}\n\nconst yieldToLoop: () => Promise<void> =\n typeof setImmediate === 'function'\n ? () => new Promise((r) => setImmediate(r))\n : () => new Promise((r) => setTimeout(r, 0));\n\n/** Bound on requestAdapter/requestDevice — a broken GPU stack must fall back, not hang. */\nconst GPU_ACQUIRE_TIMEOUT_MS = 5000;\n\nfunction entropySeed(): number {\n const cryptoObj = (globalThis as { crypto?: Crypto }).crypto;\n if (typeof cryptoObj?.getRandomValues !== 'function') {\n throw new UmapError(\n 'no global crypto available for entropy seeding — pass options.seed explicitly',\n );\n }\n const buf = new Uint32Array(2);\n cryptoObj.getRandomValues(buf);\n // stay within 2^53 so the seed is exactly representable as a JS number\n // (Pcg32.fromSeed splits it back into 32-bit words)\n return buf[0]! + (buf[1]! & 0x1fffff) * 0x100000000;\n}\n\n/** FNV-1a over bytes — cheap input-identity hash (same-data transform shortcut). */\nfunction contentHash(view: Uint8Array): string {\n let h1 = 0x811c9dc5;\n let h2 = 0xcbf29ce4;\n for (let i = 0; i < view.length; i++) {\n h1 = Math.imul(h1 ^ view[i]!, 0x01000193) >>> 0;\n h2 = Math.imul(h2 ^ view[i]!, 0x01000197) >>> 0;\n }\n return `${view.length}:${h1.toString(16)}:${h2.toString(16)}`;\n}\n\n/** Bitwise equality (confirms a contentHash match; Float32Array offsets are 4-aligned). */\nfunction sameFloat32Bits(a: Float32Array, b: Float32Array): boolean {\n if (a.length !== b.length) return false;\n const ai = new Int32Array(a.buffer, a.byteOffset, a.length);\n const bi = new Int32Array(b.buffer, b.byteOffset, b.length);\n for (let i = 0; i < ai.length; i++) {\n if (ai[i] !== bi[i]) return false;\n }\n return true;\n}\n\nexport class UMAP {\n readonly options: UmapOptions;\n protected logger: Logger;\n\n // fitted state (underscored fields are (de)serialized in serialize.ts)\n _embedding: Embedding | null = null;\n _embeddingUnique: Float32Array | null = null;\n _graph: Csr | null = null;\n _sigmas: Float32Array | null = null;\n _rhos: Float32Array | null = null;\n _knn: KnnGraph | null = null;\n _searchIndex: SearchIndex | null = null;\n _rawData: Matrix | null = null;\n _rawCsr: CSRInput | null = null;\n _uniqueIndex: Int32Array | null = null;\n _uniqueInverse: Int32Array | null = null;\n _a = 0;\n _b = 0;\n _nNeighborsUsed = 15;\n _smallData = false;\n _disconnection = Infinity;\n _supervised = false;\n _inputHash: string | null = null;\n _radOrig: Float32Array | null = null;\n _radEmb: Float32Array | null = null;\n protected _backendInfo: ResolvedBackendInfo = { knn: 'none', layout: 'none' };\n protected _timings: Record<string, number> = {};\n protected _parallel: ParallelContext | null = null;\n // biome-ignore lint/suspicious/noExplicitAny: lazy webgpu module (browser-only)\n protected _gpu: any = null;\n // biome-ignore lint/suspicious/noExplicitAny: GpuContext from the lazy module\n protected _gpuCtx: any = null;\n protected _useGpuLayout = false;\n /** name of the in-flight operation; guards against concurrent use */\n private _busy: string | null = null;\n\n constructor(options: UmapOptions = {}) {\n this.options = { ...options };\n this.logger =\n typeof options.verbose === 'object'\n ? options.verbose\n : options.verbose\n ? consoleLogger\n : silentLogger;\n this.validateOptions();\n }\n\n private validateOptions(): void {\n const o = this.options;\n const positive = (name: string, v: number | undefined) => {\n if (v !== undefined && !(v > 0)) {\n throw new UmapValidationError(`${name} must be > 0, got ${v}`);\n }\n };\n const positiveInt = (name: string, v: number | undefined) => {\n if (v !== undefined && (!Number.isInteger(v) || v <= 0)) {\n throw new UmapValidationError(`${name} must be a positive integer, got ${v}`);\n }\n };\n const inUnit = (name: string, v: number | undefined) => {\n if (v !== undefined && !(v >= 0 && v <= 1)) {\n throw new UmapValidationError(`${name} must be in [0, 1], got ${v}`);\n }\n };\n positiveInt('nNeighbors', o.nNeighbors);\n if (o.nNeighbors !== undefined && o.nNeighbors < 2) {\n throw new UmapValidationError('nNeighbors must be >= 2 (matching umap-learn)');\n }\n positiveInt('nComponents', o.nComponents);\n positiveInt('negativeSampleRate', o.negativeSampleRate);\n if (o.targetNNeighbors !== undefined && o.targetNNeighbors !== -1) {\n positiveInt('targetNNeighbors', o.targetNNeighbors);\n }\n positive('learningRate', o.learningRate);\n positive('spread', o.spread);\n positive('localConnectivity', o.localConnectivity);\n if (o.repulsionStrength !== undefined && !(o.repulsionStrength >= 0)) {\n throw new UmapValidationError(`repulsionStrength must be >= 0, got ${o.repulsionStrength}`);\n }\n if (o.minDist !== undefined && o.minDist < 0) {\n throw new UmapValidationError(`minDist must be >= 0, got ${o.minDist}`);\n }\n if (o.minDist !== undefined && o.spread !== undefined && o.minDist > o.spread) {\n throw new UmapValidationError('minDist must be <= spread');\n }\n inUnit('setOpMixRatio', o.setOpMixRatio);\n inUnit('targetWeight', o.targetWeight);\n inUnit('densFrac', o.densFrac);\n inUnit('densVarShift', o.densVarShift);\n if (o.nEpochs !== undefined && (o.nEpochs < 0 || !Number.isInteger(o.nEpochs))) {\n throw new UmapValidationError('nEpochs must be a nonnegative integer');\n }\n if ((o.a === undefined) !== (o.b === undefined)) {\n throw new UmapValidationError('a and b must be provided together (or both derived)');\n }\n if (o.concurrency !== undefined && o.concurrency !== 'auto') {\n positiveInt('concurrency', o.concurrency);\n }\n if (\n o.backend !== undefined &&\n o.backend !== 'auto' &&\n o.backend !== 'cpu' &&\n o.backend !== 'webgpu'\n ) {\n throw new UmapValidationError(\n `backend must be 'auto' | 'cpu' | 'webgpu' (custom Backend instances are not supported yet), got ${JSON.stringify(o.backend)}`,\n );\n }\n if (typeof o.metric === 'string' && o.metric !== 'precomputed' && !isNamedMetric(o.metric)) {\n throw new UmapValidationError(`unknown metric '${o.metric}'`);\n }\n if (\n o.targetMetric !== undefined &&\n o.targetMetric !== 'categorical' &&\n !isNamedMetric(o.targetMetric)\n ) {\n throw new UmapValidationError(`unknown targetMetric '${o.targetMetric}'`);\n }\n if (o.outputMetric === 'precomputed') {\n throw new UmapValidationError('outputMetric cannot be precomputed');\n }\n if (o.outputMetric !== undefined && !isEuclideanOutput(o.outputMetric)) {\n resolveOutputMetricGrad(o.outputMetric); // throws (typed) for unknown names\n }\n if (o.outputMetricOptions && Object.keys(o.outputMetricOptions).length > 0) {\n throw new UmapValidationError(\n 'outputMetricOptions is not consumed by any named output metric in this port; ' +\n 'remove it rather than have it silently ignored',\n );\n }\n if (o.densMap && o.outputMetric && !isEuclideanOutput(o.outputMetric)) {\n throw new UmapValidationError('densMap requires euclidean output metric');\n }\n if (o.unique && o.metric === 'precomputed') {\n throw new UmapValidationError('unique is poorly defined on a precomputed metric');\n }\n if (o.unique && o.precomputedKnn) {\n throw new UmapValidationError('unique cannot be used with precomputedKnn');\n }\n }\n\n get embedding(): Embedding {\n if (!this._embedding) throw new UmapError('model is not fitted');\n return this._embedding;\n }\n\n /** CSR fuzzy graph over the training data (unique rows when unique=true). */\n get graph(): Csr {\n if (!this._graph) throw new UmapError('model is not fitted');\n return this._graph;\n }\n\n get densities(): { original: Float32Array; embedded: Float32Array } {\n if (!this._radOrig || !this._radEmb) {\n throw new UmapError('densities require fitting with outputDens: true');\n }\n return { original: this._radOrig, embedded: this._radEmb };\n }\n\n /** Which backend actually executed each stage (§5.2). */\n get backendInfo(): ResolvedBackendInfo {\n return { ...this._backendInfo };\n }\n\n get phaseTimings(): Record<string, number> {\n return { ...this._timings };\n }\n\n protected resolveMetricName(): string {\n const m = this.options.metric ?? 'euclidean';\n return typeof m === 'function' ? '<custom>' : m;\n }\n\n /** Serialize operations on one instance: concurrent calls are a caller bug. */\n private async withBusy<T>(name: string, fn: () => Promise<T>): Promise<T> {\n if (this._busy) {\n throw new UmapError(\n `cannot ${name}: ${this._busy}() is already in progress on this estimator`,\n );\n }\n this._busy = name;\n try {\n return await fn();\n } finally {\n this._busy = null;\n }\n }\n\n private snapshotFittedState(): Record<string, unknown> {\n return {\n _embedding: this._embedding,\n _embeddingUnique: this._embeddingUnique,\n _graph: this._graph,\n _sigmas: this._sigmas,\n _rhos: this._rhos,\n _knn: this._knn,\n _searchIndex: this._searchIndex,\n _rawData: this._rawData,\n _rawCsr: this._rawCsr,\n _uniqueIndex: this._uniqueIndex,\n _uniqueInverse: this._uniqueInverse,\n _radOrig: this._radOrig,\n _radEmb: this._radEmb,\n _inputHash: this._inputHash,\n _a: this._a,\n _b: this._b,\n _nNeighborsUsed: this._nNeighborsUsed,\n _smallData: this._smallData,\n _disconnection: this._disconnection,\n _supervised: this._supervised,\n _useGpuLayout: this._useGpuLayout,\n _backendInfo: { ...this._backendInfo },\n _timings: { ...this._timings },\n };\n }\n\n private restoreFittedState(snapshot: Record<string, unknown>): void {\n Object.assign(this, snapshot);\n }\n\n /** Discard fitted state so a running fit never exposes a mixed old/new model. */\n private resetFittedState(): void {\n this._embedding = null;\n this._embeddingUnique = null;\n this._graph = null;\n this._sigmas = null;\n this._rhos = null;\n this._knn = null;\n this._searchIndex = null;\n this._rawData = null;\n this._rawCsr = null;\n this._uniqueIndex = null;\n this._uniqueInverse = null;\n this._radOrig = null;\n this._radEmb = null;\n this._inputHash = null;\n this._supervised = false;\n this._useGpuLayout = false;\n this._backendInfo = { knn: 'none', layout: 'none' };\n this._timings = {};\n }\n\n /** Stop using the GPU for the rest of this fit (typed failure → CPU, D-017). */\n private dropGpu(): void {\n if (this._gpuCtx && !this._gpuCtx.injected) {\n try {\n this._gpuCtx.device.destroy();\n } catch {\n // a lost device may reject destroy(); dropping the reference suffices\n }\n }\n this._gpuCtx = null;\n this._gpu = null;\n this._useGpuLayout = false;\n }\n\n /** Always runs after fit (success, error, or abort): no leaked workers/devices. */\n private async releaseBackends(): Promise<void> {\n if (this._parallel) {\n const pool = this._parallel.pool;\n this._parallel = null;\n await pool.terminate();\n }\n if (this._gpuCtx && !this._gpuCtx.injected) {\n this._gpuCtx.device.destroy();\n this._gpuCtx = null;\n this._gpu = null;\n this._useGpuLayout = false;\n }\n }\n\n async fit(\n X: DenseInput | CSRInput,\n y?: Labels | Target | null,\n { signal }: FitCallOptions = {},\n ): Promise<this> {\n return this.withBusy('fit', async () => {\n throwIfAborted(signal);\n const snapshot = this.snapshotFittedState();\n this.resetFittedState();\n try {\n return await this.fitInner(X, y, signal);\n } catch (e) {\n // failed refit keeps the previously fitted model usable\n this.restoreFittedState(snapshot);\n throw e;\n } finally {\n await this.releaseBackends();\n }\n });\n }\n\n private async fitInner(\n X: DenseInput | CSRInput,\n y: Labels | Target | null | undefined,\n signal: AbortSignal | undefined,\n ): Promise<this> {\n const o = this.options;\n const nComponents = o.nComponents ?? 2;\n const metric = o.metric ?? 'euclidean';\n const minDist = o.minDist ?? 0.1;\n const spread = o.spread ?? 1.0;\n const densMap = o.densMap ?? false;\n const outputDens = o.outputDens ?? false;\n const outputMetric = o.outputMetric ?? 'euclidean';\n const seed = o.seed ?? entropySeed();\n const rng = Pcg32.fromSeed(seed);\n\n // --- input validation / canonical form\n let denseFull: Matrix | null = null;\n let sparse: CSRInput | null = null;\n if (isCsrInput(X)) {\n sparse = validateCsr(X);\n this._rawCsr = sparse;\n } else {\n denseFull = toMatrix(X);\n this._rawData = denseFull;\n }\n const nFull = denseFull ? denseFull.rows : sparse!.rows;\n if (nFull <= 1) throw new UmapValidationError('need at least 2 samples');\n if (typeof metric === 'string' && o.metricOptions) {\n // V/w/VInv sizes can only be checked once the feature count is known\n validateMetricOptionSizes(metric, o.metricOptions, denseFull ? denseFull.cols : sparse!.cols);\n }\n\n this._inputHash = denseFull\n ? contentHash(\n new Uint8Array(\n denseFull.data.buffer,\n denseFull.data.byteOffset,\n denseFull.data.byteLength,\n ),\n )\n : contentHash(\n new Uint8Array(sparse!.data.buffer, sparse!.data.byteOffset, sparse!.data.byteLength),\n );\n\n // --- unique dedupe (dense only in this port; Python supports CSR via csr_unique)\n let dense = denseFull;\n if (o.unique) {\n if (!denseFull) throw new UmapValidationError('unique=true requires dense input');\n const { index, inverse } = uniqueRows(denseFull);\n this._uniqueIndex = index;\n this._uniqueInverse = inverse;\n if (index.length < nFull) {\n this.logger.info(`unique: ${nFull} rows → ${index.length} unique`);\n }\n const d = denseFull.cols;\n const data = new Float32Array(index.length * d);\n for (let i = 0; i < index.length; i++) {\n data.set(denseFull.data.subarray(index[i]! * d, (index[i]! + 1) * d), i * d);\n }\n dense = { data, rows: index.length, cols: d };\n }\n const n = dense ? dense.rows : sparse!.rows;\n\n let nNeighbors = o.nNeighbors ?? 15;\n if (n - 1 < nNeighbors) {\n this.logger.warn(\n `nNeighbors ${nNeighbors} is larger than dataset size ${n}; reduced to ${n - 1}`,\n );\n nNeighbors = n - 1;\n }\n this._nNeighborsUsed = nNeighbors;\n\n // --- a/b\n if (o.a !== undefined && o.b !== undefined) {\n this._a = o.a;\n this._b = o.b;\n } else {\n const ab = findABParams(spread, minDist);\n this._a = ab.a;\n this._b = ab.b;\n }\n\n const metricName = this.resolveMetricName();\n this._disconnection =\n o.disconnectionDistance ?? DISCONNECTION_DISTANCES[metricName] ?? Infinity;\n this._smallData = n < SMALL_DATA_CUTOFF && !(o.forceApproximation ?? false);\n\n // --- WebGPU backend (explicit 'webgpu', or 'auto' with an adapter + supported config)\n const backendOpt = o.backend ?? 'auto';\n let useGpuKnn = false;\n let useGpuLayout = false;\n if (backendOpt === 'webgpu' && dense === null) {\n this.logger.warn('backend \"webgpu\" requires dense input; this fit runs on the CPU');\n }\n if (backendOpt === 'webgpu' && (o.deterministic ?? false)) {\n this.logger.warn(\n 'deterministic: true forces the reproducible CPU path; backend \"webgpu\" is ignored (§5.5)',\n );\n }\n if (\n (backendOpt === 'webgpu' || backendOpt === 'auto') &&\n !(o.deterministic ?? false) &&\n dense !== null\n ) {\n const hasGpuApi =\n !!(globalThis.navigator as Navigator & { gpu?: unknown })?.gpu || o.device !== undefined;\n if (backendOpt === 'webgpu' && !hasGpuApi) {\n throw new UmapBackendError('backend \"webgpu\" requested but WebGPU is unavailable');\n }\n if (hasGpuApi) {\n const mod = await import('../backends/webgpu/index.js');\n const support = mod.gpuSupportsConfig({\n ...(typeof metric === 'string' ? { metric } : { metric: metric as never }),\n outputMetric,\n densMap,\n nNeighbors,\n nComponents,\n });\n if (backendOpt === 'webgpu' || support.knn || support.layout) {\n // a stalled GPU service (headless/driver issues) must not hang fit()\n const acquire = mod.acquireGpu(o.device as never);\n acquire.catch(() => {}); // surfaced via the race below; never an unhandled rejection\n try {\n this._gpuCtx = await raceTimeout(\n acquire,\n GPU_ACQUIRE_TIMEOUT_MS,\n 'WebGPU device acquisition',\n );\n this._gpu = mod;\n useGpuKnn = support.knn;\n useGpuLayout = support.layout;\n this._useGpuLayout = support.layout;\n if (support.reason) this.logger.warn(support.reason);\n this.logger.info(\n `WebGPU: ${this._gpuCtx.adapterInfo.vendor}/${this._gpuCtx.adapterInfo.architecture}`,\n );\n } catch (e) {\n // if the stalled acquisition eventually resolves, release the orphan device\n void acquire\n // biome-ignore lint/suspicious/noExplicitAny: GpuContext from the lazy module\n .then((ctx: any) => {\n if (ctx && !ctx.injected) ctx.device.destroy();\n })\n .catch(() => {});\n if (backendOpt === 'webgpu') throw e;\n this.logger.warn(`WebGPU unavailable (${(e as Error).message}); using CPU`);\n }\n }\n }\n }\n\n // --- worker pool (backend 'cpu'/'auto', concurrency != 1, not deterministic).\n // Seeded runs stay single-threaded and reproducible, mirroring Python (§5.5),\n // unless the caller explicitly requests a worker count.\n const wantWorkers =\n !(useGpuKnn && useGpuLayout) &&\n (o.backend === undefined || o.backend === 'auto' || o.backend === 'cpu') &&\n (o.concurrency ?? 1) !== 1 &&\n !(o.deterministic ?? false) &&\n dense !== null &&\n typeof metric === 'string' &&\n isNamedMetric(metric) &&\n !o.precomputedKnn;\n if (wantWorkers) {\n this._parallel = await createParallelContext(\n dense!,\n metric as string,\n o.metricOptions ?? {},\n o.concurrency ?? 'auto',\n o.workerUrl,\n this.logger,\n );\n if (this._parallel) {\n this.logger.info(\n `worker pool: ${this._parallel.pool.size} workers (${this._parallel.sab ? 'SharedArrayBuffer' : 'transfer fallback'})`,\n );\n }\n }\n\n // --- kNN stage\n const t0 = performance.now();\n let knn: KnnGraph;\n if (o.precomputedKnn) {\n const pk = o.precomputedKnn;\n if (pk.k < nNeighbors) {\n throw new UmapValidationError(\n `precomputedKnn.k=${pk.k} is smaller than nNeighbors=${nNeighbors}`,\n );\n }\n knn = sliceKnn(pk, n, nNeighbors);\n if (this._disconnection !== Infinity && knn.indices === pk.indices) {\n // masking must not mutate the caller's arrays\n knn = { indices: knn.indices.slice(), distances: knn.distances.slice(), k: knn.k };\n }\n applyDisconnectionToKnn(knn, this._disconnection);\n this._backendInfo.knn = 'precomputed';\n this._smallData = false;\n } else if (metric === 'precomputed') {\n if (!dense) throw new UmapValidationError(\"metric 'precomputed' requires a dense matrix\");\n knn = knnFromPrecomputed(applyDisconnectionToMatrix(dense, this._disconnection), nNeighbors);\n this._backendInfo.knn = 'precomputed-matrix';\n this._smallData = true;\n } else if (sparse) {\n const res = nearestNeighborsSparse(sparse, nNeighbors, metric as string, rng, {\n forceApproximation: o.forceApproximation ?? false,\n angularRpForest: o.angularRpForest ?? false,\n disconnectionDistance: this._disconnection,\n });\n knn = res.knn;\n this._backendInfo.knn = `cpu-${res.method}`;\n } else {\n // shared CPU path: the final fallback AND where a failed GPU kNN lands\n // (gpuKnn consumes no rng draws, so falling back here is rng-neutral)\n const runCpuKnn = (): KnnGraph => {\n const res = nearestNeighborsDense(dense!, nNeighbors, metric as string, rng, {\n metricOptions: o.metricOptions ?? {},\n forceApproximation: o.forceApproximation ?? false,\n angularRpForest: o.angularRpForest ?? false,\n disconnectionDistance: this._disconnection,\n });\n this._searchIndex = res.searchIndex;\n this._backendInfo.knn = `cpu-${res.method}`;\n return res.knn;\n };\n if (typeof metric === 'function') {\n knn = exactKnnDense(dense!, nNeighbors, metric, {\n disconnectionDistance: this._disconnection,\n });\n this._backendInfo.knn = 'cpu-exact-custom';\n this._smallData = true;\n } else if (useGpuKnn && this._gpuCtx && (!this._smallData || backendOpt === 'webgpu')) {\n let gpuKnnResult: KnnGraph | null = null;\n try {\n const plan = this._gpu.gpuMetricPlan(metric as string);\n gpuKnnResult = await this._gpu.gpuKnn(this._gpuCtx, dense!, null, nNeighbors, plan, {\n ...(signal ? { signal } : {}),\n });\n } catch (e) {\n // typed GPU failures (limits, device lost, validation) fall back to\n // CPU under 'auto' (D-017); explicit 'webgpu' and aborts propagate\n if (backendOpt === 'webgpu' || !(e instanceof UmapBackendError)) throw e;\n this.logger.warn(`WebGPU kNN failed (${e.message}); falling back to CPU`);\n this.dropGpu();\n }\n if (gpuKnnResult) {\n knn = gpuKnnResult;\n applyDisconnectionToKnn(knn, this._disconnection);\n // transform() builds its CPU search structure lazily on first use\n // (buildSearchIndexFromKnn) — no rng draws are consumed here\n this._backendInfo.knn = 'webgpu';\n } else {\n knn = runCpuKnn();\n }\n } else if (this._parallel && !this._smallData) {\n const internal = resolveInternalMetric(metric as string, o.metricOptions ?? {});\n const angular = internal.angularTrees || (o.angularRpForest ?? false);\n const par = await parallelNnDescent(this._parallel, nNeighbors, rng, angular);\n const prepared = prepareIndexFromParallel(\n dense!,\n par.knnInternal,\n metric as string,\n o.metricOptions ?? {},\n nNeighbors,\n par.searchRngState,\n angular,\n );\n knn = prepared.knn;\n applyDisconnectionToKnn(knn, this._disconnection);\n this._searchIndex = prepared.searchIndex;\n this._backendInfo.knn = `cpu-workers(${this._parallel.pool.size})`;\n } else {\n knn = runCpuKnn();\n }\n }\n this._knn = knn;\n this._timings.knn = performance.now() - t0;\n this.logger.info(`kNN done in ${this._timings.knn.toFixed(0)}ms (${this._backendInfo.knn})`);\n throwIfAborted(signal);\n o.onEpoch?.({ epoch: 0, nEpochs: 0, phase: 'knn' });\n\n // --- fuzzy simplicial set\n const t1 = performance.now();\n const fss = fuzzySimplicialSet(n, nNeighbors, knn.indices, knn.distances, {\n setOpMixRatio: o.setOpMixRatio ?? 1.0,\n localConnectivity: o.localConnectivity ?? 1.0,\n returnDists: densMap || outputDens,\n });\n let graph = fss.graph;\n this._sigmas = fss.sigmas;\n this._rhos = fss.rhos;\n\n // --- supervision (umap_.py:2692-2805; notes §5)\n this._supervised = y != null;\n if (y != null) {\n const yArr = normalizeY(y, nFull);\n const yUnique = this._uniqueIndex\n ? Float64Array.from(this._uniqueIndex, (i) => yArr[i]!)\n : yArr;\n if (yUnique.length !== n) {\n throw new UmapValidationError(`y length ${yArr.length} != number of samples ${nFull}`);\n }\n const targetMetric = o.targetMetric ?? 'categorical';\n if (targetMetric === 'categorical') {\n const farDist = farDistFromWeight(o.targetWeight ?? 0.5);\n graph = categoricalSimplicialSetIntersection(graph, yUnique, { farDist });\n } else {\n // continuous target: fuzzy set on y (l2/euclidean on 1-D), NOT symmetrized\n const targetK =\n (o.targetNNeighbors ?? -1) === -1 ? nNeighbors : (o.targetNNeighbors as number);\n const yMatrix: Matrix = {\n data: Float32Array.from(yUnique),\n rows: n,\n cols: 1,\n };\n // exact kNN on 1-D target values ≡ Python's precomputed ydmat argsort\n const tKnn = exactKnnDense(yMatrix, Math.min(targetK, n - 1), 'euclidean');\n const tFss = fuzzySimplicialSet(n, Math.min(targetK, n - 1), tKnn.indices, tKnn.distances, {\n setOpMixRatio: 1.0,\n localConnectivity: 1.0,\n applySetOperations: false,\n });\n graph = generalSimplicialSetIntersection(graph, tFss.graph, o.targetWeight ?? 0.5);\n graph = resetLocalConnectivity(graph);\n }\n }\n this._graph = graph;\n this._timings.graph = performance.now() - t1;\n throwIfAborted(signal);\n\n // --- embed\n await this.embedGraph(graph, fss.dists, dense, nComponents, outputMetric, rng, {\n densMap,\n outputDens,\n ...(signal ? { signal } : {}),\n });\n\n // --- unique expansion back to full length\n if (this._uniqueInverse && this._embedding) {\n const inv = this._uniqueInverse;\n const emb = this._embedding.data;\n this._embeddingUnique = emb;\n const full = new Float32Array(nFull * nComponents);\n for (let i = 0; i < nFull; i++) {\n full.set(emb.subarray(inv[i]! * nComponents, (inv[i]! + 1) * nComponents), i * nComponents);\n }\n this._embedding = { data: full, rows: nFull, cols: nComponents };\n const expand = (arr: Float32Array | null): Float32Array | null => {\n if (!arr) return null;\n const out = new Float32Array(nFull);\n for (let i = 0; i < nFull; i++) out[i] = arr[inv[i]!]!;\n return out;\n };\n this._radOrig = expand(this._radOrig);\n this._radEmb = expand(this._radEmb);\n } else {\n this._embeddingUnique = this._embedding?.data ?? null;\n }\n return this;\n }\n\n protected async embedGraph(\n graph: Csr,\n graphDists: Csr | null,\n dense: Matrix | null,\n nComponents: number,\n outputMetric: string,\n rng: Pcg32,\n {\n densMap,\n outputDens,\n signal,\n initOverride,\n nEpochsOverride,\n }: {\n densMap: boolean;\n outputDens: boolean;\n signal?: AbortSignal;\n initOverride?: Float32Array;\n nEpochsOverride?: number;\n },\n ): Promise<void> {\n const o = this.options;\n const n = graph.rows;\n const defEpochs = defaultNEpochs(n, densMap);\n const nEpochs = nEpochsOverride ?? o.nEpochs ?? defEpochs;\n\n const pruned = pruneGraphForEpochs(graph, nEpochs, defEpochs);\n\n const nnz = pruned.indptr[n]!;\n const head = new Int32Array(nnz);\n const tail = new Int32Array(nnz);\n const weights = new Float32Array(nnz);\n for (let r = 0; r < n; r++) {\n for (let p = pruned.indptr[r]!; p < pruned.indptr[r + 1]!; p++) {\n head[p] = r;\n tail[p] = pruned.indices[p]!;\n weights[p] = Math.fround(pruned.data[p]!);\n }\n }\n\n // --- init\n const t2 = performance.now();\n let emb: Float32Array;\n if (initOverride) {\n emb = initOverride;\n } else {\n const initMethod = o.init ?? 'spectral';\n let gpuInit: { embedding: Float32Array } | null = null;\n if (initMethod === 'spectral' && this._useGpuLayout && this._gpuCtx) {\n // webgpu backend: GPU-offloaded SpMV LOBPCG (D-014); null → CPU path\n const mod = await import('../backends/webgpu/index.js');\n const rngBackup = rng.clone();\n try {\n gpuInit = await mod.gpuSpectralInit(\n this._gpuCtx,\n pruned,\n nComponents,\n rng,\n this.logger,\n signal,\n );\n } catch (e) {\n // typed GPU failures fall back to the CPU init with the rng restored,\n // so the CPU path consumes exactly the draws it would have (D-017);\n // explicit 'webgpu' and aborts propagate\n if (!(e instanceof UmapBackendError) || (o.backend ?? 'auto') === 'webgpu') throw e;\n this.logger.warn(`WebGPU spectral init failed (${e.message}); using the CPU init`);\n rng.restoreFrom(rngBackup);\n this.dropGpu();\n }\n }\n emb =\n gpuInit?.embedding ??\n initializeEmbedding(initMethod, dense, pruned, nComponents, rng, {\n logger: this.logger,\n }).embedding;\n }\n this._timings.init = performance.now() - t2;\n throwIfAborted(signal);\n o.onEpoch?.({ epoch: 0, nEpochs, phase: 'init' });\n\n const epochsPerSample = makeEpochsPerSample(weights, nEpochs);\n const rngState = rng.tauState();\n\n // --- densMAP radii\n let densParams = null;\n if ((densMap || outputDens) && graphDists) {\n const radii = computeOrigRadii(head, tail, weights, graphDists, n);\n this._radOrig = radii.ro;\n if (densMap) {\n densParams = {\n lambda: o.densLambda ?? 2.0,\n frac: o.densFrac ?? 0.3,\n varShift: o.densVarShift ?? 0.1,\n mu: weights,\n muSum: radii.muSum,\n R: radii.R,\n };\n }\n }\n\n // --- layout\n const t3 = performance.now();\n const onEpoch = o.onEpoch;\n const layoutOpts = {\n gamma: o.repulsionStrength ?? 1.0,\n initialAlpha: o.learningRate ?? 1.0,\n negativeSampleRate: o.negativeSampleRate ?? 5,\n moveOther: true,\n densmap: densParams,\n snapshotEvery: onEpoch ? 10 : 0,\n ...(onEpoch\n ? {\n onEpoch: (info: {\n epoch: number;\n nEpochs: number;\n phase: string;\n embedding?: Float32Array;\n }) => onEpoch(info),\n }\n : {}),\n ...(signal ? { signal } : {}),\n };\n let gpuLayoutDone = false;\n if (this._useGpuLayout && this._gpuCtx && isEuclideanOutput(outputMetric) && !densParams) {\n const gpuRng = rng; // continue the same stream\n const rngBackup = rng.clone();\n try {\n await this._gpu.gpuOptimizeLayout(\n this._gpuCtx,\n emb,\n nComponents,\n head,\n tail,\n nEpochs,\n n,\n epochsPerSample,\n this._a,\n this._b,\n gpuRng,\n {\n gamma: o.repulsionStrength ?? 1.0,\n initialAlpha: o.learningRate ?? 1.0,\n negativeSampleRate: o.negativeSampleRate ?? 5,\n moveOther: true,\n ...(o.gpuLayoutStrategy ? { strategy: o.gpuLayoutStrategy } : {}),\n ...(onEpoch ? { onEpoch, snapshotEvery: 10 } : {}),\n ...(signal ? { signal } : {}),\n },\n );\n this._backendInfo.layout = 'webgpu';\n gpuLayoutDone = true;\n } catch (e) {\n // typed GPU failures fall back to the CPU layout with the rng restored\n // (the CPU kernels consume rngState, drawn before this attempt — the\n // run then matches a pure-CPU run of the same seed, D-017); explicit\n // 'webgpu' and aborts propagate\n if (!(e instanceof UmapBackendError) || (o.backend ?? 'auto') === 'webgpu') throw e;\n this.logger.warn(`WebGPU layout failed (${e.message}); falling back to CPU layout`);\n rng.restoreFrom(rngBackup);\n this.dropGpu();\n }\n }\n if (gpuLayoutDone) {\n // layout complete on the GPU\n } else if (\n this._parallel &&\n isEuclideanOutput(outputMetric) &&\n !densParams // densMAP runs single-thread (per-epoch density stats)\n ) {\n await parallelOptimizeLayout(\n this._parallel,\n emb,\n nComponents,\n head,\n tail,\n nEpochs,\n n,\n epochsPerSample,\n this._a,\n this._b,\n rngState,\n {\n gamma: layoutOpts.gamma,\n initialAlpha: layoutOpts.initialAlpha,\n negativeSampleRate: layoutOpts.negativeSampleRate,\n moveOther: true,\n ...(onEpoch\n ? { onEpoch: layoutOpts.onEpoch as NonNullable<typeof layoutOpts.onEpoch> }\n : {}),\n ...(signal ? { signal } : {}),\n snapshotEvery: layoutOpts.snapshotEvery,\n },\n );\n this._backendInfo.layout = `cpu-workers(${this._parallel.pool.size})`;\n } else if (isEuclideanOutput(outputMetric)) {\n await yieldToLoop();\n optimizeLayoutEuclidean(\n emb,\n emb,\n nComponents,\n head,\n tail,\n nEpochs,\n n,\n epochsPerSample,\n this._a,\n this._b,\n rngState,\n layoutOpts,\n );\n } else {\n const grad = resolveOutputMetricGrad(outputMetric);\n await yieldToLoop();\n optimizeLayoutGeneric(\n emb,\n emb,\n nComponents,\n head,\n tail,\n nEpochs,\n n,\n epochsPerSample,\n this._a,\n this._b,\n rngState,\n grad,\n layoutOpts,\n );\n }\n this._timings.layout = performance.now() - t3;\n if (\n !this._backendInfo.layout.startsWith('cpu-workers') &&\n this._backendInfo.layout !== 'webgpu'\n ) {\n this._backendInfo.layout = 'cpu-single';\n }\n this._embedding = { data: emb, rows: n, cols: nComponents };\n\n // --- outputDens embedding radii\n if (outputDens) {\n const embMatrix: Matrix = { data: emb, rows: n, cols: nComponents };\n const kDens = Math.min(o.nNeighbors ?? 15, n - 1);\n const embRng = Pcg32.fromSeed((o.seed ?? 0) + 0x9e3779b9);\n const res = nearestNeighborsDense(embMatrix, kDens, 'euclidean', embRng, {});\n const fss2 = fuzzySimplicialSet(n, kDens, res.knn.indices, res.knn.distances, {\n returnDists: true,\n });\n this._radEmb = computeEmbRadii(fss2.graph, fss2.dists!, n);\n }\n }\n\n async fitTransform(\n X: DenseInput | CSRInput,\n y?: Labels | Target | null,\n opts: FitCallOptions = {},\n ): Promise<Embedding> {\n await this.fit(X, y, opts);\n return this.embedding;\n }\n\n // -------------------------------------------------------------------------\n // transform (umap_.py:2950-3188; notes §12)\n // -------------------------------------------------------------------------\n\n async transform(Xnew: DenseInput, { signal }: FitCallOptions = {}): Promise<Embedding> {\n return this.withBusy('transform', async () => {\n const graphOrEmb = await this.transformInner(Xnew, signal);\n if (graphOrEmb.kind === 'embedding') return graphOrEmb.embedding;\n throw new UmapError('transformMode is \"graph\"; use transformGraph() for the CSR result');\n });\n }\n\n /** transformMode 'graph': the bipartite membership CSR (nNew × nTrain). */\n async transformGraph(Xnew: DenseInput, { signal }: FitCallOptions = {}): Promise<Csr> {\n return this.withBusy('transformGraph', async () => {\n const res = await this.transformInner(Xnew, signal, true);\n if (res.kind === 'graph') return res.graph;\n throw new UmapError('internal: expected graph result');\n });\n }\n\n private async transformInner(\n Xnew: DenseInput,\n signal?: AbortSignal,\n forceGraph = false,\n ): Promise<{ kind: 'embedding'; embedding: Embedding } | { kind: 'graph'; graph: Csr }> {\n if (!this._embedding) throw new UmapError('model is not fitted');\n if (this.options.densMap) throw new UmapError('transform is unsupported with densMap');\n if (this._rawCsr) throw new UmapError('transform on sparse-fitted models is not supported');\n if (!this._rawData) throw new UmapError('transform requires the training data');\n const o = this.options;\n const metric = o.metric ?? 'euclidean';\n const Q = toMatrix(Xnew, 'Xnew');\n if (metric !== 'precomputed' && Q.cols !== this._rawData.cols) {\n throw new UmapValidationError(\n `Xnew has ${Q.cols} features but the model was fitted with ${this._rawData.cols}`,\n );\n }\n throwIfAborted(signal);\n\n const graphMode = forceGraph || o.transformMode === 'graph';\n const qHash = contentHash(new Uint8Array(Q.data.buffer, Q.data.byteOffset, Q.data.byteLength));\n if (\n !graphMode &&\n qHash === this._inputHash &&\n sameFloat32Bits(Q.data, this._rawData.data) // hash collisions must not echo the fit\n ) {\n return { kind: 'embedding', embedding: this.embedding };\n }\n\n const k = this._nNeighborsUsed;\n const nTrainUnique = this._graph!.rows;\n const trainEmb = this._embeddingUnique!;\n const nComponents = this._embedding.cols;\n const transformSeed = o.transformSeed ?? 42;\n const rng = Pcg32.fromSeed(transformSeed);\n\n // GPU-fitted large models have no fit-time search structure: build it once,\n // lazily, from the stored kNN graph (fit-time rng untouched — GPU fits stay\n // byte-deterministic per D-013; see D-018)\n if (!this._searchIndex && !this._smallData && this._knn && typeof metric === 'string') {\n this._searchIndex = this.buildSearchIndexFromKnn(metric);\n }\n\n // --- query kNN\n let qKnn: KnnGraph;\n if (metric === 'precomputed') {\n // Xnew is (nNew × nTrain) distances\n if (Q.cols !== nTrainUnique) {\n throw new UmapValidationError(\n `precomputed transform input must be (nNew × ${nTrainUnique})`,\n );\n }\n qKnn = precomputedQueryKnn(Q, k);\n } else if (this._smallData || !this._searchIndex) {\n qKnn = smallDataQueryKnn(\n Q,\n this.uniqueTrainMatrix(),\n k,\n typeof metric === 'function' ? metric : resolveMetric(metric, o.metricOptions ?? {}),\n );\n } else {\n const epsilon = this._searchIndex.angular ? 0.24 : 0.12;\n qKnn = searchKnn(this._searchIndex, Q, k, epsilon);\n }\n throwIfAborted(signal);\n\n // disconnection masking\n for (let t = 0; t < qKnn.distances.length; t++) {\n if (qKnn.distances[t]! >= this._disconnection) {\n qKnn.indices[t] = -1;\n qKnn.distances[t] = Infinity;\n }\n }\n\n // --- adjusted smoothing + bipartite memberships\n const adjustedLc = Math.max(0.0, (o.localConnectivity ?? 1.0) - 1.0);\n const { sigmas, rhos } = smoothKnnDist(qKnn.distances, k, k, {\n localConnectivity: adjustedLc,\n });\n const { rows, cols, vals } = computeMembershipStrengths(\n qKnn.indices,\n qKnn.distances,\n sigmas,\n rhos,\n k,\n false,\n true, // bipartite\n );\n let graph = csrFromCoo(Q.rows, nTrainUnique, rows, cols, vals);\n graph = csrEliminateZeros(graph);\n if (graphMode) return { kind: 'graph', graph };\n\n // --- init from weighted means of train embedding\n const emb = initGraphTransform(graph, trainEmb, nComponents);\n\n // --- epochs rule + prune (no >10 guard; umap_.py:3125-3135)\n let nEpochs: number;\n if (o.nEpochs === undefined) {\n nEpochs = Q.rows <= 10000 ? 100 : 30;\n } else {\n nEpochs = Math.floor(o.nEpochs / 3.0);\n }\n let wMax = -Infinity;\n for (let t = 0; t < graph.data.length; t++) if (graph.data[t]! > wMax) wMax = graph.data[t]!;\n const thresh = wMax / nEpochs;\n const gData = graph.data.slice();\n for (let t = 0; t < gData.length; t++) if (gData[t]! < thresh) gData[t] = 0;\n graph = csrEliminateZeros({ ...graph, data: gData });\n\n const nnz = graph.indptr[Q.rows]!;\n const head = new Int32Array(nnz);\n const tail = new Int32Array(nnz);\n const weights = new Float32Array(nnz);\n for (let r = 0; r < Q.rows; r++) {\n for (let p = graph.indptr[r]!; p < graph.indptr[r + 1]!; p++) {\n head[p] = r;\n tail[p] = graph.indices[p]!;\n weights[p] = Math.fround(graph.data[p]!);\n }\n }\n const epochsPerSample = makeEpochsPerSample(weights, nEpochs);\n const rngState = rng.tauState();\n const tailEmbedding = trainEmb.slice(); // train points stay fixed (move_other=false)\n\n const outputMetric = o.outputMetric ?? 'euclidean';\n const layoutOpts = {\n gamma: o.repulsionStrength ?? 1.0,\n initialAlpha: (o.learningRate ?? 1.0) / 4.0,\n negativeSampleRate: o.negativeSampleRate ?? 5,\n moveOther: false,\n ...(signal ? { signal } : {}),\n };\n await yieldToLoop();\n if (isEuclideanOutput(outputMetric)) {\n optimizeLayoutEuclidean(\n emb,\n tailEmbedding,\n nComponents,\n head,\n tail,\n nEpochs,\n nTrainUnique,\n epochsPerSample,\n this._a,\n this._b,\n rngState,\n layoutOpts,\n );\n } else {\n optimizeLayoutGeneric(\n emb,\n tailEmbedding,\n nComponents,\n head,\n tail,\n nEpochs,\n nTrainUnique,\n epochsPerSample,\n this._a,\n this._b,\n rngState,\n resolveOutputMetricGrad(outputMetric),\n layoutOpts,\n );\n }\n return { kind: 'embedding', embedding: { data: emb, rows: Q.rows, cols: nComponents } };\n }\n\n /**\n * Build the prepared search structure from the stored kNN graph (D-018):\n * used when the fit produced no index (GPU kNN path, deserialized blobs\n * without one). Internal-space distances are recomputed exactly via the\n * internal metric — n·k evaluations, no correction inversion. The rng for\n * hub-tree tie-breaks/query descent derives from transformSeed on its own\n * PCG stream, so fit-time determinism (D-013) is untouched and transforms\n * stay reproducible for a given transformSeed.\n */\n private buildSearchIndexFromKnn(metricName: string): SearchIndex | null {\n if (!this._knn || !this._rawData || !isNamedMetric(metricName)) return null;\n const t0 = performance.now();\n const X = this.uniqueTrainMatrix();\n const internal = resolveInternalMetric(metricName, this.options.metricOptions ?? {});\n const k = this._knn.k;\n const n = X.rows;\n const d = X.cols;\n const indices = this._knn.indices;\n const distInternal = new Float32Array(n * k);\n for (let i = 0; i < n; i++) {\n const xi = X.data.subarray(i * d, (i + 1) * d);\n for (let j = 0; j < k; j++) {\n const t = i * k + j;\n const nb = indices[t]!;\n distInternal[t] =\n nb < 0 ? Infinity : internal.dist(xi, X.data.subarray(nb * d, (nb + 1) * d));\n }\n }\n const knnInternal: KnnGraph = { indices, distances: distInternal, k };\n // distinct PCG stream so it does not mirror transform's own rng draws\n const searchRngState = Pcg32.fromSeed(this.options.transformSeed ?? 42, 63).tauState();\n const searchIndex = prepareSearchIndex(\n X,\n knnInternal,\n (a, b) => internal.dist(a, b),\n internal.correction,\n internal.angularTrees || (this.options.angularRpForest ?? false),\n this._nNeighborsUsed,\n searchRngState,\n );\n this.logger.info(\n `built the transform search index lazily in ${(performance.now() - t0).toFixed(0)}ms`,\n );\n return searchIndex;\n }\n\n private uniqueTrainMatrix(): Matrix {\n if (!this._uniqueIndex || !this._rawData) return this._rawData!;\n const d = this._rawData.cols;\n const data = new Float32Array(this._uniqueIndex.length * d);\n for (let i = 0; i < this._uniqueIndex.length; i++) {\n data.set(\n this._rawData.data.subarray(this._uniqueIndex[i]! * d, (this._uniqueIndex[i]! + 1) * d),\n i * d,\n );\n }\n return { data, rows: this._uniqueIndex.length, cols: d };\n }\n\n // -------------------------------------------------------------------------\n // inverseTransform (umap_.py:3190-3355; notes §13; D-008)\n // -------------------------------------------------------------------------\n\n async inverseTransform(points: DenseInput, { signal }: FitCallOptions = {}): Promise<Embedding> {\n return this.withBusy('inverseTransform', () => this.inverseTransformInner(points, signal));\n }\n\n private async inverseTransformInner(\n points: DenseInput,\n signal: AbortSignal | undefined,\n ): Promise<Embedding> {\n throwIfAborted(signal);\n if (!this._embedding) throw new UmapError('model is not fitted');\n if (this._rawCsr) {\n throw new UmapValidationError('inverseTransform is unsupported for sparse-fitted models');\n }\n if (this.options.densMap) {\n throw new UmapValidationError('inverseTransform is unsupported with densMap');\n }\n const outputMetric = this.options.outputMetric ?? 'euclidean';\n if (!isEuclideanOutput(outputMetric)) {\n throw new UmapValidationError('inverseTransform requires euclidean output');\n }\n const metric = this.options.metric ?? 'euclidean';\n if (typeof metric !== 'function' && !['euclidean', 'l2'].includes(metric)) {\n // Python requires a metric with a gradient; this port supports euclidean data space\n throw new UmapValidationError(\n `inverseTransform supports euclidean data metric in this port, got '${metric}'`,\n );\n }\n const P = toMatrix(points, 'points');\n const trainEmb = this._embeddingUnique!;\n const raw = this.uniqueTrainMatrix();\n const nTrain = raw.rows;\n const dim = this._embedding.cols;\n const dataDim = raw.cols;\n if (P.cols !== dim) {\n throw new UmapValidationError(`points must be (n × ${dim})`);\n }\n const rng = Pcg32.fromSeed(this.options.transformSeed ?? 42);\n\n // Neighborhoods in EMBEDDING space: min_vertices nearest train points.\n // (Python explores Delaunay-BFS candidates then keeps the nearest\n // min_vertices; we take exact nearest — same selection criterion, D-008.)\n const minVertices = Math.min(dataDim, nTrain);\n const trainEmbMatrix: Matrix = { data: trainEmb, rows: nTrain, cols: dim };\n const nn = smallDataQueryKnn(P, trainEmbMatrix, minVertices, resolveMetric('euclidean'));\n throwIfAborted(signal);\n\n // weights = 1/(1 + a d^{2b}), row-l1-normalized\n const weights = new Float32Array(P.rows * minVertices);\n for (let i = 0; i < P.rows; i++) {\n let rowSum = 0;\n for (let j = 0; j < minVertices; j++) {\n const d = nn.distances[i * minVertices + j]!;\n const w = 1.0 / (1.0 + this._a * d ** (2 * this._b));\n weights[i * minVertices + j] = w;\n rowSum += w;\n }\n for (let j = 0; j < minVertices; j++) {\n weights[i * minVertices + j] = weights[i * minVertices + j]! / rowSum;\n }\n }\n const inv = initTransform(nn.indices, weights, minVertices, raw.data, dataDim);\n\n // epochs rule identical to transform; no pruning here (commented out upstream)\n let nEpochs: number;\n if (this.options.nEpochs === undefined) {\n nEpochs = P.rows <= 10000 ? 100 : 30;\n } else {\n nEpochs = Math.floor(this.options.nEpochs / 3.0);\n }\n // graph.data here are the (un-normalized) kernel weights in COO row-major order\n const kernelW = new Float32Array(P.rows * minVertices);\n for (let i = 0; i < P.rows; i++) {\n for (let j = 0; j < minVertices; j++) {\n const d = nn.distances[i * minVertices + j]!;\n kernelW[i * minVertices + j] = Math.fround(1.0 / (1.0 + this._a * d ** (2 * this._b)));\n }\n }\n const head = new Int32Array(P.rows * minVertices);\n const tail = new Int32Array(P.rows * minVertices);\n for (let i = 0; i < P.rows; i++) {\n for (let j = 0; j < minVertices; j++) {\n head[i * minVertices + j] = i;\n tail[i * minVertices + j] = nn.indices[i * minVertices + j]!;\n }\n }\n const epochsPerSample = makeEpochsPerSample(kernelW, nEpochs);\n const rngState = rng.tauState();\n await yieldToLoop();\n optimizeLayoutInverse(\n inv,\n raw.data,\n dataDim,\n head,\n tail,\n kernelW,\n this._sigmas!,\n this._rhos!,\n nEpochs,\n nTrain,\n epochsPerSample,\n rngState,\n resolveOutputMetricGrad('euclidean'),\n {\n gamma: this.options.repulsionStrength ?? 1.0,\n initialAlpha: (this.options.learningRate ?? 1.0) / 4.0,\n negativeSampleRate: this.options.negativeSampleRate ?? 5,\n ...(signal ? { signal } : {}),\n },\n );\n return { data: inv, rows: P.rows, cols: dataDim };\n }\n\n // -------------------------------------------------------------------------\n // update (umap_.py:3357-3586; notes §14; D-009)\n // -------------------------------------------------------------------------\n\n async update(Xmore: DenseInput, { signal }: FitCallOptions = {}): Promise<this> {\n return this.withBusy('update', async () => {\n const snapshot = this.snapshotFittedState();\n try {\n return await this.updateInner(Xmore, signal);\n } catch (e) {\n // failed update keeps the pre-update model usable\n this.restoreFittedState(snapshot);\n throw e;\n }\n });\n }\n\n private async updateInner(Xmore: DenseInput, signal: AbortSignal | undefined): Promise<this> {\n throwIfAborted(signal);\n if (!this._embedding) throw new UmapError('model is not fitted');\n if (this.options.metric === 'precomputed') {\n throw new UmapValidationError('update is unsupported with a precomputed metric');\n }\n if (this._supervised) {\n throw new UmapValidationError('update is unsupported for supervised models');\n }\n if (this._uniqueIndex) throw new UmapError('update after unique=true is unsupported');\n if (this._rawCsr) throw new UmapError('update on sparse-fitted models is unsupported');\n const o = this.options;\n const Xn = toMatrix(Xmore, 'Xmore');\n if (Xn.cols !== this._rawData!.cols) {\n throw new UmapValidationError('Xmore feature count differs from training data');\n }\n const originalSize = this._rawData!.rows;\n const merged = new Float32Array((originalSize + Xn.rows) * Xn.cols);\n merged.set(this._rawData!.data, 0);\n merged.set(Xn.data, originalSize * Xn.cols);\n const X: Matrix = { data: merged, rows: originalSize + Xn.rows, cols: Xn.cols };\n this._rawData = X;\n const n = X.rows;\n const rng = Pcg32.fromSeed(this.options.transformSeed ?? 42);\n const metric = (o.metric ?? 'euclidean') as string;\n const nNeighbors = this._nNeighborsUsed;\n\n // recompute the full kNN + fuzzy graph over merged data (index rebuilt; D-009)\n const res = nearestNeighborsDense(X, nNeighbors, metric, rng, {\n metricOptions: o.metricOptions ?? {},\n forceApproximation: (o.forceApproximation ?? false) || !this._smallData,\n angularRpForest: o.angularRpForest ?? false,\n disconnectionDistance: this._disconnection,\n });\n this._smallData = res.method === 'exact';\n this._searchIndex = res.searchIndex;\n this._knn = res.knn;\n const fss = fuzzySimplicialSet(n, nNeighbors, res.knn.indices, res.knn.distances, {\n setOpMixRatio: o.setOpMixRatio ?? 1.0,\n localConnectivity: o.localConnectivity ?? 1.0,\n returnDists: (o.densMap ?? false) || (o.outputDens ?? false),\n });\n this._graph = fss.graph;\n this._sigmas = fss.sigmas;\n this._rhos = fss.rhos;\n\n // init: old embedding + init_update for new points\n const nComponents = this._embedding.cols;\n const init = new Float32Array(n * nComponents);\n init.set(this._embedding.data, 0);\n initUpdate(init, nComponents, originalSize, res.knn.indices, nNeighbors);\n\n // pinned quirk: n_epochs None → 0 epochs (no SGD) — notes §14\n const nEpochs = o.nEpochs === undefined ? 0 : o.nEpochs;\n await this.embedGraph(\n fss.graph,\n fss.dists,\n X,\n nComponents,\n o.outputMetric ?? 'euclidean',\n rng,\n {\n densMap: o.densMap ?? false,\n outputDens: o.outputDens ?? false,\n initOverride: init,\n nEpochsOverride: nEpochs,\n ...(signal ? { signal } : {}),\n },\n );\n this._embeddingUnique = this._embedding!.data;\n this._inputHash = contentHash(\n new Uint8Array(X.data.buffer, X.data.byteOffset, X.data.byteLength),\n );\n return this;\n }\n\n // -------------------------------------------------------------------------\n // serialization (§4.7)\n // -------------------------------------------------------------------------\n\n serialize(): Uint8Array {\n return serializeModel(this);\n }\n\n static deserialize(blob: Uint8Array): UMAP {\n return deserializeModel(blob, UMAP);\n }\n}\n\n// ---------------------------------------------------------------------------\n// helpers\n// ---------------------------------------------------------------------------\n\nfunction normalizeY(y: Labels | Target, n: number): Float64Array {\n const arr = new Float64Array(n);\n const src = y as ArrayLike<number>;\n if (src.length !== n) {\n throw new UmapValidationError(`y length ${src.length} != number of samples ${n}`);\n }\n for (let i = 0; i < n; i++) {\n const v = src[i] as number;\n if (!Number.isFinite(v)) throw new UmapValidationError('y contains a non-finite value');\n arr[i] = v;\n }\n return arr;\n}\n\nfunction uniqueRows(X: Matrix): { index: Int32Array; inverse: Int32Array } {\n const seen = new Map<string, number>();\n const index: number[] = [];\n const inverse = new Int32Array(X.rows);\n for (let i = 0; i < X.rows; i++) {\n const key = Array.prototype.join.call(X.data.subarray(i * X.cols, (i + 1) * X.cols), ',');\n let u = seen.get(key);\n if (u === undefined) {\n u = index.length;\n seen.set(key, u);\n index.push(i);\n }\n inverse[i] = u;\n }\n return { index: Int32Array.from(index), inverse };\n}\n\nfunction sliceKnn(\n pk: { indices: Int32Array; distances: Float32Array; k: number },\n n: number,\n k: number,\n): KnnGraph {\n if (pk.indices.length !== n * pk.k || pk.distances.length !== n * pk.k) {\n throw new UmapValidationError(\n `precomputedKnn arrays must have n*k = ${n * pk.k} entries ` +\n `(indices: ${pk.indices.length}, distances: ${pk.distances.length})`,\n );\n }\n if (pk.k === k) return { indices: pk.indices, distances: pk.distances, k };\n const indices = new Int32Array(n * k);\n const distances = new Float32Array(n * k);\n for (let i = 0; i < n; i++) {\n indices.set(pk.indices.subarray(i * pk.k, i * pk.k + k), i * k);\n distances.set(pk.distances.subarray(i * pk.k, i * pk.k + k), i * k);\n }\n return { indices, distances, k };\n}\n\nfunction applyDisconnectionToKnn(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\nfunction applyDisconnectionToMatrix(X: Matrix, dc: number): Matrix {\n if (dc === Infinity) return X;\n const data = X.data.slice();\n for (let i = 0; i < data.length; i++) {\n if (data[i]! >= dc) data[i] = Infinity;\n }\n return { data, rows: X.rows, cols: X.cols };\n}\n\n/** Query kNN of Q against T by brute force (transform small-data path). */\nfunction smallDataQueryKnn(\n Q: Matrix,\n T: Matrix,\n k: number,\n metric: (a: Float32Array, b: Float32Array) => number,\n): KnnGraph {\n const nq = Q.rows;\n const nt = T.rows;\n const d = Q.cols;\n const indices = new Int32Array(nq * k);\n const distances = new Float32Array(nq * k);\n const row = new Float64Array(nt);\n const heapIdx = new Int32Array(k);\n const heapDst = new Float64Array(k);\n for (let i = 0; i < nq; i++) {\n const qi = Q.data.subarray(i * d, (i + 1) * d);\n for (let j = 0; j < nt; j++) {\n row[j] = metric(qi, T.data.subarray(j * d, (j + 1) * d));\n }\n // selection identical to exact kNN\n selectK(row, nt, k, heapIdx, heapDst);\n for (let j = 0; j < k; j++) {\n indices[i * k + j] = heapIdx[j]!;\n distances[i * k + j] = heapDst[j]!;\n }\n }\n return { indices, distances, k };\n}\n\nfunction selectK(\n rowDist: Float64Array,\n n: number,\n k: number,\n outIdx: Int32Array,\n outDst: Float64Array,\n): void {\n const gt = (d1: number, i1: number, d2: number, i2: number) => d1 > d2 || (d1 === d2 && i1 > i2);\n let count = 0;\n for (let j = 0; j < n; j++) {\n const dj = rowDist[j]!;\n if (count < k) {\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 const td = outDst[c]!;\n outDst[c] = outDst[parent]!;\n outDst[parent] = td;\n const ti = outIdx[c]!;\n outIdx[c] = outIdx[parent]!;\n outIdx[parent] = ti;\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 const td = outDst[c]!;\n outDst[c] = outDst[m]!;\n outDst[m] = td;\n const ti = outIdx[c]!;\n outIdx[c] = outIdx[m]!;\n outIdx[m] = ti;\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 const idxArr = Array.from({ length: k }, (_, j) => j).sort(\n (a, b) => outDst[a]! - outDst[b]! || outIdx[a]! - outIdx[b]!,\n );\n const tmpD = Float64Array.from(idxArr, (j) => outDst[j]!);\n const tmpI = Int32Array.from(idxArr, (j) => outIdx[j]!);\n outDst.set(tmpD);\n outIdx.set(tmpI);\n}\n\n/** transform with metric='precomputed': rows are distances to train points. */\nfunction precomputedQueryKnn(Q: Matrix, k: number): KnnGraph {\n const indices = new Int32Array(Q.rows * k);\n const distances = new Float32Array(Q.rows * k);\n const row = new Float64Array(Q.cols);\n const heapIdx = new Int32Array(k);\n const heapDst = new Float64Array(k);\n for (let i = 0; i < Q.rows; i++) {\n for (let j = 0; j < Q.cols; j++) row[j] = Q.data[i * Q.cols + j]!;\n selectK(row, Q.cols, k, heapIdx, heapDst);\n for (let j = 0; j < k; j++) {\n indices[i * k + j] = heapIdx[j]!;\n distances[i * k + j] = heapDst[j]!;\n }\n }\n return { indices, distances, k };\n}\n","/**\n * AlignedUMAP (aligned_umap.py; notes §19): per-slice UMAP graphs, spectral inits\n * scaled by 10/|max| and Procrustes-rotated to the previous slice, then the aligned\n * euclidean optimizer with window regularisation.\n */\n\nimport { makeEpochsPerSample } from '../graph/epochs.js';\nimport { spectralLayout } from '../init/spectral.js';\nimport { clip } from '../layout/sgd.js';\nimport { symmetricEigen } from '../linalg.js';\nimport { Pcg32, tauRandInt } from '../rng.js';\nimport type { Csr } from '../sparse.js';\nimport {\n type DenseInput,\n type Embedding,\n type Labels,\n type Matrix,\n throwIfAborted,\n UmapError,\n UmapValidationError,\n} from '../types.js';\nimport { toMatrix } from '../util.js';\nimport type { FitCallOptions, UmapOptions } from './options.js';\nimport { UMAP } from './umap.js';\n\nexport interface AlignedUmapOptions extends UmapOptions {\n alignmentRegularisation?: number; // 1e-2\n alignmentWindowSize?: number; // 3\n}\n\n/** Row-index mapping from slice i to slice i+1. */\nexport type Relation = Record<number, number> | Map<number, number>;\n\nfunction relGet(rel: Relation, k: number): number | undefined {\n return rel instanceof Map ? rel.get(k) : rel[k];\n}\n\n/** expand_relations (aligned_umap.py:43-82). */\nexport function expandRelations(\n relations: Relation[],\n windowSize: number,\n sliceSizes: number[],\n): Int32Array[] {\n const nSlices = relations.length + 1;\n const maxN = Math.max(...sliceSizes);\n const W = 2 * windowSize + 1;\n const out: Int32Array[] = [];\n for (let i = 0; i < nSlices; i++) {\n const arr = new Int32Array(W * maxN).fill(-1);\n for (let off = -windowSize; off <= windowSize; off++) {\n const t = i + off;\n if (t < 0 || t >= nSlices || off === 0) {\n if (off === 0) {\n for (let v = 0; v < sliceSizes[i]!; v++) arr[(windowSize + 0) * maxN + v] = v;\n }\n continue;\n }\n for (let v = 0; v < sliceSizes[i]!; v++) {\n let cur = v;\n let ok = true;\n if (off > 0) {\n for (let s = i; s < i + off; s++) {\n const nxt = relGet(relations[s]!, cur);\n if (nxt === undefined) {\n ok = false;\n break;\n }\n cur = nxt;\n }\n } else {\n for (let s = i - 1; s >= i + off; s--) {\n // inverted relation: find key whose value is cur\n const rel = relations[s]!;\n let found = -1;\n if (rel instanceof Map) {\n for (const [k2, v2] of rel) {\n if (v2 === cur) {\n found = k2;\n break;\n }\n }\n } else {\n for (const k2 of Object.keys(rel)) {\n if (rel[k2 as unknown as number] === cur) {\n found = Number(k2);\n break;\n }\n }\n }\n if (found < 0) {\n ok = false;\n break;\n }\n cur = found;\n }\n }\n if (ok) arr[(windowSize + off) * maxN + v] = cur;\n }\n }\n out.push(arr);\n }\n return out;\n}\n\n/** build_neighborhood_similarities (aligned_umap.py:85-129): Jaccard of mapped kNN sets. */\nexport function buildNeighborhoodSimilarities(\n graphs: Csr[],\n relations: Int32Array[],\n windowSize: number,\n maxN: number,\n): Float32Array[] {\n const nSlices = graphs.length;\n const W = 2 * windowSize + 1;\n const out: Float32Array[] = [];\n for (let i = 0; i < nSlices; i++) {\n const weights = new Float32Array(W * maxN);\n for (let off = -windowSize; off <= windowSize; off++) {\n const t = i + off;\n if (t < 0 || t >= nSlices || off === 0) continue;\n const rel = relations[i]!;\n // image of the relation row (values ≥ 0) — Python filters the counterpart's\n // neighbors by membership in relations[i, j] (aligned_umap.py:114-118)\n const image = new Set<number>();\n for (let v = 0; v < maxN; v++) {\n const m = rel[(windowSize + off) * maxN + v]!;\n if (m >= 0) image.add(m);\n }\n for (let v = 0; v < graphs[i]!.rows; v++) {\n const counterpart = rel[(windowSize + off) * maxN + v]!;\n if (counterpart < 0) continue;\n // neighbor set of v mapped through the relation, restricted to mapped vertices\n const mapped = new Set<number>();\n for (let p = graphs[i]!.indptr[v]!; p < graphs[i]!.indptr[v + 1]!; p++) {\n const nb = graphs[i]!.indices[p]!;\n if (nb >= maxN) continue;\n const m = rel[(windowSize + off) * maxN + nb]!;\n if (m >= 0) mapped.add(m);\n }\n const other = new Set<number>();\n for (\n let p = graphs[t]!.indptr[counterpart]!;\n p < graphs[t]!.indptr[counterpart + 1]!;\n p++\n ) {\n const nb = graphs[t]!.indices[p]!;\n if (image.has(nb)) other.add(nb);\n }\n let inter = 0;\n for (const m of mapped) if (other.has(m)) inter++;\n const union = mapped.size + other.size - inter;\n weights[(windowSize + off) * maxN + v] = union === 0 ? 1.0 : inter / union;\n }\n }\n out.push(weights);\n }\n return out;\n}\n\n/** procrustes_align (aligned_umap.py:33-40): rotation-only via SVD of subset2ᵀ·subset1. */\nexport function procrustesRotate(\n embedding: Float32Array,\n dim: number,\n anchorsSelf: Int32Array, // rows in `embedding`\n anchorsPrev: Int32Array, // rows in prev\n prev: Float32Array,\n): void {\n const d = dim;\n // M = subset2ᵀ subset1 (subset1 = prev anchors, subset2 = self anchors)\n const M = new Float64Array(d * d);\n for (let t = 0; t < anchorsSelf.length; t++) {\n const a = anchorsSelf[t]!;\n const b = anchorsPrev[t]!;\n for (let r = 0; r < d; r++) {\n for (let c = 0; c < d; c++) {\n M[r * d + c] = M[r * d + c]! + embedding[a * d + r]! * prev[b * d + c]!;\n }\n }\n }\n // SVD of M via eigen of MᵀM: V; U = M V Σ⁻¹; R = U Vᵀ\n const MtM = new Float64Array(d * d);\n for (let r = 0; r < d; r++) {\n for (let c = 0; c < d; c++) {\n let s = 0;\n for (let k2 = 0; k2 < d; k2++) s += M[k2 * d + r]! * M[k2 * d + c]!;\n MtM[r * d + c] = s;\n }\n }\n const eig = symmetricEigen(MtM, d);\n const U = new Float64Array(d * d);\n const V = new Float64Array(d * d); // columns\n for (let c = 0; c < d; c++) {\n const col = d - 1 - c; // descending singular values\n const sigma = Math.sqrt(Math.max(eig.values[col]!, 1e-30));\n for (let r = 0; r < d; r++) V[r * d + c] = eig.vectors[col * d + r]!;\n for (let r = 0; r < d; r++) {\n let s = 0;\n for (let k2 = 0; k2 < d; k2++) s += M[r * d + k2]! * V[k2 * d + c]!;\n U[r * d + c] = s / sigma;\n }\n }\n const R = new Float64Array(d * d);\n for (let r = 0; r < d; r++) {\n for (let c = 0; c < d; c++) {\n let s = 0;\n for (let k2 = 0; k2 < d; k2++) s += U[r * d + k2]! * V[c * d + k2]!;\n R[r * d + c] = s;\n }\n }\n // embedding ← embedding @ R\n const n = embedding.length / d;\n const tmp = new Float64Array(d);\n for (let i = 0; i < n; i++) {\n for (let c = 0; c < d; c++) {\n let s = 0;\n for (let k2 = 0; k2 < d; k2++) s += embedding[i * d + k2]! * R[k2 * d + c]!;\n tmp[c] = s;\n }\n for (let c = 0; c < d; c++) embedding[i * d + c] = tmp[c]!;\n }\n}\n\nexport class AlignedUMAP {\n readonly options: AlignedUmapOptions;\n private _embeddings: Embedding[] | null = null;\n private _mappers: UMAP[] = [];\n private _relations: Relation[] = [];\n\n constructor(options: AlignedUmapOptions = {}) {\n this.options = { ...options };\n }\n\n get embeddings(): Embedding[] {\n if (!this._embeddings) throw new UmapError('model is not fitted');\n return this._embeddings;\n }\n\n async fit(\n XList: DenseInput[],\n yList?: (Labels | null)[] | null,\n relations?: Relation[],\n { signal }: FitCallOptions = {},\n ): Promise<this> {\n throwIfAborted(signal);\n if (!relations || relations.length !== XList.length - 1) {\n throw new UmapValidationError('relations must have length len(X) - 1');\n }\n this._relations = relations;\n const o = this.options;\n const windowSize = o.alignmentWindowSize ?? 3;\n const lambda = o.alignmentRegularisation ?? 1.0e-2;\n const nComponents = o.nComponents ?? 2;\n const nEpochs = o.nEpochs ?? 200; // aligned fit default (aligned_umap.py:318-319)\n\n const slices: Matrix[] = XList.map((X, i) => toMatrix(X, `X[${i}]`));\n const sliceSizes = slices.map((s) => s.rows);\n const maxN = Math.max(...sliceSizes);\n\n // 1. independent per-slice UMAP fits (graphs retained)\n this._mappers = [];\n for (let i = 0; i < slices.length; i++) {\n const {\n alignmentRegularisation: _ar,\n alignmentWindowSize: _aw,\n nEpochs: _ne,\n ...umapOpts\n } = o;\n const mapper = new UMAP({ ...umapOpts, nComponents });\n await mapper.fit(slices[i]!, yList?.[i] ?? null, signal ? { signal } : {});\n this._mappers.push(mapper);\n }\n const graphs = this._mappers.map((m) => m.graph);\n throwIfAborted(signal);\n\n // 2/4. expanded relations + regularisation weights\n const expanded = expandRelations(relations, windowSize, sliceSizes);\n const regWeights = buildNeighborhoodSimilarities(graphs, expanded, windowSize, maxN);\n\n // 3. per-slice COO + epochs_per_sample\n const heads: Int32Array[] = [];\n const tails: Int32Array[] = [];\n const epochsPerSamples: Float64Array[] = [];\n for (const g of graphs) {\n const nnz = g.indptr[g.rows]!;\n const h = new Int32Array(nnz);\n const t = new Int32Array(nnz);\n const w = new Float32Array(nnz);\n for (let r = 0; r < g.rows; r++) {\n for (let p = g.indptr[r]!; p < g.indptr[r + 1]!; p++) {\n h[p] = r;\n t[p] = g.indices[p]!;\n w[p] = Math.fround(g.data[p]!);\n }\n }\n heads.push(h);\n tails.push(t);\n epochsPerSamples.push(makeEpochsPerSample(w, nEpochs));\n }\n\n // 5/6. spectral inits: ×(10/|max|), Procrustes-rotate to the previous slice\n const seed = o.seed ?? 42;\n const rng = Pcg32.fromSeed(seed);\n const embeddings: Float32Array[] = [];\n for (let i = 0; i < slices.length; i++) {\n const res = spectralLayout(slices[i]!, graphs[i]!, nComponents, rng);\n let mx = 0;\n for (const v of res.embedding) mx = Math.max(mx, Math.abs(v));\n const expansion = mx > 0 ? 10.0 / mx : 1;\n const emb = new Float32Array(res.embedding.length);\n for (let t = 0; t < emb.length; t++) emb[t] = Math.fround(res.embedding[t]! * expansion);\n if (i > 0) {\n // anchors: relations[i-1] maps prev slice → this slice\n const anchorsPrev: number[] = [];\n const anchorsSelf: number[] = [];\n const rel = relations[i - 1]!;\n const entries = rel instanceof Map ? rel.entries() : Object.entries(rel);\n for (const [kRaw, v] of entries) {\n anchorsPrev.push(Number(kRaw));\n anchorsSelf.push(v as number);\n }\n procrustesRotate(\n emb,\n nComponents,\n Int32Array.from(anchorsSelf),\n Int32Array.from(anchorsPrev),\n embeddings[i - 1]!,\n );\n }\n embeddings.push(emb);\n }\n\n // 7. aligned optimization\n const rngTransform = Pcg32.fromSeed(o.transformSeed ?? 42);\n const rngState = rngTransform.tauState();\n optimizeLayoutAlignedEuclidean(\n embeddings,\n nComponents,\n heads,\n tails,\n nEpochs,\n epochsPerSamples,\n regWeights,\n expanded,\n windowSize,\n maxN,\n rngState,\n {\n lambda,\n a: 1.576943460405378,\n b: 0.8950608781227859,\n gamma: o.repulsionStrength ?? 1.0,\n initialAlpha: o.learningRate ?? 1.0,\n negativeSampleRate: o.negativeSampleRate ?? 5,\n moveOther: true,\n ...(signal ? { signal } : {}),\n },\n );\n this._embeddings = embeddings.map((e, i) => ({\n data: e,\n rows: sliceSizes[i]!,\n cols: nComponents,\n }));\n return this;\n }\n\n async fitTransform(\n XList: DenseInput[],\n yList?: (Labels | null)[] | null,\n relations?: Relation[],\n opts: FitCallOptions = {},\n ): Promise<Embedding[]> {\n await this.fit(XList, yList, relations, opts);\n return this.embeddings;\n }\n\n /** Append a new slice (aligned_umap.py:446-562): old slices frozen except pulls. */\n async update(\n Xnew: DenseInput,\n relation: Relation,\n { signal }: FitCallOptions = {},\n ): Promise<this> {\n throwIfAborted(signal);\n if (!this._embeddings) throw new UmapError('model is not fitted');\n const o = this.options;\n const windowSize = o.alignmentWindowSize ?? 3;\n const lambda = o.alignmentRegularisation ?? 1.0e-2;\n const nComponents = o.nComponents ?? 2;\n const nEpochs = o.nEpochs ?? 200;\n const X = toMatrix(Xnew, 'Xnew');\n const { alignmentRegularisation: _ar, alignmentWindowSize: _aw, nEpochs: _ne, ...umapOpts } = o;\n const mapper = new UMAP({ ...umapOpts, nComponents });\n await mapper.fit(X, null, signal ? { signal } : {});\n this._mappers.push(mapper);\n this._relations.push(relation);\n const graphs = this._mappers.map((m) => m.graph);\n const sliceSizes = graphs.map((g) => g.rows);\n const maxN = Math.max(...sliceSizes);\n const expanded = expandRelations(this._relations, windowSize, sliceSizes);\n const regWeights = buildNeighborhoodSimilarities(graphs, expanded, windowSize, maxN);\n\n const heads: Int32Array[] = [];\n const tails: Int32Array[] = [];\n const epochsPerSamples: Float64Array[] = [];\n for (let i = 0; i < graphs.length; i++) {\n const g = graphs[i]!;\n if (i < graphs.length - 1) {\n // old slices: never-due schedule (frozen except alignment pulls)\n heads.push(new Int32Array(0));\n tails.push(new Int32Array(0));\n epochsPerSamples.push(new Float64Array(0));\n continue;\n }\n const nnz = g.indptr[g.rows]!;\n const h = new Int32Array(nnz);\n const t = new Int32Array(nnz);\n const w = new Float32Array(nnz);\n for (let r = 0; r < g.rows; r++) {\n for (let p = g.indptr[r]!; p < g.indptr[r + 1]!; p++) {\n h[p] = r;\n t[p] = g.indices[p]!;\n w[p] = Math.fround(g.data[p]!);\n }\n }\n heads.push(h);\n tails.push(t);\n epochsPerSamples.push(makeEpochsPerSample(w, nEpochs));\n }\n\n // init_from_existing: related point's position, else uniform(-10, 10)\n const prev = this._embeddings[this._embeddings.length - 1]!;\n const rng = Pcg32.fromSeed(o.transformSeed ?? 42);\n const emb = new Float32Array(X.rows * nComponents);\n for (let v = 0; v < X.rows; v++) {\n // inverted relation: prev row → new row\n let src = -1;\n const entries = relation instanceof Map ? relation.entries() : Object.entries(relation);\n for (const [kRaw, val] of entries) {\n if ((val as number) === v) {\n src = Number(kRaw);\n break;\n }\n }\n if (src >= 0) {\n for (let c = 0; c < nComponents; c++)\n emb[v * nComponents + c] = prev.data[src * nComponents + c]!;\n } else {\n for (let c = 0; c < nComponents; c++) emb[v * nComponents + c] = rng.uniform(-10, 10);\n }\n }\n const embeddings = [...this._embeddings.map((e) => e.data), emb];\n const rngState = rng.tauState();\n optimizeLayoutAlignedEuclidean(\n embeddings,\n nComponents,\n heads,\n tails,\n nEpochs,\n epochsPerSamples,\n regWeights,\n expanded,\n windowSize,\n maxN,\n rngState,\n {\n lambda,\n a: 1.576943460405378,\n b: 0.8950608781227859,\n gamma: o.repulsionStrength ?? 1.0,\n initialAlpha: o.learningRate ?? 1.0,\n negativeSampleRate: o.negativeSampleRate ?? 5,\n moveOther: false,\n ...(signal ? { signal } : {}),\n },\n );\n this._embeddings = embeddings.map((e, i) => ({\n data: e,\n rows: sliceSizes[i]!,\n cols: nComponents,\n }));\n return this;\n }\n}\n\ninterface AlignedLayoutParams {\n lambda: number;\n a: number;\n b: number;\n gamma: number;\n initialAlpha: number;\n negativeSampleRate: number;\n moveOther: boolean;\n signal?: AbortSignal;\n}\n\n/** optimize_layout_aligned_euclidean (layouts.py:877-1104; notes §19.4). */\nexport function optimizeLayoutAlignedEuclidean(\n embeddings: Float32Array[],\n dim: number,\n heads: Int32Array[],\n tails: Int32Array[],\n nEpochs: number,\n epochsPerSamples: Float64Array[],\n regWeights: Float32Array[],\n relations: Int32Array[],\n windowSize: number,\n maxN: number,\n rngState: Int32Array,\n P: AlignedLayoutParams,\n): void {\n const nEmbeddings = embeddings.length;\n const { a, b, gamma, lambda, negativeSampleRate, moveOther } = P;\n let alpha = P.initialAlpha;\n\n const epochsPerNegative = epochsPerSamples.map((eps) => {\n const out = new Float64Array(eps.length);\n for (let i = 0; i < eps.length; i++) out[i] = eps[i]! / negativeSampleRate;\n return out;\n });\n const epochOfNext = epochsPerSamples.map((eps) => eps.slice());\n const epochOfNextNeg = epochsPerNegative.map((e) => e.slice());\n const maxNEdges = Math.max(...epochsPerSamples.map((e) => e.length));\n\n const order = new Int32Array(nEmbeddings);\n\n const applyRegularisation = (m: number, vertex: number, d: number, coord: number): number => {\n let g = 0;\n for (let offset = -windowSize; offset < windowSize; offset++) {\n const nm = m + offset;\n if (offset === 0 || nm < 0 || nm >= nEmbeddings) continue;\n const identified = relations[m]![(windowSize + offset) * maxN + vertex]!;\n if (identified < 0) continue;\n g -= clip(\n lambda *\n Math.exp(-(Math.abs(offset) - 1)) *\n regWeights[m]![(windowSize + offset) * maxN + vertex]! *\n (coord - embeddings[nm]![identified * dim + d]!),\n );\n }\n return g;\n };\n\n for (let n = 0; n < nEpochs; n++) {\n throwIfAborted(P.signal);\n // Python reseeds np.random from |rng_state[0]| (which the negative sampling\n // mutates) and shuffles the slice order EVERY epoch (layouts.py:906-908)\n for (let i2 = 0; i2 < nEmbeddings; i2++) order[i2] = i2;\n const shuffleRng = Pcg32.fromSeed(Math.abs(rngState[0]!));\n shuffleRng.shuffle(order);\n for (let i = 0; i < maxNEdges; i++) {\n for (const m of order) {\n const eons = epochOfNext[m]!;\n if (i >= eons.length || eons[i]! > n) continue;\n const emb = embeddings[m]!;\n const j = heads[m]![i]!;\n let k = tails[m]![i]!;\n const jb = j * dim;\n let kb = k * dim;\n let d2 = 0;\n for (let d = 0; d < dim; d++) {\n const diff = emb[jb + d]! - emb[kb + d]!;\n d2 += diff * diff;\n }\n let gradCoeff = 0;\n if (d2 > 0) {\n // pow(d2, b-1) kept separate from pow(d2, b): numba op order, bit-exact\n gradCoeff = (-2.0 * a * b * d2 ** (b - 1.0)) / (a * d2 ** b + 1.0);\n }\n for (let d = 0; d < dim; d++) {\n let gradD = clip(gradCoeff * (emb[jb + d]! - emb[kb + d]!));\n gradD += applyRegularisation(m, j, d, emb[jb + d]!);\n emb[jb + d] = emb[jb + d]! + clip(gradD) * alpha;\n if (moveOther) {\n let otherGrad = clip(gradCoeff * (emb[kb + d]! - emb[jb + d]!));\n otherGrad += applyRegularisation(m, k, d, emb[kb + d]!);\n emb[kb + d] = emb[kb + d]! + clip(otherGrad) * alpha;\n }\n }\n eons[i] = eons[i]! + epochsPerSamples[m]![i]!;\n\n const epn = epochsPerNegative[m]![i]!;\n let nNeg = 0;\n if (epn > 0) {\n nNeg = Math.trunc((n - epochOfNextNeg[m]![i]!) / epn);\n }\n const nVertices = emb.length / dim;\n for (let p = 0; p < nNeg; p++) {\n const r = tauRandInt(rngState);\n k = (r % nVertices) + (r % nVertices < 0 ? nVertices : 0);\n kb = k * dim;\n let dn = 0;\n for (let d = 0; d < dim; d++) {\n const diff = emb[jb + d]! - emb[kb + d]!;\n dn += diff * diff;\n }\n let repCoeff = 0;\n if (dn > 0) {\n repCoeff = (2.0 * gamma * b) / ((0.001 + dn) * (a * dn ** b + 1));\n } else if (j === k) {\n continue;\n }\n for (let d = 0; d < dim; d++) {\n let gradD = 0;\n if (repCoeff > 0) {\n gradD = clip(repCoeff * (emb[jb + d]! - emb[kb + d]!));\n }\n gradD += applyRegularisation(m, j, d, emb[jb + d]!);\n emb[jb + d] = emb[jb + d]! + clip(gradD) * alpha;\n }\n }\n epochOfNextNeg[m]![i] = epochOfNextNeg[m]![i]! + nNeg * epn;\n }\n }\n alpha = P.initialAlpha * (1.0 - n / nEpochs);\n }\n}\n","/**\n * umap-web — standalone TypeScript UMAP for browsers and Node.js.\n *\n * Public entry point. See `umap-web/core` for the low-level functional API.\n */\nexport const VERSION = '0.1.0';\n\nexport * from './core.js';\nexport type { AlignedUmapOptions, Relation } from './estimator/aligned.js';\nexport { AlignedUMAP } from './estimator/aligned.js';\nexport type { FitCallOptions, UmapOptions } from './estimator/options.js';\nexport { DISCONNECTION_DISTANCES } from './estimator/options.js';\nexport { UMAP } from './estimator/umap.js';\nexport type {\n CSRInput,\n DenseInput,\n Embedding,\n KnnGraph,\n Labels,\n Logger,\n MetricFn,\n Target,\n} from './types.js';\nexport {\n UmapBackendError,\n UmapConvergenceWarning,\n UmapError,\n UmapValidationError,\n} from './types.js';\n"],"mappings":"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"}