@danielsimonjr/mathts-matrix 0.1.12 → 0.1.13
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 +29 -55
- package/dist/index.js +636 -331
- package/dist/wasm/mathts-as.wasm +0 -0
- package/dist/wasm/wasm-manifest.json +1 -1
- package/package.json +1 -1
- package/dist/chunk-JRSQE7LB.js +0 -607
- package/dist/eig-PIFFHFJF.js +0 -11
package/dist/index.js
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
applyHouseholderLeft,
|
|
3
|
-
applyHouseholderRight,
|
|
4
|
-
cloneMatrix,
|
|
5
|
-
eig,
|
|
6
|
-
eigvals,
|
|
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-JRSQE7LB.js";
|
|
19
1
|
import {
|
|
20
2
|
__esm,
|
|
21
3
|
__export,
|
|
@@ -196,7 +178,7 @@ function scale(a, scalar) {
|
|
|
196
178
|
for (let i = 0; i < ad.length; i++) result[i] = ad[i] * scalar;
|
|
197
179
|
return result;
|
|
198
180
|
}
|
|
199
|
-
function
|
|
181
|
+
function transpose(a) {
|
|
200
182
|
const ad = flat(a);
|
|
201
183
|
const rows = a.rows;
|
|
202
184
|
const cols = a.cols;
|
|
@@ -1301,7 +1283,7 @@ var init_DenseMatrix = __esm({
|
|
|
1301
1283
|
* Matrix transpose
|
|
1302
1284
|
*/
|
|
1303
1285
|
transpose() {
|
|
1304
|
-
return new _DenseMatrix(this.cols, this.rows,
|
|
1286
|
+
return new _DenseMatrix(this.cols, this.rows, transpose(this));
|
|
1305
1287
|
}
|
|
1306
1288
|
/**
|
|
1307
1289
|
* Negate all elements
|
|
@@ -2485,7 +2467,7 @@ var WASMBackend = class {
|
|
|
2485
2467
|
try {
|
|
2486
2468
|
const path = this.config.wasmPath || await this.resolveAsWasmPath();
|
|
2487
2469
|
const loaded = await this.loadAsModule(path);
|
|
2488
|
-
if (typeof loaded.__new !== "function" || typeof loaded.
|
|
2470
|
+
if (typeof loaded.__new !== "function" || typeof loaded.matrix_multiply_simd_ptr !== "function") {
|
|
2489
2471
|
console.warn(
|
|
2490
2472
|
"WASMBackend: loaded module is not the AssemblyScript artifact; falling back to JS. Pass an explicit wasmPath (the AS binary, mathts-as.wasm)."
|
|
2491
2473
|
);
|
|
@@ -2559,7 +2541,15 @@ var WASMBackend = class {
|
|
|
2559
2541
|
}
|
|
2560
2542
|
return instance.exports;
|
|
2561
2543
|
}
|
|
2562
|
-
|
|
2544
|
+
/**
|
|
2545
|
+
* WASM is only worth its copy/alloc overhead for compute-dense ops. The 2026-07-01
|
|
2546
|
+
* backend audit (`tools/benchmarks/backend-audit`) measured element-wise / transpose
|
|
2547
|
+
* ops 4–6× SLOWER on WASM than JS (memory-bound; the SIMD matmul kernel is the only
|
|
2548
|
+
* clear win, 9–12×). So WASM is reserved for `opKind: 'matmul'`; everything else stays
|
|
2549
|
+
* on JS via each method's existing `jsBackend` fallback.
|
|
2550
|
+
*/
|
|
2551
|
+
shouldUseWasm(elementCount, opKind = "elementwise") {
|
|
2552
|
+
if (opKind !== "matmul") return false;
|
|
2563
2553
|
return this.wasmModule !== null && elementCount >= this.config.minElements;
|
|
2564
2554
|
}
|
|
2565
2555
|
getFeatures() {
|
|
@@ -2568,137 +2558,49 @@ var WASMBackend = class {
|
|
|
2568
2558
|
// =========================================================================
|
|
2569
2559
|
// Element-wise Operations
|
|
2570
2560
|
// =========================================================================
|
|
2561
|
+
// Element-wise ops run on JS. The AS element-wise kernels (matrix_add/sub/mul/div/scale/neg,
|
|
2562
|
+
// array_abs) were measured 4–6× SLOWER than JS (memory-bound + copy/alloc overhead —
|
|
2563
|
+
// tools/benchmarks/backend-audit) and retired via `shouldUseWasm` (returns false for
|
|
2564
|
+
// non-matmul). These delegate to `jsBackend`; the dead WASM branches were removed 2026-07-02.
|
|
2571
2565
|
add(a, b) {
|
|
2572
|
-
|
|
2573
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.add(a, b);
|
|
2574
|
-
const mod = this.wasmModule;
|
|
2575
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2576
|
-
const bAlloc = writeAsFloat64Array(this.allocCache, mod, b.toFloat64Array());
|
|
2577
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2578
|
-
try {
|
|
2579
|
-
mod.matrix_add(aAlloc.headerPtr, bAlloc.headerPtr, rAlloc.headerPtr);
|
|
2580
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2581
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2582
|
-
} finally {
|
|
2583
|
-
this.allocCache.release(aAlloc);
|
|
2584
|
-
this.allocCache.release(bAlloc);
|
|
2585
|
-
this.allocCache.release(rAlloc);
|
|
2586
|
-
}
|
|
2566
|
+
return jsBackend.add(a, b);
|
|
2587
2567
|
}
|
|
2588
2568
|
subtract(a, b) {
|
|
2589
|
-
|
|
2590
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.subtract(a, b);
|
|
2591
|
-
const mod = this.wasmModule;
|
|
2592
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2593
|
-
const bAlloc = writeAsFloat64Array(this.allocCache, mod, b.toFloat64Array());
|
|
2594
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2595
|
-
try {
|
|
2596
|
-
mod.matrix_sub(aAlloc.headerPtr, bAlloc.headerPtr, rAlloc.headerPtr);
|
|
2597
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2598
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2599
|
-
} finally {
|
|
2600
|
-
this.allocCache.release(aAlloc);
|
|
2601
|
-
this.allocCache.release(bAlloc);
|
|
2602
|
-
this.allocCache.release(rAlloc);
|
|
2603
|
-
}
|
|
2569
|
+
return jsBackend.subtract(a, b);
|
|
2604
2570
|
}
|
|
2605
2571
|
multiplyElementwise(a, b) {
|
|
2606
|
-
|
|
2607
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.multiplyElementwise(a, b);
|
|
2608
|
-
const mod = this.wasmModule;
|
|
2609
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2610
|
-
const bAlloc = writeAsFloat64Array(this.allocCache, mod, b.toFloat64Array());
|
|
2611
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2612
|
-
try {
|
|
2613
|
-
mod.matrix_mul_elementwise(aAlloc.headerPtr, bAlloc.headerPtr, rAlloc.headerPtr);
|
|
2614
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2615
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2616
|
-
} finally {
|
|
2617
|
-
this.allocCache.release(aAlloc);
|
|
2618
|
-
this.allocCache.release(bAlloc);
|
|
2619
|
-
this.allocCache.release(rAlloc);
|
|
2620
|
-
}
|
|
2572
|
+
return jsBackend.multiplyElementwise(a, b);
|
|
2621
2573
|
}
|
|
2622
2574
|
divideElementwise(a, b) {
|
|
2623
|
-
|
|
2624
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.divideElementwise(a, b);
|
|
2625
|
-
const mod = this.wasmModule;
|
|
2626
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2627
|
-
const bAlloc = writeAsFloat64Array(this.allocCache, mod, b.toFloat64Array());
|
|
2628
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2629
|
-
try {
|
|
2630
|
-
mod.matrix_div_elementwise(aAlloc.headerPtr, bAlloc.headerPtr, rAlloc.headerPtr);
|
|
2631
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2632
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2633
|
-
} finally {
|
|
2634
|
-
this.allocCache.release(aAlloc);
|
|
2635
|
-
this.allocCache.release(bAlloc);
|
|
2636
|
-
this.allocCache.release(rAlloc);
|
|
2637
|
-
}
|
|
2575
|
+
return jsBackend.divideElementwise(a, b);
|
|
2638
2576
|
}
|
|
2639
2577
|
scale(a, scalar) {
|
|
2640
|
-
|
|
2641
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.scale(a, scalar);
|
|
2642
|
-
const mod = this.wasmModule;
|
|
2643
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2644
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2645
|
-
try {
|
|
2646
|
-
mod.matrix_scale(aAlloc.headerPtr, scalar, rAlloc.headerPtr);
|
|
2647
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2648
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2649
|
-
} finally {
|
|
2650
|
-
this.allocCache.release(aAlloc);
|
|
2651
|
-
this.allocCache.release(rAlloc);
|
|
2652
|
-
}
|
|
2578
|
+
return jsBackend.scale(a, scalar);
|
|
2653
2579
|
}
|
|
2654
2580
|
abs(a) {
|
|
2655
|
-
|
|
2656
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.abs(a);
|
|
2657
|
-
const mod = this.wasmModule;
|
|
2658
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2659
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2660
|
-
try {
|
|
2661
|
-
mod.array_abs(aAlloc.headerPtr, rAlloc.headerPtr);
|
|
2662
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2663
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2664
|
-
} finally {
|
|
2665
|
-
this.allocCache.release(aAlloc);
|
|
2666
|
-
this.allocCache.release(rAlloc);
|
|
2667
|
-
}
|
|
2581
|
+
return jsBackend.abs(a);
|
|
2668
2582
|
}
|
|
2669
2583
|
negate(a) {
|
|
2670
|
-
|
|
2671
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.negate(a);
|
|
2672
|
-
const mod = this.wasmModule;
|
|
2673
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2674
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2675
|
-
try {
|
|
2676
|
-
mod.matrix_neg(aAlloc.headerPtr, rAlloc.headerPtr);
|
|
2677
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2678
|
-
return DenseMatrix.fromFlat(a.rows, a.cols, Array.from(result));
|
|
2679
|
-
} finally {
|
|
2680
|
-
this.allocCache.release(aAlloc);
|
|
2681
|
-
this.allocCache.release(rAlloc);
|
|
2682
|
-
}
|
|
2584
|
+
return jsBackend.negate(a);
|
|
2683
2585
|
}
|
|
2684
2586
|
// =========================================================================
|
|
2685
2587
|
// Matrix Operations
|
|
2686
2588
|
// =========================================================================
|
|
2687
2589
|
multiply(a, b) {
|
|
2688
2590
|
const elementCount = a.rows * a.cols + b.rows * b.cols;
|
|
2689
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.multiply(a, b);
|
|
2591
|
+
if (!this.shouldUseWasm(elementCount, "matmul")) return jsBackend.multiply(a, b);
|
|
2690
2592
|
const mod = this.wasmModule;
|
|
2691
2593
|
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2692
2594
|
const bAlloc = writeAsFloat64Array(this.allocCache, mod, b.toFloat64Array());
|
|
2693
2595
|
const rAlloc = allocAsFloat64Array(this.allocCache, mod, a.rows * b.cols);
|
|
2694
2596
|
try {
|
|
2695
|
-
mod.
|
|
2696
|
-
aAlloc.
|
|
2597
|
+
mod.matrix_multiply_simd_ptr(
|
|
2598
|
+
aAlloc.bufferPtr,
|
|
2697
2599
|
a.rows,
|
|
2698
2600
|
a.cols,
|
|
2699
|
-
bAlloc.
|
|
2601
|
+
bAlloc.bufferPtr,
|
|
2700
2602
|
b.cols,
|
|
2701
|
-
rAlloc.
|
|
2603
|
+
rAlloc.bufferPtr
|
|
2702
2604
|
);
|
|
2703
2605
|
const result = readAsFloat64Array(mod, rAlloc);
|
|
2704
2606
|
return DenseMatrix.fromFlat(a.rows, b.cols, Array.from(result));
|
|
@@ -2708,61 +2610,24 @@ var WASMBackend = class {
|
|
|
2708
2610
|
this.allocCache.release(rAlloc);
|
|
2709
2611
|
}
|
|
2710
2612
|
}
|
|
2613
|
+
// transpose is memory-bound (like element-wise) — retired from WASM, runs on JS.
|
|
2711
2614
|
transpose(a) {
|
|
2712
|
-
|
|
2713
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.transpose(a);
|
|
2714
|
-
const mod = this.wasmModule;
|
|
2715
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2716
|
-
const rAlloc = allocAsFloat64Array(this.allocCache, mod, elementCount);
|
|
2717
|
-
try {
|
|
2718
|
-
mod.matrix_transpose(aAlloc.headerPtr, a.rows, a.cols, rAlloc.headerPtr);
|
|
2719
|
-
const result = readAsFloat64Array(mod, rAlloc);
|
|
2720
|
-
return DenseMatrix.fromFlat(a.cols, a.rows, Array.from(result));
|
|
2721
|
-
} finally {
|
|
2722
|
-
this.allocCache.release(aAlloc);
|
|
2723
|
-
this.allocCache.release(rAlloc);
|
|
2724
|
-
}
|
|
2615
|
+
return jsBackend.transpose(a);
|
|
2725
2616
|
}
|
|
2726
2617
|
// =========================================================================
|
|
2727
|
-
// Reduction Operations
|
|
2618
|
+
// Reduction Operations — memory-bound (single pass), retired from WASM → JS.
|
|
2728
2619
|
// =========================================================================
|
|
2729
2620
|
sum(a) {
|
|
2730
|
-
|
|
2731
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.sum(a);
|
|
2732
|
-
const mod = this.wasmModule;
|
|
2733
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2734
|
-
try {
|
|
2735
|
-
return mod.matrix_sum(aAlloc.headerPtr);
|
|
2736
|
-
} finally {
|
|
2737
|
-
this.allocCache.release(aAlloc);
|
|
2738
|
-
}
|
|
2621
|
+
return jsBackend.sum(a);
|
|
2739
2622
|
}
|
|
2740
2623
|
sumAxis(a, axis) {
|
|
2741
2624
|
return jsBackend.sumAxis(a, axis);
|
|
2742
2625
|
}
|
|
2743
2626
|
norm(a) {
|
|
2744
|
-
|
|
2745
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.norm(a);
|
|
2746
|
-
const mod = this.wasmModule;
|
|
2747
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2748
|
-
try {
|
|
2749
|
-
return mod.matrix_norm_frobenius(aAlloc.headerPtr);
|
|
2750
|
-
} finally {
|
|
2751
|
-
this.allocCache.release(aAlloc);
|
|
2752
|
-
}
|
|
2627
|
+
return jsBackend.norm(a);
|
|
2753
2628
|
}
|
|
2754
2629
|
dot(a, b) {
|
|
2755
|
-
|
|
2756
|
-
if (!this.shouldUseWasm(elementCount)) return jsBackend.dot(a, b);
|
|
2757
|
-
const mod = this.wasmModule;
|
|
2758
|
-
const aAlloc = writeAsFloat64Array(this.allocCache, mod, a.toFloat64Array());
|
|
2759
|
-
const bAlloc = writeAsFloat64Array(this.allocCache, mod, b.toFloat64Array());
|
|
2760
|
-
try {
|
|
2761
|
-
return mod.array_dot(aAlloc.headerPtr, bAlloc.headerPtr);
|
|
2762
|
-
} finally {
|
|
2763
|
-
this.allocCache.release(aAlloc);
|
|
2764
|
-
this.allocCache.release(bAlloc);
|
|
2765
|
-
}
|
|
2630
|
+
return jsBackend.dot(a, b);
|
|
2766
2631
|
}
|
|
2767
2632
|
// =========================================================================
|
|
2768
2633
|
// LU / QR / Cholesky / Inverse / Determinant
|
|
@@ -5070,8 +4935,13 @@ backendRegistry.register(wasmBackend);
|
|
|
5070
4935
|
var DEFAULT_EXTENDED_HINTS = {
|
|
5071
4936
|
...DEFAULT_BACKEND_HINTS,
|
|
5072
4937
|
operationThresholds: {
|
|
5073
|
-
|
|
4938
|
+
// matmul: the SIMD-WASM kernel wins from ~256 elems (16²), solidly 1.3–2.2× (measured,
|
|
4939
|
+
// tools/benchmarks/matmul-threshold.mjs); below that copy/alloc overhead dominates (8²
|
|
4940
|
+
// loses, 12² marginal). Dropped 500→256 to stop forcing 16²–22² matmuls onto JS.
|
|
4941
|
+
multiply: { wasm: 256, gpu: 5e4 },
|
|
5074
4942
|
decomposition: { wasm: 100, gpu: 1e4 },
|
|
4943
|
+
// transpose WASM is retired (memory-bound, lost 4–6×) — WASMBackend.transpose always uses
|
|
4944
|
+
// JS regardless of this gate; kept high so the manager doesn't even select the WASM backend.
|
|
5075
4945
|
transpose: { wasm: 2e3, gpu: 2e5 }
|
|
5076
4946
|
},
|
|
5077
4947
|
autoSIMD: true,
|
|
@@ -5760,7 +5630,7 @@ var WasmLoader = class _WasmLoader {
|
|
|
5760
5630
|
}
|
|
5761
5631
|
/**
|
|
5762
5632
|
* Decode a managed Float64Array RETURNED by an AssemblyScript export
|
|
5763
|
-
* (e.g. `
|
|
5633
|
+
* (e.g. the `matrix_lu_decompose` / `matrix_qr_decompose` outputs) into a fresh JS copy.
|
|
5764
5634
|
*
|
|
5765
5635
|
* AS exports that return a `Float64Array` hand back the typed-array
|
|
5766
5636
|
* *header* pointer. The header is a 12-byte block laid out as
|
|
@@ -5972,6 +5842,590 @@ var WasmLoader = class _WasmLoader {
|
|
|
5972
5842
|
};
|
|
5973
5843
|
var wasmLoader = WasmLoader.getInstance();
|
|
5974
5844
|
|
|
5845
|
+
// src/operations/common.ts
|
|
5846
|
+
function eye(n) {
|
|
5847
|
+
return Array.from(
|
|
5848
|
+
{ length: n },
|
|
5849
|
+
(_, i) => Array.from({ length: n }, (_2, j) => i === j ? 1 : 0)
|
|
5850
|
+
);
|
|
5851
|
+
}
|
|
5852
|
+
function cloneMatrix(A) {
|
|
5853
|
+
return A.map((row2) => [...row2]);
|
|
5854
|
+
}
|
|
5855
|
+
function transpose2(A) {
|
|
5856
|
+
const m = A.length;
|
|
5857
|
+
const n = A[0].length;
|
|
5858
|
+
return Array.from({ length: n }, (_, j) => Array.from({ length: m }, (_2, i) => A[i][j]));
|
|
5859
|
+
}
|
|
5860
|
+
function isSymmetric(matrix2, tolerance = 1e-10) {
|
|
5861
|
+
const n = matrix2.length;
|
|
5862
|
+
if (n === 0) return true;
|
|
5863
|
+
if (matrix2[0].length !== n) return false;
|
|
5864
|
+
for (let i = 0; i < n; i++) {
|
|
5865
|
+
for (let j = i + 1; j < n; j++) {
|
|
5866
|
+
if (Math.abs(matrix2[i][j] - matrix2[j][i]) > tolerance) {
|
|
5867
|
+
return false;
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
return true;
|
|
5872
|
+
}
|
|
5873
|
+
function matMul(A, B2) {
|
|
5874
|
+
const m = A.length;
|
|
5875
|
+
const p = A[0].length;
|
|
5876
|
+
const n = B2[0].length;
|
|
5877
|
+
const C = Array.from({ length: m }, () => new Array(n).fill(0));
|
|
5878
|
+
for (let i = 0; i < m; i++) {
|
|
5879
|
+
for (let k = 0; k < p; k++) {
|
|
5880
|
+
const aik = A[i][k];
|
|
5881
|
+
if (aik === 0) continue;
|
|
5882
|
+
for (let j = 0; j < n; j++) C[i][j] += aik * B2[k][j];
|
|
5883
|
+
}
|
|
5884
|
+
}
|
|
5885
|
+
return C;
|
|
5886
|
+
}
|
|
5887
|
+
function matAdd(A, B2) {
|
|
5888
|
+
const n = A.length;
|
|
5889
|
+
return Array.from(
|
|
5890
|
+
{ length: n },
|
|
5891
|
+
(_, i) => Array.from({ length: n }, (_2, j) => A[i][j] + B2[i][j])
|
|
5892
|
+
);
|
|
5893
|
+
}
|
|
5894
|
+
function matSub(A, B2) {
|
|
5895
|
+
const n = A.length;
|
|
5896
|
+
return Array.from(
|
|
5897
|
+
{ length: n },
|
|
5898
|
+
(_, i) => Array.from({ length: n }, (_2, j) => A[i][j] - B2[i][j])
|
|
5899
|
+
);
|
|
5900
|
+
}
|
|
5901
|
+
function matScale(A, c) {
|
|
5902
|
+
return A.map((row2) => row2.map((v) => v * c));
|
|
5903
|
+
}
|
|
5904
|
+
function normInf(A) {
|
|
5905
|
+
let mx = 0;
|
|
5906
|
+
for (const row2 of A) for (const v of row2) if (Math.abs(v) > mx) mx = Math.abs(v);
|
|
5907
|
+
return mx;
|
|
5908
|
+
}
|
|
5909
|
+
function norm1(A) {
|
|
5910
|
+
const m = A.length;
|
|
5911
|
+
const n = A[0].length;
|
|
5912
|
+
let maxColSum = 0;
|
|
5913
|
+
for (let j = 0; j < n; j++) {
|
|
5914
|
+
let colSum = 0;
|
|
5915
|
+
for (let i = 0; i < m; i++) colSum += Math.abs(A[i][j]);
|
|
5916
|
+
if (colSum > maxColSum) maxColSum = colSum;
|
|
5917
|
+
}
|
|
5918
|
+
return maxColSum;
|
|
5919
|
+
}
|
|
5920
|
+
function householder(x, degenerateBeta = -2) {
|
|
5921
|
+
const n = x.length;
|
|
5922
|
+
let sigma = 0;
|
|
5923
|
+
for (let i = 1; i < n; i++) {
|
|
5924
|
+
sigma += x[i] * x[i];
|
|
5925
|
+
}
|
|
5926
|
+
const v = [...x];
|
|
5927
|
+
v[0] = 1;
|
|
5928
|
+
if (sigma === 0 && x[0] >= 0) {
|
|
5929
|
+
return { v, beta: 0 };
|
|
5930
|
+
} else if (sigma === 0 && x[0] < 0) {
|
|
5931
|
+
return { v, beta: degenerateBeta };
|
|
5932
|
+
} else {
|
|
5933
|
+
const mu = Math.sqrt(x[0] * x[0] + sigma);
|
|
5934
|
+
if (x[0] <= 0) {
|
|
5935
|
+
v[0] = x[0] - mu;
|
|
5936
|
+
} else {
|
|
5937
|
+
v[0] = -sigma / (x[0] + mu);
|
|
5938
|
+
}
|
|
5939
|
+
const beta = 2 * v[0] * v[0] / (sigma + v[0] * v[0]);
|
|
5940
|
+
const v0 = v[0];
|
|
5941
|
+
for (let i = 0; i < n; i++) {
|
|
5942
|
+
v[i] /= v0;
|
|
5943
|
+
}
|
|
5944
|
+
return { v, beta };
|
|
5945
|
+
}
|
|
5946
|
+
}
|
|
5947
|
+
function applyHouseholderLeft(A, v, beta, startRow, startCol) {
|
|
5948
|
+
const n = A[0].length;
|
|
5949
|
+
const len = v.length;
|
|
5950
|
+
for (let j = startCol; j < n; j++) {
|
|
5951
|
+
let dot = 0;
|
|
5952
|
+
for (let i = 0; i < len; i++) {
|
|
5953
|
+
dot += v[i] * A[startRow + i][j];
|
|
5954
|
+
}
|
|
5955
|
+
dot *= beta;
|
|
5956
|
+
for (let i = 0; i < len; i++) {
|
|
5957
|
+
A[startRow + i][j] -= dot * v[i];
|
|
5958
|
+
}
|
|
5959
|
+
}
|
|
5960
|
+
}
|
|
5961
|
+
function applyHouseholderRight(A, v, beta, startRow, startCol) {
|
|
5962
|
+
const m = A.length;
|
|
5963
|
+
const len = v.length;
|
|
5964
|
+
for (let i = startRow; i < m; i++) {
|
|
5965
|
+
let dot = 0;
|
|
5966
|
+
for (let j = 0; j < len; j++) {
|
|
5967
|
+
dot += A[i][startCol + j] * v[j];
|
|
5968
|
+
}
|
|
5969
|
+
dot *= beta;
|
|
5970
|
+
for (let j = 0; j < len; j++) {
|
|
5971
|
+
A[i][startCol + j] -= dot * v[j];
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
|
|
5976
|
+
// src/operations/eig.ts
|
|
5977
|
+
var EIG_GEN_EPS = 2220446049250313e-31;
|
|
5978
|
+
function cdiv(xr, xi, yr, yi) {
|
|
5979
|
+
let rr;
|
|
5980
|
+
let d;
|
|
5981
|
+
if (Math.abs(yr) > Math.abs(yi)) {
|
|
5982
|
+
rr = yi / yr;
|
|
5983
|
+
d = yr + rr * yi;
|
|
5984
|
+
return { r: (xr + rr * xi) / d, i: (xi - rr * xr) / d };
|
|
5985
|
+
} else {
|
|
5986
|
+
rr = yr / yi;
|
|
5987
|
+
d = yi + rr * yr;
|
|
5988
|
+
return { r: (rr * xr + xi) / d, i: (rr * xi - xr) / d };
|
|
5989
|
+
}
|
|
5990
|
+
}
|
|
5991
|
+
function orthesGeneral(H, V, ort, nn) {
|
|
5992
|
+
const low = 0;
|
|
5993
|
+
const high = nn - 1;
|
|
5994
|
+
for (let m = low + 1; m <= high - 1; m++) {
|
|
5995
|
+
let scale2 = 0;
|
|
5996
|
+
for (let i = m; i <= high; i++) {
|
|
5997
|
+
scale2 += Math.abs(H[i * nn + (m - 1)]);
|
|
5998
|
+
}
|
|
5999
|
+
if (scale2 !== 0) {
|
|
6000
|
+
let h = 0;
|
|
6001
|
+
for (let i = high; i >= m; i--) {
|
|
6002
|
+
ort[i] = H[i * nn + (m - 1)] / scale2;
|
|
6003
|
+
h += ort[i] * ort[i];
|
|
6004
|
+
}
|
|
6005
|
+
let g = Math.sqrt(h);
|
|
6006
|
+
if (ort[m] > 0) g = -g;
|
|
6007
|
+
h = h - ort[m] * g;
|
|
6008
|
+
ort[m] = ort[m] - g;
|
|
6009
|
+
for (let j = m; j < nn; j++) {
|
|
6010
|
+
let f = 0;
|
|
6011
|
+
for (let i = high; i >= m; i--) f += ort[i] * H[i * nn + j];
|
|
6012
|
+
f = f / h;
|
|
6013
|
+
for (let i = m; i <= high; i++) H[i * nn + j] -= f * ort[i];
|
|
6014
|
+
}
|
|
6015
|
+
for (let i = 0; i <= high; i++) {
|
|
6016
|
+
let f = 0;
|
|
6017
|
+
for (let j = high; j >= m; j--) f += ort[j] * H[i * nn + j];
|
|
6018
|
+
f = f / h;
|
|
6019
|
+
for (let j = m; j <= high; j++) H[i * nn + j] -= f * ort[j];
|
|
6020
|
+
}
|
|
6021
|
+
ort[m] = scale2 * ort[m];
|
|
6022
|
+
H[m * nn + (m - 1)] = scale2 * g;
|
|
6023
|
+
}
|
|
6024
|
+
}
|
|
6025
|
+
for (let m = high - 1; m >= low + 1; m--) {
|
|
6026
|
+
if (H[m * nn + (m - 1)] !== 0) {
|
|
6027
|
+
for (let i = m + 1; i <= high; i++) ort[i] = H[i * nn + (m - 1)];
|
|
6028
|
+
for (let j = m; j <= high; j++) {
|
|
6029
|
+
let g = 0;
|
|
6030
|
+
for (let i = m; i <= high; i++) g += ort[i] * V[i * nn + j];
|
|
6031
|
+
g = g / ort[m] / H[m * nn + (m - 1)];
|
|
6032
|
+
for (let i = m; i <= high; i++) V[i * nn + j] += g * ort[i];
|
|
6033
|
+
}
|
|
6034
|
+
}
|
|
6035
|
+
}
|
|
6036
|
+
}
|
|
6037
|
+
function eigGeneral(A, computeVectors, symmetric) {
|
|
6038
|
+
const nn = A.length;
|
|
6039
|
+
const eps = EIG_GEN_EPS;
|
|
6040
|
+
const H = new Float64Array(nn * nn);
|
|
6041
|
+
for (let i = 0; i < nn; i++) {
|
|
6042
|
+
for (let j = 0; j < nn; j++) H[i * nn + j] = A[i][j];
|
|
6043
|
+
}
|
|
6044
|
+
const V = new Float64Array(nn * nn);
|
|
6045
|
+
for (let i = 0; i < nn; i++) V[i * nn + i] = 1;
|
|
6046
|
+
const d = new Float64Array(nn);
|
|
6047
|
+
const e = new Float64Array(nn);
|
|
6048
|
+
const ort = new Float64Array(nn);
|
|
6049
|
+
orthesGeneral(H, V, ort, nn);
|
|
6050
|
+
const low = 0;
|
|
6051
|
+
const high = nn - 1;
|
|
6052
|
+
let exshift = 0;
|
|
6053
|
+
let p = 0;
|
|
6054
|
+
let q = 0;
|
|
6055
|
+
let r = 0;
|
|
6056
|
+
let s = 0;
|
|
6057
|
+
let z = 0;
|
|
6058
|
+
let t;
|
|
6059
|
+
let w;
|
|
6060
|
+
let x;
|
|
6061
|
+
let y;
|
|
6062
|
+
let norm4 = 0;
|
|
6063
|
+
for (let i = 0; i < nn; i++) {
|
|
6064
|
+
for (let j = Math.max(i - 1, 0); j < nn; j++) {
|
|
6065
|
+
norm4 += Math.abs(H[i * nn + j]);
|
|
6066
|
+
}
|
|
6067
|
+
}
|
|
6068
|
+
let nIdx = nn - 1;
|
|
6069
|
+
let iter = 0;
|
|
6070
|
+
while (nIdx >= low) {
|
|
6071
|
+
let l = nIdx;
|
|
6072
|
+
while (l > low) {
|
|
6073
|
+
s = Math.abs(H[(l - 1) * nn + (l - 1)]) + Math.abs(H[l * nn + l]);
|
|
6074
|
+
if (s === 0) s = norm4;
|
|
6075
|
+
if (Math.abs(H[l * nn + (l - 1)]) < eps * s) break;
|
|
6076
|
+
l--;
|
|
6077
|
+
}
|
|
6078
|
+
if (l === nIdx) {
|
|
6079
|
+
H[nIdx * nn + nIdx] = H[nIdx * nn + nIdx] + exshift;
|
|
6080
|
+
d[nIdx] = H[nIdx * nn + nIdx];
|
|
6081
|
+
e[nIdx] = 0;
|
|
6082
|
+
nIdx--;
|
|
6083
|
+
iter = 0;
|
|
6084
|
+
} else if (l === nIdx - 1) {
|
|
6085
|
+
w = H[nIdx * nn + (nIdx - 1)] * H[(nIdx - 1) * nn + nIdx];
|
|
6086
|
+
p = (H[(nIdx - 1) * nn + (nIdx - 1)] - H[nIdx * nn + nIdx]) / 2;
|
|
6087
|
+
q = p * p + w;
|
|
6088
|
+
z = Math.sqrt(Math.abs(q));
|
|
6089
|
+
H[nIdx * nn + nIdx] = H[nIdx * nn + nIdx] + exshift;
|
|
6090
|
+
H[(nIdx - 1) * nn + (nIdx - 1)] = H[(nIdx - 1) * nn + (nIdx - 1)] + exshift;
|
|
6091
|
+
x = H[nIdx * nn + nIdx];
|
|
6092
|
+
if (q >= 0) {
|
|
6093
|
+
z = p >= 0 ? p + z : p - z;
|
|
6094
|
+
d[nIdx - 1] = x + z;
|
|
6095
|
+
d[nIdx] = d[nIdx - 1];
|
|
6096
|
+
if (z !== 0) d[nIdx] = x - w / z;
|
|
6097
|
+
e[nIdx - 1] = 0;
|
|
6098
|
+
e[nIdx] = 0;
|
|
6099
|
+
x = H[nIdx * nn + (nIdx - 1)];
|
|
6100
|
+
s = Math.abs(x) + Math.abs(z);
|
|
6101
|
+
p = x / s;
|
|
6102
|
+
q = z / s;
|
|
6103
|
+
r = Math.sqrt(p * p + q * q);
|
|
6104
|
+
p = p / r;
|
|
6105
|
+
q = q / r;
|
|
6106
|
+
for (let j = nIdx - 1; j < nn; j++) {
|
|
6107
|
+
z = H[(nIdx - 1) * nn + j];
|
|
6108
|
+
H[(nIdx - 1) * nn + j] = q * z + p * H[nIdx * nn + j];
|
|
6109
|
+
H[nIdx * nn + j] = q * H[nIdx * nn + j] - p * z;
|
|
6110
|
+
}
|
|
6111
|
+
for (let i = 0; i <= nIdx; i++) {
|
|
6112
|
+
z = H[i * nn + (nIdx - 1)];
|
|
6113
|
+
H[i * nn + (nIdx - 1)] = q * z + p * H[i * nn + nIdx];
|
|
6114
|
+
H[i * nn + nIdx] = q * H[i * nn + nIdx] - p * z;
|
|
6115
|
+
}
|
|
6116
|
+
for (let i = low; i <= high; i++) {
|
|
6117
|
+
z = V[i * nn + (nIdx - 1)];
|
|
6118
|
+
V[i * nn + (nIdx - 1)] = q * z + p * V[i * nn + nIdx];
|
|
6119
|
+
V[i * nn + nIdx] = q * V[i * nn + nIdx] - p * z;
|
|
6120
|
+
}
|
|
6121
|
+
} else {
|
|
6122
|
+
d[nIdx - 1] = x + p;
|
|
6123
|
+
d[nIdx] = x + p;
|
|
6124
|
+
e[nIdx - 1] = z;
|
|
6125
|
+
e[nIdx] = -z;
|
|
6126
|
+
}
|
|
6127
|
+
nIdx = nIdx - 2;
|
|
6128
|
+
iter = 0;
|
|
6129
|
+
} else {
|
|
6130
|
+
x = H[nIdx * nn + nIdx];
|
|
6131
|
+
y = 0;
|
|
6132
|
+
w = 0;
|
|
6133
|
+
if (l < nIdx) {
|
|
6134
|
+
y = H[(nIdx - 1) * nn + (nIdx - 1)];
|
|
6135
|
+
w = H[nIdx * nn + (nIdx - 1)] * H[(nIdx - 1) * nn + nIdx];
|
|
6136
|
+
}
|
|
6137
|
+
if (iter === 10) {
|
|
6138
|
+
exshift += x;
|
|
6139
|
+
for (let i = low; i <= nIdx; i++) H[i * nn + i] -= x;
|
|
6140
|
+
s = Math.abs(H[nIdx * nn + (nIdx - 1)]) + Math.abs(H[(nIdx - 1) * nn + (nIdx - 2)]);
|
|
6141
|
+
x = y = 0.75 * s;
|
|
6142
|
+
w = -0.4375 * s * s;
|
|
6143
|
+
}
|
|
6144
|
+
if (iter === 30) {
|
|
6145
|
+
s = (y - x) / 2;
|
|
6146
|
+
s = s * s + w;
|
|
6147
|
+
if (s > 0) {
|
|
6148
|
+
s = Math.sqrt(s);
|
|
6149
|
+
if (y < x) s = -s;
|
|
6150
|
+
s = x - w / ((y - x) / 2 + s);
|
|
6151
|
+
for (let i = low; i <= nIdx; i++) H[i * nn + i] -= s;
|
|
6152
|
+
exshift += s;
|
|
6153
|
+
x = y = w = 0.964;
|
|
6154
|
+
}
|
|
6155
|
+
}
|
|
6156
|
+
iter = iter + 1;
|
|
6157
|
+
let m = nIdx - 2;
|
|
6158
|
+
while (m >= l) {
|
|
6159
|
+
z = H[m * nn + m];
|
|
6160
|
+
r = x - z;
|
|
6161
|
+
s = y - z;
|
|
6162
|
+
p = (r * s - w) / H[(m + 1) * nn + m] + H[m * nn + (m + 1)];
|
|
6163
|
+
q = H[(m + 1) * nn + (m + 1)] - z - r - s;
|
|
6164
|
+
r = H[(m + 2) * nn + (m + 1)];
|
|
6165
|
+
s = Math.abs(p) + Math.abs(q) + Math.abs(r);
|
|
6166
|
+
p = p / s;
|
|
6167
|
+
q = q / s;
|
|
6168
|
+
r = r / s;
|
|
6169
|
+
if (m === l) break;
|
|
6170
|
+
if (Math.abs(H[m * nn + (m - 1)]) * (Math.abs(q) + Math.abs(r)) < eps * (Math.abs(p) * (Math.abs(H[(m - 1) * nn + (m - 1)]) + Math.abs(z) + Math.abs(H[(m + 1) * nn + (m + 1)])))) {
|
|
6171
|
+
break;
|
|
6172
|
+
}
|
|
6173
|
+
m--;
|
|
6174
|
+
}
|
|
6175
|
+
for (let i = m + 2; i <= nIdx; i++) {
|
|
6176
|
+
H[i * nn + (i - 2)] = 0;
|
|
6177
|
+
if (i > m + 2) H[i * nn + (i - 3)] = 0;
|
|
6178
|
+
}
|
|
6179
|
+
for (let k = m; k <= nIdx - 1; k++) {
|
|
6180
|
+
const notlast = k !== nIdx - 1;
|
|
6181
|
+
if (k !== m) {
|
|
6182
|
+
p = H[k * nn + (k - 1)];
|
|
6183
|
+
q = H[(k + 1) * nn + (k - 1)];
|
|
6184
|
+
r = notlast ? H[(k + 2) * nn + (k - 1)] : 0;
|
|
6185
|
+
x = Math.abs(p) + Math.abs(q) + Math.abs(r);
|
|
6186
|
+
if (x !== 0) {
|
|
6187
|
+
p = p / x;
|
|
6188
|
+
q = q / x;
|
|
6189
|
+
r = r / x;
|
|
6190
|
+
}
|
|
6191
|
+
}
|
|
6192
|
+
if (x === 0) break;
|
|
6193
|
+
s = Math.sqrt(p * p + q * q + r * r);
|
|
6194
|
+
if (p < 0) s = -s;
|
|
6195
|
+
if (s !== 0) {
|
|
6196
|
+
if (k !== m) {
|
|
6197
|
+
H[k * nn + (k - 1)] = -s * x;
|
|
6198
|
+
} else if (l !== m) {
|
|
6199
|
+
H[k * nn + (k - 1)] = -H[k * nn + (k - 1)];
|
|
6200
|
+
}
|
|
6201
|
+
p = p + s;
|
|
6202
|
+
x = p / s;
|
|
6203
|
+
y = q / s;
|
|
6204
|
+
z = r / s;
|
|
6205
|
+
q = q / p;
|
|
6206
|
+
r = r / p;
|
|
6207
|
+
for (let j = k; j < nn; j++) {
|
|
6208
|
+
p = H[k * nn + j] + q * H[(k + 1) * nn + j];
|
|
6209
|
+
if (notlast) {
|
|
6210
|
+
p = p + r * H[(k + 2) * nn + j];
|
|
6211
|
+
H[(k + 2) * nn + j] = H[(k + 2) * nn + j] - p * z;
|
|
6212
|
+
}
|
|
6213
|
+
H[k * nn + j] = H[k * nn + j] - p * x;
|
|
6214
|
+
H[(k + 1) * nn + j] = H[(k + 1) * nn + j] - p * y;
|
|
6215
|
+
}
|
|
6216
|
+
const colEnd = Math.min(nIdx, k + 3);
|
|
6217
|
+
for (let i = 0; i <= colEnd; i++) {
|
|
6218
|
+
p = x * H[i * nn + k] + y * H[i * nn + (k + 1)];
|
|
6219
|
+
if (notlast) {
|
|
6220
|
+
p = p + z * H[i * nn + (k + 2)];
|
|
6221
|
+
H[i * nn + (k + 2)] = H[i * nn + (k + 2)] - p * r;
|
|
6222
|
+
}
|
|
6223
|
+
H[i * nn + k] = H[i * nn + k] - p;
|
|
6224
|
+
H[i * nn + (k + 1)] = H[i * nn + (k + 1)] - p * q;
|
|
6225
|
+
}
|
|
6226
|
+
for (let i = low; i <= high; i++) {
|
|
6227
|
+
p = x * V[i * nn + k] + y * V[i * nn + (k + 1)];
|
|
6228
|
+
if (notlast) {
|
|
6229
|
+
p = p + z * V[i * nn + (k + 2)];
|
|
6230
|
+
V[i * nn + (k + 2)] = V[i * nn + (k + 2)] - p * r;
|
|
6231
|
+
}
|
|
6232
|
+
V[i * nn + k] = V[i * nn + k] - p;
|
|
6233
|
+
V[i * nn + (k + 1)] = V[i * nn + (k + 1)] - p * q;
|
|
6234
|
+
}
|
|
6235
|
+
}
|
|
6236
|
+
}
|
|
6237
|
+
}
|
|
6238
|
+
}
|
|
6239
|
+
if (norm4 !== 0) {
|
|
6240
|
+
for (nIdx = nn - 1; nIdx >= 0; nIdx--) {
|
|
6241
|
+
p = d[nIdx];
|
|
6242
|
+
q = e[nIdx];
|
|
6243
|
+
if (q === 0) {
|
|
6244
|
+
let l = nIdx;
|
|
6245
|
+
H[nIdx * nn + nIdx] = 1;
|
|
6246
|
+
for (let i = nIdx - 1; i >= 0; i--) {
|
|
6247
|
+
w = H[i * nn + i] - p;
|
|
6248
|
+
r = 0;
|
|
6249
|
+
for (let j = l; j <= nIdx; j++) r += H[i * nn + j] * H[j * nn + nIdx];
|
|
6250
|
+
if (e[i] < 0) {
|
|
6251
|
+
z = w;
|
|
6252
|
+
s = r;
|
|
6253
|
+
} else {
|
|
6254
|
+
l = i;
|
|
6255
|
+
if (e[i] === 0) {
|
|
6256
|
+
H[i * nn + nIdx] = w !== 0 ? -r / w : -r / (eps * norm4);
|
|
6257
|
+
} else {
|
|
6258
|
+
x = H[i * nn + (i + 1)];
|
|
6259
|
+
y = H[(i + 1) * nn + i];
|
|
6260
|
+
q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
|
|
6261
|
+
t = (x * s - z * r) / q;
|
|
6262
|
+
H[i * nn + nIdx] = t;
|
|
6263
|
+
if (Math.abs(x) > Math.abs(z)) {
|
|
6264
|
+
H[(i + 1) * nn + nIdx] = (-r - w * t) / x;
|
|
6265
|
+
} else {
|
|
6266
|
+
H[(i + 1) * nn + nIdx] = (-s - y * t) / z;
|
|
6267
|
+
}
|
|
6268
|
+
}
|
|
6269
|
+
t = Math.abs(H[i * nn + nIdx]);
|
|
6270
|
+
if (eps * t * t > 1) {
|
|
6271
|
+
for (let j = i; j <= nIdx; j++) H[j * nn + nIdx] = H[j * nn + nIdx] / t;
|
|
6272
|
+
}
|
|
6273
|
+
}
|
|
6274
|
+
}
|
|
6275
|
+
} else if (q < 0) {
|
|
6276
|
+
let l = nIdx - 1;
|
|
6277
|
+
if (Math.abs(H[nIdx * nn + (nIdx - 1)]) > Math.abs(H[(nIdx - 1) * nn + nIdx])) {
|
|
6278
|
+
H[(nIdx - 1) * nn + (nIdx - 1)] = q / H[nIdx * nn + (nIdx - 1)];
|
|
6279
|
+
H[(nIdx - 1) * nn + nIdx] = -(H[nIdx * nn + nIdx] - p) / H[nIdx * nn + (nIdx - 1)];
|
|
6280
|
+
} else {
|
|
6281
|
+
const cd = cdiv(0, -H[(nIdx - 1) * nn + nIdx], H[(nIdx - 1) * nn + (nIdx - 1)] - p, q);
|
|
6282
|
+
H[(nIdx - 1) * nn + (nIdx - 1)] = cd.r;
|
|
6283
|
+
H[(nIdx - 1) * nn + nIdx] = cd.i;
|
|
6284
|
+
}
|
|
6285
|
+
H[nIdx * nn + (nIdx - 1)] = 0;
|
|
6286
|
+
H[nIdx * nn + nIdx] = 1;
|
|
6287
|
+
for (let i = nIdx - 2; i >= 0; i--) {
|
|
6288
|
+
let ra = 0;
|
|
6289
|
+
let sa = 0;
|
|
6290
|
+
for (let j = l; j <= nIdx; j++) {
|
|
6291
|
+
ra += H[i * nn + j] * H[j * nn + (nIdx - 1)];
|
|
6292
|
+
sa += H[i * nn + j] * H[j * nn + nIdx];
|
|
6293
|
+
}
|
|
6294
|
+
w = H[i * nn + i] - p;
|
|
6295
|
+
if (e[i] < 0) {
|
|
6296
|
+
z = w;
|
|
6297
|
+
r = ra;
|
|
6298
|
+
s = sa;
|
|
6299
|
+
} else {
|
|
6300
|
+
l = i;
|
|
6301
|
+
if (e[i] === 0) {
|
|
6302
|
+
const cd = cdiv(-ra, -sa, w, q);
|
|
6303
|
+
H[i * nn + (nIdx - 1)] = cd.r;
|
|
6304
|
+
H[i * nn + nIdx] = cd.i;
|
|
6305
|
+
} else {
|
|
6306
|
+
x = H[i * nn + (i + 1)];
|
|
6307
|
+
y = H[(i + 1) * nn + i];
|
|
6308
|
+
let vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
|
|
6309
|
+
const vi = (d[i] - p) * 2 * q;
|
|
6310
|
+
if (vr === 0 && vi === 0) {
|
|
6311
|
+
vr = eps * norm4 * (Math.abs(w) + Math.abs(q) + Math.abs(x) + Math.abs(y) + Math.abs(z));
|
|
6312
|
+
}
|
|
6313
|
+
const cd = cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi);
|
|
6314
|
+
H[i * nn + (nIdx - 1)] = cd.r;
|
|
6315
|
+
H[i * nn + nIdx] = cd.i;
|
|
6316
|
+
if (Math.abs(x) > Math.abs(z) + Math.abs(q)) {
|
|
6317
|
+
H[(i + 1) * nn + (nIdx - 1)] = (-ra - w * H[i * nn + (nIdx - 1)] + q * H[i * nn + nIdx]) / x;
|
|
6318
|
+
H[(i + 1) * nn + nIdx] = (-sa - w * H[i * nn + nIdx] - q * H[i * nn + (nIdx - 1)]) / x;
|
|
6319
|
+
} else {
|
|
6320
|
+
const cd2 = cdiv(-r - y * H[i * nn + (nIdx - 1)], -s - y * H[i * nn + nIdx], z, q);
|
|
6321
|
+
H[(i + 1) * nn + (nIdx - 1)] = cd2.r;
|
|
6322
|
+
H[(i + 1) * nn + nIdx] = cd2.i;
|
|
6323
|
+
}
|
|
6324
|
+
}
|
|
6325
|
+
t = Math.max(Math.abs(H[i * nn + (nIdx - 1)]), Math.abs(H[i * nn + nIdx]));
|
|
6326
|
+
if (eps * t * t > 1) {
|
|
6327
|
+
for (let j = i; j <= nIdx; j++) {
|
|
6328
|
+
H[j * nn + (nIdx - 1)] = H[j * nn + (nIdx - 1)] / t;
|
|
6329
|
+
H[j * nn + nIdx] = H[j * nn + nIdx] / t;
|
|
6330
|
+
}
|
|
6331
|
+
}
|
|
6332
|
+
}
|
|
6333
|
+
}
|
|
6334
|
+
}
|
|
6335
|
+
}
|
|
6336
|
+
for (let j = nn - 1; j >= low; j--) {
|
|
6337
|
+
for (let i = low; i <= high; i++) {
|
|
6338
|
+
z = 0;
|
|
6339
|
+
const kEnd = Math.min(j, high);
|
|
6340
|
+
for (let k = low; k <= kEnd; k++) z += V[i * nn + k] * H[k * nn + j];
|
|
6341
|
+
V[i * nn + j] = z;
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
}
|
|
6345
|
+
const values = [];
|
|
6346
|
+
for (let j = 0; j < nn; j++) values.push({ re: d[j], im: e[j] });
|
|
6347
|
+
let vectors;
|
|
6348
|
+
if (computeVectors) {
|
|
6349
|
+
vectors = [];
|
|
6350
|
+
for (let j = 0; j < nn; j++) {
|
|
6351
|
+
const vec = new Array(nn).fill(0);
|
|
6352
|
+
if (e[j] === 0) {
|
|
6353
|
+
let colNorm = 0;
|
|
6354
|
+
for (let i = 0; i < nn; i++) colNorm += V[i * nn + j] * V[i * nn + j];
|
|
6355
|
+
colNorm = Math.sqrt(colNorm);
|
|
6356
|
+
if (colNorm > 1e-300) {
|
|
6357
|
+
for (let i = 0; i < nn; i++) vec[i] = V[i * nn + j] / colNorm;
|
|
6358
|
+
} else {
|
|
6359
|
+
for (let i = 0; i < nn; i++) vec[i] = V[i * nn + j];
|
|
6360
|
+
}
|
|
6361
|
+
}
|
|
6362
|
+
vectors.push(vec);
|
|
6363
|
+
}
|
|
6364
|
+
} else {
|
|
6365
|
+
vectors = eye(nn);
|
|
6366
|
+
}
|
|
6367
|
+
return { values, vectors, isSymmetric: symmetric };
|
|
6368
|
+
}
|
|
6369
|
+
function eig(matrix2, options = {}) {
|
|
6370
|
+
const { computeVectors = true } = options;
|
|
6371
|
+
let A;
|
|
6372
|
+
if (matrix2 instanceof Float64Array) {
|
|
6373
|
+
const n2 = Math.sqrt(matrix2.length);
|
|
6374
|
+
if (n2 !== Math.floor(n2)) {
|
|
6375
|
+
throw new Error("Float64Array length must be a perfect square");
|
|
6376
|
+
}
|
|
6377
|
+
A = Array.from({ length: n2 }, (_, i) => Array.from({ length: n2 }, (_2, j) => matrix2[i * n2 + j]));
|
|
6378
|
+
} else {
|
|
6379
|
+
A = matrix2;
|
|
6380
|
+
}
|
|
6381
|
+
const n = A.length;
|
|
6382
|
+
if (n === 0) {
|
|
6383
|
+
return { values: [], vectors: [], isSymmetric: true };
|
|
6384
|
+
}
|
|
6385
|
+
for (let i = 0; i < n; i++) {
|
|
6386
|
+
if (A[i].length !== n) {
|
|
6387
|
+
throw new Error("Matrix must be square");
|
|
6388
|
+
}
|
|
6389
|
+
}
|
|
6390
|
+
const symmetric = isSymmetric(A);
|
|
6391
|
+
if (n === 1) {
|
|
6392
|
+
return {
|
|
6393
|
+
values: [{ re: A[0][0], im: 0 }],
|
|
6394
|
+
vectors: [[1]],
|
|
6395
|
+
isSymmetric: symmetric
|
|
6396
|
+
};
|
|
6397
|
+
}
|
|
6398
|
+
return eigGeneral(A, computeVectors, symmetric);
|
|
6399
|
+
}
|
|
6400
|
+
function eigvals(matrix2, options) {
|
|
6401
|
+
return eig(matrix2, { ...options, computeVectors: false }).values;
|
|
6402
|
+
}
|
|
6403
|
+
function powerIteration(matrix2, options = {}) {
|
|
6404
|
+
const { maxIterations = 1e3, tolerance = 1e-12 } = options;
|
|
6405
|
+
const n = matrix2.length;
|
|
6406
|
+
let v = Array.from({ length: n }, () => Math.random() - 0.5);
|
|
6407
|
+
let norm4 = Math.sqrt(v.reduce((sum3, x) => sum3 + x * x, 0));
|
|
6408
|
+
v = v.map((x) => x / norm4);
|
|
6409
|
+
let eigenvalue = 0;
|
|
6410
|
+
let prevEigenvalue = 0;
|
|
6411
|
+
for (let iter = 0; iter < maxIterations; iter++) {
|
|
6412
|
+
const w = new Array(n).fill(0);
|
|
6413
|
+
for (let i = 0; i < n; i++) {
|
|
6414
|
+
for (let j = 0; j < n; j++) {
|
|
6415
|
+
w[i] += matrix2[i][j] * v[j];
|
|
6416
|
+
}
|
|
6417
|
+
}
|
|
6418
|
+
eigenvalue = v.reduce((sum3, vi, i) => sum3 + vi * w[i], 0);
|
|
6419
|
+
norm4 = Math.sqrt(w.reduce((sum3, x) => sum3 + x * x, 0));
|
|
6420
|
+
v = w.map((x) => x / norm4);
|
|
6421
|
+
if (Math.abs(eigenvalue - prevEigenvalue) < tolerance * Math.abs(eigenvalue)) {
|
|
6422
|
+
break;
|
|
6423
|
+
}
|
|
6424
|
+
prevEigenvalue = eigenvalue;
|
|
6425
|
+
}
|
|
6426
|
+
return { value: eigenvalue, vector: v };
|
|
6427
|
+
}
|
|
6428
|
+
|
|
5975
6429
|
// src/operations/svd.ts
|
|
5976
6430
|
var DEFAULT_MAX_ITERATIONS = 1e3;
|
|
5977
6431
|
var DEFAULT_TOLERANCE = 1e-12;
|
|
@@ -6263,17 +6717,6 @@ function normFro(matrix2) {
|
|
|
6263
6717
|
}
|
|
6264
6718
|
|
|
6265
6719
|
// src/operations/eig-wasm.ts
|
|
6266
|
-
var WASM_EIG_THRESHOLD = 8;
|
|
6267
|
-
function flattenMatrix(matrix2) {
|
|
6268
|
-
const n = matrix2.length;
|
|
6269
|
-
const flat2 = new Float64Array(n * n);
|
|
6270
|
-
for (let i = 0; i < n; i++) {
|
|
6271
|
-
for (let j = 0; j < n; j++) {
|
|
6272
|
-
flat2[i * n + j] = matrix2[i][j];
|
|
6273
|
-
}
|
|
6274
|
-
}
|
|
6275
|
-
return flat2;
|
|
6276
|
-
}
|
|
6277
6720
|
async function eigWasm(matrix2, options) {
|
|
6278
6721
|
const n = matrix2.length;
|
|
6279
6722
|
if (n === 0) {
|
|
@@ -6284,113 +6727,14 @@ async function eigWasm(matrix2, options) {
|
|
|
6284
6727
|
throw new Error("Matrix must be square");
|
|
6285
6728
|
}
|
|
6286
6729
|
}
|
|
6287
|
-
|
|
6288
|
-
if (!module) {
|
|
6289
|
-
try {
|
|
6290
|
-
module = await wasmLoader.load();
|
|
6291
|
-
} catch {
|
|
6292
|
-
module = null;
|
|
6293
|
-
}
|
|
6294
|
-
}
|
|
6295
|
-
const symmetric = isSymmetric(matrix2);
|
|
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) {
|
|
6299
|
-
return eig(matrix2, options);
|
|
6300
|
-
}
|
|
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
|
-
});
|
|
6307
|
-
const flatMatrix = flattenMatrix(matrix2);
|
|
6308
|
-
const matrixAlloc = wasmLoader.allocateFloat64Array(Array.from(flatMatrix));
|
|
6309
|
-
try {
|
|
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) {
|
|
6338
|
-
return eig(matrix2, options);
|
|
6339
|
-
}
|
|
6340
|
-
const values = [];
|
|
6341
|
-
for (let j = 0; j < n; j++) {
|
|
6342
|
-
values.push({ re: packed[j], im: packed[n + j] });
|
|
6343
|
-
}
|
|
6344
|
-
let vectors;
|
|
6345
|
-
if (computeVectors) {
|
|
6346
|
-
vectors = [];
|
|
6347
|
-
for (let j = 0; j < n; j++) {
|
|
6348
|
-
const vec = [];
|
|
6349
|
-
for (let i = 0; i < n; i++) {
|
|
6350
|
-
vec.push(packed[2 * n + i * n + j]);
|
|
6351
|
-
}
|
|
6352
|
-
vectors.push(vec);
|
|
6353
|
-
}
|
|
6354
|
-
} else {
|
|
6355
|
-
vectors = identityVectors();
|
|
6356
|
-
}
|
|
6357
|
-
return { values, vectors, isSymmetric: false };
|
|
6358
|
-
} catch {
|
|
6359
|
-
return eig(matrix2, options);
|
|
6360
|
-
} finally {
|
|
6361
|
-
wasmLoader.free(matrixAlloc.ptr);
|
|
6362
|
-
}
|
|
6730
|
+
return eig(matrix2, options);
|
|
6363
6731
|
}
|
|
6364
6732
|
async function eigvalsWasm(matrix2, options) {
|
|
6365
|
-
|
|
6366
|
-
return result.values;
|
|
6733
|
+
return eigvals(matrix2, options);
|
|
6367
6734
|
}
|
|
6368
6735
|
async function spectralRadiusWasm(matrix2, options) {
|
|
6369
|
-
const
|
|
6370
|
-
|
|
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-PIFFHFJF.js");
|
|
6380
|
-
const result = powerIteration2(matrix2, options);
|
|
6381
|
-
return Math.abs(result.value);
|
|
6382
|
-
}
|
|
6383
|
-
const flatMatrix = flattenMatrix(matrix2);
|
|
6384
|
-
const matrixAlloc = wasmLoader.allocateFloat64Array(Array.from(flatMatrix));
|
|
6385
|
-
try {
|
|
6386
|
-
return module.matrix_spectral_radius(matrixAlloc.ptr, n);
|
|
6387
|
-
} catch {
|
|
6388
|
-
const { powerIteration: powerIteration2 } = await import("./eig-PIFFHFJF.js");
|
|
6389
|
-
const result = powerIteration2(matrix2, options);
|
|
6390
|
-
return Math.abs(result.value);
|
|
6391
|
-
} finally {
|
|
6392
|
-
wasmLoader.free(matrixAlloc.ptr);
|
|
6393
|
-
}
|
|
6736
|
+
const result = powerIteration(matrix2, options);
|
|
6737
|
+
return Math.abs(result.value);
|
|
6394
6738
|
}
|
|
6395
6739
|
|
|
6396
6740
|
// src/operations/svd-wasm.ts
|
|
@@ -6418,46 +6762,7 @@ async function svdWasm(matrix2, options) {
|
|
|
6418
6762
|
}
|
|
6419
6763
|
const k = Math.min(m, n);
|
|
6420
6764
|
const rankTolerance = options?.rankTolerance ?? 1e-10;
|
|
6421
|
-
|
|
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") {
|
|
6430
|
-
return toThin(svd(matrix2, options), k, rankTolerance);
|
|
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);
|
|
6437
|
-
try {
|
|
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) {
|
|
6441
|
-
return toThin(svd(matrix2, options), k, rankTolerance);
|
|
6442
|
-
}
|
|
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);
|
|
6446
|
-
const U = [];
|
|
6447
|
-
for (let i = 0; i < m; i++) {
|
|
6448
|
-
U.push(Array.from(uFlat.subarray(i * k, i * k + k)));
|
|
6449
|
-
}
|
|
6450
|
-
const V = [];
|
|
6451
|
-
for (let i = 0; i < n; i++) {
|
|
6452
|
-
V.push(Array.from(vFlat.subarray(i * k, i * k + k)));
|
|
6453
|
-
}
|
|
6454
|
-
const S = Array.from(sFlat);
|
|
6455
|
-
return { U, S, V, rank: estimateRank(S, rankTolerance) };
|
|
6456
|
-
} catch {
|
|
6457
|
-
return toThin(svd(matrix2, options), k, rankTolerance);
|
|
6458
|
-
} finally {
|
|
6459
|
-
wasmLoader.free(aAlloc.ptr);
|
|
6460
|
-
}
|
|
6765
|
+
return toThin(svd(matrix2, options), k, rankTolerance);
|
|
6461
6766
|
}
|
|
6462
6767
|
|
|
6463
6768
|
// src/operations/pinv.ts
|
|
@@ -7155,7 +7460,7 @@ function logmSchur(A, tol) {
|
|
|
7155
7460
|
const scale2 = Math.pow(2, numSqrt);
|
|
7156
7461
|
logT = logT.map((row2) => row2.map((v) => v * scale2));
|
|
7157
7462
|
}
|
|
7158
|
-
const Qt =
|
|
7463
|
+
const Qt = transpose2(Q);
|
|
7159
7464
|
return matMul(matMul(Q, logT), Qt);
|
|
7160
7465
|
}
|
|
7161
7466
|
function validateEigenvalues(A) {
|
|
@@ -7189,7 +7494,7 @@ function logmEig(A) {
|
|
|
7189
7494
|
}
|
|
7190
7495
|
}
|
|
7191
7496
|
const V = vectors;
|
|
7192
|
-
const Q =
|
|
7497
|
+
const Q = transpose2(V);
|
|
7193
7498
|
const Qinv = matInv(Q);
|
|
7194
7499
|
if (Qinv === null) {
|
|
7195
7500
|
throw new Error(
|
|
@@ -7314,9 +7619,9 @@ function sqrtmSymmetric(A) {
|
|
|
7314
7619
|
}
|
|
7315
7620
|
const Ynewton = sqrtmNewton(Asym);
|
|
7316
7621
|
if (Ynewton !== null) return Ynewton;
|
|
7317
|
-
const Qraw =
|
|
7622
|
+
const Qraw = transpose2(vectors);
|
|
7318
7623
|
const Q = gramSchmidt(Qraw);
|
|
7319
|
-
const Qt =
|
|
7624
|
+
const Qt = transpose2(Q);
|
|
7320
7625
|
const Dsqrt = eye(n);
|
|
7321
7626
|
for (let i = 0; i < n; i++) Dsqrt[i][i] = Math.sqrt(Math.max(values[i].re, 0));
|
|
7322
7627
|
return matMul(matMul(Q, Dsqrt), Qt);
|
|
@@ -7362,7 +7667,7 @@ function sqrtmGeneral(A) {
|
|
|
7362
7667
|
const Ynewton = sqrtmNewton(A);
|
|
7363
7668
|
if (Ynewton !== null) return Ynewton;
|
|
7364
7669
|
const V = vectors;
|
|
7365
|
-
const Q =
|
|
7670
|
+
const Q = transpose2(V);
|
|
7366
7671
|
const Qinv = matInv2(Q);
|
|
7367
7672
|
if (Qinv === null) {
|
|
7368
7673
|
throw new Error(
|
|
@@ -7490,7 +7795,7 @@ function sqrtmSchur(A) {
|
|
|
7490
7795
|
const { H: T, Q } = schurInternal(A);
|
|
7491
7796
|
const U = sqrtmQuasiTriangular(T);
|
|
7492
7797
|
if (U === null) return null;
|
|
7493
|
-
const Qt =
|
|
7798
|
+
const Qt = transpose2(Q);
|
|
7494
7799
|
return matMul(matMul(Q, U), Qt);
|
|
7495
7800
|
}
|
|
7496
7801
|
function matrixSqrtm(A, opts) {
|