pca-web 0.1.0
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/LICENSE +21 -0
- package/README.md +421 -0
- package/dist/base.d.ts +79 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +358 -0
- package/dist/base.js.map +1 -0
- package/dist/incremental-pca.d.ts +86 -0
- package/dist/incremental-pca.d.ts.map +1 -0
- package/dist/incremental-pca.js +397 -0
- package/dist/incremental-pca.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/matrix.d.ts +44 -0
- package/dist/matrix.d.ts.map +1 -0
- package/dist/matrix.js +99 -0
- package/dist/matrix.js.map +1 -0
- package/dist/model.d.ts +86 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +132 -0
- package/dist/model.js.map +1 -0
- package/dist/numeric/blas.d.ts +33 -0
- package/dist/numeric/blas.d.ts.map +1 -0
- package/dist/numeric/blas.js +130 -0
- package/dist/numeric/blas.js.map +1 -0
- package/dist/numeric/eigh.d.ts +21 -0
- package/dist/numeric/eigh.d.ts.map +1 -0
- package/dist/numeric/eigh.js +233 -0
- package/dist/numeric/eigh.js.map +1 -0
- package/dist/numeric/lanczos.d.ts +31 -0
- package/dist/numeric/lanczos.d.ts.map +1 -0
- package/dist/numeric/lanczos.js +287 -0
- package/dist/numeric/lanczos.js.map +1 -0
- package/dist/numeric/lu.d.ts +27 -0
- package/dist/numeric/lu.d.ts.map +1 -0
- package/dist/numeric/lu.js +149 -0
- package/dist/numeric/lu.js.map +1 -0
- package/dist/numeric/mle.d.ts +5 -0
- package/dist/numeric/mle.d.ts.map +1 -0
- package/dist/numeric/mle.js +67 -0
- package/dist/numeric/mle.js.map +1 -0
- package/dist/numeric/qr.d.ts +15 -0
- package/dist/numeric/qr.d.ts.map +1 -0
- package/dist/numeric/qr.js +88 -0
- package/dist/numeric/qr.js.map +1 -0
- package/dist/numeric/randomized.d.ts +54 -0
- package/dist/numeric/randomized.d.ts.map +1 -0
- package/dist/numeric/randomized.js +130 -0
- package/dist/numeric/randomized.js.map +1 -0
- package/dist/numeric/rng.d.ts +40 -0
- package/dist/numeric/rng.d.ts.map +1 -0
- package/dist/numeric/rng.js +127 -0
- package/dist/numeric/rng.js.map +1 -0
- package/dist/numeric/special.d.ts +2 -0
- package/dist/numeric/special.d.ts.map +1 -0
- package/dist/numeric/special.js +25 -0
- package/dist/numeric/special.js.map +1 -0
- package/dist/numeric/stats.d.ts +27 -0
- package/dist/numeric/stats.d.ts.map +1 -0
- package/dist/numeric/stats.js +110 -0
- package/dist/numeric/stats.js.map +1 -0
- package/dist/numeric/svd.d.ts +27 -0
- package/dist/numeric/svd.d.ts.map +1 -0
- package/dist/numeric/svd.js +374 -0
- package/dist/numeric/svd.js.map +1 -0
- package/dist/numeric/svdflip.d.ts +9 -0
- package/dist/numeric/svdflip.d.ts.map +1 -0
- package/dist/numeric/svdflip.js +32 -0
- package/dist/numeric/svdflip.js.map +1 -0
- package/dist/pca.d.ts +170 -0
- package/dist/pca.d.ts.map +1 -0
- package/dist/pca.js +649 -0
- package/dist/pca.js.map +1 -0
- package/dist/progress.d.ts +155 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +173 -0
- package/dist/progress.js.map +1 -0
- package/dist/scheduling.d.ts +66 -0
- package/dist/scheduling.d.ts.map +1 -0
- package/dist/scheduling.js +160 -0
- package/dist/scheduling.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +17 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +36 -0
- package/dist/validation.js.map +1 -0
- package/dist/webgpu/df64.d.ts +18 -0
- package/dist/webgpu/df64.d.ts.map +1 -0
- package/dist/webgpu/df64.js +42 -0
- package/dist/webgpu/df64.js.map +1 -0
- package/dist/webgpu/engine.d.ts +74 -0
- package/dist/webgpu/engine.d.ts.map +1 -0
- package/dist/webgpu/engine.js +326 -0
- package/dist/webgpu/engine.js.map +1 -0
- package/dist/webgpu/gpu-pca.d.ts +90 -0
- package/dist/webgpu/gpu-pca.d.ts.map +1 -0
- package/dist/webgpu/gpu-pca.js +407 -0
- package/dist/webgpu/gpu-pca.js.map +1 -0
- package/dist/webgpu/index.d.ts +19 -0
- package/dist/webgpu/index.d.ts.map +1 -0
- package/dist/webgpu/index.js +16 -0
- package/dist/webgpu/index.js.map +1 -0
- package/dist/webgpu/kernels.d.ts +47 -0
- package/dist/webgpu/kernels.d.ts.map +1 -0
- package/dist/webgpu/kernels.js +147 -0
- package/dist/webgpu/kernels.js.map +1 -0
- package/dist/worker/client.d.ts +174 -0
- package/dist/worker/client.d.ts.map +1 -0
- package/dist/worker/client.js +482 -0
- package/dist/worker/client.js.map +1 -0
- package/dist/worker/handler.d.ts +17 -0
- package/dist/worker/handler.d.ts.map +1 -0
- package/dist/worker/handler.js +404 -0
- package/dist/worker/handler.js.map +1 -0
- package/dist/worker/protocol.d.ts +192 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +70 -0
- package/dist/worker/protocol.js.map +1 -0
- package/dist/worker/worker.d.ts +14 -0
- package/dist/worker/worker.d.ts.map +1 -0
- package/dist/worker/worker.js +20 -0
- package/dist/worker/worker.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Economy QR decomposition via Householder reflections, matching
|
|
3
|
+
* `scipy.linalg.qr(mode='economic')` (LAPACK dgeqrf/dorgqr) up to roundoff,
|
|
4
|
+
* including the sign convention (R's diagonal is -sign(a_kk)·‖column‖), so
|
|
5
|
+
* Q matches scipy's column-for-column on the same input.
|
|
6
|
+
*/
|
|
7
|
+
export interface QrResult {
|
|
8
|
+
/** Q, m × k orthonormal columns, k = min(m, n). */
|
|
9
|
+
q: Float64Array;
|
|
10
|
+
/** R, k × n upper triangular. */
|
|
11
|
+
r: Float64Array;
|
|
12
|
+
}
|
|
13
|
+
/** Economy QR of `a` (m×n row-major, read-only). */
|
|
14
|
+
export declare function qrEconomic(a: Float64Array, m: number, n: number): QrResult;
|
|
15
|
+
//# sourceMappingURL=qr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../../src/numeric/qr.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,mDAAmD;IACnD,CAAC,EAAE,YAAY,CAAC;IAChB,iCAAiC;IACjC,CAAC,EAAE,YAAY,CAAC;CACjB;AAgBD,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAsE1E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Economy QR decomposition via Householder reflections, matching
|
|
3
|
+
* `scipy.linalg.qr(mode='economic')` (LAPACK dgeqrf/dorgqr) up to roundoff,
|
|
4
|
+
* including the sign convention (R's diagonal is -sign(a_kk)·‖column‖), so
|
|
5
|
+
* Q matches scipy's column-for-column on the same input.
|
|
6
|
+
*/
|
|
7
|
+
function hypot2(a, b) {
|
|
8
|
+
const aa = Math.abs(a);
|
|
9
|
+
const ab = Math.abs(b);
|
|
10
|
+
if (aa > ab) {
|
|
11
|
+
const t = ab / aa;
|
|
12
|
+
return aa * Math.sqrt(1 + t * t);
|
|
13
|
+
}
|
|
14
|
+
if (ab === 0) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
const t = aa / ab;
|
|
18
|
+
return ab * Math.sqrt(1 + t * t);
|
|
19
|
+
}
|
|
20
|
+
/** Economy QR of `a` (m×n row-major, read-only). */
|
|
21
|
+
export function qrEconomic(a, m, n) {
|
|
22
|
+
const k = Math.min(m, n);
|
|
23
|
+
const qr = a.slice();
|
|
24
|
+
const rdiag = new Float64Array(k);
|
|
25
|
+
for (let c = 0; c < k; c++) {
|
|
26
|
+
// LAPACK dlarfg semantics: when nothing is stored below the diagonal
|
|
27
|
+
// (norm of the subvector is zero), tau = 0 and H = I — no reflection,
|
|
28
|
+
// and R keeps the diagonal entry's original sign.
|
|
29
|
+
let nrmBelow = 0;
|
|
30
|
+
for (let i = c + 1; i < m; i++) {
|
|
31
|
+
nrmBelow = hypot2(nrmBelow, qr[i * n + c]);
|
|
32
|
+
}
|
|
33
|
+
if (nrmBelow === 0) {
|
|
34
|
+
rdiag[c] = qr[c * n + c];
|
|
35
|
+
qr[c * n + c] = 0; // flags "no reflector" for the Q accumulation
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
let nrm = hypot2(qr[c * n + c], nrmBelow);
|
|
39
|
+
if (qr[c * n + c] < 0) {
|
|
40
|
+
nrm = -nrm;
|
|
41
|
+
}
|
|
42
|
+
for (let i = c; i < m; i++) {
|
|
43
|
+
qr[i * n + c] /= nrm;
|
|
44
|
+
}
|
|
45
|
+
qr[c * n + c] += 1.0;
|
|
46
|
+
for (let j = c + 1; j < n; j++) {
|
|
47
|
+
let s = 0;
|
|
48
|
+
for (let i = c; i < m; i++) {
|
|
49
|
+
s += qr[i * n + c] * qr[i * n + j];
|
|
50
|
+
}
|
|
51
|
+
s = -s / qr[c * n + c];
|
|
52
|
+
for (let i = c; i < m; i++) {
|
|
53
|
+
qr[i * n + j] += s * qr[i * n + c];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
rdiag[c] = -nrm;
|
|
57
|
+
}
|
|
58
|
+
// R (k×n): upper triangle of the reduced matrix with rdiag on the diagonal.
|
|
59
|
+
const r = new Float64Array(k * n);
|
|
60
|
+
for (let i = 0; i < k; i++) {
|
|
61
|
+
r[i * n + i] = rdiag[i];
|
|
62
|
+
for (let j = i + 1; j < n; j++) {
|
|
63
|
+
r[i * n + j] = qr[i * n + j];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Q (m×k): accumulate reflectors backwards.
|
|
67
|
+
const q = new Float64Array(m * k);
|
|
68
|
+
for (let c = k - 1; c >= 0; c--) {
|
|
69
|
+
for (let i = 0; i < m; i++) {
|
|
70
|
+
q[i * k + c] = 0;
|
|
71
|
+
}
|
|
72
|
+
q[c * k + c] = 1;
|
|
73
|
+
for (let j = c; j < k; j++) {
|
|
74
|
+
if (qr[c * n + c] !== 0) {
|
|
75
|
+
let s = 0;
|
|
76
|
+
for (let i = c; i < m; i++) {
|
|
77
|
+
s += qr[i * n + c] * q[i * k + j];
|
|
78
|
+
}
|
|
79
|
+
s = -s / qr[c * n + c];
|
|
80
|
+
for (let i = c; i < m; i++) {
|
|
81
|
+
q[i * k + j] += s * qr[i * n + c];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { q, r };
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=qr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr.js","sourceRoot":"","sources":["../../src/numeric/qr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of sklearn's `_randomized_svd` (Halko et al.), matching the 1.9.0
|
|
3
|
+
* implementation step for step: same transpose heuristic, same Gaussian test
|
|
4
|
+
* matrix drawn from the numpy RandomState replica, same power-iteration
|
|
5
|
+
* normalizers ('auto' → LU when n_iter > 2, else none), same final economic
|
|
6
|
+
* QR and small SVD. With the same seed this reproduces sklearn's randomized
|
|
7
|
+
* PCA output to floating-point accuracy.
|
|
8
|
+
*
|
|
9
|
+
* The algorithm is written once, as a generator that yields the three
|
|
10
|
+
* products against the (large, possibly device-resident) input matrix and
|
|
11
|
+
* receives their results; everything between yields — panel QR/LU, the small
|
|
12
|
+
* SVD, truncation — is plain CPU code. `randomizedSvd` drives the generator
|
|
13
|
+
* synchronously against the CPU BLAS; the WebGPU backend drives the same
|
|
14
|
+
* generator asynchronously against device-resident buffers, so the two paths
|
|
15
|
+
* cannot drift structurally.
|
|
16
|
+
*/
|
|
17
|
+
import type { SolverHooks } from '../progress.js';
|
|
18
|
+
import type { FloatArray } from '../types.js';
|
|
19
|
+
import type { RandomState } from './rng.js';
|
|
20
|
+
import { type SvdResult } from './svd.js';
|
|
21
|
+
export interface RandomizedSvdOptions {
|
|
22
|
+
nOversamples: number;
|
|
23
|
+
nIter: number | 'auto';
|
|
24
|
+
powerIterationNormalizer: 'auto' | 'QR' | 'LU' | 'none';
|
|
25
|
+
rng: RandomState;
|
|
26
|
+
/** Round the Gaussian test matrix to float32, as sklearn does for float32 inputs. */
|
|
27
|
+
float32Stream: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Progress/snapshot channel (type-only dependency). Emits one event per
|
|
30
|
+
* power iteration; snapshot decompositions (an extra `finishFromBasis`
|
|
31
|
+
* pass whose GEMMs ride the ordinary yield channel) are computed only
|
|
32
|
+
* when `wantSnapshot` says so. Draws no RNG either way, so the stream is
|
|
33
|
+
* bit-identical with hooks on or off.
|
|
34
|
+
*/
|
|
35
|
+
hooks?: SolverHooks | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A product request against the input matrix A (rows×cols):
|
|
39
|
+
* - mulA: A @ b (b is cols×w, result rows×w)
|
|
40
|
+
* - mulAT: Aᵀ @ b (b is rows×w, result cols×w)
|
|
41
|
+
* - mulTA: bᵀ @ A (b is rows×w, result w×cols)
|
|
42
|
+
*/
|
|
43
|
+
export interface BigGemmRequest {
|
|
44
|
+
op: 'mulA' | 'mulAT' | 'mulTA';
|
|
45
|
+
b: Float64Array;
|
|
46
|
+
w: number;
|
|
47
|
+
}
|
|
48
|
+
/** The randomized-SVD algorithm, independent of how A-products are computed. */
|
|
49
|
+
export declare function randomizedSvdSteps(rows: number, cols: number, k: number, opts: RandomizedSvdOptions): Generator<BigGemmRequest, SvdResult, Float64Array>;
|
|
50
|
+
/** Computes one A-product request on the CPU BLAS. */
|
|
51
|
+
export declare function computeBigGemm(a: FloatArray, rows: number, cols: number, req: BigGemmRequest): Float64Array;
|
|
52
|
+
/** Top-k randomized SVD of `a` (rows×cols). Returns U (rows×k), s (k), Vt (k×cols). */
|
|
53
|
+
export declare function randomizedSvd(a: FloatArray, rows: number, cols: number, k: number, opts: RandomizedSvdOptions): SvdResult;
|
|
54
|
+
//# sourceMappingURL=randomized.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomized.d.ts","sourceRoot":"","sources":["../../src/numeric/randomized.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,KAAK,SAAS,EAAO,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IACxD,GAAG,EAAE,WAAW,CAAC;IACjB,qFAAqF;IACrF,aAAa,EAAE,OAAO,CAAC;IACvB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/B,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,MAAM,CAAC;CACX;AAED,gFAAgF;AAChF,wBAAiB,kBAAkB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,oBAAoB,GACzB,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE,YAAY,CAAC,CAoHpD;AAED,sDAAsD;AACtD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,UAAU,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,GAClB,YAAY,CAQd;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAC3B,CAAC,EAAE,UAAU,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,oBAAoB,GACzB,SAAS,CAOX"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { matmul, matmulTransA, transpose } from './blas.js';
|
|
2
|
+
import { luFactor, permutedL } from './lu.js';
|
|
3
|
+
import { qrEconomic } from './qr.js';
|
|
4
|
+
import { svd } from './svd.js';
|
|
5
|
+
/** The randomized-SVD algorithm, independent of how A-products are computed. */
|
|
6
|
+
export function* randomizedSvdSteps(rows, cols, k, opts) {
|
|
7
|
+
const nRandom = k + opts.nOversamples;
|
|
8
|
+
let nIter;
|
|
9
|
+
if (opts.nIter === 'auto') {
|
|
10
|
+
// "7 was found a good compromise for PCA" — sklearn #5299.
|
|
11
|
+
nIter = k < 0.1 * Math.min(rows, cols) ? 7 : 4;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
nIter = opts.nIter;
|
|
15
|
+
}
|
|
16
|
+
const transposed = rows < cols;
|
|
17
|
+
const effRows = transposed ? cols : rows;
|
|
18
|
+
const effCols = transposed ? rows : cols;
|
|
19
|
+
// Aeff @ B and Aeffᵀ @ B without materializing the transpose.
|
|
20
|
+
const mulAeff = (b, w) => transposed ? { op: 'mulAT', b, w } : { op: 'mulA', b, w };
|
|
21
|
+
const mulAeffT = (b, w) => transposed ? { op: 'mulA', b, w } : { op: 'mulAT', b, w };
|
|
22
|
+
// Gaussian test matrix, shape (effCols, nRandom), C-order draw.
|
|
23
|
+
let q = new Float64Array(effCols * nRandom);
|
|
24
|
+
opts.rng.standardNormal(q);
|
|
25
|
+
if (opts.float32Stream) {
|
|
26
|
+
for (let i = 0; i < q.length; i++) {
|
|
27
|
+
q[i] = Math.fround(q[i]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let qWidth = nRandom;
|
|
31
|
+
let normalizer = opts.powerIterationNormalizer;
|
|
32
|
+
if (normalizer === 'auto') {
|
|
33
|
+
normalizer = nIter <= 2 ? 'none' : 'LU';
|
|
34
|
+
}
|
|
35
|
+
const applyNormalizer = (m_, mRows, mCols) => {
|
|
36
|
+
if (normalizer === 'LU') {
|
|
37
|
+
const f = luFactor(m_, mRows, mCols);
|
|
38
|
+
return permutedL(f, mRows, mCols);
|
|
39
|
+
}
|
|
40
|
+
if (normalizer === 'QR') {
|
|
41
|
+
return qrEconomic(m_, mRows, mCols).q;
|
|
42
|
+
}
|
|
43
|
+
return m_;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Finishes a decomposition from a range basis: orthonormalize, form
|
|
47
|
+
* B = QᵀAeff, small SVD, truncate to k, undo the transpose — exactly like
|
|
48
|
+
* sklearn. Shared verbatim by the final path and mid-fit snapshots, so
|
|
49
|
+
* the two cannot drift. Reads `basis` only (qrEconomic copies), draws no
|
|
50
|
+
* RNG, and returns fresh arrays.
|
|
51
|
+
*/
|
|
52
|
+
function* finishFromBasis(basis, basisWidth) {
|
|
53
|
+
// Orthonormal basis of the sampled range.
|
|
54
|
+
const proj = yield mulAeff(basis, basisWidth); // effRows × basisWidth
|
|
55
|
+
const qFinal = qrEconomic(proj, effRows, basisWidth).q;
|
|
56
|
+
const qCols = Math.min(effRows, basisWidth);
|
|
57
|
+
// B = Qᵀ Aeff (qCols × effCols), then SVD of the small B.
|
|
58
|
+
let b;
|
|
59
|
+
if (transposed) {
|
|
60
|
+
// B = Qᵀ Aᵀ = (A Q)ᵀ.
|
|
61
|
+
const aq = yield { op: 'mulA', b: qFinal, w: qCols };
|
|
62
|
+
b = transpose(aq, rows, qCols);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
b = yield { op: 'mulTA', b: qFinal, w: qCols };
|
|
66
|
+
}
|
|
67
|
+
const { u: uhat, s, vt } = svd(b, qCols, effCols);
|
|
68
|
+
const nu = Math.min(qCols, effCols);
|
|
69
|
+
const uFull = matmul(qFinal, uhat, effRows, qCols, nu); // effRows × nu
|
|
70
|
+
// Truncate to k and undo the transpose, exactly like sklearn.
|
|
71
|
+
if (!transposed) {
|
|
72
|
+
const u = new Float64Array(rows * k);
|
|
73
|
+
for (let i = 0; i < rows; i++) {
|
|
74
|
+
for (let c = 0; c < k; c++) {
|
|
75
|
+
u[i * k + c] = uFull[i * nu + c];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { u, s: s.slice(0, k), vt: vt.slice(0, k * effCols) };
|
|
79
|
+
}
|
|
80
|
+
// A = (Aeff)ᵀ = V Σ Uᵀ: U_A = Vt[:k].T (rows×k), Vt_A = (U[:, :k])ᵀ (k×cols).
|
|
81
|
+
const uA = new Float64Array(rows * k);
|
|
82
|
+
for (let i = 0; i < rows; i++) {
|
|
83
|
+
for (let c = 0; c < k; c++) {
|
|
84
|
+
uA[i * k + c] = vt[c * effCols + i];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const vtA = new Float64Array(k * cols);
|
|
88
|
+
for (let c = 0; c < k; c++) {
|
|
89
|
+
for (let i = 0; i < cols; i++) {
|
|
90
|
+
vtA[c * cols + i] = uFull[i * nu + c];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { u: uA, s: s.slice(0, k), vt: vtA };
|
|
94
|
+
}
|
|
95
|
+
// Power iterations imprint the top singular vectors of Aeff onto Q.
|
|
96
|
+
const hooks = opts.hooks ?? null;
|
|
97
|
+
for (let it = 0; it < nIter; it++) {
|
|
98
|
+
let t = yield mulAeff(q, qWidth); // effRows × qWidth
|
|
99
|
+
t = applyNormalizer(t, effRows, qWidth);
|
|
100
|
+
const tWidth = normalizer === 'none' ? qWidth : Math.min(effRows, qWidth);
|
|
101
|
+
q = yield mulAeffT(t, tWidth); // effCols × tWidth
|
|
102
|
+
q = applyNormalizer(q, effCols, tWidth);
|
|
103
|
+
qWidth = normalizer === 'none' ? tWidth : Math.min(effCols, tWidth);
|
|
104
|
+
if (hooks) {
|
|
105
|
+
const dec = hooks.wantSnapshot(it + 1) ? yield* finishFromBasis(q, qWidth) : null;
|
|
106
|
+
hooks.emit({ phase: 'power-iteration', step: it + 1, totalSteps: nIter, dec });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return yield* finishFromBasis(q, qWidth);
|
|
110
|
+
}
|
|
111
|
+
/** Computes one A-product request on the CPU BLAS. */
|
|
112
|
+
export function computeBigGemm(a, rows, cols, req) {
|
|
113
|
+
if (req.op === 'mulA') {
|
|
114
|
+
return matmul(a, req.b, rows, cols, req.w);
|
|
115
|
+
}
|
|
116
|
+
if (req.op === 'mulAT') {
|
|
117
|
+
return matmulTransA(a, req.b, rows, cols, req.w);
|
|
118
|
+
}
|
|
119
|
+
return matmulTransA(req.b, a, rows, req.w, cols);
|
|
120
|
+
}
|
|
121
|
+
/** Top-k randomized SVD of `a` (rows×cols). Returns U (rows×k), s (k), Vt (k×cols). */
|
|
122
|
+
export function randomizedSvd(a, rows, cols, k, opts) {
|
|
123
|
+
const gen = randomizedSvdSteps(rows, cols, k, opts);
|
|
124
|
+
let step = gen.next();
|
|
125
|
+
while (!step.done) {
|
|
126
|
+
step = gen.next(computeBigGemm(a, rows, cols, step.value));
|
|
127
|
+
}
|
|
128
|
+
return step.value;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=randomized.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomized.js","sourceRoot":"","sources":["../../src/numeric/randomized.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replica of numpy's legacy `numpy.random.RandomState` for the streams PCA
|
|
3
|
+
* needs: `uniform` and `normal` (the legacy Box–Muller *polar* Gaussian with
|
|
4
|
+
* its one-value cache). Bit-compatible MT19937 core; floating-point results
|
|
5
|
+
* match numpy to within 1–2 ulp (Math.log may differ from C libm by ≤1 ulp).
|
|
6
|
+
*
|
|
7
|
+
* This is what makes `svdSolver: 'randomized'` reproduce scikit-learn's
|
|
8
|
+
* output for the same `randomState` seed: sklearn draws its Gaussian test
|
|
9
|
+
* matrix from `RandomState(seed).normal(...)`.
|
|
10
|
+
*/
|
|
11
|
+
export declare class RandomState {
|
|
12
|
+
private mt;
|
|
13
|
+
private mti;
|
|
14
|
+
private hasGauss;
|
|
15
|
+
private gauss;
|
|
16
|
+
/**
|
|
17
|
+
* Seeds like `numpy.random.RandomState(seed)`: an integer in [0, 2^32)
|
|
18
|
+
* (numpy's legacy seeding rejects anything larger). Omitted seed draws one
|
|
19
|
+
* from `Math.random()` (non-reproducible, mirroring sklearn's
|
|
20
|
+
* `random_state=None`).
|
|
21
|
+
*/
|
|
22
|
+
constructor(seed?: number | null);
|
|
23
|
+
private initGenrand;
|
|
24
|
+
/** Next 32-bit unsigned integer from the MT19937 stream. */
|
|
25
|
+
nextUint32(): number;
|
|
26
|
+
/** numpy `random_sample()`: 53-bit uniform double in [0, 1). */
|
|
27
|
+
randomSample(): number;
|
|
28
|
+
/** numpy legacy `gauss`: polar Box–Muller with one-value cache. */
|
|
29
|
+
nextGauss(): number;
|
|
30
|
+
/** Fills `out` with N(0,1) draws in C order, like `normal(size=...)`. */
|
|
31
|
+
standardNormal(out: Float64Array): Float64Array;
|
|
32
|
+
/** Fills `out` with `low + (high-low) * random_sample()` draws. */
|
|
33
|
+
uniform(low: number, high: number, out: Float64Array): Float64Array;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* sklearn's `check_random_state`: an integer seeds a fresh RandomState, an
|
|
37
|
+
* existing RandomState passes through, null/undefined gives an unseeded one.
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkRandomState(state: number | RandomState | null | undefined): RandomState;
|
|
40
|
+
//# sourceMappingURL=rng.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rng.d.ts","sourceRoot":"","sources":["../../src/numeric/rng.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAsB;IAChC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAK;IAElB;;;;;OAKG;gBACS,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAWhC,OAAO,CAAC,WAAW;IAanB,4DAA4D;IAC5D,UAAU,IAAI,MAAM;IAwBpB,gEAAgE;IAChE,YAAY,IAAI,MAAM;IAMtB,mEAAmE;IACnE,SAAS,IAAI,MAAM;IAqBnB,yEAAyE;IACzE,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY;IAO/C,mEAAmE;IACnE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,YAAY;CAOpE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,WAAW,CAK5F"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replica of numpy's legacy `numpy.random.RandomState` for the streams PCA
|
|
3
|
+
* needs: `uniform` and `normal` (the legacy Box–Muller *polar* Gaussian with
|
|
4
|
+
* its one-value cache). Bit-compatible MT19937 core; floating-point results
|
|
5
|
+
* match numpy to within 1–2 ulp (Math.log may differ from C libm by ≤1 ulp).
|
|
6
|
+
*
|
|
7
|
+
* This is what makes `svdSolver: 'randomized'` reproduce scikit-learn's
|
|
8
|
+
* output for the same `randomState` seed: sklearn draws its Gaussian test
|
|
9
|
+
* matrix from `RandomState(seed).normal(...)`.
|
|
10
|
+
*/
|
|
11
|
+
const N = 624;
|
|
12
|
+
const M = 397;
|
|
13
|
+
const MATRIX_A = 0x9908b0df;
|
|
14
|
+
const UPPER_MASK = 0x80000000;
|
|
15
|
+
const LOWER_MASK = 0x7fffffff;
|
|
16
|
+
export class RandomState {
|
|
17
|
+
mt = new Uint32Array(N);
|
|
18
|
+
mti = N + 1;
|
|
19
|
+
hasGauss = false;
|
|
20
|
+
gauss = 0;
|
|
21
|
+
/**
|
|
22
|
+
* Seeds like `numpy.random.RandomState(seed)`: an integer in [0, 2^32)
|
|
23
|
+
* (numpy's legacy seeding rejects anything larger). Omitted seed draws one
|
|
24
|
+
* from `Math.random()` (non-reproducible, mirroring sklearn's
|
|
25
|
+
* `random_state=None`).
|
|
26
|
+
*/
|
|
27
|
+
constructor(seed) {
|
|
28
|
+
if (seed === undefined || seed === null) {
|
|
29
|
+
this.initGenrand((Math.random() * 0x100000000) >>> 0);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) {
|
|
33
|
+
throw new RangeError(`randomState seed must be an integer in [0, 2**32 - 1], got ${seed}`);
|
|
34
|
+
}
|
|
35
|
+
this.initGenrand(seed);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
initGenrand(s) {
|
|
39
|
+
const mt = this.mt;
|
|
40
|
+
mt[0] = s >>> 0;
|
|
41
|
+
for (let i = 1; i < N; i++) {
|
|
42
|
+
const prev = mt[i - 1] ^ (mt[i - 1] >>> 30);
|
|
43
|
+
// 1812433253 * prev + i (mod 2^32)
|
|
44
|
+
mt[i] = (Math.imul(1812433253, prev) + i) >>> 0;
|
|
45
|
+
}
|
|
46
|
+
this.mti = N;
|
|
47
|
+
this.hasGauss = false;
|
|
48
|
+
this.gauss = 0;
|
|
49
|
+
}
|
|
50
|
+
/** Next 32-bit unsigned integer from the MT19937 stream. */
|
|
51
|
+
nextUint32() {
|
|
52
|
+
const mt = this.mt;
|
|
53
|
+
if (this.mti >= N) {
|
|
54
|
+
let y;
|
|
55
|
+
for (let kk = 0; kk < N - M; kk++) {
|
|
56
|
+
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
|
|
57
|
+
mt[kk] = mt[kk + M] ^ (y >>> 1) ^ (y & 1 ? MATRIX_A : 0);
|
|
58
|
+
}
|
|
59
|
+
for (let kk = N - M; kk < N - 1; kk++) {
|
|
60
|
+
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
|
|
61
|
+
mt[kk] = mt[kk + (M - N)] ^ (y >>> 1) ^ (y & 1 ? MATRIX_A : 0);
|
|
62
|
+
}
|
|
63
|
+
y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
|
64
|
+
mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ (y & 1 ? MATRIX_A : 0);
|
|
65
|
+
this.mti = 0;
|
|
66
|
+
}
|
|
67
|
+
let y = mt[this.mti++];
|
|
68
|
+
y ^= y >>> 11;
|
|
69
|
+
y = (y ^ ((y << 7) & 0x9d2c5680)) >>> 0;
|
|
70
|
+
y = (y ^ ((y << 15) & 0xefc60000)) >>> 0;
|
|
71
|
+
y ^= y >>> 18;
|
|
72
|
+
return y >>> 0;
|
|
73
|
+
}
|
|
74
|
+
/** numpy `random_sample()`: 53-bit uniform double in [0, 1). */
|
|
75
|
+
randomSample() {
|
|
76
|
+
const a = this.nextUint32() >>> 5;
|
|
77
|
+
const b = this.nextUint32() >>> 6;
|
|
78
|
+
return (a * 67108864 + b) / 9007199254740992;
|
|
79
|
+
}
|
|
80
|
+
/** numpy legacy `gauss`: polar Box–Muller with one-value cache. */
|
|
81
|
+
nextGauss() {
|
|
82
|
+
if (this.hasGauss) {
|
|
83
|
+
const temp = this.gauss;
|
|
84
|
+
this.hasGauss = false;
|
|
85
|
+
this.gauss = 0;
|
|
86
|
+
return temp;
|
|
87
|
+
}
|
|
88
|
+
let x1;
|
|
89
|
+
let x2;
|
|
90
|
+
let r2;
|
|
91
|
+
do {
|
|
92
|
+
x1 = 2.0 * this.randomSample() - 1.0;
|
|
93
|
+
x2 = 2.0 * this.randomSample() - 1.0;
|
|
94
|
+
r2 = x1 * x1 + x2 * x2;
|
|
95
|
+
} while (r2 >= 1.0 || r2 === 0.0);
|
|
96
|
+
const f = Math.sqrt((-2.0 * Math.log(r2)) / r2);
|
|
97
|
+
this.gauss = f * x1;
|
|
98
|
+
this.hasGauss = true;
|
|
99
|
+
return f * x2;
|
|
100
|
+
}
|
|
101
|
+
/** Fills `out` with N(0,1) draws in C order, like `normal(size=...)`. */
|
|
102
|
+
standardNormal(out) {
|
|
103
|
+
for (let i = 0; i < out.length; i++) {
|
|
104
|
+
out[i] = this.nextGauss();
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/** Fills `out` with `low + (high-low) * random_sample()` draws. */
|
|
109
|
+
uniform(low, high, out) {
|
|
110
|
+
const scale = high - low;
|
|
111
|
+
for (let i = 0; i < out.length; i++) {
|
|
112
|
+
out[i] = low + scale * this.randomSample();
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* sklearn's `check_random_state`: an integer seeds a fresh RandomState, an
|
|
119
|
+
* existing RandomState passes through, null/undefined gives an unseeded one.
|
|
120
|
+
*/
|
|
121
|
+
export function checkRandomState(state) {
|
|
122
|
+
if (state instanceof RandomState) {
|
|
123
|
+
return state;
|
|
124
|
+
}
|
|
125
|
+
return new RandomState(state ?? null);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=rng.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rng.js","sourceRoot":"","sources":["../../src/numeric/rng.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"special.d.ts","sourceRoot":"","sources":["../../src/numeric/special.ts"],"names":[],"mappings":"AAYA,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAYxC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log-gamma via the Lanczos approximation (g = 7, 9 coefficients), accurate
|
|
3
|
+
* to ~1e-15 relative for the positive arguments Minka's MLE uses.
|
|
4
|
+
*/
|
|
5
|
+
const LANCZOS_G = 7;
|
|
6
|
+
const LANCZOS_COEF = [
|
|
7
|
+
0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313,
|
|
8
|
+
-176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6,
|
|
9
|
+
1.5056327351493116e-7,
|
|
10
|
+
];
|
|
11
|
+
const LOG_SQRT_2PI = 0.9189385332046727; // log(sqrt(2*pi))
|
|
12
|
+
export function lgamma(x) {
|
|
13
|
+
if (x < 0.5) {
|
|
14
|
+
// Reflection formula.
|
|
15
|
+
return Math.log(Math.PI / Math.sin(Math.PI * x)) - lgamma(1 - x);
|
|
16
|
+
}
|
|
17
|
+
const z = x - 1;
|
|
18
|
+
let a = LANCZOS_COEF[0];
|
|
19
|
+
const t = z + LANCZOS_G + 0.5;
|
|
20
|
+
for (let i = 1; i < LANCZOS_COEF.length; i++) {
|
|
21
|
+
a += LANCZOS_COEF[i] / (z + i);
|
|
22
|
+
}
|
|
23
|
+
return LOG_SQRT_2PI + (z + 0.5) * Math.log(t) - t + Math.log(a);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=special.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"special.js","sourceRoot":"","sources":["../../src/numeric/special.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,MAAM,YAAY,GAAG;IACnB,mBAAmB,EAAE,iBAAiB,EAAE,CAAC,kBAAkB,EAAE,kBAAkB;IAC/E,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,CAAC,mBAAmB,EAAE,qBAAqB;IACpF,qBAAqB;CACtB,CAAC;AACF,MAAM,YAAY,GAAG,kBAAkB,CAAC,CAAC,kBAAkB;AAE3D,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACZ,sBAAsB;QACtB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,GAAG,GAAG,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,YAAY,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column statistics and small array helpers. All accumulation is float64
|
|
3
|
+
* regardless of the storage dtype of the inputs.
|
|
4
|
+
*/
|
|
5
|
+
import type { FloatArray } from '../types.js';
|
|
6
|
+
/** Per-column mean of X (m×n), float64 accumulation. */
|
|
7
|
+
export declare function colMeans(x: FloatArray, m: number, n: number): Float64Array;
|
|
8
|
+
/** Per-column sum of X (m×n), float64 accumulation. */
|
|
9
|
+
export declare function colSums(x: FloatArray, m: number, n: number): Float64Array;
|
|
10
|
+
/** X[i][j] -= mean[j], in place (rounds into X's dtype). */
|
|
11
|
+
export declare function centerInPlace(x: FloatArray, m: number, n: number, mean: Float64Array): void;
|
|
12
|
+
export interface IncrementalStats {
|
|
13
|
+
mean: Float64Array;
|
|
14
|
+
variance: Float64Array;
|
|
15
|
+
count: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* sklearn's `_incremental_mean_and_var` (Chan/Golub/LeVeque update) for the
|
|
19
|
+
* uniform-count case IncrementalPCA uses. Float64 accumulators throughout,
|
|
20
|
+
* matching sklearn's `_safe_accumulator_op` upcasting for float32 input.
|
|
21
|
+
*/
|
|
22
|
+
export declare function incrementalMeanAndVar(x: FloatArray, m: number, n: number, lastMean: Float64Array | null, lastVariance: Float64Array | null, lastCount: number): IncrementalStats;
|
|
23
|
+
/** Cumulative sum (sequential, like xp.cumulative_sum). */
|
|
24
|
+
export declare function cumsum(a: FloatArray): Float64Array;
|
|
25
|
+
/** numpy searchsorted(a, v, side='right') for an ascending array. */
|
|
26
|
+
export declare function searchsortedRight(a: Float64Array, v: number): number;
|
|
27
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/numeric/stats.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,CAY1E;AAED,uDAAuD;AACvD,wBAAgB,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,CASzE;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAO3F;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,QAAQ,EAAE,YAAY,GAAG,IAAI,EAC7B,YAAY,EAAE,YAAY,GAAG,IAAI,EACjC,SAAS,EAAE,MAAM,GAChB,gBAAgB,CA4ClB;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,CAAC,EAAE,UAAU,GAAG,YAAY,CAQlD;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAYpE"}
|