@elarsaks/umap-wasm 0.1.2 → 0.1.4

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.
Files changed (52) hide show
  1. package/dist/{src/heap.d.ts → heap.d.ts} +1 -1
  2. package/dist/heap.js +184 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +2 -0
  5. package/dist/lib.d.ts +2 -0
  6. package/dist/lib.js +2 -0
  7. package/dist/matrix.js +257 -0
  8. package/dist/{src/nn_descent.d.ts → nn_descent.d.ts} +4 -4
  9. package/dist/nn_descent.js +127 -0
  10. package/dist/{src/tree.d.ts → tree.d.ts} +2 -2
  11. package/dist/tree.js +228 -0
  12. package/dist/{src/umap.d.ts → umap.d.ts} +1 -1
  13. package/dist/umap.js +700 -0
  14. package/dist/{src/utils.d.ts → utils.d.ts} +1 -1
  15. package/dist/utils.js +98 -0
  16. package/dist/wasmBridge.js +188 -0
  17. package/lib/umap-js.js +6842 -7490
  18. package/lib/umap-js.min.js +1 -1
  19. package/package.json +64 -63
  20. package/dist/src/heap.js +0 -226
  21. package/dist/src/index.d.ts +0 -2
  22. package/dist/src/index.js +0 -8
  23. package/dist/src/lib.d.ts +0 -1
  24. package/dist/src/lib.js +0 -5
  25. package/dist/src/matrix.js +0 -360
  26. package/dist/src/nn_descent.js +0 -204
  27. package/dist/src/tree.js +0 -320
  28. package/dist/src/umap.js +0 -842
  29. package/dist/src/utils.js +0 -137
  30. package/dist/src/wasmBridge.js +0 -290
  31. package/dist/test/matrix.test.d.ts +0 -1
  32. package/dist/test/matrix.test.js +0 -169
  33. package/dist/test/nn_descent.test.d.ts +0 -1
  34. package/dist/test/nn_descent.test.js +0 -58
  35. package/dist/test/smoke.playwright.test.d.ts +0 -1
  36. package/dist/test/smoke.playwright.test.js +0 -98
  37. package/dist/test/test_data.d.ts +0 -13
  38. package/dist/test/test_data.js +0 -1054
  39. package/dist/test/tree.test.d.ts +0 -1
  40. package/dist/test/tree.test.js +0 -60
  41. package/dist/test/umap.test.d.ts +0 -1
  42. package/dist/test/umap.test.js +0 -293
  43. package/dist/test/utils.test.d.ts +0 -1
  44. package/dist/test/utils.test.js +0 -128
  45. package/dist/test/wasmDistance.test.d.ts +0 -1
  46. package/dist/test/wasmDistance.test.js +0 -124
  47. package/dist/test/wasmMatrix.test.d.ts +0 -1
  48. package/dist/test/wasmMatrix.test.js +0 -389
  49. package/dist/test/wasmTree.test.d.ts +0 -1
  50. package/dist/test/wasmTree.test.js +0 -212
  51. /package/dist/{src/matrix.d.ts → matrix.d.ts} +0 -0
  52. /package/dist/{src/wasmBridge.d.ts → wasmBridge.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { RandomFn } from './umap';
1
+ import { RandomFn } from './umap.js';
2
2
  export declare function tauRandInt(n: number, random: RandomFn): number;
3
3
  export declare function tauRand(random: RandomFn): number;
4
4
  export declare function norm(vec: number[]): number;
package/dist/utils.js ADDED
@@ -0,0 +1,98 @@
1
+ export function tauRandInt(n, random) {
2
+ return Math.floor(random() * n);
3
+ }
4
+ export function tauRand(random) {
5
+ return random();
6
+ }
7
+ export function norm(vec) {
8
+ let result = 0;
9
+ for (let item of vec) {
10
+ result += item ** 2;
11
+ }
12
+ return Math.sqrt(result);
13
+ }
14
+ export function empty(n) {
15
+ const output = [];
16
+ for (let i = 0; i < n; i++) {
17
+ output.push(undefined);
18
+ }
19
+ return output;
20
+ }
21
+ export function range(n) {
22
+ return empty(n).map((_, i) => i);
23
+ }
24
+ export function filled(n, v) {
25
+ return empty(n).map(() => v);
26
+ }
27
+ export function zeros(n) {
28
+ return filled(n, 0);
29
+ }
30
+ export function ones(n) {
31
+ return filled(n, 1);
32
+ }
33
+ export function linear(a, b, len) {
34
+ return empty(len).map((_, i) => {
35
+ return a + i * ((b - a) / (len - 1));
36
+ });
37
+ }
38
+ export function sum(input) {
39
+ return input.reduce((sum, val) => sum + val);
40
+ }
41
+ export function mean(input) {
42
+ return sum(input) / input.length;
43
+ }
44
+ export function max(input) {
45
+ let max = 0;
46
+ for (let i = 0; i < input.length; i++) {
47
+ max = input[i] > max ? input[i] : max;
48
+ }
49
+ return max;
50
+ }
51
+ export function max2d(input) {
52
+ let max = 0;
53
+ for (let i = 0; i < input.length; i++) {
54
+ for (let j = 0; j < input[i].length; j++) {
55
+ max = input[i][j] > max ? input[i][j] : max;
56
+ }
57
+ }
58
+ return max;
59
+ }
60
+ export function rejectionSample(nSamples, poolSize, random) {
61
+ const result = zeros(nSamples);
62
+ for (let i = 0; i < nSamples; i++) {
63
+ let rejectSample = true;
64
+ while (rejectSample) {
65
+ const j = tauRandInt(poolSize, random);
66
+ let broken = false;
67
+ for (let k = 0; k < i; k++) {
68
+ if (j === result[k]) {
69
+ broken = true;
70
+ break;
71
+ }
72
+ }
73
+ if (!broken) {
74
+ rejectSample = false;
75
+ }
76
+ result[i] = j;
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ export function reshape2d(x, a, b) {
82
+ const rows = [];
83
+ let count = 0;
84
+ let index = 0;
85
+ if (x.length !== a * b) {
86
+ throw new Error('Array dimensions must match input length.');
87
+ }
88
+ for (let i = 0; i < a; i++) {
89
+ const col = [];
90
+ for (let j = 0; j < b; j++) {
91
+ col.push(x[index]);
92
+ index += 1;
93
+ }
94
+ rows.push(col);
95
+ count += 1;
96
+ }
97
+ return rows;
98
+ }
@@ -0,0 +1,188 @@
1
+ let wasmReady = null;
2
+ let wasmModule = null;
3
+ export async function initWasm() {
4
+ if (wasmReady)
5
+ return wasmReady;
6
+ wasmReady = (async () => {
7
+ try {
8
+ const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
9
+ const wasmPath = isNode
10
+ ? '../wasm/pkg/node/umap_wasm_core.js'
11
+ : '../wasm/pkg/web/umap_wasm_core.js';
12
+ const mod = await import(wasmPath);
13
+ if (typeof mod.default === 'function') {
14
+ await mod.default();
15
+ }
16
+ wasmModule = mod;
17
+ return mod;
18
+ }
19
+ catch (err) {
20
+ wasmReady = null;
21
+ wasmModule = null;
22
+ throw new Error(`Failed to load WASM module: ${err}`);
23
+ }
24
+ })();
25
+ return wasmReady;
26
+ }
27
+ export function isWasmAvailable() {
28
+ return wasmModule !== null;
29
+ }
30
+ export function euclideanWasm(x, y) {
31
+ if (!wasmModule)
32
+ throw new Error('WASM module not initialized');
33
+ const xa = new Float64Array(x);
34
+ const ya = new Float64Array(y);
35
+ return wasmModule.euclidean(xa, ya);
36
+ }
37
+ export function cosineWasm(x, y) {
38
+ if (!wasmModule)
39
+ throw new Error('WASM module not initialized');
40
+ const xa = new Float64Array(x);
41
+ const ya = new Float64Array(y);
42
+ return wasmModule.cosine(xa, ya);
43
+ }
44
+ export function buildRpTreeWasm(data, nSamples, dim, leafSize, seed) {
45
+ if (!wasmModule)
46
+ throw new Error('WASM module not initialized');
47
+ const flatData = new Float64Array(nSamples * dim);
48
+ for (let i = 0; i < nSamples; i++) {
49
+ for (let j = 0; j < dim; j++) {
50
+ flatData[i * dim + j] = data[i][j];
51
+ }
52
+ }
53
+ return wasmModule.build_rp_tree(flatData, nSamples, dim, leafSize, BigInt(seed));
54
+ }
55
+ export function searchFlatTreeWasm(tree, point, seed) {
56
+ if (!wasmModule)
57
+ throw new Error('WASM module not initialized');
58
+ const pointArray = new Float64Array(point);
59
+ const result = wasmModule.search_flat_tree(tree, pointArray, BigInt(seed));
60
+ return Array.from(result);
61
+ }
62
+ export function wasmTreeToJs(wasmTree) {
63
+ const hyperplanesFlat = Array.from(wasmTree.hyperplanes());
64
+ const offsetsArray = Array.from(wasmTree.offsets());
65
+ const childrenFlat = Array.from(wasmTree.children());
66
+ const indicesFlat = Array.from(wasmTree.indices());
67
+ const dim = wasmTree.dim();
68
+ const nNodes = wasmTree.n_nodes();
69
+ const hyperplanes = [];
70
+ for (let i = 0; i < nNodes; i++) {
71
+ hyperplanes.push(hyperplanesFlat.slice(i * dim, (i + 1) * dim));
72
+ }
73
+ const children = [];
74
+ for (let i = 0; i < nNodes; i++) {
75
+ children.push([childrenFlat[i * 2], childrenFlat[i * 2 + 1]]);
76
+ }
77
+ let maxLeafIdx = 0;
78
+ for (let i = 0; i < childrenFlat.length; i++) {
79
+ const v = childrenFlat[i];
80
+ if (v <= 0) {
81
+ const leafIdx = -v;
82
+ if (leafIdx > maxLeafIdx)
83
+ maxLeafIdx = leafIdx;
84
+ }
85
+ }
86
+ const nLeaves = maxLeafIdx + 1;
87
+ const leafSize = nLeaves > 0 ? Math.floor(indicesFlat.length / nLeaves) : 0;
88
+ const indices = [];
89
+ for (let i = 0; i < nLeaves; i++) {
90
+ const slice = indicesFlat.slice(i * leafSize, (i + 1) * leafSize);
91
+ while (slice.length < leafSize)
92
+ slice.push(-1);
93
+ indices.push(slice);
94
+ }
95
+ return {
96
+ hyperplanes,
97
+ offsets: offsetsArray,
98
+ children,
99
+ indices,
100
+ };
101
+ }
102
+ export function createSparseMatrixWasm(rows, cols, values, nRows, nCols) {
103
+ if (!wasmModule)
104
+ throw new Error('WASM module not initialized');
105
+ const rowsArray = new Int32Array(rows);
106
+ const colsArray = new Int32Array(cols);
107
+ const valuesArray = new Float64Array(values);
108
+ return new wasmModule.WasmSparseMatrix(rowsArray, colsArray, valuesArray, nRows, nCols);
109
+ }
110
+ export function sparseTransposeWasm(matrix) {
111
+ if (!wasmModule)
112
+ throw new Error('WASM module not initialized');
113
+ return wasmModule.sparse_transpose(matrix);
114
+ }
115
+ export function sparseIdentityWasm(size) {
116
+ if (!wasmModule)
117
+ throw new Error('WASM module not initialized');
118
+ return wasmModule.sparse_identity(size);
119
+ }
120
+ export function sparseAddWasm(a, b) {
121
+ if (!wasmModule)
122
+ throw new Error('WASM module not initialized');
123
+ return wasmModule.sparse_add(a, b);
124
+ }
125
+ export function sparseSubtractWasm(a, b) {
126
+ if (!wasmModule)
127
+ throw new Error('WASM module not initialized');
128
+ return wasmModule.sparse_subtract(a, b);
129
+ }
130
+ export function sparsePairwiseMultiplyWasm(a, b) {
131
+ if (!wasmModule)
132
+ throw new Error('WASM module not initialized');
133
+ return wasmModule.sparse_pairwise_multiply(a, b);
134
+ }
135
+ export function sparseMaximumWasm(a, b) {
136
+ if (!wasmModule)
137
+ throw new Error('WASM module not initialized');
138
+ return wasmModule.sparse_maximum(a, b);
139
+ }
140
+ export function sparseMultiplyScalarWasm(matrix, scalar) {
141
+ if (!wasmModule)
142
+ throw new Error('WASM module not initialized');
143
+ return wasmModule.sparse_multiply_scalar(matrix, scalar);
144
+ }
145
+ export function sparseEliminateZerosWasm(matrix) {
146
+ if (!wasmModule)
147
+ throw new Error('WASM module not initialized');
148
+ return wasmModule.sparse_eliminate_zeros(matrix);
149
+ }
150
+ export function sparseNormalizeWasm(matrix, normType = 'l2') {
151
+ if (!wasmModule)
152
+ throw new Error('WASM module not initialized');
153
+ return wasmModule.sparse_normalize(matrix, normType);
154
+ }
155
+ export function sparseGetCSRWasm(matrix) {
156
+ if (!wasmModule)
157
+ throw new Error('WASM module not initialized');
158
+ const result = Array.from(wasmModule.sparse_get_csr(matrix));
159
+ const nIndices = result[0];
160
+ const nValues = result[1];
161
+ const nIndptr = result[2];
162
+ const indices = result.slice(3, 3 + nIndices);
163
+ const values = result.slice(3 + nIndices, 3 + nIndices + nValues);
164
+ const indptr = result.slice(3 + nIndices + nValues, 3 + nIndices + nValues + nIndptr);
165
+ return { indices, values, indptr };
166
+ }
167
+ export function wasmSparseMatrixToArray(matrix) {
168
+ const flat = Array.from(matrix.to_array());
169
+ const nRows = matrix.n_rows;
170
+ const nCols = matrix.n_cols;
171
+ const result = [];
172
+ for (let i = 0; i < nRows; i++) {
173
+ result.push(flat.slice(i * nCols, (i + 1) * nCols));
174
+ }
175
+ return result;
176
+ }
177
+ export function wasmSparseMatrixGetAll(matrix) {
178
+ const flat = Array.from(matrix.get_all_ordered());
179
+ const entries = [];
180
+ for (let i = 0; i < flat.length; i += 3) {
181
+ entries.push({
182
+ row: flat[i],
183
+ col: flat[i + 1],
184
+ value: flat[i + 2],
185
+ });
186
+ }
187
+ return entries;
188
+ }