@danielsimonjr/mathts-matrix 0.1.14 → 0.2.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/dist/index.d.ts CHANGED
@@ -1125,7 +1125,7 @@ declare function getCachedFeatures(): WasmFeatures | null;
1125
1125
  * WASM Matrix Backend (AssemblyScript)
1126
1126
  *
1127
1127
  * Implements MatrixBackend using the AssemblyScript-compiled WebAssembly
1128
- * module (`lib/wasm/mathts-as.wasm`, ~42 KB). Falls back to JSBackend when
1128
+ * module (`dist/wasm/mathts-as.wasm`, ~65 KB). Falls back to JSBackend when
1129
1129
  * the WASM module is unavailable or for small matrices.
1130
1130
  *
1131
1131
  * ABI:
@@ -1178,7 +1178,7 @@ declare function getCachedFeatures(): WasmFeatures | null;
1178
1178
  interface WASMBackendConfig {
1179
1179
  /** Minimum elements to use WASM (default: 100) */
1180
1180
  minElements?: number;
1181
- /** Path to WASM file (defaults to the AS artifact, `lib/wasm/mathts-as.wasm`) */
1181
+ /** Path to WASM file (defaults to the packaged AS artifact, `dist/wasm/mathts-as.wasm`) */
1182
1182
  wasmPath?: string;
1183
1183
  /** Enable SIMD code paths if the AS module exposes them (currently a no-op
1184
1184
  * — AS export surface does not include `simd*` ops; kept for API stability). */
@@ -1203,11 +1203,7 @@ declare class WASMBackend implements MatrixBackend {
1203
1203
  initialize(): Promise<void>;
1204
1204
  private doInitialize;
1205
1205
  /**
1206
- * Resolve the path to the AssemblyScript artifact (`lib/wasm/mathts-as.wasm`).
1207
- *
1208
- * On Windows, `URL.pathname` returns "/C:/foo/bar.wasm" which fs.readFile
1209
- * interprets as drive-relative ("C:\C:\foo\..."). `fileURLToPath` does the
1210
- * platform-correct conversion.
1206
+ * Resolve the path to the AssemblyScript artifact (`dist/wasm/mathts-as.wasm`).
1211
1207
  */
1212
1208
  private resolveAsWasmPath;
1213
1209
  /**
@@ -2478,18 +2474,17 @@ interface SVDOptions {
2478
2474
  maxIterations?: number;
2479
2475
  /** Convergence tolerance */
2480
2476
  tolerance?: number;
2481
- /** Whether to compute full U and V matrices */
2477
+ /**
2478
+ * Complete the thin factor to a square orthonormal basis (U → m×m for tall
2479
+ * inputs, V → n×n for wide ones), numpy `full_matrices=True` style, so the
2480
+ * rectangular-Σ reconstruction `A = U·Σ·Vᵀ` holds. Default `false` = thin
2481
+ * factors (the library's long-standing behavior; the option was previously
2482
+ * accepted but ignored — B-4).
2483
+ */
2482
2484
  fullMatrices?: boolean;
2483
2485
  /** Threshold for rank determination */
2484
2486
  rankTolerance?: number;
2485
2487
  }
2486
- /**
2487
- * Compute SVD of a matrix
2488
- *
2489
- * @param matrix - Input matrix (m x n)
2490
- * @param options - Computation options
2491
- * @returns SVD decomposition
2492
- */
2493
2488
  declare function svd(matrix: number[][] | Float64Array, options?: SVDOptions): SVDResult;
2494
2489
  /**
2495
2490
  * Compute only singular values (faster than full SVD)
package/dist/index.js CHANGED
@@ -2481,22 +2481,17 @@ var WASMBackend = class {
2481
2481
  }
2482
2482
  }
2483
2483
  /**
2484
- * Resolve the path to the AssemblyScript artifact (`lib/wasm/mathts-as.wasm`).
2485
- *
2486
- * On Windows, `URL.pathname` returns "/C:/foo/bar.wasm" which fs.readFile
2487
- * interprets as drive-relative ("C:\C:\foo\..."). `fileURLToPath` does the
2488
- * platform-correct conversion.
2484
+ * Resolve the path to the AssemblyScript artifact (`dist/wasm/mathts-as.wasm`).
2489
2485
  */
2490
2486
  async resolveAsWasmPath() {
2491
2487
  const isNode = typeof process !== "undefined" && process.versions?.node !== void 0;
2488
+ const { resolvePackagedWasm, defaultWasmLocation } = await import("./resolve-VJX3YTS6.js");
2492
2489
  if (isNode) {
2493
- const { resolvePackagedWasm } = await import("./resolve-JRHDDNVQ.js");
2494
2490
  const found = await resolvePackagedWasm(import.meta.url, "mathts-as.wasm");
2495
2491
  if (found) return found;
2496
- const { fileURLToPath } = await import("url");
2497
- return fileURLToPath(new URL(`../../../lib/wasm/mathts-as.wasm`, import.meta.url));
2492
+ return defaultWasmLocation(import.meta.url, "mathts-as.wasm");
2498
2493
  }
2499
- return new URL(`../../../lib/wasm/mathts-as.wasm`, import.meta.url).href;
2494
+ return defaultWasmLocation(import.meta.url, "mathts-as.wasm", { browser: true });
2500
2495
  }
2501
2496
  /**
2502
2497
  * Compile + instantiate the AssemblyScript WASM artifact. Each
@@ -5483,27 +5478,22 @@ var WasmLoader = class _WasmLoader {
5483
5478
  * (`mathts-as.wasm`); the legacy second toolchain was removed in the
5484
5479
  * WASM-backend migration (complete 2026-06-26).
5485
5480
  *
5486
- * The path is resolved relative to this source file's location so it is
5487
- * CWD-independent. This file lives at:
5488
- * <repo-root>/matrix/src/backends/WasmLoader.ts
5489
- * so the repo root is three directories up, and the artifact is at
5490
- * <repo-root>/lib/wasm/mathts-as.wasm
5491
- *
5492
- * Both branches use `new URL(relative, import.meta.url)` to resolve a
5493
- * file: URL. In Node we convert via `fileURLToPath` (which correctly
5494
- * strips the leading slash on Windows so the drive letter is not
5495
- * doubled); in the browser we keep the full `.href` for fetch().
5481
+ * Resolution is package-relative and CWD-independent: the packaged artifact
5482
+ * (`dist/wasm/`) is preferred via `resolvePackagedWasm`; when absent, the
5483
+ * canonical expected location is returned so the missing-binary warning is
5484
+ * actionable (see `defaultWasmLocation` in wasm/resolve.ts B-3).
5496
5485
  */
5497
5486
  async getDefaultWasmPath() {
5498
5487
  const wasmFile = "mathts-as.wasm";
5499
5488
  if (this.isNode) {
5500
- const { resolvePackagedWasm } = await import("./resolve-JRHDDNVQ.js");
5489
+ const { resolvePackagedWasm } = await import("./resolve-VJX3YTS6.js");
5501
5490
  const found = await resolvePackagedWasm(import.meta.url, wasmFile);
5502
5491
  if (found) return found;
5503
- const { fileURLToPath } = await import("url");
5504
- return fileURLToPath(new URL(`../../../lib/wasm/${wasmFile}`, import.meta.url));
5492
+ const { defaultWasmLocation: defaultWasmLocation2 } = await import("./resolve-VJX3YTS6.js");
5493
+ return defaultWasmLocation2(import.meta.url, wasmFile);
5505
5494
  }
5506
- return new URL(`../../../lib/wasm/${wasmFile}`, import.meta.url).href;
5495
+ const { defaultWasmLocation } = await import("./resolve-VJX3YTS6.js");
5496
+ return defaultWasmLocation(import.meta.url, wasmFile, { browser: true });
5507
5497
  }
5508
5498
  async loadNodeWasm(path, totalStart) {
5509
5499
  const fs = await import("fs");
@@ -6622,11 +6612,32 @@ function jacobiSVD(A) {
6622
6612
  }
6623
6613
  return { d, U, V };
6624
6614
  }
6615
+ function completeOrthonormalBasis(cols, m) {
6616
+ const k = cols[0]?.length ?? 0;
6617
+ const basis = Array.from({ length: k }, (_, j) => cols.map((row2) => row2[j]));
6618
+ for (let cand = 0; cand < m && basis.length < m; cand++) {
6619
+ const v = Array.from({ length: m }, (_, i) => i === cand ? 1 : 0);
6620
+ for (let pass = 0; pass < 2; pass++) {
6621
+ for (const b of basis) {
6622
+ let dot = 0;
6623
+ for (let i = 0; i < m; i++) dot += v[i] * b[i];
6624
+ for (let i = 0; i < m; i++) v[i] -= dot * b[i];
6625
+ }
6626
+ }
6627
+ let norm4 = 0;
6628
+ for (let i = 0; i < m; i++) norm4 += v[i] * v[i];
6629
+ norm4 = Math.sqrt(norm4);
6630
+ if (norm4 > 0.1) {
6631
+ basis.push(v.map((x) => x / norm4));
6632
+ }
6633
+ }
6634
+ return Array.from({ length: m }, (_, i) => basis.map((b) => b[i]));
6635
+ }
6625
6636
  function svd(matrix2, options = {}) {
6626
6637
  const {
6627
6638
  maxIterations = DEFAULT_MAX_ITERATIONS,
6628
6639
  tolerance = DEFAULT_TOLERANCE,
6629
- fullMatrices: _fullMatrices = true,
6640
+ fullMatrices = false,
6630
6641
  rankTolerance = 1e-10
6631
6642
  } = options;
6632
6643
  let A;
@@ -6727,12 +6738,12 @@ function svd(matrix2, options = {}) {
6727
6738
  return {
6728
6739
  U: sortedV,
6729
6740
  S: sortedS,
6730
- V: sortedU,
6741
+ V: fullMatrices && sortedU.length > (sortedU[0]?.length ?? 0) ? completeOrthonormalBasis(sortedU, sortedU.length) : sortedU,
6731
6742
  rank
6732
6743
  };
6733
6744
  }
6734
6745
  return {
6735
- U: sortedU,
6746
+ U: fullMatrices && sortedU.length > (sortedU[0]?.length ?? 0) ? completeOrthonormalBasis(sortedU, sortedU.length) : sortedU,
6736
6747
  S: sortedS,
6737
6748
  V: sortedV,
6738
6749
  rank
@@ -19,6 +19,25 @@ async function resolvePackagedWasm(metaUrl, wasmFile) {
19
19
  }
20
20
  return null;
21
21
  }
22
+ async function defaultWasmLocation(metaUrl, wasmFile, opts) {
23
+ if (opts?.browser) {
24
+ return new URL(`./wasm/${wasmFile}`, metaUrl).href;
25
+ }
26
+ const { fileURLToPath } = await import("url");
27
+ const { dirname, join } = await import("path");
28
+ const { existsSync } = await import("fs");
29
+ let dir = dirname(fileURLToPath(metaUrl));
30
+ for (let depth = 0; depth < 8; depth++) {
31
+ if (existsSync(join(dir, "package.json"))) {
32
+ return join(dir, "dist", "wasm", wasmFile);
33
+ }
34
+ const parent = dirname(dir);
35
+ if (parent === dir) break;
36
+ dir = parent;
37
+ }
38
+ return join(dirname(fileURLToPath(metaUrl)), "wasm", wasmFile);
39
+ }
22
40
  export {
41
+ defaultWasmLocation,
23
42
  resolvePackagedWasm
24
43
  };
Binary file
@@ -1,3 +1,3 @@
1
1
  {
2
- "mathts-as.wasm": "sha384-eSck1dw9Rtu8oUAQ/0GMpC1L4bhAPNVS72581QGAyd1xDlRvonQT/XA2RZjpxghB"
2
+ "mathts-as.wasm": "sha384-q4RGhtVhsLmeCfG5lYpL70f51laygEpfcKGuxKWFnoC9iSXZPXMUEYE9V8W8gYZu"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielsimonjr/mathts-matrix",
3
- "version": "0.1.14",
3
+ "version": "0.2.1",
4
4
  "description": "Matrix operations for MathTS with WASM/WebGPU backend support",
5
5
  "author": "Daniel Simon Jr.",
6
6
  "license": "MIT",
@@ -32,8 +32,8 @@
32
32
  "build:prod": "tsup src/index.ts --format esm --dts --clean --minify --treeshake && node scripts/copy-wasm.mjs"
33
33
  },
34
34
  "dependencies": {
35
- "@danielsimonjr/mathts-core": "^0.4.0",
36
- "@danielsimonjr/mathts-parallel": "^0.3.0"
35
+ "@danielsimonjr/mathts-core": "^0.5.0",
36
+ "@danielsimonjr/mathts-parallel": "^0.3.3"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^25.5.2",