@elarsaks/umap-wasm 0.5.1 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,13 @@
1
- # 🚧 UNDER DEVELOPMENT 🚧
2
-
3
1
  # UMAP-WASM: WebAssembly-Accelerated UMAP for JavaScript
4
2
 
5
3
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
6
4
 
5
+ > **⚠️ Thesis Project Notice**: This library was developed as part of a master's thesis research project and is **not actively maintained**. While functional and tested, it is provided as-is for academic and experimental purposes.
6
+
7
+ ![Performance Comparison](docs/runtime_by_machine.png)
8
+
9
+ *Performance comparison across different machines. The baseline represents the pure JavaScript implementation (umap-js), while UMAP-WASM shows the WebAssembly-accelerated version. Note: The MacBook is approximately 5 years newer and more performant hardware compared to the Linux machine.*
10
+
7
11
  A high-performance implementation of Uniform Manifold Approximation and Projection (UMAP) for JavaScript environments, featuring selective WebAssembly acceleration for compute-intensive operations.
8
12
 
9
13
  ## 📦 Installation
@@ -16,17 +20,40 @@ yarn add umap-wasm
16
20
 
17
21
  ### Make the WASM artifacts available in the browser
18
22
 
19
- For browser builds the loader expects the compiled WASM bundle at `/wasm/pkg/web/umap_wasm_core.js` (and the accompanying `.wasm` binary) to be served as static assets. If your bundler does not automatically copy files from `node_modules`, add a `postinstall` script that copies only the web build into your public/static directory:
23
+ For browser usage, WASM files must be served as static assets. The package includes pre-built WASM artifacts in `wasm/pkg/web/`. If your bundler doesn't automatically copy files from `node_modules`, add a postinstall script:
20
24
 
21
25
  ```json
22
26
  {
23
27
  "scripts": {
24
- "postinstall": "mkdir -p public/wasm/pkg/web && cp -r node_modules/@elarsaks/umap-wasm/wasm/pkg/web/* public/wasm/pkg/web/"
28
+ "postinstall": "mkdir -p public/wasm && cp -r node_modules/@elarsaks/umap-wasm/wasm/pkg/web public/wasm/"
25
29
  }
26
30
  }
27
31
  ```
28
32
 
29
- Adjust the destination (`public/wasm/pkg`) to match your framework's static assets folder (e.g., `static/` for SvelteKit, `public/` for Vite/Next). Node.js-only usage does not need this step.
33
+ Adjust the destination to match your framework:
34
+ - Vite/React: `public/wasm/`
35
+ - Next.js: `public/wasm/`
36
+ - SvelteKit: `static/wasm/`
37
+
38
+ The WASM loader will look for files at `/wasm/web/umap_wasm_core.js` and `/wasm/web/umap_wasm_core_bg.wasm`.
39
+
40
+ Node.js environments don't require this step.
41
+
42
+ ## Reproducible WASM build (short note)
43
+
44
+ If you need to rebuild the WASM artifacts locally, use the locked toolchain and skip post-build optimization to avoid runtime issues with externref tables. Recommended minimal steps:
45
+
46
+ - Ensure the repository `rust-toolchain.toml` is respected (Rust 1.83.0).
47
+ - Use `wasm-pack 0.13.1` and Node.js `22.22.0`.
48
+ - Build with `--no-opt` to skip `wasm-opt` (example):
49
+
50
+ ```bash
51
+ cd wasm
52
+ RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --no-opt --target web --out-dir pkg/web --release
53
+ RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --no-opt --target nodejs --out-dir pkg/node --release
54
+ ```
55
+
56
+ Skipping `wasm-opt` avoids a post-processing pass that may break WebAssembly externref table handling; it yields larger but correct binaries. Only publish optimized binaries after ensuring they pass the full test-suite.
30
57
 
31
58
  ## 🚀 Usage
32
59
 
@@ -46,14 +73,13 @@ const embedding = umap.fit(data);
46
73
 
47
74
  ### WASM loading with progress
48
75
 
49
- If you want a progress bar while the WASM module downloads, pass a `wasmUrl`
50
- and `onProgress` callback:
76
+ For progress tracking during WASM module loading:
51
77
 
52
78
  ```typescript
53
79
  import { initWasm } from 'umap-wasm';
54
80
 
55
81
  await initWasm({
56
- wasmUrl: '/wasm/pkg/web/umap_wasm_core_bg.wasm',
82
+ wasmUrl: '/wasm/web/umap_wasm_core_bg.wasm',
57
83
  onProgress: ({ percent, phase }) => {
58
84
  console.log(`WASM ${phase}: ${percent ?? 0}%`);
59
85
  }
@@ -131,22 +157,33 @@ The UMAP constructor accepts a `UMAPParameters` object with the following option
131
157
  | `spread` | `number` | `1.0` | Effective scale of embedded points |
132
158
  | `random` | `() => number` | `Math.random` | PRNG for reproducibility |
133
159
  | `distanceFn` | `DistanceFn` | `euclidean` | Distance metric for input space |
134
- | `useWasmDistance` | `boolean` | `false` | Whether to use Rust/WASM distance functions when available |
135
- | `useWasmNNDescent` | `boolean` | `false` | Whether to use Rust/WASM NN-Descent implementation when available |
136
- | `useWasmTree` | `boolean` | `false` | Whether to use Rust/WASM random projection tree construction when available |
137
- | `useWasmMatrix` | `boolean` | `false` | Whether to use Rust/WASM sparse matrix operations when available |
138
- | `useWasmOptimizer` | `boolean` | `false` | Whether to use Rust/WASM gradient descent optimizer when available |
160
+ | `useWasmDistance` | `boolean` | `false` | Use Rust/WASM distance functions (Euclidean, cosine, etc.) |
161
+ | `useWasmNNDescent` | `boolean` | `false` | Use Rust/WASM NN-Descent for nearest neighbor graph refinement |
162
+ | `useWasmTree` | `boolean` | `false` | Use Rust/WASM random projection trees for neighbor search |
163
+ | `useWasmMatrix` | `boolean` | `false` | Use Rust/WASM sparse matrix operations |
164
+ | `useWasmOptimizer` | `boolean` | `false` | Use Rust/WASM gradient descent optimizer |
139
165
 
166
+ **WASM Performance Note**: Enable WASM features for improved performance on large datasets (1000+ points). For small datasets, JavaScript may be faster due to overhead.
140
167
 
141
- ### Example with WASM Parameters
168
+ ### Example Configuration
142
169
 
143
170
  ```typescript
144
171
  import { UMAP } from 'umap-wasm';
145
172
 
173
+ // Basic 2D embedding
146
174
  const umap = new UMAP({
147
- nComponents: 3, // 3D embedding
175
+ nComponents: 2,
176
+ nNeighbors: 15,
177
+ minDist: 0.1
178
+ });
179
+
180
+ // 3D embedding with WASM acceleration
181
+ const umapWasm = new UMAP({
182
+ nComponents: 3,
183
+ nNeighbors: 30,
148
184
  useWasmDistance: true,
149
- useWasmNNDescent: true
185
+ useWasmNNDescent: true,
186
+ useWasmOptimizer: true
150
187
  });
151
188
  ```
152
189
  ---
@@ -312,6 +349,8 @@ yarn test:ui
312
349
  yarn test:coverage
313
350
  ```
314
351
 
352
+ **Note**: Some unit tests depend on the execution environment (CPU architecture, floating-point precision, random number generation). Test results may vary slightly across different machines and may fail in environments different from the development setup.
353
+
315
354
  ## 📊 Benchmarking
316
355
 
317
356
  Performance benchmarks are available in the companion `umap-bench` repository, which includes:
@@ -366,4 +405,4 @@ Tampere University of Applied Sciences
366
405
 
367
406
  ---
368
407
 
369
- *This README is maintained as part of academic research. Last updated: January 2026*
408
+ *This README is maintained as part of academic research. Last updated: February 2026*
package/package.json CHANGED
@@ -1,16 +1,31 @@
1
1
  {
2
2
  "name": "@elarsaks/umap-wasm",
3
- "version": "0.5.1",
4
- "description": "JavaScript implementation of UMAP",
3
+ "version": "0.9.1",
4
+ "description": "WebAssembly-Accelerated UMAP for JavaScript - High-performance dimension reduction for browser and Node.js",
5
+ "keywords": [
6
+ "umap",
7
+ "wasm",
8
+ "webassembly",
9
+ "dimension-reduction",
10
+ "machine-learning",
11
+ "visualization",
12
+ "manifold-learning",
13
+ "javascript",
14
+ "typescript",
15
+ "rust"
16
+ ],
5
17
  "author": {
6
18
  "name": "Elar Saks",
7
19
  "email": "elarsaks@gmail.com"
8
20
  },
9
- "license": "MIT",
21
+ "license": "Apache-2.0",
10
22
  "repository": {
11
23
  "type": "git",
12
24
  "url": "git+https://github.com/elarsaks/umap-wasm.git"
13
25
  },
26
+ "bugs": {
27
+ "url": "https://github.com/elarsaks/umap-wasm/issues"
28
+ },
14
29
  "main": "lib/umap-js.js",
15
30
  "module": "dist/index.js",
16
31
  "unpkg": "lib/umap-js.min.js",
@@ -36,7 +51,7 @@
36
51
  "preview": "npx serve . -p 4173",
37
52
  "bundle": "rm -rf lib && webpack --config ./webpack/lib.config.mjs && webpack --config ./webpack/lib.min.config.mjs",
38
53
  "build": "rm -rf dist && tsc && yarn bundle",
39
- "build:wasm": "cd wasm && RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --target web --out-dir pkg/web --release && wasm-opt -O4 -o pkg/web/umap_wasm_core_bg.wasm pkg/web/umap_wasm_core_bg.wasm && RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --target nodejs --out-dir pkg/node --release && wasm-opt -O4 -o pkg/node/umap_wasm_core_bg.wasm pkg/node/umap_wasm_core_bg.wasm && rm -f pkg/web/.gitignore pkg/node/.gitignore"
54
+ "build:wasm": "cd wasm && RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --no-opt --target web --out-dir pkg/web --release && RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --no-opt --target nodejs --out-dir pkg/node --release && rm -f pkg/web/.gitignore pkg/node/.gitignore"
40
55
  },
41
56
  "devDependencies": {
42
57
  "@playwright/test": "^1.57.0",
@@ -10,58 +10,58 @@ export class FlatTree {
10
10
  */
11
11
  hyperplanes(): Float64Array;
12
12
  /**
13
- * Get the dimensionality
13
+ * Get the offsets as a Float64Array
14
14
  */
15
- dim(): number;
15
+ offsets(): Float64Array;
16
16
  /**
17
- * Get the leaf indices array
17
+ * Get the children array (pairs of child indices)
18
18
  */
19
- indices(): Int32Array;
19
+ children(): Int32Array;
20
20
  /**
21
- * Get number of nodes
21
+ * Get the leaf indices array
22
22
  */
23
- n_nodes(): number;
23
+ indices(): Int32Array;
24
24
  /**
25
- * Get the offsets as a Float64Array
25
+ * Get the dimensionality
26
26
  */
27
- offsets(): Float64Array;
27
+ dim(): number;
28
28
  /**
29
- * Get the children array (pairs of child indices)
29
+ * Get number of nodes
30
30
  */
31
- children(): Int32Array;
31
+ n_nodes(): number;
32
32
  }
33
33
 
34
34
  export class OptimizerState {
35
35
  free(): void;
36
36
  [Symbol.dispose](): void;
37
37
  /**
38
- * Seed the internal RNG used by the optimizer.
39
- */
40
- set_rng_seed(seed: bigint): void;
41
- /**
42
- * Get the length of the embedding buffer.
38
+ * Create a new optimizer state with the given parameters.
43
39
  */
44
- head_embedding_len(): number;
40
+ constructor(head: Uint32Array, tail: Uint32Array, head_embedding: Float64Array, tail_embedding: Float64Array, epochs_per_sample: Float64Array, epochs_per_negative_sample: Float64Array, move_other: boolean, initial_alpha: number, gamma: number, a: number, b: number, dim: number, n_epochs: number, n_vertices: number);
45
41
  /**
46
42
  * Get a pointer to the embedding buffer (for zero-copy views).
47
43
  */
48
44
  head_embedding_ptr(): number;
49
45
  /**
50
- * Create a new optimizer state with the given parameters.
46
+ * Get the length of the embedding buffer.
51
47
  */
52
- constructor(head: Uint32Array, tail: Uint32Array, head_embedding: Float64Array, tail_embedding: Float64Array, epochs_per_sample: Float64Array, epochs_per_negative_sample: Float64Array, move_other: boolean, initial_alpha: number, gamma: number, a: number, b: number, dim: number, n_epochs: number, n_vertices: number);
48
+ head_embedding_len(): number;
53
49
  /**
54
- * Get the current RNG seed/state.
50
+ * Seed the internal RNG used by the optimizer.
55
51
  */
56
- rng_seed(): bigint;
52
+ set_rng_seed(seed: bigint): void;
57
53
  /**
58
- * Get the current epoch number.
54
+ * Get the current RNG seed/state.
59
55
  */
60
- readonly current_epoch: number;
56
+ rng_seed(): bigint;
61
57
  /**
62
58
  * Get the current embedding as a flat array.
63
59
  */
64
60
  readonly head_embedding: Float64Array;
61
+ /**
62
+ * Get the current epoch number.
63
+ */
64
+ readonly current_epoch: number;
65
65
  /**
66
66
  * Get the total number of epochs.
67
67
  */
@@ -71,22 +71,6 @@ export class OptimizerState {
71
71
  export class WasmSparseMatrix {
72
72
  free(): void;
73
73
  [Symbol.dispose](): void;
74
- /**
75
- * Get all values
76
- */
77
- get_values(): Float64Array;
78
- /**
79
- * Apply a scalar operation to all values (map with scalar)
80
- */
81
- map_scalar(operation: string, scalar: number): WasmSparseMatrix;
82
- /**
83
- * Get all entries as flat arrays [rows, cols, values] - ordered by row then col
84
- */
85
- get_all_ordered(): Float64Array;
86
- /**
87
- * Get a value at the given row and column, with a default value if not present
88
- */
89
- get(row: number, col: number, default_value: number): number;
90
74
  /**
91
75
  * Create a new sparse matrix from rows, cols, values, and dimensions.
92
76
  *
@@ -98,18 +82,14 @@ export class WasmSparseMatrix {
98
82
  * * `n_cols` - Number of columns in the matrix
99
83
  */
100
84
  constructor(rows: Int32Array, cols: Int32Array, values: Float64Array, n_rows: number, n_cols: number);
101
- /**
102
- * Get number of non-zero entries
103
- */
104
- nnz(): number;
105
85
  /**
106
86
  * Set a value at the given row and column
107
87
  */
108
88
  set(row: number, col: number, value: number): void;
109
89
  /**
110
- * Get all column indices
90
+ * Get a value at the given row and column, with a default value if not present
111
91
  */
112
- get_cols(): Int32Array;
92
+ get(row: number, col: number, default_value: number): number;
113
93
  /**
114
94
  * Get the dimensions as [nRows, nCols]
115
95
  */
@@ -118,18 +98,38 @@ export class WasmSparseMatrix {
118
98
  * Get all row indices
119
99
  */
120
100
  get_rows(): Int32Array;
101
+ /**
102
+ * Get all column indices
103
+ */
104
+ get_cols(): Int32Array;
105
+ /**
106
+ * Get all values
107
+ */
108
+ get_values(): Float64Array;
109
+ /**
110
+ * Get all entries as flat arrays [rows, cols, values] - ordered by row then col
111
+ */
112
+ get_all_ordered(): Float64Array;
113
+ /**
114
+ * Get number of non-zero entries
115
+ */
116
+ nnz(): number;
121
117
  /**
122
118
  * Convert to dense 2D array (row-major, flattened)
123
119
  */
124
120
  to_array(): Float64Array;
125
121
  /**
126
- * Get the number of columns
122
+ * Apply a scalar operation to all values (map with scalar)
127
123
  */
128
- readonly n_cols: number;
124
+ map_scalar(operation: string, scalar: number): WasmSparseMatrix;
129
125
  /**
130
126
  * Get the number of rows
131
127
  */
132
128
  readonly n_rows: number;
129
+ /**
130
+ * Get the number of columns
131
+ */
132
+ readonly n_cols: number;
133
133
  }
134
134
 
135
135
  /**
@@ -181,12 +181,22 @@ class FlatTree {
181
181
  return ret;
182
182
  }
183
183
  /**
184
- * Get the dimensionality
185
- * @returns {number}
184
+ * Get the offsets as a Float64Array
185
+ * @returns {Float64Array}
186
186
  */
187
- dim() {
188
- const ret = wasm.flattree_dim(this.__wbg_ptr);
189
- return ret >>> 0;
187
+ offsets() {
188
+ const ret = wasm.flattree_offsets(this.__wbg_ptr);
189
+ return ret;
190
+ }
191
+ /**
192
+ * Get the children array (pairs of child indices)
193
+ * @returns {Int32Array}
194
+ */
195
+ children() {
196
+ const ret = wasm.flattree_children(this.__wbg_ptr);
197
+ var v1 = getArrayI32FromWasm0(ret[0], ret[1]).slice();
198
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
199
+ return v1;
190
200
  }
191
201
  /**
192
202
  * Get the leaf indices array
@@ -199,30 +209,20 @@ class FlatTree {
199
209
  return v1;
200
210
  }
201
211
  /**
202
- * Get number of nodes
212
+ * Get the dimensionality
203
213
  * @returns {number}
204
214
  */
205
- n_nodes() {
206
- const ret = wasm.flattree_n_nodes(this.__wbg_ptr);
215
+ dim() {
216
+ const ret = wasm.flattree_dim(this.__wbg_ptr);
207
217
  return ret >>> 0;
208
218
  }
209
219
  /**
210
- * Get the offsets as a Float64Array
211
- * @returns {Float64Array}
212
- */
213
- offsets() {
214
- const ret = wasm.flattree_offsets(this.__wbg_ptr);
215
- return ret;
216
- }
217
- /**
218
- * Get the children array (pairs of child indices)
219
- * @returns {Int32Array}
220
+ * Get number of nodes
221
+ * @returns {number}
220
222
  */
221
- children() {
222
- const ret = wasm.flattree_children(this.__wbg_ptr);
223
- var v1 = getArrayI32FromWasm0(ret[0], ret[1]).slice();
224
- wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
225
- return v1;
223
+ n_nodes() {
224
+ const ret = wasm.flattree_n_nodes(this.__wbg_ptr);
225
+ return ret >>> 0;
226
226
  }
227
227
  }
228
228
  if (Symbol.dispose) FlatTree.prototype[Symbol.dispose] = FlatTree.prototype.free;
@@ -243,47 +243,6 @@ class OptimizerState {
243
243
  const ptr = this.__destroy_into_raw();
244
244
  wasm.__wbg_optimizerstate_free(ptr, 0);
245
245
  }
246
- /**
247
- * Seed the internal RNG used by the optimizer.
248
- * @param {bigint} seed
249
- */
250
- set_rng_seed(seed) {
251
- wasm.optimizerstate_set_rng_seed(this.__wbg_ptr, seed);
252
- }
253
- /**
254
- * Get the current epoch number.
255
- * @returns {number}
256
- */
257
- get current_epoch() {
258
- const ret = wasm.optimizerstate_current_epoch(this.__wbg_ptr);
259
- return ret >>> 0;
260
- }
261
- /**
262
- * Get the current embedding as a flat array.
263
- * @returns {Float64Array}
264
- */
265
- get head_embedding() {
266
- const ret = wasm.optimizerstate_head_embedding(this.__wbg_ptr);
267
- var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
268
- wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
269
- return v1;
270
- }
271
- /**
272
- * Get the length of the embedding buffer.
273
- * @returns {number}
274
- */
275
- head_embedding_len() {
276
- const ret = wasm.optimizerstate_head_embedding_len(this.__wbg_ptr);
277
- return ret >>> 0;
278
- }
279
- /**
280
- * Get a pointer to the embedding buffer (for zero-copy views).
281
- * @returns {number}
282
- */
283
- head_embedding_ptr() {
284
- const ret = wasm.optimizerstate_head_embedding_ptr(this.__wbg_ptr);
285
- return ret >>> 0;
286
- }
287
246
  /**
288
247
  * Create a new optimizer state with the given parameters.
289
248
  * @param {Uint32Array} head
@@ -319,6 +278,40 @@ class OptimizerState {
319
278
  OptimizerStateFinalization.register(this, this.__wbg_ptr, this);
320
279
  return this;
321
280
  }
281
+ /**
282
+ * Get the current embedding as a flat array.
283
+ * @returns {Float64Array}
284
+ */
285
+ get head_embedding() {
286
+ const ret = wasm.optimizerstate_head_embedding(this.__wbg_ptr);
287
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
288
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
289
+ return v1;
290
+ }
291
+ /**
292
+ * Get a pointer to the embedding buffer (for zero-copy views).
293
+ * @returns {number}
294
+ */
295
+ head_embedding_ptr() {
296
+ const ret = wasm.optimizerstate_head_embedding_ptr(this.__wbg_ptr);
297
+ return ret >>> 0;
298
+ }
299
+ /**
300
+ * Get the length of the embedding buffer.
301
+ * @returns {number}
302
+ */
303
+ head_embedding_len() {
304
+ const ret = wasm.optimizerstate_head_embedding_len(this.__wbg_ptr);
305
+ return ret >>> 0;
306
+ }
307
+ /**
308
+ * Get the current epoch number.
309
+ * @returns {number}
310
+ */
311
+ get current_epoch() {
312
+ const ret = wasm.optimizerstate_current_epoch(this.__wbg_ptr);
313
+ return ret >>> 0;
314
+ }
322
315
  /**
323
316
  * Get the total number of epochs.
324
317
  * @returns {number}
@@ -327,6 +320,13 @@ class OptimizerState {
327
320
  const ret = wasm.optimizerstate_n_epochs(this.__wbg_ptr);
328
321
  return ret >>> 0;
329
322
  }
323
+ /**
324
+ * Seed the internal RNG used by the optimizer.
325
+ * @param {bigint} seed
326
+ */
327
+ set_rng_seed(seed) {
328
+ wasm.optimizerstate_set_rng_seed(this.__wbg_ptr, seed);
329
+ }
330
330
  /**
331
331
  * Get the current RNG seed/state.
332
332
  * @returns {bigint}
@@ -363,53 +363,6 @@ class WasmSparseMatrix {
363
363
  const ptr = this.__destroy_into_raw();
364
364
  wasm.__wbg_wasmsparsematrix_free(ptr, 0);
365
365
  }
366
- /**
367
- * Get all values
368
- * @returns {Float64Array}
369
- */
370
- get_values() {
371
- const ret = wasm.wasmsparsematrix_get_values(this.__wbg_ptr);
372
- return ret;
373
- }
374
- /**
375
- * Apply a scalar operation to all values (map with scalar)
376
- * @param {string} operation
377
- * @param {number} scalar
378
- * @returns {WasmSparseMatrix}
379
- */
380
- map_scalar(operation, scalar) {
381
- const ptr0 = passStringToWasm0(operation, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
382
- const len0 = WASM_VECTOR_LEN;
383
- const ret = wasm.wasmsparsematrix_map_scalar(this.__wbg_ptr, ptr0, len0, scalar);
384
- if (ret[2]) {
385
- throw takeFromExternrefTable0(ret[1]);
386
- }
387
- return WasmSparseMatrix.__wrap(ret[0]);
388
- }
389
- /**
390
- * Get all entries as flat arrays [rows, cols, values] - ordered by row then col
391
- * @returns {Float64Array}
392
- */
393
- get_all_ordered() {
394
- const ret = wasm.wasmsparsematrix_get_all_ordered(this.__wbg_ptr);
395
- var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
396
- wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
397
- return v1;
398
- }
399
- /**
400
- * Get a value at the given row and column, with a default value if not present
401
- * @param {number} row
402
- * @param {number} col
403
- * @param {number} default_value
404
- * @returns {number}
405
- */
406
- get(row, col, default_value) {
407
- const ret = wasm.wasmsparsematrix_get(this.__wbg_ptr, row, col, default_value);
408
- if (ret[2]) {
409
- throw takeFromExternrefTable0(ret[1]);
410
- }
411
- return ret[0];
412
- }
413
366
  /**
414
367
  * Create a new sparse matrix from rows, cols, values, and dimensions.
415
368
  *
@@ -441,11 +394,19 @@ class WasmSparseMatrix {
441
394
  return this;
442
395
  }
443
396
  /**
444
- * Get number of non-zero entries
397
+ * Get the number of rows
445
398
  * @returns {number}
446
399
  */
447
- nnz() {
448
- const ret = wasm.wasmsparsematrix_nnz(this.__wbg_ptr);
400
+ get n_rows() {
401
+ const ret = wasm.wasmsparsematrix_n_rows(this.__wbg_ptr);
402
+ return ret >>> 0;
403
+ }
404
+ /**
405
+ * Get the number of columns
406
+ * @returns {number}
407
+ */
408
+ get n_cols() {
409
+ const ret = wasm.wasmsparsematrix_n_cols(this.__wbg_ptr);
449
410
  return ret >>> 0;
450
411
  }
451
412
  /**
@@ -461,28 +422,18 @@ class WasmSparseMatrix {
461
422
  }
462
423
  }
463
424
  /**
464
- * Get the number of columns
465
- * @returns {number}
466
- */
467
- get n_cols() {
468
- const ret = wasm.wasmsparsematrix_n_cols(this.__wbg_ptr);
469
- return ret >>> 0;
470
- }
471
- /**
472
- * Get the number of rows
425
+ * Get a value at the given row and column, with a default value if not present
426
+ * @param {number} row
427
+ * @param {number} col
428
+ * @param {number} default_value
473
429
  * @returns {number}
474
430
  */
475
- get n_rows() {
476
- const ret = wasm.wasmsparsematrix_n_rows(this.__wbg_ptr);
477
- return ret >>> 0;
478
- }
479
- /**
480
- * Get all column indices
481
- * @returns {Int32Array}
482
- */
483
- get_cols() {
484
- const ret = wasm.wasmsparsematrix_get_cols(this.__wbg_ptr);
485
- return ret;
431
+ get(row, col, default_value) {
432
+ const ret = wasm.wasmsparsematrix_get(this.__wbg_ptr, row, col, default_value);
433
+ if (ret[2]) {
434
+ throw takeFromExternrefTable0(ret[1]);
435
+ }
436
+ return ret[0];
486
437
  }
487
438
  /**
488
439
  * Get the dimensions as [nRows, nCols]
@@ -502,6 +453,40 @@ class WasmSparseMatrix {
502
453
  const ret = wasm.wasmsparsematrix_get_rows(this.__wbg_ptr);
503
454
  return ret;
504
455
  }
456
+ /**
457
+ * Get all column indices
458
+ * @returns {Int32Array}
459
+ */
460
+ get_cols() {
461
+ const ret = wasm.wasmsparsematrix_get_cols(this.__wbg_ptr);
462
+ return ret;
463
+ }
464
+ /**
465
+ * Get all values
466
+ * @returns {Float64Array}
467
+ */
468
+ get_values() {
469
+ const ret = wasm.wasmsparsematrix_get_values(this.__wbg_ptr);
470
+ return ret;
471
+ }
472
+ /**
473
+ * Get all entries as flat arrays [rows, cols, values] - ordered by row then col
474
+ * @returns {Float64Array}
475
+ */
476
+ get_all_ordered() {
477
+ const ret = wasm.wasmsparsematrix_get_all_ordered(this.__wbg_ptr);
478
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
479
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
480
+ return v1;
481
+ }
482
+ /**
483
+ * Get number of non-zero entries
484
+ * @returns {number}
485
+ */
486
+ nnz() {
487
+ const ret = wasm.wasmsparsematrix_nnz(this.__wbg_ptr);
488
+ return ret >>> 0;
489
+ }
505
490
  /**
506
491
  * Convert to dense 2D array (row-major, flattened)
507
492
  * @returns {Float64Array}
@@ -510,6 +495,21 @@ class WasmSparseMatrix {
510
495
  const ret = wasm.wasmsparsematrix_to_array(this.__wbg_ptr);
511
496
  return ret;
512
497
  }
498
+ /**
499
+ * Apply a scalar operation to all values (map with scalar)
500
+ * @param {string} operation
501
+ * @param {number} scalar
502
+ * @returns {WasmSparseMatrix}
503
+ */
504
+ map_scalar(operation, scalar) {
505
+ const ptr0 = passStringToWasm0(operation, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
506
+ const len0 = WASM_VECTOR_LEN;
507
+ const ret = wasm.wasmsparsematrix_map_scalar(this.__wbg_ptr, ptr0, len0, scalar);
508
+ if (ret[2]) {
509
+ throw takeFromExternrefTable0(ret[1]);
510
+ }
511
+ return WasmSparseMatrix.__wrap(ret[0]);
512
+ }
513
513
  }
514
514
  if (Symbol.dispose) WasmSparseMatrix.prototype[Symbol.dispose] = WasmSparseMatrix.prototype.free;
515
515
  exports.WasmSparseMatrix = WasmSparseMatrix;