@danielsimonjr/mathts-matrix 0.1.7 → 0.1.10

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.js CHANGED
@@ -1,8 +1,21 @@
1
1
  import {
2
+ applyHouseholderLeft,
3
+ applyHouseholderRight,
4
+ cloneMatrix,
2
5
  eig,
3
6
  eigvals,
4
- powerIteration
5
- } from "./chunk-VCPLE6ED.js";
7
+ eye,
8
+ householder,
9
+ isSymmetric,
10
+ matAdd,
11
+ matMul,
12
+ matScale,
13
+ matSub,
14
+ norm1,
15
+ normInf,
16
+ powerIteration,
17
+ transpose
18
+ } from "./chunk-HT4ZF3LN.js";
6
19
  import {
7
20
  __esm,
8
21
  __export,
@@ -183,7 +196,7 @@ function scale(a, scalar) {
183
196
  for (let i = 0; i < ad.length; i++) result[i] = ad[i] * scalar;
184
197
  return result;
185
198
  }
186
- function transpose(a) {
199
+ function transpose2(a) {
187
200
  const ad = flat(a);
188
201
  const rows = a.rows;
189
202
  const cols = a.cols;
@@ -1288,7 +1301,7 @@ var init_DenseMatrix = __esm({
1288
1301
  * Matrix transpose
1289
1302
  */
1290
1303
  transpose() {
1291
- return new _DenseMatrix(this.cols, this.rows, transpose(this));
1304
+ return new _DenseMatrix(this.cols, this.rows, transpose2(this));
1292
1305
  }
1293
1306
  /**
1294
1307
  * Negate all elements
@@ -2474,7 +2487,7 @@ var WASMBackend = class {
2474
2487
  const loaded = await this.loadAsModule(path);
2475
2488
  if (typeof loaded.__new !== "function" || typeof loaded.matrix_multiply !== "function") {
2476
2489
  console.warn(
2477
- "WASMBackend: loaded module is not the AssemblyScript artifact; falling back to JS. Pass an explicit wasmPath or use RustWASMBackend for the Rust artifact."
2490
+ "WASMBackend: loaded module is not the AssemblyScript artifact; falling back to JS. Pass an explicit wasmPath (the AS binary, mathts-as.wasm)."
2478
2491
  );
2479
2492
  this.wasmModule = null;
2480
2493
  return;
@@ -2506,7 +2519,7 @@ var WASMBackend = class {
2506
2519
  /**
2507
2520
  * Compile + instantiate the AssemblyScript WASM artifact. Each
2508
2521
  * WASMBackend instance owns its own instance — this is intentional so
2509
- * tests and the Rust backend can coexist in the same process.
2522
+ * tests and multiple backend instances can coexist in the same process.
2510
2523
  */
2511
2524
  async loadAsModule(path) {
2512
2525
  const imports = {
@@ -2754,7 +2767,7 @@ var WASMBackend = class {
2754
2767
  // =========================================================================
2755
2768
  // LU / QR / Cholesky / Inverse / Determinant
2756
2769
  // -------------------------------------------------------------------------
2757
- // AssemblyScript now exports these alongside the Rust binary (see
2770
+ // AssemblyScript exports these (see
2758
2771
  // assembly/src/algebra/decomposition.ts). Each method dispatches to
2759
2772
  // the AS export when the loaded module exposes it; otherwise it falls
2760
2773
  // back to the in-process JS implementation that previously handled
@@ -4990,620 +5003,8 @@ function createGPUMatrixBackend(config) {
4990
5003
  return new GPUMatrixBackend(config);
4991
5004
  }
4992
5005
 
4993
- // src/backends/RustWASMBackend.ts
4994
- init_DenseMatrix();
4995
-
4996
- // src/backends/RustWasmLoader.ts
4997
- var BumpAllocator = class {
4998
- /** Next free byte offset in WASM memory */
4999
- offset;
5000
- /** Minimum offset (base of allocatable region) */
5001
- base;
5002
- constructor(baseOffset) {
5003
- this.base = baseOffset;
5004
- this.offset = baseOffset;
5005
- }
5006
- /**
5007
- * Allocate `byteLength` bytes, aligned to 8-byte boundary.
5008
- * Returns the byte offset (pointer) into WASM memory.
5009
- */
5010
- alloc(byteLength, memory) {
5011
- const aligned = this.offset + 7 & ~7;
5012
- const end = aligned + byteLength;
5013
- const currentBytes = memory.buffer.byteLength;
5014
- if (end > currentBytes) {
5015
- const pagesNeeded = Math.ceil((end - currentBytes) / 65536);
5016
- memory.grow(pagesNeeded);
5017
- }
5018
- this.offset = end;
5019
- return aligned;
5020
- }
5021
- /**
5022
- * Reset the allocator, reclaiming all temporary memory.
5023
- * Call between independent operations.
5024
- */
5025
- reset() {
5026
- this.offset = this.base;
5027
- }
5028
- /** Current high-water mark */
5029
- get highWaterMark() {
5030
- return this.offset;
5031
- }
5032
- };
5033
- var RustWasmLoader = class _RustWasmLoader {
5034
- static instance = null;
5035
- wasmInstance = null;
5036
- wasmMemory = null;
5037
- allocator = null;
5038
- _isLoaded = false;
5039
- loading = null;
5040
- lastMetrics = null;
5041
- constructor() {
5042
- }
5043
- static getInstance() {
5044
- if (!_RustWasmLoader.instance) {
5045
- _RustWasmLoader.instance = new _RustWasmLoader();
5046
- }
5047
- return _RustWasmLoader.instance;
5048
- }
5049
- get isLoaded() {
5050
- return this._isLoaded;
5051
- }
5052
- /**
5053
- * Load the Rust WASM module.
5054
- * Returns true on success, false if the binary is not available.
5055
- * Safe to call multiple times (idempotent).
5056
- */
5057
- async load(wasmPath) {
5058
- if (this._isLoaded) return true;
5059
- if (this.loading) return this.loading;
5060
- this.loading = this.doLoad(wasmPath);
5061
- const result = await this.loading;
5062
- this.loading = null;
5063
- return result;
5064
- }
5065
- async doLoad(wasmPath) {
5066
- const totalStart = performance.now();
5067
- try {
5068
- const path = wasmPath || await this.findWasmPath();
5069
- const isNode = typeof process !== "undefined" && process.versions?.node !== void 0;
5070
- const { loadWasmManifest, verifyWasmIntegrity } = await import("./integrity-X3CLNVGW.js");
5071
- let binarySize = 0;
5072
- if (isNode) {
5073
- const loadStart = performance.now();
5074
- const fs = await import("fs");
5075
- const buffer = fs.readFileSync(path);
5076
- binarySize = buffer.byteLength;
5077
- const loadEnd = performance.now();
5078
- await verifyWasmIntegrity(buffer, path);
5079
- const compileStart = performance.now();
5080
- const module = await WebAssembly.compile(buffer);
5081
- const compileEnd = performance.now();
5082
- const instStart = performance.now();
5083
- this.wasmInstance = await WebAssembly.instantiate(module, this.getImports());
5084
- const instEnd = performance.now();
5085
- this.lastMetrics = {
5086
- loadMs: loadEnd - loadStart,
5087
- compileMs: compileEnd - compileStart,
5088
- instantiateMs: instEnd - instStart,
5089
- totalMs: performance.now() - totalStart,
5090
- binarySize
5091
- };
5092
- } else {
5093
- const manifest = await loadWasmManifest(path);
5094
- const instStart = performance.now();
5095
- if (!manifest && typeof WebAssembly.instantiateStreaming === "function") {
5096
- const result = await WebAssembly.instantiateStreaming(fetch(path), this.getImports());
5097
- this.wasmInstance = result.instance;
5098
- } else {
5099
- const response = await fetch(path);
5100
- const buffer = await response.arrayBuffer();
5101
- binarySize = buffer.byteLength;
5102
- await verifyWasmIntegrity(buffer, path, { manifest });
5103
- const module = await WebAssembly.compile(buffer);
5104
- this.wasmInstance = await WebAssembly.instantiate(module, this.getImports());
5105
- }
5106
- this.lastMetrics = {
5107
- loadMs: 0,
5108
- compileMs: 0,
5109
- instantiateMs: performance.now() - instStart,
5110
- totalMs: performance.now() - totalStart,
5111
- binarySize
5112
- };
5113
- }
5114
- this.wasmMemory = this.wasmInstance.exports.memory;
5115
- const heapBaseGlobal = this.wasmInstance.exports.__heap_base;
5116
- const heapBase = heapBaseGlobal && typeof heapBaseGlobal.value === "number" ? heapBaseGlobal.value : 65536;
5117
- this.allocator = new BumpAllocator(heapBase);
5118
- this._isLoaded = true;
5119
- return true;
5120
- } catch (e) {
5121
- console.warn("Rust WASM not available, using JS fallback:", e.message);
5122
- return false;
5123
- }
5124
- }
5125
- /**
5126
- * Resolve the WASM binary path.
5127
- * Checks several locations relative to the project root.
5128
- */
5129
- async findWasmPath() {
5130
- const isNode = typeof process !== "undefined" && process.versions?.node !== void 0;
5131
- const resolvedUrl = new URL(`../../../lib/wasm/mathts.wasm`, import.meta.url);
5132
- if (isNode) {
5133
- const { fileURLToPath } = await import("url");
5134
- return fileURLToPath(resolvedUrl);
5135
- }
5136
- return resolvedUrl.href;
5137
- }
5138
- getImports() {
5139
- return {
5140
- env: {
5141
- abort: () => {
5142
- throw new Error("Rust WASM abort");
5143
- }
5144
- }
5145
- };
5146
- }
5147
- /**
5148
- * Get the typed exports from the WASM instance.
5149
- */
5150
- getExports() {
5151
- if (!this.wasmInstance) return null;
5152
- return this.wasmInstance.exports;
5153
- }
5154
- /**
5155
- * Get WASM linear memory.
5156
- */
5157
- getMemory() {
5158
- return this.wasmMemory;
5159
- }
5160
- /**
5161
- * Get loading metrics.
5162
- */
5163
- getLoadingMetrics() {
5164
- return this.lastMetrics;
5165
- }
5166
- // =========================================================================
5167
- // Memory Management (Bump Allocator)
5168
- // =========================================================================
5169
- /**
5170
- * Write a Float64Array into WASM memory and return the pointer.
5171
- */
5172
- writeF64(data) {
5173
- if (!this.wasmMemory || !this.allocator) {
5174
- throw new Error("Rust WASM not loaded");
5175
- }
5176
- const byteLength = (Array.isArray(data) ? data.length : data.length) * 8;
5177
- const ptr = this.allocator.alloc(byteLength, this.wasmMemory);
5178
- const view = new Float64Array(
5179
- this.wasmMemory.buffer,
5180
- ptr,
5181
- Array.isArray(data) ? data.length : data.length
5182
- );
5183
- view.set(data);
5184
- return ptr;
5185
- }
5186
- /**
5187
- * Allocate an empty Float64Array in WASM memory (for output buffers).
5188
- * Returns the pointer.
5189
- */
5190
- allocF64(length) {
5191
- if (!this.wasmMemory || !this.allocator) {
5192
- throw new Error("Rust WASM not loaded");
5193
- }
5194
- return this.allocator.alloc(length * 8, this.wasmMemory);
5195
- }
5196
- /**
5197
- * Write an Int32Array into WASM memory and return the pointer.
5198
- */
5199
- writeI32(data) {
5200
- if (!this.wasmMemory || !this.allocator) {
5201
- throw new Error("Rust WASM not loaded");
5202
- }
5203
- const length = Array.isArray(data) ? data.length : data.length;
5204
- const byteLength = length * 4;
5205
- const ptr = this.allocator.alloc(byteLength, this.wasmMemory);
5206
- const view = new Int32Array(this.wasmMemory.buffer, ptr, length);
5207
- view.set(data);
5208
- return ptr;
5209
- }
5210
- /**
5211
- * Allocate an empty Int32Array in WASM memory.
5212
- */
5213
- allocI32(length) {
5214
- if (!this.wasmMemory || !this.allocator) {
5215
- throw new Error("Rust WASM not loaded");
5216
- }
5217
- return this.allocator.alloc(length * 4, this.wasmMemory);
5218
- }
5219
- /**
5220
- * Read a Float64Array from WASM memory.
5221
- * Note: the returned array is a *copy* (safe after memory reset).
5222
- */
5223
- readF64(ptr, length) {
5224
- if (!this.wasmMemory) {
5225
- throw new Error("Rust WASM not loaded");
5226
- }
5227
- const view = new Float64Array(this.wasmMemory.buffer, ptr, length);
5228
- return new Float64Array(view);
5229
- }
5230
- /**
5231
- * Read an Int32Array from WASM memory.
5232
- */
5233
- readI32(ptr, length) {
5234
- if (!this.wasmMemory) {
5235
- throw new Error("Rust WASM not loaded");
5236
- }
5237
- const view = new Int32Array(this.wasmMemory.buffer, ptr, length);
5238
- return new Int32Array(view);
5239
- }
5240
- /**
5241
- * Reset the bump allocator. Call between independent operations
5242
- * to reclaim temporary memory.
5243
- */
5244
- resetAllocator() {
5245
- this.allocator?.reset();
5246
- }
5247
- /**
5248
- * Reset the loader (for testing).
5249
- */
5250
- reset() {
5251
- this.wasmInstance = null;
5252
- this.wasmMemory = null;
5253
- this.allocator = null;
5254
- this._isLoaded = false;
5255
- this.loading = null;
5256
- this.lastMetrics = null;
5257
- }
5258
- /**
5259
- * Reset the singleton (for testing).
5260
- */
5261
- static resetInstance() {
5262
- if (_RustWasmLoader.instance) {
5263
- _RustWasmLoader.instance.reset();
5264
- }
5265
- _RustWasmLoader.instance = null;
5266
- }
5267
- };
5268
- var rustWasmLoader = RustWasmLoader.getInstance();
5269
- async function initRustWasm(wasmPath) {
5270
- return rustWasmLoader.load(wasmPath);
5271
- }
5272
-
5273
- // src/backends/RustWASMBackend.ts
5274
- var DEFAULT_CONFIG3 = {
5275
- minElements: 1e3,
5276
- wasmPath: ""
5277
- };
5278
- var RustWASMBackend = class {
5279
- /**
5280
- * Backend type identifier.
5281
- * Uses 'rust-wasm' to distinguish from the AssemblyScript WASMBackend.
5282
- */
5283
- type = "rust-wasm";
5284
- config;
5285
- exports = null;
5286
- initPromise = null;
5287
- constructor(config = {}) {
5288
- this.config = { ...DEFAULT_CONFIG3, ...config };
5289
- }
5290
- /**
5291
- * Check if WebAssembly is available in the current environment.
5292
- */
5293
- isAvailable() {
5294
- return typeof WebAssembly !== "undefined";
5295
- }
5296
- /**
5297
- * Initialize the Rust WASM backend.
5298
- * Loads the WASM binary and caches the exports.
5299
- */
5300
- async initialize() {
5301
- if (this.exports) return;
5302
- if (this.initPromise) return this.initPromise;
5303
- this.initPromise = this.doInitialize();
5304
- return this.initPromise;
5305
- }
5306
- async doInitialize() {
5307
- if (!this.isAvailable()) {
5308
- throw new Error("WebAssembly is not available in this environment");
5309
- }
5310
- const loaded = await rustWasmLoader.load(this.config.wasmPath || void 0);
5311
- if (loaded) {
5312
- this.exports = rustWasmLoader.getExports();
5313
- } else {
5314
- console.warn("Rust WASM binary not available, RustWASMBackend will use JS fallback");
5315
- }
5316
- }
5317
- /**
5318
- * Whether to use Rust WASM for this operation size.
5319
- */
5320
- shouldUseRustWasm(elementCount) {
5321
- return this.exports !== null && elementCount >= this.config.minElements;
5322
- }
5323
- /**
5324
- * Whether the Rust WASM module is loaded and ready.
5325
- */
5326
- get isRustLoaded() {
5327
- return this.exports !== null;
5328
- }
5329
- // =========================================================================
5330
- // Element-wise Operations
5331
- // =========================================================================
5332
- add(a, b) {
5333
- const n = a.rows * a.cols;
5334
- if (!this.shouldUseRustWasm(n)) return jsBackend.add(a, b);
5335
- try {
5336
- rustWasmLoader.resetAllocator();
5337
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5338
- const bPtr = rustWasmLoader.writeF64(b.toFloat64Array());
5339
- const outPtr = rustWasmLoader.allocF64(n);
5340
- this.exports.simdAddF64(aPtr, bPtr, outPtr, n);
5341
- const result = rustWasmLoader.readF64(outPtr, n);
5342
- return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
5343
- } catch {
5344
- return jsBackend.add(a, b);
5345
- }
5346
- }
5347
- subtract(a, b) {
5348
- const n = a.rows * a.cols;
5349
- if (!this.shouldUseRustWasm(n)) return jsBackend.subtract(a, b);
5350
- try {
5351
- rustWasmLoader.resetAllocator();
5352
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5353
- const bPtr = rustWasmLoader.writeF64(b.toFloat64Array());
5354
- const outPtr = rustWasmLoader.allocF64(n);
5355
- this.exports.simdSubF64(aPtr, bPtr, outPtr, n);
5356
- const result = rustWasmLoader.readF64(outPtr, n);
5357
- return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
5358
- } catch {
5359
- return jsBackend.subtract(a, b);
5360
- }
5361
- }
5362
- multiplyElementwise(a, b) {
5363
- const n = a.rows * a.cols;
5364
- if (!this.shouldUseRustWasm(n)) return jsBackend.multiplyElementwise(a, b);
5365
- try {
5366
- rustWasmLoader.resetAllocator();
5367
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5368
- const bPtr = rustWasmLoader.writeF64(b.toFloat64Array());
5369
- const outPtr = rustWasmLoader.allocF64(n);
5370
- this.exports.simdMulF64(aPtr, bPtr, outPtr, n);
5371
- const result = rustWasmLoader.readF64(outPtr, n);
5372
- return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
5373
- } catch {
5374
- return jsBackend.multiplyElementwise(a, b);
5375
- }
5376
- }
5377
- divideElementwise(a, b) {
5378
- return jsBackend.divideElementwise(a, b);
5379
- }
5380
- scale(a, scalar) {
5381
- const n = a.rows * a.cols;
5382
- if (!this.shouldUseRustWasm(n)) return jsBackend.scale(a, scalar);
5383
- try {
5384
- rustWasmLoader.resetAllocator();
5385
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5386
- const outPtr = rustWasmLoader.allocF64(n);
5387
- this.exports.simdScaleF64(aPtr, scalar, outPtr, n);
5388
- const result = rustWasmLoader.readF64(outPtr, n);
5389
- return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
5390
- } catch {
5391
- return jsBackend.scale(a, scalar);
5392
- }
5393
- }
5394
- abs(a) {
5395
- const n = a.rows * a.cols;
5396
- if (!this.shouldUseRustWasm(n)) return jsBackend.abs(a);
5397
- try {
5398
- rustWasmLoader.resetAllocator();
5399
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5400
- const outPtr = rustWasmLoader.allocF64(n);
5401
- this.exports.simdAbsF64(aPtr, outPtr, n);
5402
- const result = rustWasmLoader.readF64(outPtr, n);
5403
- return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
5404
- } catch {
5405
- return jsBackend.abs(a);
5406
- }
5407
- }
5408
- negate(a) {
5409
- const n = a.rows * a.cols;
5410
- if (!this.shouldUseRustWasm(n)) return jsBackend.negate(a);
5411
- try {
5412
- rustWasmLoader.resetAllocator();
5413
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5414
- const outPtr = rustWasmLoader.allocF64(n);
5415
- this.exports.simdScaleF64(aPtr, -1, outPtr, n);
5416
- const result = rustWasmLoader.readF64(outPtr, n);
5417
- return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
5418
- } catch {
5419
- return jsBackend.negate(a);
5420
- }
5421
- }
5422
- // =========================================================================
5423
- // Matrix Operations
5424
- // =========================================================================
5425
- multiply(a, b) {
5426
- const elementCount = a.rows * a.cols + b.rows * b.cols;
5427
- if (!this.shouldUseRustWasm(elementCount)) return jsBackend.multiply(a, b);
5428
- try {
5429
- rustWasmLoader.resetAllocator();
5430
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5431
- const bPtr = rustWasmLoader.writeF64(b.toFloat64Array());
5432
- const resultSize = a.rows * b.cols;
5433
- const outPtr = rustWasmLoader.allocF64(resultSize);
5434
- this.exports.multiplyDenseSIMD(aPtr, a.rows, a.cols, bPtr, b.rows, b.cols, outPtr);
5435
- const result = rustWasmLoader.readF64(outPtr, resultSize);
5436
- return DenseMatrix.fromFlat(a.rows, b.cols, Array.from(result));
5437
- } catch {
5438
- return jsBackend.multiply(a, b);
5439
- }
5440
- }
5441
- transpose(a) {
5442
- const n = a.rows * a.cols;
5443
- if (!this.shouldUseRustWasm(n)) return jsBackend.transpose(a);
5444
- try {
5445
- rustWasmLoader.resetAllocator();
5446
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5447
- const outPtr = rustWasmLoader.allocF64(n);
5448
- this.exports.transpose(aPtr, a.rows, a.cols, outPtr);
5449
- const result = rustWasmLoader.readF64(outPtr, n);
5450
- return DenseMatrix.fromFlat(a.cols, a.rows, Array.from(result));
5451
- } catch {
5452
- return jsBackend.transpose(a);
5453
- }
5454
- }
5455
- // =========================================================================
5456
- // Reduction Operations
5457
- // =========================================================================
5458
- sum(a) {
5459
- const n = a.rows * a.cols;
5460
- if (!this.shouldUseRustWasm(n)) return jsBackend.sum(a);
5461
- try {
5462
- rustWasmLoader.resetAllocator();
5463
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5464
- return this.exports.simdSumF64(aPtr, n);
5465
- } catch {
5466
- return jsBackend.sum(a);
5467
- }
5468
- }
5469
- sumAxis(a, axis) {
5470
- return jsBackend.sumAxis(a, axis);
5471
- }
5472
- norm(a) {
5473
- const n = a.rows * a.cols;
5474
- if (!this.shouldUseRustWasm(n)) return jsBackend.norm(a);
5475
- try {
5476
- rustWasmLoader.resetAllocator();
5477
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5478
- return this.exports.simdNormF64(aPtr, n);
5479
- } catch {
5480
- return jsBackend.norm(a);
5481
- }
5482
- }
5483
- dot(a, b) {
5484
- const n = a.rows * a.cols;
5485
- if (!this.shouldUseRustWasm(n)) return jsBackend.dot(a, b);
5486
- try {
5487
- rustWasmLoader.resetAllocator();
5488
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5489
- const bPtr = rustWasmLoader.writeF64(b.toFloat64Array());
5490
- return this.exports.simdDotF64(aPtr, bPtr, n);
5491
- } catch {
5492
- return jsBackend.dot(a, b);
5493
- }
5494
- }
5495
- // =========================================================================
5496
- // Heavy Operations (unique to Rust backend)
5497
- // =========================================================================
5498
- /**
5499
- * LU Decomposition using Rust WASM.
5500
- */
5501
- async luDecomposition(a) {
5502
- const n = a.rows;
5503
- if (n !== a.cols) {
5504
- throw new Error("LU decomposition requires a square matrix");
5505
- }
5506
- if (!this.exports) {
5507
- throw new Error("Rust WASM not loaded");
5508
- }
5509
- rustWasmLoader.resetAllocator();
5510
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5511
- const permPtr = rustWasmLoader.allocI32(n);
5512
- const success = this.exports.luDecomposition(aPtr, n, permPtr);
5513
- return {
5514
- lu: DenseMatrix.fromFlat(n, n, Array.from(rustWasmLoader.readF64(aPtr, n * n))),
5515
- perm: rustWasmLoader.readI32(permPtr, n),
5516
- singular: success === 0
5517
- };
5518
- }
5519
- /**
5520
- * Eigenvalue decomposition for symmetric matrices using Rust WASM.
5521
- */
5522
- async eigsSymmetric(a, precision = 1e-12) {
5523
- const n = a.rows;
5524
- if (n !== a.cols) {
5525
- throw new Error("Eigendecomposition requires a square matrix");
5526
- }
5527
- if (!this.exports) {
5528
- throw new Error("Rust WASM not loaded");
5529
- }
5530
- rustWasmLoader.resetAllocator();
5531
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5532
- const eigvalsPtr = rustWasmLoader.allocF64(n);
5533
- const eigvecsPtr = rustWasmLoader.allocF64(n * n);
5534
- const workPtr = rustWasmLoader.allocF64(n * n);
5535
- const iterations = this.exports.eigsSymmetric(
5536
- aPtr,
5537
- n,
5538
- precision,
5539
- eigvalsPtr,
5540
- eigvecsPtr,
5541
- workPtr
5542
- );
5543
- return {
5544
- eigenvalues: rustWasmLoader.readF64(eigvalsPtr, n),
5545
- eigenvectors: DenseMatrix.fromFlat(
5546
- n,
5547
- n,
5548
- Array.from(rustWasmLoader.readF64(eigvecsPtr, n * n))
5549
- ),
5550
- iterations
5551
- };
5552
- }
5553
- /**
5554
- * Matrix inversion using Rust WASM.
5555
- */
5556
- async inverse(a) {
5557
- const n = a.rows;
5558
- if (n !== a.cols) {
5559
- throw new Error("Matrix inversion requires a square matrix");
5560
- }
5561
- if (!this.exports) {
5562
- throw new Error("Rust WASM not loaded");
5563
- }
5564
- rustWasmLoader.resetAllocator();
5565
- const aPtr = rustWasmLoader.writeF64(a.toFloat64Array());
5566
- const resultPtr = rustWasmLoader.allocF64(n * n);
5567
- const workPtr = rustWasmLoader.allocF64(n * n);
5568
- const success = this.exports.laInv(aPtr, n, resultPtr, workPtr);
5569
- return {
5570
- inverse: DenseMatrix.fromFlat(n, n, Array.from(rustWasmLoader.readF64(resultPtr, n * n))),
5571
- singular: success === 0
5572
- };
5573
- }
5574
- /**
5575
- * FFT using Rust WASM (rustfft).
5576
- * Data is interleaved complex: [re0, im0, re1, im1, ...].
5577
- */
5578
- fft(data, n, inverse = false) {
5579
- if (!this.exports) {
5580
- throw new Error("Rust WASM not loaded");
5581
- }
5582
- rustWasmLoader.resetAllocator();
5583
- const dataPtr = rustWasmLoader.writeF64(data);
5584
- this.exports.fft(dataPtr, n, inverse ? 1 : 0);
5585
- return rustWasmLoader.readF64(dataPtr, n * 2);
5586
- }
5587
- /**
5588
- * Update configuration.
5589
- */
5590
- updateConfig(config) {
5591
- this.config = { ...this.config, ...config };
5592
- }
5593
- /**
5594
- * Get current configuration.
5595
- */
5596
- getConfig() {
5597
- return { ...this.config };
5598
- }
5599
- };
5600
- var rustWasmBackend = new RustWASMBackend();
5601
- function createRustWASMBackend(config) {
5602
- return new RustWASMBackend(config);
5603
- }
5604
-
5605
5006
  // src/config.ts
5606
- var DEFAULT_CONFIG4 = {
5007
+ var DEFAULT_CONFIG3 = {
5607
5008
  backends: {
5608
5009
  js: {
5609
5010
  enabled: true,
@@ -5651,7 +5052,7 @@ var DEFAULT_CONFIG4 = {
5651
5052
  precision: "double",
5652
5053
  debug: false
5653
5054
  };
5654
- var currentConfig = { ...DEFAULT_CONFIG4 };
5055
+ var currentConfig = { ...DEFAULT_CONFIG3 };
5655
5056
  var listeners = /* @__PURE__ */ new Set();
5656
5057
  function getConfig() {
5657
5058
  return currentConfig;
@@ -5663,22 +5064,18 @@ function onConfigChange(listener) {
5663
5064
 
5664
5065
  // src/backends/register-backends.ts
5665
5066
  backendRegistry.register(jsBackend);
5666
- backendRegistry.register(rustWasmBackend);
5667
5067
  backendRegistry.register(wasmBackend);
5668
5068
 
5669
5069
  // src/backends/BackendManager.ts
5670
5070
  var DEFAULT_EXTENDED_HINTS = {
5671
5071
  ...DEFAULT_BACKEND_HINTS,
5672
5072
  operationThresholds: {
5673
- multiply: { wasm: 500, gpu: 5e4, rustWasm: 1e3 },
5674
- decomposition: { wasm: 100, gpu: 1e4, rustWasm: 100 },
5675
- transpose: { wasm: 2e3, gpu: 2e5, rustWasm: 2e3 }
5073
+ multiply: { wasm: 500, gpu: 5e4 },
5074
+ decomposition: { wasm: 100, gpu: 1e4 },
5075
+ transpose: { wasm: 2e3, gpu: 2e5 }
5676
5076
  },
5677
5077
  autoSIMD: true,
5678
- fallbackOnError: true,
5679
- rustWasmThreshold: 1e3,
5680
- /** Heavy operations that always prefer Rust WASM (faer/rustfft) when available */
5681
- rustWasmPreferredOps: ["fft", "eig", "svd", "decomposition"]
5078
+ fallbackOnError: true
5682
5079
  };
5683
5080
  var BackendManager = class {
5684
5081
  hints;
@@ -5756,48 +5153,29 @@ var BackendManager = class {
5756
5153
  *
5757
5154
  * Selection priority:
5758
5155
  * 1. Preferred backend (if explicitly set)
5759
- * 2. Heavy operations (fft, eig, svd, decomposition) -> Rust WASM (if loaded)
5760
- * 3. Elements > gpuThreshold -> GPU (if available)
5761
- * 4. Elements > rustWasmThreshold -> Rust WASM (if loaded)
5762
- * 5. Elements > wasmThreshold -> AS WASM (if loaded)
5763
- * 6. JS fallback
5156
+ * 2. Elements > gpuThreshold -> GPU (if available)
5157
+ * 3. Elements > wasmThreshold -> AS WASM (if loaded)
5158
+ * 4. JS fallback
5764
5159
  */
5765
5160
  selectBackend(elementCount, operation) {
5766
- const {
5767
- preferredBackend,
5768
- operationThresholds,
5769
- wasmThreshold,
5770
- gpuThreshold,
5771
- rustWasmThreshold,
5772
- rustWasmPreferredOps
5773
- } = this.hints;
5161
+ const { preferredBackend, operationThresholds, wasmThreshold, gpuThreshold } = this.hints;
5774
5162
  if (preferredBackend !== "js" && backendRegistry.has(preferredBackend)) {
5775
5163
  const backend = backendRegistry.get(preferredBackend);
5776
5164
  if (backend) {
5777
5165
  return backend;
5778
5166
  }
5779
5167
  }
5780
- if (operation && rustWasmPreferredOps?.includes(operation) && backendRegistry.has("rust-wasm")) {
5781
- const rustBackend = backendRegistry.get("rust-wasm");
5782
- if (rustBackend) return rustBackend;
5783
- }
5784
5168
  let wasmThresh = wasmThreshold;
5785
5169
  let gpuThresh = gpuThreshold;
5786
- let rustWasmThresh = rustWasmThreshold;
5787
5170
  if (operation && operationThresholds?.[operation]) {
5788
5171
  const opThresh = operationThresholds[operation];
5789
5172
  if (opThresh?.wasm !== void 0) wasmThresh = opThresh.wasm;
5790
5173
  if (opThresh?.gpu !== void 0) gpuThresh = opThresh.gpu;
5791
- if (opThresh?.rustWasm !== void 0) rustWasmThresh = opThresh.rustWasm;
5792
5174
  }
5793
5175
  if (elementCount >= gpuThresh && backendRegistry.has("gpu")) {
5794
5176
  const gpuBackend = backendRegistry.get("gpu");
5795
5177
  if (gpuBackend) return gpuBackend;
5796
5178
  }
5797
- if (elementCount >= rustWasmThresh && backendRegistry.has("rust-wasm")) {
5798
- const rustBackend = backendRegistry.get("rust-wasm");
5799
- if (rustBackend) return rustBackend;
5800
- }
5801
5179
  if (elementCount >= wasmThresh && backendRegistry.has("wasm")) {
5802
5180
  const wasmBackend2 = backendRegistry.get("wasm");
5803
5181
  if (wasmBackend2) return wasmBackend2;
@@ -6102,7 +5480,6 @@ var BackendManager = class {
6102
5480
  const backendUsage = {
6103
5481
  js: 0,
6104
5482
  wasm: 0,
6105
- "rust-wasm": 0,
6106
5483
  gpu: 0,
6107
5484
  parallel: 0
6108
5485
  };
@@ -6140,31 +5517,6 @@ var AS_ID_ARRAY_BUFFER2 = 1;
6140
5517
  var AS_ID_INT32_ARRAY2 = 4;
6141
5518
  var AS_ID_FLOAT64_ARRAY2 = 5;
6142
5519
  var AS_HEADER_BYTES2 = 12;
6143
- var RustBumpAllocator = class {
6144
- offset;
6145
- base;
6146
- constructor(baseOffset) {
6147
- this.base = baseOffset;
6148
- this.offset = baseOffset;
6149
- }
6150
- alloc(byteLength, memory) {
6151
- const aligned = this.offset + 7 & ~7;
6152
- const end = aligned + byteLength;
6153
- const currentBytes = memory.buffer.byteLength;
6154
- if (end > currentBytes) {
6155
- const pagesNeeded = Math.ceil((end - currentBytes) / 65536);
6156
- memory.grow(pagesNeeded);
6157
- }
6158
- this.offset = end;
6159
- return aligned;
6160
- }
6161
- reset() {
6162
- this.offset = this.base;
6163
- }
6164
- get highWaterMark() {
6165
- return this.offset;
6166
- }
6167
- };
6168
5520
  var WasmLoader = class _WasmLoader {
6169
5521
  static instance = null;
6170
5522
  wasmModule = null;
@@ -6172,11 +5524,7 @@ var WasmLoader = class _WasmLoader {
6172
5524
  loading = null;
6173
5525
  isNode;
6174
5526
  lastMetrics = null;
6175
- // Discriminant chosen at load() time. Null before load().
6176
- allocatorKind = null;
6177
- // Rust path: a bump allocator anchored at __heap_base.
6178
- rustAllocator = null;
6179
- // Memory pool for AS allocations (Rust does not use these pools).
5527
+ // Memory pool for AS allocations.
6180
5528
  float64Pool = [];
6181
5529
  int32Pool = [];
6182
5530
  poolSizeThreshold = 1024 * 1024;
@@ -6202,7 +5550,6 @@ var WasmLoader = class _WasmLoader {
6202
5550
  }
6203
5551
  this.loading = this.loadModule(wasmPath);
6204
5552
  this.wasmModule = await this.loading;
6205
- this.detectAllocatorKind(this.wasmModule);
6206
5553
  return this.wasmModule;
6207
5554
  }
6208
5555
  /**
@@ -6262,15 +5609,15 @@ var WasmLoader = class _WasmLoader {
6262
5609
  }
6263
5610
  }
6264
5611
  /**
6265
- * Get the WASM binary path based on the selected backend.
6266
- * Set MATHTS_WASM_BACKEND=assemblyscript to use the AS binary.
6267
- * Default is Rust (after migration cutover).
5612
+ * Get the WASM binary path. AssemblyScript is the sole WASM backend
5613
+ * (`mathts-as.wasm`); the legacy second toolchain was removed in the
5614
+ * WASM-backend migration (complete 2026-06-26).
6268
5615
  *
6269
5616
  * The path is resolved relative to this source file's location so it is
6270
5617
  * CWD-independent. This file lives at:
6271
5618
  * <repo-root>/matrix/src/backends/WasmLoader.ts
6272
5619
  * so the repo root is three directories up, and the artifact is at
6273
- * <repo-root>/lib/wasm/mathts[‑as].wasm
5620
+ * <repo-root>/lib/wasm/mathts-as.wasm
6274
5621
  *
6275
5622
  * Both branches use `new URL(relative, import.meta.url)` to resolve a
6276
5623
  * file: URL. In Node we convert via `fileURLToPath` (which correctly
@@ -6278,8 +5625,7 @@ var WasmLoader = class _WasmLoader {
6278
5625
  * doubled); in the browser we keep the full `.href` for fetch().
6279
5626
  */
6280
5627
  async getDefaultWasmPath() {
6281
- const useAS = typeof process !== "undefined" && process.env?.MATHTS_WASM_BACKEND === "assemblyscript";
6282
- const wasmFile = useAS ? "mathts-as.wasm" : "mathts.wasm";
5628
+ const wasmFile = "mathts-as.wasm";
6283
5629
  if (this.isNode) {
6284
5630
  const { resolvePackagedWasm } = await import("./resolve-JRHDDNVQ.js");
6285
5631
  const found = await resolvePackagedWasm(import.meta.url, wasmFile);
@@ -6364,30 +5710,6 @@ var WasmLoader = class _WasmLoader {
6364
5710
  Date
6365
5711
  };
6366
5712
  }
6367
- /**
6368
- * Inspect a freshly loaded module and set up the allocator path.
6369
- *
6370
- * Discriminant: the AssemblyScript managed runtime exports `__new`. The
6371
- * Rust artifact does not. We branch on that exactly once at load time and
6372
- * cache the result so the hot path doesn't have to re-detect.
6373
- */
6374
- detectAllocatorKind(module) {
6375
- const hasManagedRuntime = typeof module.__new === "function";
6376
- if (hasManagedRuntime) {
6377
- this.allocatorKind = "as";
6378
- this.rustAllocator = null;
6379
- return;
6380
- }
6381
- this.allocatorKind = "rust";
6382
- const heapBaseGlobal = module.__heap_base;
6383
- let heapBase = 65536;
6384
- if (typeof heapBaseGlobal === "number") {
6385
- heapBase = heapBaseGlobal;
6386
- } else if (heapBaseGlobal && typeof heapBaseGlobal.value === "number") {
6387
- heapBase = heapBaseGlobal.value;
6388
- }
6389
- this.rustAllocator = new RustBumpAllocator(heapBase);
6390
- }
6391
5713
  /**
6392
5714
  * Get the loaded WASM module
6393
5715
  */
@@ -6412,28 +5734,6 @@ var WasmLoader = class _WasmLoader {
6412
5734
  isPrecompiled() {
6413
5735
  return this.compiledModule !== null;
6414
5736
  }
6415
- /**
6416
- * Allocator kind (rust/as) chosen at load-time.
6417
- * Returns null before load() has resolved.
6418
- */
6419
- getAllocatorKind() {
6420
- return this.allocatorKind;
6421
- }
6422
- /**
6423
- * Reset the Rust bump allocator's high-water mark.
6424
- *
6425
- * This is a coarse batch-free for the Rust path: every previously
6426
- * allocated pointer becomes invalid. Use only when no pointers are still
6427
- * in flight (e.g. between matrix operations that explicitly free their
6428
- * own scratch).
6429
- *
6430
- * No-op on the AS path; AS uses per-allocation pin/unpin via release().
6431
- */
6432
- resetRustAllocator() {
6433
- if (this.allocatorKind === "rust" && this.rustAllocator) {
6434
- this.rustAllocator.reset();
6435
- }
6436
- }
6437
5737
  /**
6438
5738
  * Get loading performance metrics
6439
5739
  */
@@ -6443,35 +5743,48 @@ var WasmLoader = class _WasmLoader {
6443
5743
  // ===========================================================================
6444
5744
  // Allocation API
6445
5745
  // ---------------------------------------------------------------------------
6446
- // All allocation methods branch on `allocatorKind`. The returned handle's
6447
- // `ptr` is always the value that should be passed to WASM functions.
5746
+ // The returned handle's `ptr` is the header pointer to pass to WASM
5747
+ // functions (AssemblyScript managed runtime).
6448
5748
  // ===========================================================================
6449
5749
  /**
6450
5750
  * Allocate Float64Array in WASM memory and copy `data` into it.
6451
- * Uses memory pooling on the AS path.
5751
+ * Uses memory pooling.
6452
5752
  */
6453
5753
  allocateFloat64Array(data) {
6454
5754
  const module = this.wasmModule;
6455
5755
  if (!module) throw new Error("WASM module not loaded");
6456
5756
  const length = data.length;
6457
- if (this.allocatorKind === "rust") {
6458
- const alloc2 = this.allocateRustFloat64(module, length);
6459
- alloc2.array.set(data);
6460
- return alloc2;
6461
- }
6462
5757
  const alloc = this.allocateAsFloat64(module, length);
6463
5758
  alloc.array.set(data);
6464
5759
  return alloc;
6465
5760
  }
5761
+ /**
5762
+ * Decode a managed Float64Array RETURNED by an AssemblyScript export
5763
+ * (e.g. `matrix_svd`, `matrix_eig_symmetric`) into a fresh JS copy.
5764
+ *
5765
+ * AS exports that return a `Float64Array` hand back the typed-array
5766
+ * *header* pointer. The header is a 12-byte block laid out as
5767
+ * `[buffer, dataStart, byteLength]` (little-endian u32s) — the same shape
5768
+ * the loader writes in `makeAsFloat64`. We read `dataStart`/`byteLength`
5769
+ * and copy the data region out so it survives any later reuse of WASM
5770
+ * memory.
5771
+ */
5772
+ readReturnedFloat64Array(headerPtr) {
5773
+ const module = this.wasmModule;
5774
+ if (!module) throw new Error("WASM module not loaded");
5775
+ const hdr = headerPtr >>> 0;
5776
+ const dv = new DataView(module.memory.buffer);
5777
+ const dataStart = dv.getUint32(hdr + 4, true);
5778
+ const byteLength = dv.getUint32(hdr + 8, true);
5779
+ const view = new Float64Array(module.memory.buffer, dataStart, byteLength >>> 3);
5780
+ return new Float64Array(view);
5781
+ }
6466
5782
  /**
6467
5783
  * Allocate Float64Array without copying data (for output buffers)
6468
5784
  */
6469
5785
  allocateFloat64ArrayEmpty(length) {
6470
5786
  const module = this.wasmModule;
6471
5787
  if (!module) throw new Error("WASM module not loaded");
6472
- if (this.allocatorKind === "rust") {
6473
- return this.allocateRustFloat64(module, length);
6474
- }
6475
5788
  return this.allocateAsFloat64(module, length);
6476
5789
  }
6477
5790
  /**
@@ -6481,11 +5794,6 @@ var WasmLoader = class _WasmLoader {
6481
5794
  const module = this.wasmModule;
6482
5795
  if (!module) throw new Error("WASM module not loaded");
6483
5796
  const length = data.length;
6484
- if (this.allocatorKind === "rust") {
6485
- const alloc2 = this.allocateRustInt32(module, length);
6486
- alloc2.array.set(data);
6487
- return alloc2;
6488
- }
6489
5797
  const alloc = this.allocateAsInt32(module, length);
6490
5798
  alloc.array.set(data);
6491
5799
  return alloc;
@@ -6496,29 +5804,9 @@ var WasmLoader = class _WasmLoader {
6496
5804
  allocateInt32ArrayEmpty(length) {
6497
5805
  const module = this.wasmModule;
6498
5806
  if (!module) throw new Error("WASM module not loaded");
6499
- if (this.allocatorKind === "rust") {
6500
- return this.allocateRustInt32(module, length);
6501
- }
6502
5807
  return this.allocateAsInt32(module, length);
6503
5808
  }
6504
- // ---- Rust path (flat memory + bump allocator) --------------------------
6505
- allocateRustFloat64(module, length) {
6506
- const allocator = this.rustAllocator;
6507
- if (!allocator) throw new Error("Rust allocator not initialized");
6508
- const byteLength = length * 8;
6509
- const ptr = allocator.alloc(byteLength, module.memory);
6510
- const array = new Float64Array(module.memory.buffer, ptr, length);
6511
- return { kind: "rust", ptr, dataPtr: ptr, array, length };
6512
- }
6513
- allocateRustInt32(module, length) {
6514
- const allocator = this.rustAllocator;
6515
- if (!allocator) throw new Error("Rust allocator not initialized");
6516
- const byteLength = length * 4;
6517
- const ptr = allocator.alloc(byteLength, module.memory);
6518
- const array = new Int32Array(module.memory.buffer, ptr, length);
6519
- return { kind: "rust", ptr, dataPtr: ptr, array, length };
6520
- }
6521
- // ---- AS path (managed runtime + header pointers) -----------------------
5809
+ // ---- AS managed runtime (header pointers) ------------------------------
6522
5810
  allocateAsFloat64(module, length) {
6523
5811
  const byteLength = length * 8;
6524
5812
  if (byteLength <= this.poolSizeThreshold) {
@@ -6526,7 +5814,6 @@ var WasmLoader = class _WasmLoader {
6526
5814
  if (recycled) {
6527
5815
  const array = new Float64Array(module.memory.buffer, recycled.dataPtr, length);
6528
5816
  return {
6529
- kind: "as",
6530
5817
  ptr: recycled.ptr,
6531
5818
  dataPtr: recycled.dataPtr,
6532
5819
  array,
@@ -6543,7 +5830,6 @@ var WasmLoader = class _WasmLoader {
6543
5830
  if (recycled) {
6544
5831
  const array = new Int32Array(module.memory.buffer, recycled.dataPtr, length);
6545
5832
  return {
6546
- kind: "as",
6547
5833
  ptr: recycled.ptr,
6548
5834
  dataPtr: recycled.dataPtr,
6549
5835
  array,
@@ -6563,7 +5849,7 @@ var WasmLoader = class _WasmLoader {
6563
5849
  dv.setUint32(headerPtr + 4, bufferPtr, true);
6564
5850
  dv.setUint32(headerPtr + 8, byteLength, true);
6565
5851
  const array = new Float64Array(module.memory.buffer, bufferPtr, length);
6566
- return { kind: "as", ptr: headerPtr, dataPtr: bufferPtr, array, length };
5852
+ return { ptr: headerPtr, dataPtr: bufferPtr, array, length };
6567
5853
  }
6568
5854
  makeAsInt32(module, length) {
6569
5855
  const byteLength = length * 4;
@@ -6575,7 +5861,7 @@ var WasmLoader = class _WasmLoader {
6575
5861
  dv.setUint32(headerPtr + 4, bufferPtr, true);
6576
5862
  dv.setUint32(headerPtr + 8, byteLength, true);
6577
5863
  const array = new Int32Array(module.memory.buffer, bufferPtr, length);
6578
- return { kind: "as", ptr: headerPtr, dataPtr: bufferPtr, array, length };
5864
+ return { ptr: headerPtr, dataPtr: bufferPtr, array, length };
6579
5865
  }
6580
5866
  /**
6581
5867
  * Find a pool entry whose data region is large enough; returns null when
@@ -6605,9 +5891,6 @@ var WasmLoader = class _WasmLoader {
6605
5891
  * automatically.
6606
5892
  */
6607
5893
  release(ptr, isFloat64 = true) {
6608
- if (this.allocatorKind === "rust") {
6609
- return;
6610
- }
6611
5894
  const pool = isFloat64 ? this.float64Pool : this.int32Pool;
6612
5895
  const entry = pool.find((e) => e.ptr === ptr);
6613
5896
  if (entry) {
@@ -6617,17 +5900,11 @@ var WasmLoader = class _WasmLoader {
6617
5900
  this.free(ptr);
6618
5901
  }
6619
5902
  /**
6620
- * Free allocated memory (immediate, bypasses pool).
6621
- *
6622
- * - Rust path: no-op (use `resetRustAllocator`).
6623
- * - AS path: unpin the header pointer.
5903
+ * Free allocated memory (immediate, bypasses pool): unpin the header pointer.
6624
5904
  */
6625
5905
  free(ptr) {
6626
5906
  const module = this.wasmModule;
6627
5907
  if (!module) return;
6628
- if (this.allocatorKind === "rust") {
6629
- return;
6630
- }
6631
5908
  this.float64Pool = this.float64Pool.filter((e) => e.ptr !== ptr);
6632
5909
  this.int32Pool = this.int32Pool.filter((e) => e.ptr !== ptr);
6633
5910
  if (typeof module.__unpin === "function") {
@@ -6640,7 +5917,7 @@ var WasmLoader = class _WasmLoader {
6640
5917
  clearPool() {
6641
5918
  const module = this.wasmModule;
6642
5919
  if (!module) return;
6643
- if (this.allocatorKind === "as" && typeof module.__unpin === "function") {
5920
+ if (typeof module.__unpin === "function") {
6644
5921
  for (const entry of this.float64Pool) {
6645
5922
  module.__unpin(entry.ptr);
6646
5923
  }
@@ -6650,9 +5927,6 @@ var WasmLoader = class _WasmLoader {
6650
5927
  }
6651
5928
  this.float64Pool = [];
6652
5929
  this.int32Pool = [];
6653
- if (this.allocatorKind === "rust" && this.rustAllocator) {
6654
- this.rustAllocator.reset();
6655
- }
6656
5930
  }
6657
5931
  /**
6658
5932
  * Get pool statistics
@@ -6676,12 +5950,12 @@ var WasmLoader = class _WasmLoader {
6676
5950
  };
6677
5951
  }
6678
5952
  /**
6679
- * Run garbage collection (AS path only).
5953
+ * Run garbage collection.
6680
5954
  */
6681
5955
  collect() {
6682
5956
  const module = this.wasmModule;
6683
5957
  if (!module) return;
6684
- if (this.allocatorKind === "as" && typeof module.__collect === "function") {
5958
+ if (typeof module.__collect === "function") {
6685
5959
  module.__collect();
6686
5960
  }
6687
5961
  }
@@ -6694,8 +5968,6 @@ var WasmLoader = class _WasmLoader {
6694
5968
  this.compiledModule = null;
6695
5969
  this.loading = null;
6696
5970
  this.lastMetrics = null;
6697
- this.allocatorKind = null;
6698
- this.rustAllocator = null;
6699
5971
  }
6700
5972
  };
6701
5973
  var wasmLoader = WasmLoader.getInstance();
@@ -6703,69 +5975,6 @@ var wasmLoader = WasmLoader.getInstance();
6703
5975
  // src/operations/svd.ts
6704
5976
  var DEFAULT_MAX_ITERATIONS = 1e3;
6705
5977
  var DEFAULT_TOLERANCE = 1e-12;
6706
- function eye(n) {
6707
- const I = Array.from({ length: n }, () => new Array(n).fill(0));
6708
- for (let i = 0; i < n; i++) {
6709
- I[i][i] = 1;
6710
- }
6711
- return I;
6712
- }
6713
- function cloneMatrix(A) {
6714
- return A.map((row2) => [...row2]);
6715
- }
6716
- function householder(x) {
6717
- const n = x.length;
6718
- let sigma = 0;
6719
- for (let i = 1; i < n; i++) {
6720
- sigma += x[i] * x[i];
6721
- }
6722
- const v = [...x];
6723
- v[0] = 1;
6724
- if (sigma === 0 && x[0] >= 0) {
6725
- return { v, beta: 0 };
6726
- } else if (sigma === 0 && x[0] < 0) {
6727
- return { v, beta: -2 };
6728
- } else {
6729
- const mu = Math.sqrt(x[0] * x[0] + sigma);
6730
- if (x[0] <= 0) {
6731
- v[0] = x[0] - mu;
6732
- } else {
6733
- v[0] = -sigma / (x[0] + mu);
6734
- }
6735
- const beta = 2 * v[0] * v[0] / (sigma + v[0] * v[0]);
6736
- const v0 = v[0];
6737
- for (let i = 0; i < n; i++) {
6738
- v[i] /= v0;
6739
- }
6740
- return { v, beta };
6741
- }
6742
- }
6743
- function applyHouseholderLeft(A, v, beta, startRow, startCol, _endRow, endCol) {
6744
- const len = v.length;
6745
- for (let j = startCol; j < endCol; j++) {
6746
- let dot = 0;
6747
- for (let i = 0; i < len; i++) {
6748
- dot += v[i] * A[startRow + i][j];
6749
- }
6750
- dot *= beta;
6751
- for (let i = 0; i < len; i++) {
6752
- A[startRow + i][j] -= dot * v[i];
6753
- }
6754
- }
6755
- }
6756
- function applyHouseholderRight(A, v, beta, startRow, startCol, endRow, _endCol) {
6757
- const len = v.length;
6758
- for (let i = startRow; i < endRow; i++) {
6759
- let dot = 0;
6760
- for (let j = 0; j < len; j++) {
6761
- dot += A[i][startCol + j] * v[j];
6762
- }
6763
- dot *= beta;
6764
- for (let j = 0; j < len; j++) {
6765
- A[i][startCol + j] -= dot * v[j];
6766
- }
6767
- }
6768
- }
6769
5978
  function bidiagonalize(A) {
6770
5979
  const m = A.length;
6771
5980
  const n = A[0].length;
@@ -6781,8 +5990,8 @@ function bidiagonalize(A) {
6781
5990
  }
6782
5991
  const { v, beta } = householder(col);
6783
5992
  if (beta !== 0) {
6784
- applyHouseholderLeft(B2, v, beta, k, k, m, n);
6785
- applyHouseholderRight(U, v, beta, 0, k, m, m);
5993
+ applyHouseholderLeft(B2, v, beta, k, k);
5994
+ applyHouseholderRight(U, v, beta, 0, k);
6786
5995
  }
6787
5996
  }
6788
5997
  if (k < n - 2) {
@@ -6792,8 +6001,8 @@ function bidiagonalize(A) {
6792
6001
  }
6793
6002
  const { v, beta } = householder(row2);
6794
6003
  if (beta !== 0) {
6795
- applyHouseholderRight(B2, v, beta, k, k + 1, m, n);
6796
- applyHouseholderRight(V, v, beta, 0, k + 1, n, n);
6004
+ applyHouseholderRight(B2, v, beta, k, k + 1);
6005
+ applyHouseholderRight(V, v, beta, 0, k + 1);
6797
6006
  }
6798
6007
  }
6799
6008
  }
@@ -7055,19 +6264,6 @@ function normFro(matrix2) {
7055
6264
 
7056
6265
  // src/operations/eig-wasm.ts
7057
6266
  var WASM_EIG_THRESHOLD = 8;
7058
- function isSymmetric(matrix2, tolerance = 1e-10) {
7059
- const n = matrix2.length;
7060
- if (n === 0) return true;
7061
- if (matrix2[0].length !== n) return false;
7062
- for (let i = 0; i < n; i++) {
7063
- for (let j = i + 1; j < n; j++) {
7064
- if (Math.abs(matrix2[i][j] - matrix2[j][i]) > tolerance) {
7065
- return false;
7066
- }
7067
- }
7068
- }
7069
- return true;
7070
- }
7071
6267
  function flattenMatrix(matrix2) {
7072
6268
  const n = matrix2.length;
7073
6269
  const flat2 = new Float64Array(n * n);
@@ -7088,72 +6284,81 @@ async function eigWasm(matrix2, options) {
7088
6284
  throw new Error("Matrix must be square");
7089
6285
  }
7090
6286
  }
7091
- const wasmModule = wasmLoader.getModule();
6287
+ let module = wasmLoader.getModule();
6288
+ if (!module) {
6289
+ try {
6290
+ module = await wasmLoader.load();
6291
+ } catch {
6292
+ module = null;
6293
+ }
6294
+ }
7092
6295
  const symmetric = isSymmetric(matrix2);
7093
- if (!wasmModule || n < WASM_EIG_THRESHOLD || !symmetric) {
6296
+ const useSymWasm = !!module && n >= WASM_EIG_THRESHOLD && symmetric && typeof module.matrix_eig_symmetric === "function";
6297
+ const useGenWasm = !!module && n >= WASM_EIG_THRESHOLD && !symmetric && typeof module.matrix_eig_general === "function";
6298
+ if (!useSymWasm && !useGenWasm) {
7094
6299
  return eig(matrix2, options);
7095
6300
  }
7096
- const tolerance = options?.tolerance ?? 1e-12;
7097
6301
  const computeVectors = options?.computeVectors ?? true;
6302
+ const identityVectors = () => Array.from({ length: n }, (_, i) => {
6303
+ const row2 = new Array(n).fill(0);
6304
+ row2[i] = 1;
6305
+ return row2;
6306
+ });
7098
6307
  const flatMatrix = flattenMatrix(matrix2);
7099
6308
  const matrixAlloc = wasmLoader.allocateFloat64Array(Array.from(flatMatrix));
7100
- const eigenvaluesAlloc = wasmLoader.allocateFloat64ArrayEmpty(n);
7101
- const eigenvectorsAlloc = computeVectors ? wasmLoader.allocateFloat64ArrayEmpty(n * n) : { ptr: 0, array: new Float64Array(0) };
7102
- const workAlloc = wasmLoader.allocateFloat64ArrayEmpty(2 * n);
7103
6309
  try {
7104
- const iterations = wasmModule.eigsSymmetric(
7105
- matrixAlloc.ptr,
7106
- n,
7107
- tolerance,
7108
- eigenvaluesAlloc.ptr,
7109
- computeVectors ? eigenvectorsAlloc.ptr : 0,
7110
- workAlloc.ptr
7111
- );
7112
- if (iterations < 0) {
6310
+ if (useSymWasm) {
6311
+ const packedPtr2 = module.matrix_eig_symmetric(matrixAlloc.ptr, n);
6312
+ const packed2 = wasmLoader.readReturnedFloat64Array(packedPtr2);
6313
+ if (packed2.length < n + n * n) {
6314
+ return eig(matrix2, options);
6315
+ }
6316
+ const values2 = [];
6317
+ for (let j = 0; j < n; j++) {
6318
+ values2.push({ re: packed2[j], im: 0 });
6319
+ }
6320
+ let vectors2;
6321
+ if (computeVectors) {
6322
+ vectors2 = [];
6323
+ for (let j = 0; j < n; j++) {
6324
+ const vec = [];
6325
+ for (let i = 0; i < n; i++) {
6326
+ vec.push(packed2[n + i * n + j]);
6327
+ }
6328
+ vectors2.push(vec);
6329
+ }
6330
+ } else {
6331
+ vectors2 = identityVectors();
6332
+ }
6333
+ return { values: values2, vectors: vectors2, isSymmetric: true };
6334
+ }
6335
+ const packedPtr = module.matrix_eig_general(matrixAlloc.ptr, n);
6336
+ const packed = wasmLoader.readReturnedFloat64Array(packedPtr);
6337
+ if (packed.length < 2 * n + n * n) {
7113
6338
  return eig(matrix2, options);
7114
6339
  }
7115
- const module = wasmLoader.getModule();
7116
- const eigenvaluesResult = new Float64Array(module.memory.buffer, eigenvaluesAlloc.ptr, n);
7117
6340
  const values = [];
7118
- for (let i = 0; i < n; i++) {
7119
- values.push({ re: eigenvaluesResult[i], im: 0 });
6341
+ for (let j = 0; j < n; j++) {
6342
+ values.push({ re: packed[j], im: packed[n + j] });
7120
6343
  }
7121
6344
  let vectors;
7122
6345
  if (computeVectors) {
7123
- const eigenvectorsResult = new Float64Array(
7124
- module.memory.buffer,
7125
- eigenvectorsAlloc.ptr,
7126
- n * n
7127
- );
7128
6346
  vectors = [];
7129
- for (let i = 0; i < n; i++) {
6347
+ for (let j = 0; j < n; j++) {
7130
6348
  const vec = [];
7131
- for (let j = 0; j < n; j++) {
7132
- vec.push(eigenvectorsResult[i * n + j]);
6349
+ for (let i = 0; i < n; i++) {
6350
+ vec.push(packed[2 * n + i * n + j]);
7133
6351
  }
7134
6352
  vectors.push(vec);
7135
6353
  }
7136
6354
  } else {
7137
- vectors = Array.from({ length: n }, (_, i) => {
7138
- const row2 = new Array(n).fill(0);
7139
- row2[i] = 1;
7140
- return row2;
7141
- });
6355
+ vectors = identityVectors();
7142
6356
  }
7143
- return {
7144
- values,
7145
- vectors,
7146
- isSymmetric: true
7147
- };
6357
+ return { values, vectors, isSymmetric: false };
7148
6358
  } catch {
7149
6359
  return eig(matrix2, options);
7150
6360
  } finally {
7151
6361
  wasmLoader.free(matrixAlloc.ptr);
7152
- wasmLoader.free(eigenvaluesAlloc.ptr);
7153
- if (computeVectors && eigenvectorsAlloc.ptr !== 0) {
7154
- wasmLoader.free(eigenvectorsAlloc.ptr);
7155
- }
7156
- wasmLoader.free(workAlloc.ptr);
7157
6362
  }
7158
6363
  }
7159
6364
  async function eigvalsWasm(matrix2, options) {
@@ -7162,33 +6367,29 @@ async function eigvalsWasm(matrix2, options) {
7162
6367
  }
7163
6368
  async function spectralRadiusWasm(matrix2, options) {
7164
6369
  const n = matrix2.length;
7165
- const wasmModule = wasmLoader.getModule();
7166
- if (!wasmModule || n < WASM_EIG_THRESHOLD) {
7167
- const { powerIteration: powerIteration2 } = await import("./eig-A5GJGSJJ.js");
6370
+ let module = wasmLoader.getModule();
6371
+ if (!module) {
6372
+ try {
6373
+ module = await wasmLoader.load();
6374
+ } catch {
6375
+ module = null;
6376
+ }
6377
+ }
6378
+ if (!module || n < WASM_EIG_THRESHOLD || typeof module.matrix_spectral_radius !== "function") {
6379
+ const { powerIteration: powerIteration2 } = await import("./eig-G72TLEBA.js");
7168
6380
  const result = powerIteration2(matrix2, options);
7169
6381
  return Math.abs(result.value);
7170
6382
  }
7171
- const maxIterations = options?.maxIterations ?? 1e3;
7172
- const tolerance = options?.tolerance ?? 1e-12;
7173
6383
  const flatMatrix = flattenMatrix(matrix2);
7174
6384
  const matrixAlloc = wasmLoader.allocateFloat64Array(Array.from(flatMatrix));
7175
- const workAlloc = wasmLoader.allocateFloat64ArrayEmpty(2 * n);
7176
6385
  try {
7177
- const radius = wasmModule.spectralRadius(
7178
- matrixAlloc.ptr,
7179
- n,
7180
- workAlloc.ptr,
7181
- maxIterations,
7182
- tolerance
7183
- );
7184
- return radius;
6386
+ return module.matrix_spectral_radius(matrixAlloc.ptr, n);
7185
6387
  } catch {
7186
- const { powerIteration: powerIteration2 } = await import("./eig-A5GJGSJJ.js");
6388
+ const { powerIteration: powerIteration2 } = await import("./eig-G72TLEBA.js");
7187
6389
  const result = powerIteration2(matrix2, options);
7188
6390
  return Math.abs(result.value);
7189
6391
  } finally {
7190
6392
  wasmLoader.free(matrixAlloc.ptr);
7191
- wasmLoader.free(workAlloc.ptr);
7192
6393
  }
7193
6394
  }
7194
6395
 
@@ -7217,30 +6418,31 @@ async function svdWasm(matrix2, options) {
7217
6418
  }
7218
6419
  const k = Math.min(m, n);
7219
6420
  const rankTolerance = options?.rankTolerance ?? 1e-10;
7220
- const loader = RustWasmLoader.getInstance();
7221
- const ready = loader.isLoaded || await loader.load();
7222
- const wasm = ready ? loader.getExports() : null;
7223
- if (!wasm || typeof wasm.svd !== "function") {
6421
+ let module = wasmLoader.getModule();
6422
+ if (!module) {
6423
+ try {
6424
+ module = await wasmLoader.load();
6425
+ } catch {
6426
+ module = null;
6427
+ }
6428
+ }
6429
+ if (!module || typeof module.matrix_svd !== "function") {
7224
6430
  return toThin(svd(matrix2, options), k, rankTolerance);
7225
6431
  }
6432
+ const flat2 = new Float64Array(m * n);
6433
+ for (let i = 0; i < m; i++) {
6434
+ for (let j = 0; j < n; j++) flat2[i * n + j] = matrix2[i][j];
6435
+ }
6436
+ const aAlloc = wasmLoader.allocateFloat64Array(flat2);
7226
6437
  try {
7227
- loader.resetAllocator();
7228
- const flat2 = new Float64Array(m * n);
7229
- for (let i = 0; i < m; i++) {
7230
- for (let j = 0; j < n; j++) flat2[i * n + j] = matrix2[i][j];
7231
- }
7232
- const aPtr = loader.writeF64(flat2);
7233
- const uPtr = loader.allocF64(m * k);
7234
- const sPtr = loader.allocF64(k);
7235
- const vPtr = loader.allocF64(n * k);
7236
- const workPtr = loader.allocF64(wasm.svdWorkSize(m, n));
7237
- const status = wasm.svd(aPtr, m, n, uPtr, sPtr, vPtr, workPtr);
7238
- if (status < 0) {
6438
+ const packedPtr = module.matrix_svd(aAlloc.ptr, m, n);
6439
+ const packed = wasmLoader.readReturnedFloat64Array(packedPtr);
6440
+ if (packed.length < m * k + k + n * k) {
7239
6441
  return toThin(svd(matrix2, options), k, rankTolerance);
7240
6442
  }
7241
- const uFlat = loader.readF64(uPtr, m * k);
7242
- const sFlat = loader.readF64(sPtr, k);
7243
- const vFlat = loader.readF64(vPtr, n * k);
6443
+ const uFlat = packed.subarray(0, m * k);
6444
+ const sFlat = packed.subarray(m * k, m * k + k);
6445
+ const vFlat = packed.subarray(m * k + k, m * k + k + n * k);
7244
6446
  const U = [];
7245
6447
  for (let i = 0; i < m; i++) {
7246
6448
  U.push(Array.from(uFlat.subarray(i * k, i * k + k)));
@@ -7253,6 +6455,8 @@ async function svdWasm(matrix2, options) {
7253
6455
  return { U, S, V, rank: estimateRank(S, rankTolerance) };
7254
6456
  } catch {
7255
6457
  return toThin(svd(matrix2, options), k, rankTolerance);
6458
+ } finally {
6459
+ wasmLoader.free(aAlloc.ptr);
7256
6460
  }
7257
6461
  }
7258
6462
 
@@ -7499,55 +6703,6 @@ var B = [
7499
6703
  182,
7500
6704
  1
7501
6705
  ];
7502
- function eye2(n) {
7503
- return Array.from(
7504
- { length: n },
7505
- (_, i) => Array.from({ length: n }, (_2, j) => i === j ? 1 : 0)
7506
- );
7507
- }
7508
- function matMul(A, B2) {
7509
- const m = A.length;
7510
- const p = A[0].length;
7511
- const n = B2[0].length;
7512
- const C = Array.from({ length: m }, () => new Array(n).fill(0));
7513
- for (let i = 0; i < m; i++) {
7514
- for (let k = 0; k < p; k++) {
7515
- const aik = A[i][k];
7516
- if (aik === 0) continue;
7517
- for (let j = 0; j < n; j++) C[i][j] += aik * B2[k][j];
7518
- }
7519
- }
7520
- return C;
7521
- }
7522
- function matAdd(A, B2) {
7523
- const n = A.length;
7524
- const r = Array.from(
7525
- { length: n },
7526
- (_, i) => Array.from({ length: n }, (_2, j) => A[i][j] + B2[i][j])
7527
- );
7528
- return r;
7529
- }
7530
- function matSub(A, B2) {
7531
- const n = A.length;
7532
- return Array.from(
7533
- { length: n },
7534
- (_, i) => Array.from({ length: n }, (_2, j) => A[i][j] - B2[i][j])
7535
- );
7536
- }
7537
- function matScale(A, c) {
7538
- return A.map((row2) => row2.map((v) => v * c));
7539
- }
7540
- function norm1(A) {
7541
- const m = A.length;
7542
- const n = A[0].length;
7543
- let maxColSum = 0;
7544
- for (let j = 0; j < n; j++) {
7545
- let colSum = 0;
7546
- for (let i = 0; i < m; i++) colSum += Math.abs(A[i][j]);
7547
- if (colSum > maxColSum) maxColSum = colSum;
7548
- }
7549
- return maxColSum;
7550
- }
7551
6706
  function matSolve(M, N) {
7552
6707
  const n = M.length;
7553
6708
  const cols = N[0].length;
@@ -7576,7 +6731,7 @@ function matSolve(M, N) {
7576
6731
  }
7577
6732
  function pade13(A) {
7578
6733
  const n = A.length;
7579
- const I = eye2(n);
6734
+ const I = eye(n);
7580
6735
  const A2 = matMul(A, A);
7581
6736
  const A4 = matMul(A2, A2);
7582
6737
  const A6 = matMul(A2, A4);
@@ -7637,63 +6792,18 @@ init_DenseMatrix();
7637
6792
 
7638
6793
  // src/operations/schur.ts
7639
6794
  init_DenseMatrix();
7640
- function eye3(n) {
7641
- return Array.from({ length: n }, (_, i) => Array.from({ length: n }, (_2, j) => i === j ? 1 : 0));
7642
- }
7643
- function cloneMatrix2(A) {
7644
- return A.map((row2) => [...row2]);
7645
- }
7646
- function householder2(x) {
7647
- const n = x.length;
7648
- let sigma = 0;
7649
- for (let i = 1; i < n; i++) sigma += x[i] * x[i];
7650
- const v = [...x];
7651
- v[0] = 1;
7652
- if (sigma === 0 && x[0] >= 0) {
7653
- return { v, beta: 0 };
7654
- } else if (sigma === 0 && x[0] < 0) {
7655
- return { v, beta: 2 };
7656
- } else {
7657
- const mu = Math.sqrt(x[0] * x[0] + sigma);
7658
- v[0] = x[0] <= 0 ? x[0] - mu : -sigma / (x[0] + mu);
7659
- const beta = 2 * v[0] * v[0] / (sigma + v[0] * v[0]);
7660
- const v0 = v[0];
7661
- for (let i = 0; i < n; i++) v[i] /= v0;
7662
- return { v, beta };
7663
- }
7664
- }
7665
- function applyHouseholderLeft2(A, v, beta, startRow, startCol) {
7666
- const n = A[0].length;
7667
- const len = v.length;
7668
- for (let j = startCol; j < n; j++) {
7669
- let dot = 0;
7670
- for (let i = 0; i < len; i++) dot += v[i] * A[startRow + i][j];
7671
- dot *= beta;
7672
- for (let i = 0; i < len; i++) A[startRow + i][j] -= dot * v[i];
7673
- }
7674
- }
7675
- function applyHouseholderRight2(A, v, beta, startRow, startCol) {
7676
- const m = A.length;
7677
- const len = v.length;
7678
- for (let i = startRow; i < m; i++) {
7679
- let dot = 0;
7680
- for (let j = 0; j < len; j++) dot += A[i][startCol + j] * v[j];
7681
- dot *= beta;
7682
- for (let j = 0; j < len; j++) A[i][startCol + j] -= dot * v[j];
7683
- }
7684
- }
7685
6795
  function hessenbergReduce(A) {
7686
6796
  const n = A.length;
7687
- const H = cloneMatrix2(A);
7688
- const Q = eye3(n);
6797
+ const H = cloneMatrix(A);
6798
+ const Q = eye(n);
7689
6799
  for (let k = 0; k < n - 2; k++) {
7690
6800
  const x = [];
7691
6801
  for (let i = k + 1; i < n; i++) x.push(H[i][k]);
7692
- const { v, beta } = householder2(x);
6802
+ const { v, beta } = householder(x, 2);
7693
6803
  if (beta !== 0) {
7694
- applyHouseholderLeft2(H, v, beta, k + 1, k);
7695
- applyHouseholderRight2(H, v, beta, 0, k + 1);
7696
- applyHouseholderRight2(Q, v, beta, 0, k + 1);
6804
+ applyHouseholderLeft(H, v, beta, k + 1, k);
6805
+ applyHouseholderRight(H, v, beta, 0, k + 1);
6806
+ applyHouseholderRight(Q, v, beta, 0, k + 1);
7697
6807
  }
7698
6808
  }
7699
6809
  for (let i = 0; i < n; i++)
@@ -7769,7 +6879,7 @@ function qrStepDouble(H, Q, start, end) {
7769
6879
  let y = H[start + 1][start] * (H[start][start] + H[start + 1][start + 1] - s);
7770
6880
  let z = H[start + 1][start] * H[start + 2][start + 1];
7771
6881
  for (let k = start; k <= end - 2; k++) {
7772
- const { v, beta } = householder2([x, y, z]);
6882
+ const { v, beta } = householder([x, y, z], 2);
7773
6883
  const q = Math.max(start, k - 1);
7774
6884
  for (let j = q; j < n; j++) {
7775
6885
  let dot = v[0] * H[k][j] + v[1] * H[k + 1][j] + v[2] * H[k + 2][j];
@@ -7867,48 +6977,6 @@ function schurInternal(A, maxIterations = 1e3, tolerance = 1e-12) {
7867
6977
  }
7868
6978
 
7869
6979
  // src/operations/logm.ts
7870
- function eye4(n) {
7871
- return Array.from(
7872
- { length: n },
7873
- (_, i) => Array.from({ length: n }, (_2, j) => i === j ? 1 : 0)
7874
- );
7875
- }
7876
- function matMul2(A, B2) {
7877
- const m = A.length;
7878
- const p = A[0].length;
7879
- const n = B2[0].length;
7880
- const C = Array.from({ length: m }, () => new Array(n).fill(0));
7881
- for (let i = 0; i < m; i++)
7882
- for (let k = 0; k < p; k++) {
7883
- const aik = A[i][k];
7884
- if (aik === 0) continue;
7885
- for (let j = 0; j < n; j++) C[i][j] += aik * B2[k][j];
7886
- }
7887
- return C;
7888
- }
7889
- function transpose2(A) {
7890
- const m = A.length;
7891
- const n = A[0].length;
7892
- return Array.from({ length: n }, (_, j) => Array.from({ length: m }, (_2, i) => A[i][j]));
7893
- }
7894
- function matScale2(A, c) {
7895
- return A.map((row2) => row2.map((v) => v * c));
7896
- }
7897
- function normInf(A) {
7898
- let mx = 0;
7899
- for (const row2 of A) for (const v of row2) if (Math.abs(v) > mx) mx = Math.abs(v);
7900
- return mx;
7901
- }
7902
- function norm12(A) {
7903
- const n = A[0].length;
7904
- let mx = 0;
7905
- for (let j = 0; j < n; j++) {
7906
- let s = 0;
7907
- for (const row2 of A) s += Math.abs(row2[j]);
7908
- if (s > mx) mx = s;
7909
- }
7910
- return mx;
7911
- }
7912
6980
  function matInv(A) {
7913
6981
  const n = A.length;
7914
6982
  const M = A.map((row2, i) => {
@@ -7941,11 +7009,11 @@ function matInv(A) {
7941
7009
  }
7942
7010
  function matSqrt(A) {
7943
7011
  const n = A.length;
7944
- let Y = eye4(n);
7012
+ let Y = eye(n);
7945
7013
  for (let iter = 0; iter < 150; iter++) {
7946
7014
  const Yinv = matInv(Y);
7947
7015
  if (Yinv === null) break;
7948
- const AYinv = matMul2(A, Yinv);
7016
+ const AYinv = matMul(A, Yinv);
7949
7017
  const Ynew = Array.from(
7950
7018
  { length: n },
7951
7019
  (_, i) => Array.from({ length: n }, (_2, j) => (Y[i][j] + AYinv[i][j]) / 2)
@@ -8022,7 +7090,7 @@ function solveCol(M, b) {
8022
7090
  function logPade(X) {
8023
7091
  const n = X.length;
8024
7092
  const result = Array.from({ length: n }, () => new Array(n).fill(0));
8025
- const I = eye4(n);
7093
+ const I = eye(n);
8026
7094
  for (let q = 0; q < GL16_NODES.length; q++) {
8027
7095
  const t = GL16_NODES[q];
8028
7096
  const w = GL16_WEIGHTS[q];
@@ -8055,24 +7123,6 @@ function sqrtUpperTriangular(T) {
8055
7123
  }
8056
7124
  return U;
8057
7125
  }
8058
- function matMulArr(A, B2) {
8059
- const m = A.length;
8060
- const p = A[0].length;
8061
- const n = B2[0].length;
8062
- const C = Array.from({ length: m }, () => new Array(n).fill(0));
8063
- for (let i = 0; i < m; i++)
8064
- for (let k = 0; k < p; k++) {
8065
- const aik = A[i][k];
8066
- if (aik === 0) continue;
8067
- for (let j = 0; j < n; j++) C[i][j] += aik * B2[k][j];
8068
- }
8069
- return C;
8070
- }
8071
- function transposeArr(A) {
8072
- const m = A.length;
8073
- const n = A[0].length;
8074
- return Array.from({ length: n }, (_, j) => Array.from({ length: m }, (_2, i) => A[i][j]));
8075
- }
8076
7126
  function isStrictlyUpperTriangular(T) {
8077
7127
  const n = T.length;
8078
7128
  for (let i = 1; i < n; i++) {
@@ -8092,21 +7142,21 @@ function logmSchur(A, tol) {
8092
7142
  const maxSqrt = 64;
8093
7143
  while (numSqrt < maxSqrt) {
8094
7144
  const MminI2 = M.map((row2, i) => row2.map((v, j) => v - (i === j ? 1 : 0)));
8095
- if (norm12(MminI2) < tol) break;
7145
+ if (norm1(MminI2) < tol) break;
8096
7146
  const sqrtM = sqrtUpperTriangular(M);
8097
7147
  if (sqrtM === null || !isFinite(normInf(sqrtM))) break;
8098
7148
  M = sqrtM;
8099
7149
  numSqrt++;
8100
7150
  }
8101
7151
  const MminI = M.map((row2, i) => row2.map((v, j) => v - (i === j ? 1 : 0)));
8102
- if (norm12(MminI) >= tol) return null;
7152
+ if (norm1(MminI) >= tol) return null;
8103
7153
  let logT = logPade(MminI);
8104
7154
  if (numSqrt > 0) {
8105
7155
  const scale2 = Math.pow(2, numSqrt);
8106
7156
  logT = logT.map((row2) => row2.map((v) => v * scale2));
8107
7157
  }
8108
- const Qt = transposeArr(Q);
8109
- return matMulArr(matMulArr(Q, logT), Qt);
7158
+ const Qt = transpose(Q);
7159
+ return matMul(matMul(Q, logT), Qt);
8110
7160
  }
8111
7161
  function validateEigenvalues(A) {
8112
7162
  const { values } = eig(A, { computeVectors: false });
@@ -8139,16 +7189,16 @@ function logmEig(A) {
8139
7189
  }
8140
7190
  }
8141
7191
  const V = vectors;
8142
- const Q = transpose2(V);
7192
+ const Q = transpose(V);
8143
7193
  const Qinv = matInv(Q);
8144
7194
  if (Qinv === null) {
8145
7195
  throw new Error(
8146
7196
  "matrixLogm: eigenvector matrix is singular \u2014 matrix appears to be non-diagonalisable (Slice 5.9a limitation; full Schur-based implementation deferred to Slice 5.9b)"
8147
7197
  );
8148
7198
  }
8149
- const D = eye4(n);
7199
+ const D = eye(n);
8150
7200
  for (let i = 0; i < n; i++) D[i][i] = Math.log(values[i].re);
8151
- return matMul2(matMul2(Q, D), Qinv);
7201
+ return matMul(matMul(Q, D), Qinv);
8152
7202
  }
8153
7203
  function matrixLogm(A, opts) {
8154
7204
  const n = A.rows;
@@ -8168,7 +7218,7 @@ function matrixLogm(A, opts) {
8168
7218
  const maxSqrt = 64;
8169
7219
  while (numSqrt < maxSqrt) {
8170
7220
  const MminI2 = M.map((row2, i) => row2.map((v, j) => v - (i === j ? 1 : 0)));
8171
- if (norm12(MminI2) < tol) break;
7221
+ if (norm1(MminI2) < tol) break;
8172
7222
  const sqrtM = matSqrt(M);
8173
7223
  if (!isFinite(normInf(sqrtM))) break;
8174
7224
  M = sqrtM;
@@ -8176,14 +7226,14 @@ function matrixLogm(A, opts) {
8176
7226
  }
8177
7227
  let logM;
8178
7228
  const MminI = M.map((row2, i) => row2.map((v, j) => v - (i === j ? 1 : 0)));
8179
- if (norm12(MminI) < tol) {
7229
+ if (norm1(MminI) < tol) {
8180
7230
  logM = logPade(MminI);
8181
7231
  } else {
8182
7232
  logM = logmEig(Aarr);
8183
7233
  numSqrt = 0;
8184
7234
  }
8185
7235
  if (numSqrt > 0) {
8186
- logM = matScale2(logM, Math.pow(2, numSqrt));
7236
+ logM = matScale(logM, Math.pow(2, numSqrt));
8187
7237
  }
8188
7238
  const data = new Float64Array(n * n);
8189
7239
  for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) data[i * n + j] = logM[i][j];
@@ -8192,30 +7242,6 @@ function matrixLogm(A, opts) {
8192
7242
 
8193
7243
  // src/operations/sqrtm.ts
8194
7244
  init_DenseMatrix();
8195
- function eye5(n) {
8196
- return Array.from(
8197
- { length: n },
8198
- (_, i) => Array.from({ length: n }, (_2, j) => i === j ? 1 : 0)
8199
- );
8200
- }
8201
- function matMul3(A, B2) {
8202
- const m = A.length;
8203
- const p = A[0].length;
8204
- const n = B2[0].length;
8205
- const C = Array.from({ length: m }, () => new Array(n).fill(0));
8206
- for (let i = 0; i < m; i++)
8207
- for (let k = 0; k < p; k++) {
8208
- const aik = A[i][k];
8209
- if (aik === 0) continue;
8210
- for (let j = 0; j < n; j++) C[i][j] += aik * B2[k][j];
8211
- }
8212
- return C;
8213
- }
8214
- function transpose3(A) {
8215
- const m = A.length;
8216
- const n = A[0].length;
8217
- return Array.from({ length: n }, (_, j) => Array.from({ length: m }, (_2, i) => A[i][j]));
8218
- }
8219
7245
  function symmetrize(A) {
8220
7246
  const n = A.length;
8221
7247
  return Array.from(
@@ -8288,20 +7314,20 @@ function sqrtmSymmetric(A) {
8288
7314
  }
8289
7315
  const Ynewton = sqrtmNewton(Asym);
8290
7316
  if (Ynewton !== null) return Ynewton;
8291
- const Qraw = transpose3(vectors);
7317
+ const Qraw = transpose(vectors);
8292
7318
  const Q = gramSchmidt(Qraw);
8293
- const Qt = transpose3(Q);
8294
- const Dsqrt = eye5(n);
7319
+ const Qt = transpose(Q);
7320
+ const Dsqrt = eye(n);
8295
7321
  for (let i = 0; i < n; i++) Dsqrt[i][i] = Math.sqrt(Math.max(values[i].re, 0));
8296
- return matMul3(matMul3(Q, Dsqrt), Qt);
7322
+ return matMul(matMul(Q, Dsqrt), Qt);
8297
7323
  }
8298
7324
  function sqrtmNewton(A) {
8299
7325
  const n = A.length;
8300
- let Y = eye5(n);
7326
+ let Y = eye(n);
8301
7327
  for (let iter = 0; iter < 150; iter++) {
8302
7328
  const Yinv = matInv2(Y);
8303
7329
  if (Yinv === null) return null;
8304
- const AYinv = matMul3(A, Yinv);
7330
+ const AYinv = matMul(A, Yinv);
8305
7331
  const Ynew = Array.from(
8306
7332
  { length: n },
8307
7333
  (_, i) => Array.from({ length: n }, (_2, j) => (Y[i][j] + AYinv[i][j]) / 2)
@@ -8312,7 +7338,7 @@ function sqrtmNewton(A) {
8312
7338
  Y = Ynew;
8313
7339
  if (diff < 1e-13) return Y;
8314
7340
  }
8315
- const Y2 = matMul3(Y, Y);
7341
+ const Y2 = matMul(Y, Y);
8316
7342
  let err = 0;
8317
7343
  for (let i = 0; i < n; i++)
8318
7344
  for (let j = 0; j < n; j++) err = Math.max(err, Math.abs(Y2[i][j] - A[i][j]));
@@ -8336,16 +7362,16 @@ function sqrtmGeneral(A) {
8336
7362
  const Ynewton = sqrtmNewton(A);
8337
7363
  if (Ynewton !== null) return Ynewton;
8338
7364
  const V = vectors;
8339
- const Q = transpose3(V);
7365
+ const Q = transpose(V);
8340
7366
  const Qinv = matInv2(Q);
8341
7367
  if (Qinv === null) {
8342
7368
  throw new Error(
8343
7369
  "matrixSqrtm: eigenvector matrix is singular \u2014 matrix appears to be non-diagonalisable"
8344
7370
  );
8345
7371
  }
8346
- const Dsqrt = eye5(n);
7372
+ const Dsqrt = eye(n);
8347
7373
  for (let i = 0; i < n; i++) Dsqrt[i][i] = Math.sqrt(Math.max(values[i].re, 0));
8348
- return matMul3(matMul3(Q, Dsqrt), Qinv);
7374
+ return matMul(matMul(Q, Dsqrt), Qinv);
8349
7375
  }
8350
7376
  function sqrtmQuasiTriangular(T) {
8351
7377
  const n = T.length;
@@ -8460,30 +7486,12 @@ function solveLinearSystem(A, b) {
8460
7486
  }
8461
7487
  return Aug.map((row2) => row2[n]);
8462
7488
  }
8463
- function matMulArr2(A, B2) {
8464
- const m = A.length;
8465
- const p = A[0].length;
8466
- const n2 = B2[0].length;
8467
- const C = Array.from({ length: m }, () => new Array(n2).fill(0));
8468
- for (let i = 0; i < m; i++)
8469
- for (let k = 0; k < p; k++) {
8470
- const aik = A[i][k];
8471
- if (aik === 0) continue;
8472
- for (let j = 0; j < n2; j++) C[i][j] += aik * B2[k][j];
8473
- }
8474
- return C;
8475
- }
8476
- function transposeArr2(A) {
8477
- const m = A.length;
8478
- const n2 = A[0].length;
8479
- return Array.from({ length: n2 }, (_, j) => Array.from({ length: m }, (_2, i) => A[i][j]));
8480
- }
8481
7489
  function sqrtmSchur(A) {
8482
7490
  const { H: T, Q } = schurInternal(A);
8483
7491
  const U = sqrtmQuasiTriangular(T);
8484
7492
  if (U === null) return null;
8485
- const Qt = transposeArr2(Q);
8486
- return matMulArr2(matMulArr2(Q, U), Qt);
7493
+ const Qt = transpose(Q);
7494
+ return matMul(matMul(Q, U), Qt);
8487
7495
  }
8488
7496
  function matrixSqrtm(A, opts) {
8489
7497
  const n = A.rows;
@@ -8589,7 +7597,7 @@ var unaryMinus = mathTyped("unaryMinus", {
8589
7597
  DenseMatrix: (a) => a.negate(),
8590
7598
  number: (a) => -a
8591
7599
  });
8592
- var transpose4 = mathTyped("transpose", {
7600
+ var transpose3 = mathTyped("transpose", {
8593
7601
  DenseMatrix: (a) => a.transpose()
8594
7602
  });
8595
7603
  var sum2 = mathTyped("sum", {
@@ -8678,7 +7686,7 @@ var typedMatrixOperations = {
8678
7686
  dotMultiply,
8679
7687
  divide,
8680
7688
  unaryMinus,
8681
- transpose: transpose4,
7689
+ transpose: transpose3,
8682
7690
  // Reductions
8683
7691
  sum: sum2,
8684
7692
  mean: mean2,
@@ -9359,8 +8367,6 @@ export {
9359
8367
  JSBackend,
9360
8368
  Matrix,
9361
8369
  ParallelBackend,
9362
- RustWASMBackend,
9363
- RustWasmLoader,
9364
8370
  ShaderManager,
9365
8371
  SparseMatrix,
9366
8372
  SyncManager,
@@ -9376,7 +8382,6 @@ export {
9376
8382
  createBackendManager,
9377
8383
  createGPUMatrixBackend,
9378
8384
  createParallelBackend,
9379
- createRustWASMBackend,
9380
8385
  createSyncManager,
9381
8386
  createWASMBackend,
9382
8387
  destroyGlobalGPU,
@@ -9399,7 +8404,6 @@ export {
9399
8404
  gpuMatrixBackend,
9400
8405
  hasWebGPU,
9401
8406
  identity,
9402
- initRustWasm,
9403
8407
  initializeGlobalGPUBackend,
9404
8408
  initializeParallelMatrix,
9405
8409
  isAtomicsAvailable,
@@ -9473,8 +8477,6 @@ export {
9473
8477
  qr,
9474
8478
  random,
9475
8479
  row,
9476
- rustWasmBackend,
9477
- rustWasmLoader,
9478
8480
  singularValues,
9479
8481
  size,
9480
8482
  spectralRadiusWasm,
@@ -9487,7 +8489,7 @@ export {
9487
8489
  svdWasm,
9488
8490
  terminateParallelMatrix,
9489
8491
  trace2 as trace,
9490
- transpose4 as transpose,
8492
+ transpose3 as transpose,
9491
8493
  typedMatrixOperations,
9492
8494
  unaryMinus,
9493
8495
  wasmBackend,