@danielsimonjr/mathts-matrix 0.1.8 → 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.
@@ -0,0 +1,886 @@
1
+ // src/operations/common.ts
2
+ function eye(n) {
3
+ return Array.from(
4
+ { length: n },
5
+ (_, i) => Array.from({ length: n }, (_2, j) => i === j ? 1 : 0)
6
+ );
7
+ }
8
+ function cloneMatrix(A) {
9
+ return A.map((row) => [...row]);
10
+ }
11
+ function transpose(A) {
12
+ const m = A.length;
13
+ const n = A[0].length;
14
+ return Array.from({ length: n }, (_, j) => Array.from({ length: m }, (_2, i) => A[i][j]));
15
+ }
16
+ function isSymmetric(matrix, tolerance = 1e-10) {
17
+ const n = matrix.length;
18
+ if (n === 0) return true;
19
+ if (matrix[0].length !== n) return false;
20
+ for (let i = 0; i < n; i++) {
21
+ for (let j = i + 1; j < n; j++) {
22
+ if (Math.abs(matrix[i][j] - matrix[j][i]) > tolerance) {
23
+ return false;
24
+ }
25
+ }
26
+ }
27
+ return true;
28
+ }
29
+ function matMul(A, B) {
30
+ const m = A.length;
31
+ const p = A[0].length;
32
+ const n = B[0].length;
33
+ const C = Array.from({ length: m }, () => new Array(n).fill(0));
34
+ for (let i = 0; i < m; i++) {
35
+ for (let k = 0; k < p; k++) {
36
+ const aik = A[i][k];
37
+ if (aik === 0) continue;
38
+ for (let j = 0; j < n; j++) C[i][j] += aik * B[k][j];
39
+ }
40
+ }
41
+ return C;
42
+ }
43
+ function matAdd(A, B) {
44
+ const n = A.length;
45
+ return Array.from(
46
+ { length: n },
47
+ (_, i) => Array.from({ length: n }, (_2, j) => A[i][j] + B[i][j])
48
+ );
49
+ }
50
+ function matSub(A, B) {
51
+ const n = A.length;
52
+ return Array.from(
53
+ { length: n },
54
+ (_, i) => Array.from({ length: n }, (_2, j) => A[i][j] - B[i][j])
55
+ );
56
+ }
57
+ function matScale(A, c) {
58
+ return A.map((row) => row.map((v) => v * c));
59
+ }
60
+ function normInf(A) {
61
+ let mx = 0;
62
+ for (const row of A) for (const v of row) if (Math.abs(v) > mx) mx = Math.abs(v);
63
+ return mx;
64
+ }
65
+ function norm1(A) {
66
+ const m = A.length;
67
+ const n = A[0].length;
68
+ let maxColSum = 0;
69
+ for (let j = 0; j < n; j++) {
70
+ let colSum = 0;
71
+ for (let i = 0; i < m; i++) colSum += Math.abs(A[i][j]);
72
+ if (colSum > maxColSum) maxColSum = colSum;
73
+ }
74
+ return maxColSum;
75
+ }
76
+ function householder(x, degenerateBeta = -2) {
77
+ const n = x.length;
78
+ let sigma = 0;
79
+ for (let i = 1; i < n; i++) {
80
+ sigma += x[i] * x[i];
81
+ }
82
+ const v = [...x];
83
+ v[0] = 1;
84
+ if (sigma === 0 && x[0] >= 0) {
85
+ return { v, beta: 0 };
86
+ } else if (sigma === 0 && x[0] < 0) {
87
+ return { v, beta: degenerateBeta };
88
+ } else {
89
+ const mu = Math.sqrt(x[0] * x[0] + sigma);
90
+ if (x[0] <= 0) {
91
+ v[0] = x[0] - mu;
92
+ } else {
93
+ v[0] = -sigma / (x[0] + mu);
94
+ }
95
+ const beta = 2 * v[0] * v[0] / (sigma + v[0] * v[0]);
96
+ const v0 = v[0];
97
+ for (let i = 0; i < n; i++) {
98
+ v[i] /= v0;
99
+ }
100
+ return { v, beta };
101
+ }
102
+ }
103
+ function applyHouseholderLeft(A, v, beta, startRow, startCol) {
104
+ const n = A[0].length;
105
+ const len = v.length;
106
+ for (let j = startCol; j < n; j++) {
107
+ let dot = 0;
108
+ for (let i = 0; i < len; i++) {
109
+ dot += v[i] * A[startRow + i][j];
110
+ }
111
+ dot *= beta;
112
+ for (let i = 0; i < len; i++) {
113
+ A[startRow + i][j] -= dot * v[i];
114
+ }
115
+ }
116
+ }
117
+ function applyHouseholderRight(A, v, beta, startRow, startCol) {
118
+ const m = A.length;
119
+ const len = v.length;
120
+ for (let i = startRow; i < m; i++) {
121
+ let dot = 0;
122
+ for (let j = 0; j < len; j++) {
123
+ dot += A[i][startCol + j] * v[j];
124
+ }
125
+ dot *= beta;
126
+ for (let j = 0; j < len; j++) {
127
+ A[i][startCol + j] -= dot * v[j];
128
+ }
129
+ }
130
+ }
131
+
132
+ // src/operations/eig.ts
133
+ var DEFAULT_MAX_ITERATIONS = 1e3;
134
+ var DEFAULT_TOLERANCE = 1e-12;
135
+ function hessenberg(A) {
136
+ const n = A.length;
137
+ const H = cloneMatrix(A);
138
+ const Q = eye(n);
139
+ for (let k = 0; k < n - 2; k++) {
140
+ const x = [];
141
+ for (let i = k + 1; i < n; i++) {
142
+ x.push(H[i][k]);
143
+ }
144
+ const { v, beta } = householder(x);
145
+ if (beta !== 0) {
146
+ applyHouseholderLeft(H, v, beta, k + 1, k);
147
+ applyHouseholderRight(H, v, beta, 0, k + 1);
148
+ applyHouseholderRight(Q, v, beta, 0, k + 1);
149
+ }
150
+ }
151
+ for (let i = 0; i < n; i++) {
152
+ for (let j = 0; j < i - 1; j++) {
153
+ H[i][j] = 0;
154
+ }
155
+ }
156
+ return { H, Q };
157
+ }
158
+ function givens(a, b) {
159
+ if (b === 0) {
160
+ return { c: 1, s: 0 };
161
+ } else if (Math.abs(b) > Math.abs(a)) {
162
+ const t = -a / b;
163
+ const s = 1 / Math.sqrt(1 + t * t);
164
+ return { c: s * t, s };
165
+ } else {
166
+ const t = -b / a;
167
+ const c = 1 / Math.sqrt(1 + t * t);
168
+ return { c, s: c * t };
169
+ }
170
+ }
171
+ function applyGivensLeft(A, c, s, i, k, startCol) {
172
+ const n = A[0].length;
173
+ for (let j = startCol; j < n; j++) {
174
+ const temp = c * A[i][j] - s * A[k][j];
175
+ A[k][j] = s * A[i][j] + c * A[k][j];
176
+ A[i][j] = temp;
177
+ }
178
+ }
179
+ function applyGivensRight(A, c, s, i, k, startRow) {
180
+ const m = A.length;
181
+ for (let j = startRow; j < m; j++) {
182
+ const temp = c * A[j][i] - s * A[j][k];
183
+ A[j][k] = s * A[j][i] + c * A[j][k];
184
+ A[j][i] = temp;
185
+ }
186
+ }
187
+ function qrStep(H, Q, start, end) {
188
+ const n = end - start + 1;
189
+ if (n < 2) return;
190
+ const a = H[end - 1][end - 1];
191
+ const b = H[end - 1][end];
192
+ const c = H[end][end - 1];
193
+ const d = H[end][end];
194
+ const trace = a + d;
195
+ const det = a * d - b * c;
196
+ const disc = trace * trace - 4 * det;
197
+ let shift;
198
+ if (disc >= 0) {
199
+ const sqrtDisc = Math.sqrt(disc);
200
+ const e1 = (trace + sqrtDisc) / 2;
201
+ const e2 = (trace - sqrtDisc) / 2;
202
+ shift = Math.abs(e1 - d) < Math.abs(e2 - d) ? e1 : e2;
203
+ } else {
204
+ shift = d;
205
+ }
206
+ let x = H[start][start] - shift;
207
+ let y = H[start + 1][start];
208
+ for (let k = start; k < end; k++) {
209
+ const { c: c2, s } = givens(x, y);
210
+ applyGivensLeft(H, c2, s, k, k + 1, Math.max(0, k - 1));
211
+ applyGivensRight(H, c2, s, k, k + 1, 0);
212
+ applyGivensRight(Q, c2, s, k, k + 1, 0);
213
+ if (k < end - 1) {
214
+ x = H[k + 1][k];
215
+ y = H[k + 2][k];
216
+ }
217
+ }
218
+ }
219
+ function extractEigenvalues(H, tolerance) {
220
+ const n = H.length;
221
+ const eigenvalues = [];
222
+ let i = 0;
223
+ while (i < n) {
224
+ if (i === n - 1 || Math.abs(H[i + 1][i]) <= tolerance) {
225
+ eigenvalues.push({ re: H[i][i], im: 0 });
226
+ i++;
227
+ } else {
228
+ const a = H[i][i];
229
+ const b = H[i][i + 1];
230
+ const c = H[i + 1][i];
231
+ const d = H[i + 1][i + 1];
232
+ const trace = a + d;
233
+ const det = a * d - b * c;
234
+ const disc = trace * trace - 4 * det;
235
+ if (disc >= 0) {
236
+ const sqrtDisc = Math.sqrt(disc);
237
+ eigenvalues.push({ re: (trace + sqrtDisc) / 2, im: 0 });
238
+ eigenvalues.push({ re: (trace - sqrtDisc) / 2, im: 0 });
239
+ } else {
240
+ const realPart = trace / 2;
241
+ const imagPart = Math.sqrt(-disc) / 2;
242
+ eigenvalues.push({ re: realPart, im: imagPart });
243
+ eigenvalues.push({ re: realPart, im: -imagPart });
244
+ }
245
+ i += 2;
246
+ }
247
+ }
248
+ return eigenvalues;
249
+ }
250
+ function inverseIteration(A, eigenvalue, tolerance, maxIterations) {
251
+ const n = A.length;
252
+ if (eigenvalue.im !== 0) {
253
+ return new Array(n).fill(0);
254
+ }
255
+ const lambda = eigenvalue.re;
256
+ const shifted = cloneMatrix(A);
257
+ for (let i = 0; i < n; i++) {
258
+ shifted[i][i] -= lambda;
259
+ }
260
+ for (let i = 0; i < n; i++) {
261
+ shifted[i][i] += tolerance * 1e3;
262
+ }
263
+ const LU = cloneMatrix(shifted);
264
+ const perm = Array.from({ length: n }, (_, i) => i);
265
+ for (let k = 0; k < n; k++) {
266
+ let maxVal = Math.abs(LU[k][k]);
267
+ let maxIdx = k;
268
+ for (let i = k + 1; i < n; i++) {
269
+ if (Math.abs(LU[i][k]) > maxVal) {
270
+ maxVal = Math.abs(LU[i][k]);
271
+ maxIdx = i;
272
+ }
273
+ }
274
+ if (maxIdx !== k) {
275
+ [LU[k], LU[maxIdx]] = [LU[maxIdx], LU[k]];
276
+ [perm[k], perm[maxIdx]] = [perm[maxIdx], perm[k]];
277
+ }
278
+ if (Math.abs(LU[k][k]) < tolerance) {
279
+ LU[k][k] = tolerance;
280
+ }
281
+ for (let i = k + 1; i < n; i++) {
282
+ LU[i][k] /= LU[k][k];
283
+ for (let j = k + 1; j < n; j++) {
284
+ LU[i][j] -= LU[i][k] * LU[k][j];
285
+ }
286
+ }
287
+ }
288
+ const v = new Array(n).fill(1);
289
+ let prevNorm = 0;
290
+ for (let iter = 0; iter < maxIterations; iter++) {
291
+ const y = new Array(n).fill(0);
292
+ const b = new Array(n);
293
+ for (let i = 0; i < n; i++) {
294
+ b[i] = v[perm[i]];
295
+ }
296
+ for (let i = 0; i < n; i++) {
297
+ y[i] = b[i];
298
+ for (let j = 0; j < i; j++) {
299
+ y[i] -= LU[i][j] * y[j];
300
+ }
301
+ }
302
+ const x = new Array(n).fill(0);
303
+ for (let i = n - 1; i >= 0; i--) {
304
+ x[i] = y[i];
305
+ for (let j = i + 1; j < n; j++) {
306
+ x[i] -= LU[i][j] * x[j];
307
+ }
308
+ x[i] /= LU[i][i];
309
+ }
310
+ let norm = 0;
311
+ for (let i = 0; i < n; i++) {
312
+ norm += x[i] * x[i];
313
+ }
314
+ norm = Math.sqrt(norm);
315
+ if (norm < tolerance) {
316
+ return x;
317
+ }
318
+ for (let i = 0; i < n; i++) {
319
+ v[i] = x[i] / norm;
320
+ }
321
+ if (Math.abs(norm - prevNorm) < tolerance * norm) {
322
+ break;
323
+ }
324
+ prevNorm = norm;
325
+ }
326
+ return v;
327
+ }
328
+ var EIG_GEN_EPS = 2220446049250313e-31;
329
+ function cdiv(xr, xi, yr, yi) {
330
+ let rr;
331
+ let d;
332
+ if (Math.abs(yr) > Math.abs(yi)) {
333
+ rr = yi / yr;
334
+ d = yr + rr * yi;
335
+ return { r: (xr + rr * xi) / d, i: (xi - rr * xr) / d };
336
+ } else {
337
+ rr = yr / yi;
338
+ d = yi + rr * yr;
339
+ return { r: (rr * xr + xi) / d, i: (rr * xi - xr) / d };
340
+ }
341
+ }
342
+ function orthesGeneral(H, V, ort, nn) {
343
+ const low = 0;
344
+ const high = nn - 1;
345
+ for (let m = low + 1; m <= high - 1; m++) {
346
+ let scale = 0;
347
+ for (let i = m; i <= high; i++) {
348
+ scale += Math.abs(H[i * nn + (m - 1)]);
349
+ }
350
+ if (scale !== 0) {
351
+ let h = 0;
352
+ for (let i = high; i >= m; i--) {
353
+ ort[i] = H[i * nn + (m - 1)] / scale;
354
+ h += ort[i] * ort[i];
355
+ }
356
+ let g = Math.sqrt(h);
357
+ if (ort[m] > 0) g = -g;
358
+ h = h - ort[m] * g;
359
+ ort[m] = ort[m] - g;
360
+ for (let j = m; j < nn; j++) {
361
+ let f = 0;
362
+ for (let i = high; i >= m; i--) f += ort[i] * H[i * nn + j];
363
+ f = f / h;
364
+ for (let i = m; i <= high; i++) H[i * nn + j] -= f * ort[i];
365
+ }
366
+ for (let i = 0; i <= high; i++) {
367
+ let f = 0;
368
+ for (let j = high; j >= m; j--) f += ort[j] * H[i * nn + j];
369
+ f = f / h;
370
+ for (let j = m; j <= high; j++) H[i * nn + j] -= f * ort[j];
371
+ }
372
+ ort[m] = scale * ort[m];
373
+ H[m * nn + (m - 1)] = scale * g;
374
+ }
375
+ }
376
+ for (let m = high - 1; m >= low + 1; m--) {
377
+ if (H[m * nn + (m - 1)] !== 0) {
378
+ for (let i = m + 1; i <= high; i++) ort[i] = H[i * nn + (m - 1)];
379
+ for (let j = m; j <= high; j++) {
380
+ let g = 0;
381
+ for (let i = m; i <= high; i++) g += ort[i] * V[i * nn + j];
382
+ g = g / ort[m] / H[m * nn + (m - 1)];
383
+ for (let i = m; i <= high; i++) V[i * nn + j] += g * ort[i];
384
+ }
385
+ }
386
+ }
387
+ }
388
+ function eigGeneral(A, computeVectors, symmetric) {
389
+ const nn = A.length;
390
+ const eps = EIG_GEN_EPS;
391
+ const H = new Float64Array(nn * nn);
392
+ for (let i = 0; i < nn; i++) {
393
+ for (let j = 0; j < nn; j++) H[i * nn + j] = A[i][j];
394
+ }
395
+ const V = new Float64Array(nn * nn);
396
+ for (let i = 0; i < nn; i++) V[i * nn + i] = 1;
397
+ const d = new Float64Array(nn);
398
+ const e = new Float64Array(nn);
399
+ const ort = new Float64Array(nn);
400
+ orthesGeneral(H, V, ort, nn);
401
+ const low = 0;
402
+ const high = nn - 1;
403
+ let exshift = 0;
404
+ let p = 0;
405
+ let q = 0;
406
+ let r = 0;
407
+ let s = 0;
408
+ let z = 0;
409
+ let t;
410
+ let w;
411
+ let x;
412
+ let y;
413
+ let norm = 0;
414
+ for (let i = 0; i < nn; i++) {
415
+ for (let j = Math.max(i - 1, 0); j < nn; j++) {
416
+ norm += Math.abs(H[i * nn + j]);
417
+ }
418
+ }
419
+ let nIdx = nn - 1;
420
+ let iter = 0;
421
+ while (nIdx >= low) {
422
+ let l = nIdx;
423
+ while (l > low) {
424
+ s = Math.abs(H[(l - 1) * nn + (l - 1)]) + Math.abs(H[l * nn + l]);
425
+ if (s === 0) s = norm;
426
+ if (Math.abs(H[l * nn + (l - 1)]) < eps * s) break;
427
+ l--;
428
+ }
429
+ if (l === nIdx) {
430
+ H[nIdx * nn + nIdx] = H[nIdx * nn + nIdx] + exshift;
431
+ d[nIdx] = H[nIdx * nn + nIdx];
432
+ e[nIdx] = 0;
433
+ nIdx--;
434
+ iter = 0;
435
+ } else if (l === nIdx - 1) {
436
+ w = H[nIdx * nn + (nIdx - 1)] * H[(nIdx - 1) * nn + nIdx];
437
+ p = (H[(nIdx - 1) * nn + (nIdx - 1)] - H[nIdx * nn + nIdx]) / 2;
438
+ q = p * p + w;
439
+ z = Math.sqrt(Math.abs(q));
440
+ H[nIdx * nn + nIdx] = H[nIdx * nn + nIdx] + exshift;
441
+ H[(nIdx - 1) * nn + (nIdx - 1)] = H[(nIdx - 1) * nn + (nIdx - 1)] + exshift;
442
+ x = H[nIdx * nn + nIdx];
443
+ if (q >= 0) {
444
+ z = p >= 0 ? p + z : p - z;
445
+ d[nIdx - 1] = x + z;
446
+ d[nIdx] = d[nIdx - 1];
447
+ if (z !== 0) d[nIdx] = x - w / z;
448
+ e[nIdx - 1] = 0;
449
+ e[nIdx] = 0;
450
+ x = H[nIdx * nn + (nIdx - 1)];
451
+ s = Math.abs(x) + Math.abs(z);
452
+ p = x / s;
453
+ q = z / s;
454
+ r = Math.sqrt(p * p + q * q);
455
+ p = p / r;
456
+ q = q / r;
457
+ for (let j = nIdx - 1; j < nn; j++) {
458
+ z = H[(nIdx - 1) * nn + j];
459
+ H[(nIdx - 1) * nn + j] = q * z + p * H[nIdx * nn + j];
460
+ H[nIdx * nn + j] = q * H[nIdx * nn + j] - p * z;
461
+ }
462
+ for (let i = 0; i <= nIdx; i++) {
463
+ z = H[i * nn + (nIdx - 1)];
464
+ H[i * nn + (nIdx - 1)] = q * z + p * H[i * nn + nIdx];
465
+ H[i * nn + nIdx] = q * H[i * nn + nIdx] - p * z;
466
+ }
467
+ for (let i = low; i <= high; i++) {
468
+ z = V[i * nn + (nIdx - 1)];
469
+ V[i * nn + (nIdx - 1)] = q * z + p * V[i * nn + nIdx];
470
+ V[i * nn + nIdx] = q * V[i * nn + nIdx] - p * z;
471
+ }
472
+ } else {
473
+ d[nIdx - 1] = x + p;
474
+ d[nIdx] = x + p;
475
+ e[nIdx - 1] = z;
476
+ e[nIdx] = -z;
477
+ }
478
+ nIdx = nIdx - 2;
479
+ iter = 0;
480
+ } else {
481
+ x = H[nIdx * nn + nIdx];
482
+ y = 0;
483
+ w = 0;
484
+ if (l < nIdx) {
485
+ y = H[(nIdx - 1) * nn + (nIdx - 1)];
486
+ w = H[nIdx * nn + (nIdx - 1)] * H[(nIdx - 1) * nn + nIdx];
487
+ }
488
+ if (iter === 10) {
489
+ exshift += x;
490
+ for (let i = low; i <= nIdx; i++) H[i * nn + i] -= x;
491
+ s = Math.abs(H[nIdx * nn + (nIdx - 1)]) + Math.abs(H[(nIdx - 1) * nn + (nIdx - 2)]);
492
+ x = y = 0.75 * s;
493
+ w = -0.4375 * s * s;
494
+ }
495
+ if (iter === 30) {
496
+ s = (y - x) / 2;
497
+ s = s * s + w;
498
+ if (s > 0) {
499
+ s = Math.sqrt(s);
500
+ if (y < x) s = -s;
501
+ s = x - w / ((y - x) / 2 + s);
502
+ for (let i = low; i <= nIdx; i++) H[i * nn + i] -= s;
503
+ exshift += s;
504
+ x = y = w = 0.964;
505
+ }
506
+ }
507
+ iter = iter + 1;
508
+ let m = nIdx - 2;
509
+ while (m >= l) {
510
+ z = H[m * nn + m];
511
+ r = x - z;
512
+ s = y - z;
513
+ p = (r * s - w) / H[(m + 1) * nn + m] + H[m * nn + (m + 1)];
514
+ q = H[(m + 1) * nn + (m + 1)] - z - r - s;
515
+ r = H[(m + 2) * nn + (m + 1)];
516
+ s = Math.abs(p) + Math.abs(q) + Math.abs(r);
517
+ p = p / s;
518
+ q = q / s;
519
+ r = r / s;
520
+ if (m === l) break;
521
+ 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)])))) {
522
+ break;
523
+ }
524
+ m--;
525
+ }
526
+ for (let i = m + 2; i <= nIdx; i++) {
527
+ H[i * nn + (i - 2)] = 0;
528
+ if (i > m + 2) H[i * nn + (i - 3)] = 0;
529
+ }
530
+ for (let k = m; k <= nIdx - 1; k++) {
531
+ const notlast = k !== nIdx - 1;
532
+ if (k !== m) {
533
+ p = H[k * nn + (k - 1)];
534
+ q = H[(k + 1) * nn + (k - 1)];
535
+ r = notlast ? H[(k + 2) * nn + (k - 1)] : 0;
536
+ x = Math.abs(p) + Math.abs(q) + Math.abs(r);
537
+ if (x !== 0) {
538
+ p = p / x;
539
+ q = q / x;
540
+ r = r / x;
541
+ }
542
+ }
543
+ if (x === 0) break;
544
+ s = Math.sqrt(p * p + q * q + r * r);
545
+ if (p < 0) s = -s;
546
+ if (s !== 0) {
547
+ if (k !== m) {
548
+ H[k * nn + (k - 1)] = -s * x;
549
+ } else if (l !== m) {
550
+ H[k * nn + (k - 1)] = -H[k * nn + (k - 1)];
551
+ }
552
+ p = p + s;
553
+ x = p / s;
554
+ y = q / s;
555
+ z = r / s;
556
+ q = q / p;
557
+ r = r / p;
558
+ for (let j = k; j < nn; j++) {
559
+ p = H[k * nn + j] + q * H[(k + 1) * nn + j];
560
+ if (notlast) {
561
+ p = p + r * H[(k + 2) * nn + j];
562
+ H[(k + 2) * nn + j] = H[(k + 2) * nn + j] - p * z;
563
+ }
564
+ H[k * nn + j] = H[k * nn + j] - p * x;
565
+ H[(k + 1) * nn + j] = H[(k + 1) * nn + j] - p * y;
566
+ }
567
+ const colEnd = Math.min(nIdx, k + 3);
568
+ for (let i = 0; i <= colEnd; i++) {
569
+ p = x * H[i * nn + k] + y * H[i * nn + (k + 1)];
570
+ if (notlast) {
571
+ p = p + z * H[i * nn + (k + 2)];
572
+ H[i * nn + (k + 2)] = H[i * nn + (k + 2)] - p * r;
573
+ }
574
+ H[i * nn + k] = H[i * nn + k] - p;
575
+ H[i * nn + (k + 1)] = H[i * nn + (k + 1)] - p * q;
576
+ }
577
+ for (let i = low; i <= high; i++) {
578
+ p = x * V[i * nn + k] + y * V[i * nn + (k + 1)];
579
+ if (notlast) {
580
+ p = p + z * V[i * nn + (k + 2)];
581
+ V[i * nn + (k + 2)] = V[i * nn + (k + 2)] - p * r;
582
+ }
583
+ V[i * nn + k] = V[i * nn + k] - p;
584
+ V[i * nn + (k + 1)] = V[i * nn + (k + 1)] - p * q;
585
+ }
586
+ }
587
+ }
588
+ }
589
+ }
590
+ if (norm !== 0) {
591
+ for (nIdx = nn - 1; nIdx >= 0; nIdx--) {
592
+ p = d[nIdx];
593
+ q = e[nIdx];
594
+ if (q === 0) {
595
+ let l = nIdx;
596
+ H[nIdx * nn + nIdx] = 1;
597
+ for (let i = nIdx - 1; i >= 0; i--) {
598
+ w = H[i * nn + i] - p;
599
+ r = 0;
600
+ for (let j = l; j <= nIdx; j++) r += H[i * nn + j] * H[j * nn + nIdx];
601
+ if (e[i] < 0) {
602
+ z = w;
603
+ s = r;
604
+ } else {
605
+ l = i;
606
+ if (e[i] === 0) {
607
+ H[i * nn + nIdx] = w !== 0 ? -r / w : -r / (eps * norm);
608
+ } else {
609
+ x = H[i * nn + (i + 1)];
610
+ y = H[(i + 1) * nn + i];
611
+ q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
612
+ t = (x * s - z * r) / q;
613
+ H[i * nn + nIdx] = t;
614
+ if (Math.abs(x) > Math.abs(z)) {
615
+ H[(i + 1) * nn + nIdx] = (-r - w * t) / x;
616
+ } else {
617
+ H[(i + 1) * nn + nIdx] = (-s - y * t) / z;
618
+ }
619
+ }
620
+ t = Math.abs(H[i * nn + nIdx]);
621
+ if (eps * t * t > 1) {
622
+ for (let j = i; j <= nIdx; j++) H[j * nn + nIdx] = H[j * nn + nIdx] / t;
623
+ }
624
+ }
625
+ }
626
+ } else if (q < 0) {
627
+ let l = nIdx - 1;
628
+ if (Math.abs(H[nIdx * nn + (nIdx - 1)]) > Math.abs(H[(nIdx - 1) * nn + nIdx])) {
629
+ H[(nIdx - 1) * nn + (nIdx - 1)] = q / H[nIdx * nn + (nIdx - 1)];
630
+ H[(nIdx - 1) * nn + nIdx] = -(H[nIdx * nn + nIdx] - p) / H[nIdx * nn + (nIdx - 1)];
631
+ } else {
632
+ const cd = cdiv(0, -H[(nIdx - 1) * nn + nIdx], H[(nIdx - 1) * nn + (nIdx - 1)] - p, q);
633
+ H[(nIdx - 1) * nn + (nIdx - 1)] = cd.r;
634
+ H[(nIdx - 1) * nn + nIdx] = cd.i;
635
+ }
636
+ H[nIdx * nn + (nIdx - 1)] = 0;
637
+ H[nIdx * nn + nIdx] = 1;
638
+ for (let i = nIdx - 2; i >= 0; i--) {
639
+ let ra = 0;
640
+ let sa = 0;
641
+ for (let j = l; j <= nIdx; j++) {
642
+ ra += H[i * nn + j] * H[j * nn + (nIdx - 1)];
643
+ sa += H[i * nn + j] * H[j * nn + nIdx];
644
+ }
645
+ w = H[i * nn + i] - p;
646
+ if (e[i] < 0) {
647
+ z = w;
648
+ r = ra;
649
+ s = sa;
650
+ } else {
651
+ l = i;
652
+ if (e[i] === 0) {
653
+ const cd = cdiv(-ra, -sa, w, q);
654
+ H[i * nn + (nIdx - 1)] = cd.r;
655
+ H[i * nn + nIdx] = cd.i;
656
+ } else {
657
+ x = H[i * nn + (i + 1)];
658
+ y = H[(i + 1) * nn + i];
659
+ let vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
660
+ const vi = (d[i] - p) * 2 * q;
661
+ if (vr === 0 && vi === 0) {
662
+ vr = eps * norm * (Math.abs(w) + Math.abs(q) + Math.abs(x) + Math.abs(y) + Math.abs(z));
663
+ }
664
+ const cd = cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi);
665
+ H[i * nn + (nIdx - 1)] = cd.r;
666
+ H[i * nn + nIdx] = cd.i;
667
+ if (Math.abs(x) > Math.abs(z) + Math.abs(q)) {
668
+ H[(i + 1) * nn + (nIdx - 1)] = (-ra - w * H[i * nn + (nIdx - 1)] + q * H[i * nn + nIdx]) / x;
669
+ H[(i + 1) * nn + nIdx] = (-sa - w * H[i * nn + nIdx] - q * H[i * nn + (nIdx - 1)]) / x;
670
+ } else {
671
+ const cd2 = cdiv(
672
+ -r - y * H[i * nn + (nIdx - 1)],
673
+ -s - y * H[i * nn + nIdx],
674
+ z,
675
+ q
676
+ );
677
+ H[(i + 1) * nn + (nIdx - 1)] = cd2.r;
678
+ H[(i + 1) * nn + nIdx] = cd2.i;
679
+ }
680
+ }
681
+ t = Math.max(Math.abs(H[i * nn + (nIdx - 1)]), Math.abs(H[i * nn + nIdx]));
682
+ if (eps * t * t > 1) {
683
+ for (let j = i; j <= nIdx; j++) {
684
+ H[j * nn + (nIdx - 1)] = H[j * nn + (nIdx - 1)] / t;
685
+ H[j * nn + nIdx] = H[j * nn + nIdx] / t;
686
+ }
687
+ }
688
+ }
689
+ }
690
+ }
691
+ }
692
+ for (let j = nn - 1; j >= low; j--) {
693
+ for (let i = low; i <= high; i++) {
694
+ z = 0;
695
+ const kEnd = Math.min(j, high);
696
+ for (let k = low; k <= kEnd; k++) z += V[i * nn + k] * H[k * nn + j];
697
+ V[i * nn + j] = z;
698
+ }
699
+ }
700
+ }
701
+ const values = [];
702
+ for (let j = 0; j < nn; j++) values.push({ re: d[j], im: e[j] });
703
+ let vectors;
704
+ if (computeVectors) {
705
+ vectors = [];
706
+ for (let j = 0; j < nn; j++) {
707
+ const vec = new Array(nn).fill(0);
708
+ if (e[j] === 0) {
709
+ let colNorm = 0;
710
+ for (let i = 0; i < nn; i++) colNorm += V[i * nn + j] * V[i * nn + j];
711
+ colNorm = Math.sqrt(colNorm);
712
+ if (colNorm > 1e-300) {
713
+ for (let i = 0; i < nn; i++) vec[i] = V[i * nn + j] / colNorm;
714
+ } else {
715
+ for (let i = 0; i < nn; i++) vec[i] = V[i * nn + j];
716
+ }
717
+ }
718
+ vectors.push(vec);
719
+ }
720
+ } else {
721
+ vectors = eye(nn);
722
+ }
723
+ return { values, vectors, isSymmetric: symmetric };
724
+ }
725
+ function eig(matrix, options = {}) {
726
+ const {
727
+ maxIterations = DEFAULT_MAX_ITERATIONS,
728
+ tolerance = DEFAULT_TOLERANCE,
729
+ computeVectors = true
730
+ } = options;
731
+ let A;
732
+ if (matrix instanceof Float64Array) {
733
+ const n2 = Math.sqrt(matrix.length);
734
+ if (n2 !== Math.floor(n2)) {
735
+ throw new Error("Float64Array length must be a perfect square");
736
+ }
737
+ A = Array.from({ length: n2 }, (_, i) => Array.from({ length: n2 }, (_2, j) => matrix[i * n2 + j]));
738
+ } else {
739
+ A = matrix;
740
+ }
741
+ const n = A.length;
742
+ if (n === 0) {
743
+ return { values: [], vectors: [], isSymmetric: true };
744
+ }
745
+ for (let i = 0; i < n; i++) {
746
+ if (A[i].length !== n) {
747
+ throw new Error("Matrix must be square");
748
+ }
749
+ }
750
+ const symmetric = isSymmetric(A);
751
+ if (n === 1) {
752
+ return {
753
+ values: [{ re: A[0][0], im: 0 }],
754
+ vectors: [[1]],
755
+ isSymmetric: symmetric
756
+ };
757
+ }
758
+ if (!symmetric) {
759
+ return eigGeneral(A, computeVectors, symmetric);
760
+ }
761
+ if (n === 2) {
762
+ const a = A[0][0], b = A[0][1], c = A[1][0], d = A[1][1];
763
+ const trace = a + d;
764
+ const det = a * d - b * c;
765
+ const disc = trace * trace - 4 * det;
766
+ let values2;
767
+ let vectors2;
768
+ if (disc >= 0) {
769
+ const sqrtDisc = Math.sqrt(disc);
770
+ const e1 = (trace + sqrtDisc) / 2;
771
+ const e2 = (trace - sqrtDisc) / 2;
772
+ values2 = [
773
+ { re: e1, im: 0 },
774
+ { re: e2, im: 0 }
775
+ ];
776
+ if (computeVectors) {
777
+ vectors2 = [];
778
+ for (const e of [e1, e2]) {
779
+ if (Math.abs(b) > tolerance) {
780
+ const v = [b, e - a];
781
+ const norm = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
782
+ vectors2.push([v[0] / norm, v[1] / norm]);
783
+ } else if (Math.abs(c) > tolerance) {
784
+ const v = [e - d, c];
785
+ const norm = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
786
+ vectors2.push([v[0] / norm, v[1] / norm]);
787
+ } else {
788
+ vectors2.push(e === a ? [1, 0] : [0, 1]);
789
+ }
790
+ }
791
+ } else {
792
+ vectors2 = eye(2);
793
+ }
794
+ } else {
795
+ const realPart = trace / 2;
796
+ const imagPart = Math.sqrt(-disc) / 2;
797
+ values2 = [
798
+ { re: realPart, im: imagPart },
799
+ { re: realPart, im: -imagPart }
800
+ ];
801
+ vectors2 = eye(2);
802
+ }
803
+ return { values: values2, vectors: vectors2, isSymmetric: symmetric };
804
+ }
805
+ const { H, Q } = hessenberg(A);
806
+ let end = n - 1;
807
+ let iter = 0;
808
+ while (end > 0 && iter < maxIterations) {
809
+ let start = end;
810
+ while (start > 0) {
811
+ const scale = Math.abs(H[start - 1][start - 1]) + Math.abs(H[start][start]);
812
+ if (Math.abs(H[start][start - 1]) <= tolerance * scale) {
813
+ H[start][start - 1] = 0;
814
+ break;
815
+ }
816
+ start--;
817
+ }
818
+ if (start === end) {
819
+ end--;
820
+ } else if (start === end - 1) {
821
+ end -= 2;
822
+ } else {
823
+ qrStep(H, Q, start, end);
824
+ }
825
+ iter++;
826
+ }
827
+ const values = extractEigenvalues(H, tolerance);
828
+ let vectors;
829
+ if (computeVectors) {
830
+ vectors = [];
831
+ for (const eigenvalue of values) {
832
+ const v = inverseIteration(A, eigenvalue, tolerance, 100);
833
+ vectors.push(v);
834
+ }
835
+ } else {
836
+ vectors = eye(n);
837
+ }
838
+ return { values, vectors, isSymmetric: symmetric };
839
+ }
840
+ function eigvals(matrix, options) {
841
+ return eig(matrix, { ...options, computeVectors: false }).values;
842
+ }
843
+ function powerIteration(matrix, options = {}) {
844
+ const { maxIterations = 1e3, tolerance = 1e-12 } = options;
845
+ const n = matrix.length;
846
+ let v = Array.from({ length: n }, () => Math.random() - 0.5);
847
+ let norm = Math.sqrt(v.reduce((sum, x) => sum + x * x, 0));
848
+ v = v.map((x) => x / norm);
849
+ let eigenvalue = 0;
850
+ let prevEigenvalue = 0;
851
+ for (let iter = 0; iter < maxIterations; iter++) {
852
+ const w = new Array(n).fill(0);
853
+ for (let i = 0; i < n; i++) {
854
+ for (let j = 0; j < n; j++) {
855
+ w[i] += matrix[i][j] * v[j];
856
+ }
857
+ }
858
+ eigenvalue = v.reduce((sum, vi, i) => sum + vi * w[i], 0);
859
+ norm = Math.sqrt(w.reduce((sum, x) => sum + x * x, 0));
860
+ v = w.map((x) => x / norm);
861
+ if (Math.abs(eigenvalue - prevEigenvalue) < tolerance * Math.abs(eigenvalue)) {
862
+ break;
863
+ }
864
+ prevEigenvalue = eigenvalue;
865
+ }
866
+ return { value: eigenvalue, vector: v };
867
+ }
868
+
869
+ export {
870
+ eye,
871
+ cloneMatrix,
872
+ transpose,
873
+ isSymmetric,
874
+ matMul,
875
+ matAdd,
876
+ matSub,
877
+ matScale,
878
+ normInf,
879
+ norm1,
880
+ householder,
881
+ applyHouseholderLeft,
882
+ applyHouseholderRight,
883
+ eig,
884
+ eigvals,
885
+ powerIteration
886
+ };