numbl 0.4.19 → 0.4.21

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.
Files changed (50) hide show
  1. package/dist-browser/browser.js +1 -1
  2. package/dist-browser/numbl-core/helpers/sparse-direct.d.ts +107 -0
  3. package/dist-browser/numbl-core/helpers/warn.d.ts +9 -0
  4. package/dist-browser/numbl-core/interpreter/builtins/index.d.ts +1 -0
  5. package/dist-browser/numbl-core/interpreter/builtins/sparse-solvers.d.ts +16 -0
  6. package/dist-browser/numbl-core/native/lapack-bridge.d.ts +29 -1
  7. package/dist-browser/numbl-core/native/ts-lapack-eig-hermitian.d.ts +33 -0
  8. package/dist-browser/numbl-core/runtime/types.d.ts +12 -0
  9. package/dist-browser/numbl-core/version.d.ts +1 -1
  10. package/dist-browser/ts-lapack/src/BLAS/dsymv.d.ts +1 -0
  11. package/dist-browser/ts-lapack/src/BLAS/dsyr2.d.ts +1 -0
  12. package/dist-browser/ts-lapack/src/SRC/dlae2.d.ts +4 -0
  13. package/dist-browser/ts-lapack/src/SRC/dlaev2.d.ts +6 -0
  14. package/dist-browser/ts-lapack/src/SRC/dlanst.d.ts +1 -0
  15. package/dist-browser/ts-lapack/src/SRC/dlansy.d.ts +1 -0
  16. package/dist-browser/ts-lapack/src/SRC/dlasrt.d.ts +1 -0
  17. package/dist-browser/ts-lapack/src/SRC/dorgtr.d.ts +1 -0
  18. package/dist-browser/ts-lapack/src/SRC/dsteqr.d.ts +4 -0
  19. package/dist-browser/ts-lapack/src/SRC/dsyev.d.ts +1 -0
  20. package/dist-browser/ts-lapack/src/SRC/dsytd2.d.ts +1 -0
  21. package/dist-cli/cli.js +3464 -172
  22. package/dist-lib/lib.js +3338 -46
  23. package/dist-lib/numbl-core/helpers/sparse-direct.d.ts +107 -0
  24. package/dist-lib/numbl-core/helpers/warn.d.ts +9 -0
  25. package/dist-lib/numbl-core/interpreter/builtins/index.d.ts +1 -0
  26. package/dist-lib/numbl-core/interpreter/builtins/sparse-solvers.d.ts +16 -0
  27. package/dist-lib/numbl-core/native/lapack-bridge.d.ts +29 -1
  28. package/dist-lib/numbl-core/native/ts-lapack-eig-hermitian.d.ts +33 -0
  29. package/dist-lib/numbl-core/runtime/types.d.ts +12 -0
  30. package/dist-lib/numbl-core/version.d.ts +1 -1
  31. package/dist-lib/ts-lapack/src/BLAS/dsymv.d.ts +1 -0
  32. package/dist-lib/ts-lapack/src/BLAS/dsyr2.d.ts +1 -0
  33. package/dist-lib/ts-lapack/src/SRC/dlae2.d.ts +4 -0
  34. package/dist-lib/ts-lapack/src/SRC/dlaev2.d.ts +6 -0
  35. package/dist-lib/ts-lapack/src/SRC/dlanst.d.ts +1 -0
  36. package/dist-lib/ts-lapack/src/SRC/dlansy.d.ts +1 -0
  37. package/dist-lib/ts-lapack/src/SRC/dlasrt.d.ts +1 -0
  38. package/dist-lib/ts-lapack/src/SRC/dorgtr.d.ts +1 -0
  39. package/dist-lib/ts-lapack/src/SRC/dsteqr.d.ts +4 -0
  40. package/dist-lib/ts-lapack/src/SRC/dsyev.d.ts +1 -0
  41. package/dist-lib/ts-lapack/src/SRC/dsytd2.d.ts +1 -0
  42. package/dist-site-viewer/assets/index-DrtkDG_M.js +4832 -0
  43. package/dist-site-viewer/assets/numbl-worker-Dz_Z8B9u.js +5327 -0
  44. package/dist-site-viewer/index.html +1 -1
  45. package/native/lapack_eig.cpp +156 -0
  46. package/native/numbl_addon.cpp +7 -1
  47. package/native/numbl_addon_common.h +14 -0
  48. package/package.json +1 -1
  49. package/dist-site-viewer/assets/index-B5Y5557F.js +0 -4831
  50. package/dist-site-viewer/assets/numbl-worker-CtoT7C0f.js +0 -5355
package/dist-lib/lib.js CHANGED
@@ -372,6 +372,9 @@ var RuntimeSparseMatrix = class extends Refcounted {
372
372
  jc;
373
373
  pr;
374
374
  pi;
375
+ /** Lazily computed by triangularInfo(); valid because sparse matrices are
376
+ * never mutated in place (indexed assignment builds a new matrix). */
377
+ _triInfo = void 0;
375
378
  constructor(m, n, ir, jc, pr, pi2) {
376
379
  super();
377
380
  this.m = m;
@@ -1171,6 +1174,7 @@ function formatClassInstance(v) {
1171
1174
  const lines = [` ${v.className} with properties:
1172
1175
  `];
1173
1176
  for (const [key, val] of v.fields) {
1177
+ if (key.startsWith("_")) continue;
1174
1178
  lines.push(` ${key}: ${displayValue(val)}`);
1175
1179
  }
1176
1180
  return lines.join("\n");
@@ -1484,6 +1488,8 @@ var PIVOT_T = 1;
1484
1488
  var PIVOT_B = 2;
1485
1489
  var DIRECT_F = 0;
1486
1490
  var DIRECT_B = 1;
1491
+ var SORT_INC = 0;
1492
+ var SORT_DEC = 1;
1487
1493
  var VECT_Q = 0;
1488
1494
  var VECT_P = 1;
1489
1495
 
@@ -18090,6 +18096,1357 @@ function eigComplexTs(dataRe, dataIm, n, computeVL, computeVR) {
18090
18096
  return result;
18091
18097
  }
18092
18098
 
18099
+ // src/ts-lapack/src/SRC/dlanst.ts
18100
+ var NORM_MAX5 = 0;
18101
+ var NORM_ONE2 = 1;
18102
+ var NORM_INF2 = 2;
18103
+ var NORM_FRO2 = 3;
18104
+ function dlanst(norm2, n, d, dOff, e, eOff) {
18105
+ let anorm = 0;
18106
+ if (n <= 0) {
18107
+ anorm = 0;
18108
+ } else if (norm2 === NORM_MAX5) {
18109
+ anorm = Math.abs(d[dOff + (n - 1)]);
18110
+ for (let i = 1; i <= n - 1; i++) {
18111
+ let sum2 = Math.abs(d[dOff + (i - 1)]);
18112
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
18113
+ sum2 = Math.abs(e[eOff + (i - 1)]);
18114
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
18115
+ }
18116
+ } else if (norm2 === NORM_ONE2 || norm2 === NORM_INF2) {
18117
+ if (n === 1) {
18118
+ anorm = Math.abs(d[dOff]);
18119
+ } else {
18120
+ anorm = Math.abs(d[dOff]) + Math.abs(e[eOff]);
18121
+ let sum2 = Math.abs(e[eOff + (n - 2)]) + Math.abs(d[dOff + (n - 1)]);
18122
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
18123
+ for (let i = 2; i <= n - 1; i++) {
18124
+ sum2 = Math.abs(d[dOff + (i - 1)]) + Math.abs(e[eOff + (i - 1)]) + Math.abs(e[eOff + (i - 2)]);
18125
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
18126
+ }
18127
+ }
18128
+ } else if (norm2 === NORM_FRO2) {
18129
+ const scale = { val: 0 };
18130
+ const sum2 = { val: 1 };
18131
+ if (n > 1) {
18132
+ dlassq(n - 1, e, eOff, 1, scale, sum2);
18133
+ sum2.val = 2 * sum2.val;
18134
+ }
18135
+ dlassq(n, d, dOff, 1, scale, sum2);
18136
+ anorm = scale.val * Math.sqrt(sum2.val);
18137
+ }
18138
+ return anorm;
18139
+ }
18140
+
18141
+ // src/ts-lapack/src/SRC/dlae2.ts
18142
+ function dlae2(a, b, c) {
18143
+ const ONE10 = 1;
18144
+ const TWO = 2;
18145
+ const HALF = 0.5;
18146
+ const sm = a + c;
18147
+ const df = a - c;
18148
+ const adf = Math.abs(df);
18149
+ const tb = b + b;
18150
+ const ab = Math.abs(tb);
18151
+ let acmx, acmn;
18152
+ if (Math.abs(a) > Math.abs(c)) {
18153
+ acmx = a;
18154
+ acmn = c;
18155
+ } else {
18156
+ acmx = c;
18157
+ acmn = a;
18158
+ }
18159
+ let rt;
18160
+ if (adf > ab) {
18161
+ rt = adf * Math.sqrt(ONE10 + (ab / adf) ** 2);
18162
+ } else if (adf < ab) {
18163
+ rt = ab * Math.sqrt(ONE10 + (adf / ab) ** 2);
18164
+ } else {
18165
+ rt = ab * Math.sqrt(TWO);
18166
+ }
18167
+ let rt1, rt2;
18168
+ if (sm < 0) {
18169
+ rt1 = HALF * (sm - rt);
18170
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
18171
+ } else if (sm > 0) {
18172
+ rt1 = HALF * (sm + rt);
18173
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
18174
+ } else {
18175
+ rt1 = HALF * rt;
18176
+ rt2 = -HALF * rt;
18177
+ }
18178
+ return { rt1, rt2 };
18179
+ }
18180
+
18181
+ // src/ts-lapack/src/SRC/dlaev2.ts
18182
+ function dlaev2(a, b, c) {
18183
+ const ONE10 = 1;
18184
+ const TWO = 2;
18185
+ const HALF = 0.5;
18186
+ const sm = a + c;
18187
+ const df = a - c;
18188
+ const adf = Math.abs(df);
18189
+ const tb = b + b;
18190
+ const ab = Math.abs(tb);
18191
+ let acmx, acmn;
18192
+ if (Math.abs(a) > Math.abs(c)) {
18193
+ acmx = a;
18194
+ acmn = c;
18195
+ } else {
18196
+ acmx = c;
18197
+ acmn = a;
18198
+ }
18199
+ let rt;
18200
+ if (adf > ab) {
18201
+ rt = adf * Math.sqrt(ONE10 + (ab / adf) ** 2);
18202
+ } else if (adf < ab) {
18203
+ rt = ab * Math.sqrt(ONE10 + (adf / ab) ** 2);
18204
+ } else {
18205
+ rt = ab * Math.sqrt(TWO);
18206
+ }
18207
+ let rt1, rt2, sgn1;
18208
+ if (sm < 0) {
18209
+ rt1 = HALF * (sm - rt);
18210
+ sgn1 = -1;
18211
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
18212
+ } else if (sm > 0) {
18213
+ rt1 = HALF * (sm + rt);
18214
+ sgn1 = 1;
18215
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
18216
+ } else {
18217
+ rt1 = HALF * rt;
18218
+ rt2 = -HALF * rt;
18219
+ sgn1 = 1;
18220
+ }
18221
+ let cs, sgn2;
18222
+ if (df >= 0) {
18223
+ cs = df + rt;
18224
+ sgn2 = 1;
18225
+ } else {
18226
+ cs = df - rt;
18227
+ sgn2 = -1;
18228
+ }
18229
+ let cs1, sn1;
18230
+ const acs = Math.abs(cs);
18231
+ if (acs > ab) {
18232
+ const ct = -tb / cs;
18233
+ sn1 = ONE10 / Math.sqrt(ONE10 + ct * ct);
18234
+ cs1 = ct * sn1;
18235
+ } else {
18236
+ if (ab === 0) {
18237
+ cs1 = ONE10;
18238
+ sn1 = 0;
18239
+ } else {
18240
+ const tn = -cs / tb;
18241
+ cs1 = ONE10 / Math.sqrt(ONE10 + tn * tn);
18242
+ sn1 = tn * cs1;
18243
+ }
18244
+ }
18245
+ if (sgn1 === sgn2) {
18246
+ const tn = cs1;
18247
+ cs1 = -sn1;
18248
+ sn1 = tn;
18249
+ }
18250
+ return { rt1, rt2, cs1, sn1 };
18251
+ }
18252
+
18253
+ // src/ts-lapack/src/SRC/dlasrt.ts
18254
+ function dlasrt(id, n, d, dOff) {
18255
+ const SELECT = 20;
18256
+ let info = 0;
18257
+ let dir = -1;
18258
+ if (id === SORT_DEC) {
18259
+ dir = 0;
18260
+ } else if (id === SORT_INC) {
18261
+ dir = 1;
18262
+ }
18263
+ if (dir === -1) {
18264
+ info = -1;
18265
+ } else if (n < 0) {
18266
+ info = -2;
18267
+ }
18268
+ if (info !== 0) {
18269
+ return info;
18270
+ }
18271
+ if (n <= 1) {
18272
+ return 0;
18273
+ }
18274
+ const stack1 = new Int32Array(33);
18275
+ const stack2 = new Int32Array(33);
18276
+ let stkpnt = 1;
18277
+ stack1[1] = 1;
18278
+ stack2[1] = n;
18279
+ while (stkpnt > 0) {
18280
+ const start = stack1[stkpnt];
18281
+ const endd = stack2[stkpnt];
18282
+ stkpnt--;
18283
+ if (endd - start <= SELECT && endd - start > 0) {
18284
+ if (dir === 0) {
18285
+ for (let i = start + 1; i <= endd; i++) {
18286
+ for (let j = i; j >= start + 1; j--) {
18287
+ if (d[dOff + (j - 1)] > d[dOff + (j - 2)]) {
18288
+ const dmnmx = d[dOff + (j - 1)];
18289
+ d[dOff + (j - 1)] = d[dOff + (j - 2)];
18290
+ d[dOff + (j - 2)] = dmnmx;
18291
+ } else {
18292
+ break;
18293
+ }
18294
+ }
18295
+ }
18296
+ } else {
18297
+ for (let i = start + 1; i <= endd; i++) {
18298
+ for (let j = i; j >= start + 1; j--) {
18299
+ if (d[dOff + (j - 1)] < d[dOff + (j - 2)]) {
18300
+ const dmnmx = d[dOff + (j - 1)];
18301
+ d[dOff + (j - 1)] = d[dOff + (j - 2)];
18302
+ d[dOff + (j - 2)] = dmnmx;
18303
+ } else {
18304
+ break;
18305
+ }
18306
+ }
18307
+ }
18308
+ }
18309
+ } else if (endd - start > SELECT) {
18310
+ const d1 = d[dOff + (start - 1)];
18311
+ const d2 = d[dOff + (endd - 1)];
18312
+ const ii = Math.trunc((start + endd) / 2);
18313
+ const d3 = d[dOff + (ii - 1)];
18314
+ let dmnmx;
18315
+ if (d1 < d2) {
18316
+ if (d3 < d1) {
18317
+ dmnmx = d1;
18318
+ } else if (d3 < d2) {
18319
+ dmnmx = d3;
18320
+ } else {
18321
+ dmnmx = d2;
18322
+ }
18323
+ } else {
18324
+ if (d3 < d2) {
18325
+ dmnmx = d2;
18326
+ } else if (d3 < d1) {
18327
+ dmnmx = d3;
18328
+ } else {
18329
+ dmnmx = d1;
18330
+ }
18331
+ }
18332
+ let i;
18333
+ let j;
18334
+ if (dir === 0) {
18335
+ i = start - 1;
18336
+ j = endd + 1;
18337
+ while (true) {
18338
+ do {
18339
+ j--;
18340
+ } while (d[dOff + (j - 1)] < dmnmx);
18341
+ do {
18342
+ i++;
18343
+ } while (d[dOff + (i - 1)] > dmnmx);
18344
+ if (i < j) {
18345
+ const tmp = d[dOff + (i - 1)];
18346
+ d[dOff + (i - 1)] = d[dOff + (j - 1)];
18347
+ d[dOff + (j - 1)] = tmp;
18348
+ } else {
18349
+ break;
18350
+ }
18351
+ }
18352
+ if (j - start > endd - j - 1) {
18353
+ stkpnt++;
18354
+ stack1[stkpnt] = start;
18355
+ stack2[stkpnt] = j;
18356
+ stkpnt++;
18357
+ stack1[stkpnt] = j + 1;
18358
+ stack2[stkpnt] = endd;
18359
+ } else {
18360
+ stkpnt++;
18361
+ stack1[stkpnt] = j + 1;
18362
+ stack2[stkpnt] = endd;
18363
+ stkpnt++;
18364
+ stack1[stkpnt] = start;
18365
+ stack2[stkpnt] = j;
18366
+ }
18367
+ } else {
18368
+ i = start - 1;
18369
+ j = endd + 1;
18370
+ while (true) {
18371
+ do {
18372
+ j--;
18373
+ } while (d[dOff + (j - 1)] > dmnmx);
18374
+ do {
18375
+ i++;
18376
+ } while (d[dOff + (i - 1)] < dmnmx);
18377
+ if (i < j) {
18378
+ const tmp = d[dOff + (i - 1)];
18379
+ d[dOff + (i - 1)] = d[dOff + (j - 1)];
18380
+ d[dOff + (j - 1)] = tmp;
18381
+ } else {
18382
+ break;
18383
+ }
18384
+ }
18385
+ if (j - start > endd - j - 1) {
18386
+ stkpnt++;
18387
+ stack1[stkpnt] = start;
18388
+ stack2[stkpnt] = j;
18389
+ stkpnt++;
18390
+ stack1[stkpnt] = j + 1;
18391
+ stack2[stkpnt] = endd;
18392
+ } else {
18393
+ stkpnt++;
18394
+ stack1[stkpnt] = j + 1;
18395
+ stack2[stkpnt] = endd;
18396
+ stkpnt++;
18397
+ stack1[stkpnt] = start;
18398
+ stack2[stkpnt] = j;
18399
+ }
18400
+ }
18401
+ }
18402
+ }
18403
+ return 0;
18404
+ }
18405
+
18406
+ // src/ts-lapack/src/SRC/dsteqr.ts
18407
+ var COMPZ_N = 0;
18408
+ var COMPZ_V = 1;
18409
+ var COMPZ_I = 2;
18410
+ var NORM_MAX6 = 0;
18411
+ var TYPE_G3 = 0;
18412
+ var UPLO_FULL2 = -1;
18413
+ function fsign6(a, b) {
18414
+ return b >= 0 ? Math.abs(a) : -Math.abs(a);
18415
+ }
18416
+ function dsteqr(compz, n, d, dOff, e, eOff, z, zOff, ldz, work, workOff) {
18417
+ const ZERO9 = 0;
18418
+ const ONE10 = 1;
18419
+ const TWO = 2;
18420
+ const THREE = 3;
18421
+ const MAXIT = 30;
18422
+ let info = 0;
18423
+ if (compz !== COMPZ_N && compz !== COMPZ_V && compz !== COMPZ_I) {
18424
+ info = -1;
18425
+ } else if (n < 0) {
18426
+ info = -2;
18427
+ } else if (ldz < 1 || compz > 0 && ldz < Math.max(1, n)) {
18428
+ info = -6;
18429
+ }
18430
+ if (info !== 0) {
18431
+ xerbla("DSTEQR", -info);
18432
+ return info;
18433
+ }
18434
+ if (n === 0) return 0;
18435
+ if (n === 1) {
18436
+ if (compz === COMPZ_I) z[zOff] = ONE10;
18437
+ return 0;
18438
+ }
18439
+ const D = (i) => dOff + (i - 1);
18440
+ const E = (i) => eOff + (i - 1);
18441
+ const Zc = (j) => zOff + (j - 1) * ldz;
18442
+ const W = (i) => workOff + (i - 1);
18443
+ const eps2 = dlamch(MACH_EPS);
18444
+ const eps22 = eps2 * eps2;
18445
+ const safmin = dlamch(MACH_SFMIN);
18446
+ const safmax = ONE10 / safmin;
18447
+ const ssfmax = Math.sqrt(safmax) / THREE;
18448
+ const ssfmin = Math.sqrt(safmin) / eps22;
18449
+ if (compz === COMPZ_I) dlaset(UPLO_FULL2, n, n, ZERO9, ONE10, z, zOff, ldz);
18450
+ const nmaxit = n * MAXIT;
18451
+ let jtot = 0;
18452
+ let l1 = 1;
18453
+ const nm1 = n - 1;
18454
+ let ordered = false;
18455
+ outer: for (; ; ) {
18456
+ if (l1 > n) {
18457
+ ordered = true;
18458
+ break outer;
18459
+ }
18460
+ if (l1 > 1) e[E(l1 - 1)] = ZERO9;
18461
+ let m = n;
18462
+ if (l1 <= nm1) {
18463
+ let split = false;
18464
+ for (m = l1; m <= nm1; m++) {
18465
+ const tst = Math.abs(e[E(m)]);
18466
+ if (tst === ZERO9) {
18467
+ split = true;
18468
+ break;
18469
+ }
18470
+ if (tst <= Math.sqrt(Math.abs(d[D(m)])) * Math.sqrt(Math.abs(d[D(m + 1)])) * eps2) {
18471
+ e[E(m)] = ZERO9;
18472
+ split = true;
18473
+ break;
18474
+ }
18475
+ }
18476
+ if (!split) m = n;
18477
+ }
18478
+ let l = l1;
18479
+ const lsv = l;
18480
+ let lend = m;
18481
+ const lendsv = lend;
18482
+ l1 = m + 1;
18483
+ if (lend === l) continue outer;
18484
+ const anorm = dlanst(NORM_MAX6, lend - l + 1, d, D(l), e, E(l));
18485
+ let iscale = 0;
18486
+ if (anorm === ZERO9) continue outer;
18487
+ if (anorm > ssfmax) {
18488
+ iscale = 1;
18489
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmax, lend - l + 1, 1, d, D(l), n);
18490
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmax, lend - l, 1, e, E(l), n);
18491
+ } else if (anorm < ssfmin) {
18492
+ iscale = 2;
18493
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmin, lend - l + 1, 1, d, D(l), n);
18494
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmin, lend - l, 1, e, E(l), n);
18495
+ }
18496
+ if (Math.abs(d[D(lend)]) < Math.abs(d[D(l)])) {
18497
+ lend = lsv;
18498
+ l = lendsv;
18499
+ }
18500
+ if (lend > l) {
18501
+ ql: for (; ; ) {
18502
+ if (l !== lend) {
18503
+ let found = false;
18504
+ for (m = l; m <= lend - 1; m++) {
18505
+ const tst = Math.abs(e[E(m)]) ** 2;
18506
+ if (tst <= eps22 * Math.abs(d[D(m)]) * Math.abs(d[D(m + 1)]) + safmin) {
18507
+ found = true;
18508
+ break;
18509
+ }
18510
+ }
18511
+ if (!found) m = lend;
18512
+ } else {
18513
+ m = lend;
18514
+ }
18515
+ if (m < lend) e[E(m)] = ZERO9;
18516
+ let p2 = d[D(l)];
18517
+ if (m === l) {
18518
+ d[D(l)] = p2;
18519
+ l = l + 1;
18520
+ if (l <= lend) continue ql;
18521
+ break ql;
18522
+ }
18523
+ if (m === l + 1) {
18524
+ if (compz > 0) {
18525
+ const r2 = dlaev2(d[D(l)], e[E(l)], d[D(l + 1)]);
18526
+ work[W(l)] = r2.cs1;
18527
+ work[W(n - 1 + l)] = r2.sn1;
18528
+ dlasr(
18529
+ RIGHT,
18530
+ PIVOT_V,
18531
+ DIRECT_B,
18532
+ n,
18533
+ 2,
18534
+ work,
18535
+ W(l),
18536
+ work,
18537
+ W(n - 1 + l),
18538
+ z,
18539
+ Zc(l),
18540
+ ldz
18541
+ );
18542
+ d[D(l)] = r2.rt1;
18543
+ d[D(l + 1)] = r2.rt2;
18544
+ } else {
18545
+ const r2 = dlae2(d[D(l)], e[E(l)], d[D(l + 1)]);
18546
+ d[D(l)] = r2.rt1;
18547
+ d[D(l + 1)] = r2.rt2;
18548
+ }
18549
+ e[E(l)] = ZERO9;
18550
+ l = l + 2;
18551
+ if (l <= lend) continue ql;
18552
+ break ql;
18553
+ }
18554
+ if (jtot === nmaxit) break ql;
18555
+ jtot = jtot + 1;
18556
+ let g = (d[D(l + 1)] - p2) / (TWO * e[E(l)]);
18557
+ let r = dlapy2(g, ONE10);
18558
+ g = d[D(m)] - p2 + e[E(l)] / (g + fsign6(r, g));
18559
+ let s = ONE10;
18560
+ let c = ONE10;
18561
+ p2 = ZERO9;
18562
+ for (let i = m - 1; i >= l; i--) {
18563
+ const f = s * e[E(i)];
18564
+ const b = c * e[E(i)];
18565
+ const rot = dlartg(g, f);
18566
+ c = rot.cs;
18567
+ s = rot.sn;
18568
+ r = rot.r;
18569
+ if (i !== m - 1) e[E(i + 1)] = r;
18570
+ g = d[D(i + 1)] - p2;
18571
+ r = (d[D(i)] - g) * s + TWO * c * b;
18572
+ p2 = s * r;
18573
+ d[D(i + 1)] = g + p2;
18574
+ g = c * r - b;
18575
+ if (compz > 0) {
18576
+ work[W(i)] = c;
18577
+ work[W(n - 1 + i)] = -s;
18578
+ }
18579
+ }
18580
+ if (compz > 0) {
18581
+ const mm = m - l + 1;
18582
+ dlasr(
18583
+ RIGHT,
18584
+ PIVOT_V,
18585
+ DIRECT_B,
18586
+ n,
18587
+ mm,
18588
+ work,
18589
+ W(l),
18590
+ work,
18591
+ W(n - 1 + l),
18592
+ z,
18593
+ Zc(l),
18594
+ ldz
18595
+ );
18596
+ }
18597
+ d[D(l)] = d[D(l)] - p2;
18598
+ e[E(l)] = g;
18599
+ continue ql;
18600
+ }
18601
+ } else {
18602
+ qr: for (; ; ) {
18603
+ if (l !== lend) {
18604
+ let found = false;
18605
+ for (m = l; m >= lend + 1; m--) {
18606
+ const tst = Math.abs(e[E(m - 1)]) ** 2;
18607
+ if (tst <= eps22 * Math.abs(d[D(m)]) * Math.abs(d[D(m - 1)]) + safmin) {
18608
+ found = true;
18609
+ break;
18610
+ }
18611
+ }
18612
+ if (!found) m = lend;
18613
+ } else {
18614
+ m = lend;
18615
+ }
18616
+ if (m > lend) e[E(m - 1)] = ZERO9;
18617
+ let p2 = d[D(l)];
18618
+ if (m === l) {
18619
+ d[D(l)] = p2;
18620
+ l = l - 1;
18621
+ if (l >= lend) continue qr;
18622
+ break qr;
18623
+ }
18624
+ if (m === l - 1) {
18625
+ if (compz > 0) {
18626
+ const r2 = dlaev2(d[D(l - 1)], e[E(l - 1)], d[D(l)]);
18627
+ work[W(m)] = r2.cs1;
18628
+ work[W(n - 1 + m)] = r2.sn1;
18629
+ dlasr(
18630
+ RIGHT,
18631
+ PIVOT_V,
18632
+ DIRECT_F,
18633
+ n,
18634
+ 2,
18635
+ work,
18636
+ W(m),
18637
+ work,
18638
+ W(n - 1 + m),
18639
+ z,
18640
+ Zc(l - 1),
18641
+ ldz
18642
+ );
18643
+ d[D(l - 1)] = r2.rt1;
18644
+ d[D(l)] = r2.rt2;
18645
+ } else {
18646
+ const r2 = dlae2(d[D(l - 1)], e[E(l - 1)], d[D(l)]);
18647
+ d[D(l - 1)] = r2.rt1;
18648
+ d[D(l)] = r2.rt2;
18649
+ }
18650
+ e[E(l - 1)] = ZERO9;
18651
+ l = l - 2;
18652
+ if (l >= lend) continue qr;
18653
+ break qr;
18654
+ }
18655
+ if (jtot === nmaxit) break qr;
18656
+ jtot = jtot + 1;
18657
+ let g = (d[D(l - 1)] - p2) / (TWO * e[E(l - 1)]);
18658
+ let r = dlapy2(g, ONE10);
18659
+ g = d[D(m)] - p2 + e[E(l - 1)] / (g + fsign6(r, g));
18660
+ let s = ONE10;
18661
+ let c = ONE10;
18662
+ p2 = ZERO9;
18663
+ for (let i = m; i <= l - 1; i++) {
18664
+ const f = s * e[E(i)];
18665
+ const b = c * e[E(i)];
18666
+ const rot = dlartg(g, f);
18667
+ c = rot.cs;
18668
+ s = rot.sn;
18669
+ r = rot.r;
18670
+ if (i !== m) e[E(i - 1)] = r;
18671
+ g = d[D(i)] - p2;
18672
+ r = (d[D(i + 1)] - g) * s + TWO * c * b;
18673
+ p2 = s * r;
18674
+ d[D(i)] = g + p2;
18675
+ g = c * r - b;
18676
+ if (compz > 0) {
18677
+ work[W(i)] = c;
18678
+ work[W(n - 1 + i)] = s;
18679
+ }
18680
+ }
18681
+ if (compz > 0) {
18682
+ const mm = l - m + 1;
18683
+ dlasr(
18684
+ RIGHT,
18685
+ PIVOT_V,
18686
+ DIRECT_F,
18687
+ n,
18688
+ mm,
18689
+ work,
18690
+ W(m),
18691
+ work,
18692
+ W(n - 1 + m),
18693
+ z,
18694
+ Zc(m),
18695
+ ldz
18696
+ );
18697
+ }
18698
+ d[D(l)] = d[D(l)] - p2;
18699
+ e[E(l - 1)] = g;
18700
+ continue qr;
18701
+ }
18702
+ }
18703
+ if (iscale === 1) {
18704
+ dlascl(TYPE_G3, 0, 0, ssfmax, anorm, lendsv - lsv + 1, 1, d, D(lsv), n);
18705
+ dlascl(TYPE_G3, 0, 0, ssfmax, anorm, lendsv - lsv, 1, e, E(lsv), n);
18706
+ } else if (iscale === 2) {
18707
+ dlascl(TYPE_G3, 0, 0, ssfmin, anorm, lendsv - lsv + 1, 1, d, D(lsv), n);
18708
+ dlascl(TYPE_G3, 0, 0, ssfmin, anorm, lendsv - lsv, 1, e, E(lsv), n);
18709
+ }
18710
+ if (jtot < nmaxit) continue outer;
18711
+ for (let i = 1; i <= n - 1; i++) {
18712
+ if (e[E(i)] !== ZERO9) info = info + 1;
18713
+ }
18714
+ break outer;
18715
+ }
18716
+ if (!ordered) return info;
18717
+ if (compz === COMPZ_N) {
18718
+ const sortInfo = dlasrt(SORT_INC, n, d, dOff);
18719
+ if (sortInfo !== 0) return sortInfo;
18720
+ } else {
18721
+ for (let ii = 2; ii <= n; ii++) {
18722
+ const i = ii - 1;
18723
+ let k = i;
18724
+ let p2 = d[D(i)];
18725
+ for (let j = ii; j <= n; j++) {
18726
+ if (d[D(j)] < p2) {
18727
+ k = j;
18728
+ p2 = d[D(j)];
18729
+ }
18730
+ }
18731
+ if (k !== i) {
18732
+ d[D(k)] = d[D(i)];
18733
+ d[D(i)] = p2;
18734
+ dswap(n, z, Zc(i), 1, z, Zc(k), 1);
18735
+ }
18736
+ }
18737
+ }
18738
+ return info;
18739
+ }
18740
+
18741
+ // src/numbl-core/native/ts-lapack-eig-hermitian.ts
18742
+ var EPS2 = 2220446049250313e-31;
18743
+ var SAFMIN2 = 22250738585072014e-324;
18744
+ function dlapy3(x, y, z) {
18745
+ const w = Math.max(Math.abs(x), Math.abs(y), Math.abs(z));
18746
+ if (w === 0 || !Number.isFinite(w))
18747
+ return Math.abs(x) + Math.abs(y) + Math.abs(z);
18748
+ return w * Math.sqrt((x / w) ** 2 + (y / w) ** 2 + (z / w) ** 2);
18749
+ }
18750
+ function fsign7(mag2, s) {
18751
+ return s >= 0 ? Math.abs(mag2) : -Math.abs(mag2);
18752
+ }
18753
+ function cdiv2(ar, ai, br, bi) {
18754
+ if (Math.abs(br) >= Math.abs(bi)) {
18755
+ const r2 = bi / br;
18756
+ const t2 = br + bi * r2;
18757
+ return [(ar + ai * r2) / t2, (ai - ar * r2) / t2];
18758
+ }
18759
+ const r = br / bi;
18760
+ const t = br * r + bi;
18761
+ return [(ar * r + ai) / t, (ai * r - ar) / t];
18762
+ }
18763
+ function dznrm2(n, re, im, off, incx) {
18764
+ let scale = 0;
18765
+ let ssq = 1;
18766
+ for (let i = 0, k = off; i < n; i++, k += incx) {
18767
+ for (const v of [re[k], im[k]]) {
18768
+ if (v !== 0) {
18769
+ const a = Math.abs(v);
18770
+ if (scale < a) {
18771
+ ssq = 1 + ssq * (scale / a) ** 2;
18772
+ scale = a;
18773
+ } else {
18774
+ ssq += (a / scale) ** 2;
18775
+ }
18776
+ }
18777
+ }
18778
+ }
18779
+ return scale * Math.sqrt(ssq);
18780
+ }
18781
+ function zlarfg2(n, re, im, off, incx) {
18782
+ if (n <= 0) return { tauRe: 0, tauIm: 0 };
18783
+ let xnorm = dznrm2(n - 1, re, im, off + incx, incx);
18784
+ let alphr = re[off];
18785
+ let alphi = im[off];
18786
+ if (xnorm === 0 && alphi === 0) {
18787
+ return { tauRe: 0, tauIm: 0 };
18788
+ }
18789
+ let beta = -fsign7(dlapy3(alphr, alphi, xnorm), alphr);
18790
+ const safmin = SAFMIN2 / EPS2;
18791
+ const rsafmn = 1 / safmin;
18792
+ let knt = 0;
18793
+ if (Math.abs(beta) < safmin) {
18794
+ do {
18795
+ knt++;
18796
+ for (let i = 1, k = off + incx; i < n; i++, k += incx) {
18797
+ re[k] *= rsafmn;
18798
+ im[k] *= rsafmn;
18799
+ }
18800
+ beta *= rsafmn;
18801
+ alphi *= rsafmn;
18802
+ alphr *= rsafmn;
18803
+ } while (Math.abs(beta) < safmin && knt < 20);
18804
+ xnorm = dznrm2(n - 1, re, im, off + incx, incx);
18805
+ beta = -fsign7(dlapy3(alphr, alphi, xnorm), alphr);
18806
+ }
18807
+ const tauRe = (beta - alphr) / beta;
18808
+ const tauIm = -alphi / beta;
18809
+ const [sr, si] = cdiv2(1, 0, alphr - beta, alphi);
18810
+ for (let i = 1, k = off + incx; i < n; i++, k += incx) {
18811
+ const xr = re[k];
18812
+ const xi = im[k];
18813
+ re[k] = xr * sr - xi * si;
18814
+ im[k] = xr * si + xi * sr;
18815
+ }
18816
+ for (let j = 1; j <= knt; j++) beta *= safmin;
18817
+ re[off] = beta;
18818
+ im[off] = 0;
18819
+ return { tauRe, tauIm };
18820
+ }
18821
+ function zhemvLower(n, alphaRe, alphaIm, aRe, aIm, aOff, lda, xRe, xIm, xOff, yRe, yIm, yOff) {
18822
+ for (let i = 0; i < n; i++) {
18823
+ yRe[yOff + i] = 0;
18824
+ yIm[yOff + i] = 0;
18825
+ }
18826
+ for (let j = 0; j < n; j++) {
18827
+ const xjr = xRe[xOff + j];
18828
+ const xji = xIm[xOff + j];
18829
+ const t1r = alphaRe * xjr - alphaIm * xji;
18830
+ const t1i = alphaRe * xji + alphaIm * xjr;
18831
+ let t2r = 0;
18832
+ let t2i = 0;
18833
+ const col = aOff + j * lda;
18834
+ yRe[yOff + j] += t1r * aRe[col + j];
18835
+ yIm[yOff + j] += t1i * aRe[col + j];
18836
+ for (let i = j + 1; i < n; i++) {
18837
+ const ar = aRe[col + i];
18838
+ const ai = aIm[col + i];
18839
+ yRe[yOff + i] += t1r * ar - t1i * ai;
18840
+ yIm[yOff + i] += t1r * ai + t1i * ar;
18841
+ const xir = xRe[xOff + i];
18842
+ const xii = xIm[xOff + i];
18843
+ t2r += ar * xir + ai * xii;
18844
+ t2i += ar * xii - ai * xir;
18845
+ }
18846
+ yRe[yOff + j] += alphaRe * t2r - alphaIm * t2i;
18847
+ yIm[yOff + j] += alphaRe * t2i + alphaIm * t2r;
18848
+ }
18849
+ }
18850
+ function zher2LowerMinus(n, xRe, xIm, xOff, yRe, yIm, yOff, aRe, aIm, aOff, lda) {
18851
+ for (let j = 0; j < n; j++) {
18852
+ const xjr = xRe[xOff + j];
18853
+ const xji = xIm[xOff + j];
18854
+ const yjr = yRe[yOff + j];
18855
+ const yji = yIm[yOff + j];
18856
+ const col = aOff + j * lda;
18857
+ if (xjr !== 0 || xji !== 0 || yjr !== 0 || yji !== 0) {
18858
+ const t1r = -yjr;
18859
+ const t1i = yji;
18860
+ const t2r = -xjr;
18861
+ const t2i = xji;
18862
+ aRe[col + j] = aRe[col + j] + (xjr * t1r - xji * t1i) + (yjr * t2r - yji * t2i);
18863
+ aIm[col + j] = 0;
18864
+ for (let i = j + 1; i < n; i++) {
18865
+ const xir = xRe[xOff + i];
18866
+ const xii = xIm[xOff + i];
18867
+ const yir = yRe[yOff + i];
18868
+ const yii = yIm[yOff + i];
18869
+ aRe[col + i] += xir * t1r - xii * t1i + (yir * t2r - yii * t2i);
18870
+ aIm[col + i] += xir * t1i + xii * t1r + (yir * t2i + yii * t2r);
18871
+ }
18872
+ } else {
18873
+ aIm[col + j] = 0;
18874
+ }
18875
+ }
18876
+ }
18877
+ function zhetd2Lower(n, aRe, aIm, lda, d, e, tauRe, tauIm) {
18878
+ const wRe = allocFloat64Array(Math.max(1, n));
18879
+ const wIm = allocFloat64Array(Math.max(1, n));
18880
+ for (let i = 1; i <= n - 1; i++) {
18881
+ const off = i + (i - 1) * lda;
18882
+ const t = zlarfg2(n - i, aRe, aIm, off, 1);
18883
+ e[i - 1] = aRe[off];
18884
+ const taur = t.tauRe;
18885
+ const taui = t.tauIm;
18886
+ if (taur !== 0 || taui !== 0) {
18887
+ aRe[off] = 1;
18888
+ aIm[off] = 0;
18889
+ const m = n - i;
18890
+ const a11 = i + i * lda;
18891
+ zhemvLower(m, taur, taui, aRe, aIm, a11, lda, aRe, aIm, off, wRe, wIm, 0);
18892
+ let dr = 0;
18893
+ let di = 0;
18894
+ for (let k = 0; k < m; k++) {
18895
+ const vr = aRe[off + k];
18896
+ const vi = aIm[off + k];
18897
+ dr += wRe[k] * vr + wIm[k] * vi;
18898
+ di += wRe[k] * vi - wIm[k] * vr;
18899
+ }
18900
+ const ar = -0.5 * (taur * dr - taui * di);
18901
+ const ai = -0.5 * (taur * di + taui * dr);
18902
+ for (let k = 0; k < m; k++) {
18903
+ const vr = aRe[off + k];
18904
+ const vi = aIm[off + k];
18905
+ wRe[k] += ar * vr - ai * vi;
18906
+ wIm[k] += ar * vi + ai * vr;
18907
+ }
18908
+ zher2LowerMinus(m, aRe, aIm, off, wRe, wIm, 0, aRe, aIm, a11, lda);
18909
+ } else {
18910
+ const a11 = i + i * lda;
18911
+ aIm[a11] = 0;
18912
+ }
18913
+ aRe[off] = e[i - 1];
18914
+ aIm[off] = 0;
18915
+ d[i - 1] = aRe[i - 1 + (i - 1) * lda];
18916
+ tauRe[i - 1] = taur;
18917
+ tauIm[i - 1] = taui;
18918
+ }
18919
+ d[n - 1] = aRe[n - 1 + (n - 1) * lda];
18920
+ }
18921
+ function zungtrLower(n, aRe, aIm, lda, tauRe, tauIm) {
18922
+ for (let j = n; j >= 2; j--) {
18923
+ aRe[(j - 1) * lda] = 0;
18924
+ aIm[(j - 1) * lda] = 0;
18925
+ for (let i = j + 1; i <= n; i++) {
18926
+ aRe[i - 1 + (j - 1) * lda] = aRe[i - 1 + (j - 2) * lda];
18927
+ aIm[i - 1 + (j - 1) * lda] = aIm[i - 1 + (j - 2) * lda];
18928
+ }
18929
+ }
18930
+ aRe[0] = 1;
18931
+ aIm[0] = 0;
18932
+ for (let i = 2; i <= n; i++) {
18933
+ aRe[i - 1] = 0;
18934
+ aIm[i - 1] = 0;
18935
+ }
18936
+ if (n <= 1) return;
18937
+ const m = n - 1;
18938
+ const base = 1 + lda;
18939
+ const workRe = allocFloat64Array(Math.max(1, m));
18940
+ const workIm = allocFloat64Array(Math.max(1, m));
18941
+ for (let i = m; i >= 1; i--) {
18942
+ const vOff = base + (i - 1) + (i - 1) * lda;
18943
+ const tr = tauRe[i - 1];
18944
+ const ti = tauIm[i - 1];
18945
+ if (i < m) {
18946
+ aRe[vOff] = 1;
18947
+ aIm[vOff] = 0;
18948
+ const rows = m - i + 1;
18949
+ const cols = m - i;
18950
+ const cOff = base + (i - 1) + i * lda;
18951
+ for (let j = 0; j < cols; j++) {
18952
+ let sr = 0;
18953
+ let si = 0;
18954
+ for (let k = 0; k < rows; k++) {
18955
+ const cr = aRe[cOff + k + j * lda];
18956
+ const ci = aIm[cOff + k + j * lda];
18957
+ const vr = aRe[vOff + k];
18958
+ const vi = aIm[vOff + k];
18959
+ sr += cr * vr + ci * vi;
18960
+ si += cr * vi - ci * vr;
18961
+ }
18962
+ workRe[j] = sr;
18963
+ workIm[j] = si;
18964
+ }
18965
+ for (let j = 0; j < cols; j++) {
18966
+ const wr = workRe[j];
18967
+ const wi = -workIm[j];
18968
+ const fr = -(tr * wr - ti * wi);
18969
+ const fi = -(tr * wi + ti * wr);
18970
+ for (let k = 0; k < rows; k++) {
18971
+ const vr = aRe[vOff + k];
18972
+ const vi = aIm[vOff + k];
18973
+ aRe[cOff + k + j * lda] += fr * vr - fi * vi;
18974
+ aIm[cOff + k + j * lda] += fr * vi + fi * vr;
18975
+ }
18976
+ }
18977
+ }
18978
+ if (i < m) {
18979
+ for (let k = 1; k <= m - i; k++) {
18980
+ const vr = aRe[vOff + k];
18981
+ const vi = aIm[vOff + k];
18982
+ aRe[vOff + k] = -(tr * vr - ti * vi);
18983
+ aIm[vOff + k] = -(tr * vi + ti * vr);
18984
+ }
18985
+ }
18986
+ aRe[vOff] = 1 - tr;
18987
+ aIm[vOff] = -ti;
18988
+ for (let k = 1; k <= i - 1; k++) {
18989
+ aRe[base + (k - 1) + (i - 1) * lda] = 0;
18990
+ aIm[base + (k - 1) + (i - 1) * lda] = 0;
18991
+ }
18992
+ }
18993
+ }
18994
+ function eigHermTs(dataRe, dataIm, n, computeV) {
18995
+ const w = allocFloat64Array(n);
18996
+ if (n === 0)
18997
+ return { w, VRe: allocFloat64Array(0), VIm: allocFloat64Array(0) };
18998
+ if (n === 1) {
18999
+ w[0] = dataRe[0];
19000
+ if (!computeV) return { w };
19001
+ const VRe2 = allocFloat64Array(1);
19002
+ VRe2[0] = 1;
19003
+ return { w, VRe: VRe2, VIm: allocFloat64Array(1) };
19004
+ }
19005
+ const aRe = allocFloat64Array(dataRe);
19006
+ const aIm = allocFloat64Array(dataIm);
19007
+ const e = allocFloat64Array(Math.max(1, n - 1));
19008
+ const tauRe = allocFloat64Array(Math.max(1, n - 1));
19009
+ const tauIm = allocFloat64Array(Math.max(1, n - 1));
19010
+ zhetd2Lower(n, aRe, aIm, n, w, e, tauRe, tauIm);
19011
+ if (!computeV) {
19012
+ const work2 = allocFloat64Array(Math.max(1, 2 * n - 2));
19013
+ const dummy = allocFloat64Array(1);
19014
+ dsteqr(COMPZ_N, n, w, 0, e, 0, dummy, 0, 1, work2, 0);
19015
+ return { w };
19016
+ }
19017
+ zungtrLower(n, aRe, aIm, n, tauRe, tauIm);
19018
+ const S = allocFloat64Array(n * n);
19019
+ const work = allocFloat64Array(Math.max(1, 2 * n - 2));
19020
+ dsteqr(COMPZ_I, n, w, 0, e, 0, S, 0, n, work, 0);
19021
+ const VRe = allocFloat64Array(n * n);
19022
+ const VIm = allocFloat64Array(n * n);
19023
+ for (let j = 0; j < n; j++) {
19024
+ for (let k = 0; k < n; k++) {
19025
+ const s = S[k + j * n];
19026
+ if (s === 0) continue;
19027
+ for (let i = 0; i < n; i++) {
19028
+ VRe[i + j * n] += aRe[i + k * n] * s;
19029
+ VIm[i + j * n] += aIm[i + k * n] * s;
19030
+ }
19031
+ }
19032
+ }
19033
+ return { w, VRe, VIm };
19034
+ }
19035
+
19036
+ // src/ts-lapack/src/SRC/dlansy.ts
19037
+ var NORM_MAX7 = 0;
19038
+ var NORM_ONE3 = 1;
19039
+ var NORM_INF3 = 2;
19040
+ var NORM_FRO3 = 3;
19041
+ function dlansy(norm2, uplo, n, a, aOff, lda, work, workOff) {
19042
+ let value = 0;
19043
+ if (n === 0) {
19044
+ value = 0;
19045
+ } else if (norm2 === NORM_MAX7) {
19046
+ value = 0;
19047
+ if (uplo === UPPER) {
19048
+ for (let j = 1; j <= n; j++) {
19049
+ for (let i = 1; i <= j; i++) {
19050
+ const sum2 = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
19051
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
19052
+ }
19053
+ }
19054
+ } else {
19055
+ for (let j = 1; j <= n; j++) {
19056
+ for (let i = j; i <= n; i++) {
19057
+ const sum2 = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
19058
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
19059
+ }
19060
+ }
19061
+ }
19062
+ } else if (norm2 === NORM_ONE3 || norm2 === NORM_INF3) {
19063
+ value = 0;
19064
+ if (uplo === UPPER) {
19065
+ for (let j = 1; j <= n; j++) {
19066
+ let sum2 = 0;
19067
+ for (let i = 1; i <= j - 1; i++) {
19068
+ const absa = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
19069
+ sum2 += absa;
19070
+ work[workOff + (i - 1)] += absa;
19071
+ }
19072
+ work[workOff + (j - 1)] = sum2 + Math.abs(a[aOff + (j - 1) + (j - 1) * lda]);
19073
+ }
19074
+ for (let i = 1; i <= n; i++) {
19075
+ const sum2 = work[workOff + (i - 1)];
19076
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
19077
+ }
19078
+ } else {
19079
+ for (let i = 1; i <= n; i++) work[workOff + (i - 1)] = 0;
19080
+ for (let j = 1; j <= n; j++) {
19081
+ let sum2 = work[workOff + (j - 1)] + Math.abs(a[aOff + (j - 1) + (j - 1) * lda]);
19082
+ for (let i = j + 1; i <= n; i++) {
19083
+ const absa = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
19084
+ sum2 += absa;
19085
+ work[workOff + (i - 1)] += absa;
19086
+ }
19087
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
19088
+ }
19089
+ }
19090
+ } else if (norm2 === NORM_FRO3) {
19091
+ const scale = { val: 0 };
19092
+ const sum2 = { val: 1 };
19093
+ if (uplo === UPPER) {
19094
+ for (let j = 2; j <= n; j++) {
19095
+ dlassq(j - 1, a, aOff + (j - 1) * lda, 1, scale, sum2);
19096
+ }
19097
+ } else {
19098
+ for (let j = 1; j <= n - 1; j++) {
19099
+ dlassq(n - j, a, aOff + j + (j - 1) * lda, 1, scale, sum2);
19100
+ }
19101
+ }
19102
+ sum2.val = 2 * sum2.val;
19103
+ dlassq(n, a, aOff, lda + 1, scale, sum2);
19104
+ value = scale.val * Math.sqrt(sum2.val);
19105
+ }
19106
+ return value;
19107
+ }
19108
+
19109
+ // src/ts-lapack/src/BLAS/dsymv.ts
19110
+ function dsymv(uplo, n, alpha, a, aOff, lda, x, xOff, incx, beta, y, yOff, incy) {
19111
+ const ZERO9 = 0;
19112
+ const ONE10 = 1;
19113
+ let info = 0;
19114
+ if (uplo !== UPPER && uplo !== LOWER) {
19115
+ info = 1;
19116
+ } else if (n < 0) {
19117
+ info = 2;
19118
+ } else if (lda < Math.max(1, n)) {
19119
+ info = 5;
19120
+ } else if (incx === 0) {
19121
+ info = 7;
19122
+ } else if (incy === 0) {
19123
+ info = 10;
19124
+ }
19125
+ if (info !== 0) {
19126
+ xerbla("DSYMV ", info);
19127
+ return;
19128
+ }
19129
+ if (n === 0 || alpha === ZERO9 && beta === ONE10) return;
19130
+ const kx = incx > 0 ? 0 : -(n - 1) * incx;
19131
+ const ky = incy > 0 ? 0 : -(n - 1) * incy;
19132
+ if (beta !== ONE10) {
19133
+ let iy = ky;
19134
+ if (beta === ZERO9) {
19135
+ for (let i = 0; i < n; i++) {
19136
+ y[yOff + iy] = ZERO9;
19137
+ iy += incy;
19138
+ }
19139
+ } else {
19140
+ for (let i = 0; i < n; i++) {
19141
+ y[yOff + iy] *= beta;
19142
+ iy += incy;
19143
+ }
19144
+ }
19145
+ }
19146
+ if (alpha === ZERO9) return;
19147
+ if (uplo === UPPER) {
19148
+ let jx = kx;
19149
+ let jy = ky;
19150
+ for (let j = 1; j <= n; j++) {
19151
+ const temp1 = alpha * x[xOff + jx];
19152
+ let temp2 = ZERO9;
19153
+ const aCol = aOff + (j - 1) * lda;
19154
+ let ix = kx;
19155
+ let iy = ky;
19156
+ for (let i = 1; i <= j - 1; i++) {
19157
+ const aij = a[aCol + (i - 1)];
19158
+ y[yOff + iy] += temp1 * aij;
19159
+ temp2 += aij * x[xOff + ix];
19160
+ ix += incx;
19161
+ iy += incy;
19162
+ }
19163
+ y[yOff + jy] += temp1 * a[aCol + (j - 1)] + alpha * temp2;
19164
+ jx += incx;
19165
+ jy += incy;
19166
+ }
19167
+ } else {
19168
+ let jx = kx;
19169
+ let jy = ky;
19170
+ for (let j = 1; j <= n; j++) {
19171
+ const temp1 = alpha * x[xOff + jx];
19172
+ let temp2 = ZERO9;
19173
+ const aCol = aOff + (j - 1) * lda;
19174
+ y[yOff + jy] += temp1 * a[aCol + (j - 1)];
19175
+ let ix = jx;
19176
+ let iy = jy;
19177
+ for (let i = j + 1; i <= n; i++) {
19178
+ ix += incx;
19179
+ iy += incy;
19180
+ const aij = a[aCol + (i - 1)];
19181
+ y[yOff + iy] += temp1 * aij;
19182
+ temp2 += aij * x[xOff + ix];
19183
+ }
19184
+ y[yOff + jy] += alpha * temp2;
19185
+ jx += incx;
19186
+ jy += incy;
19187
+ }
19188
+ }
19189
+ }
19190
+
19191
+ // src/ts-lapack/src/BLAS/dsyr2.ts
19192
+ function dsyr2(uplo, n, alpha, x, xOff, incx, y, yOff, incy, a, aOff, lda) {
19193
+ const ZERO9 = 0;
19194
+ let info = 0;
19195
+ if (uplo !== UPPER && uplo !== LOWER) {
19196
+ info = 1;
19197
+ } else if (n < 0) {
19198
+ info = 2;
19199
+ } else if (incx === 0) {
19200
+ info = 5;
19201
+ } else if (incy === 0) {
19202
+ info = 7;
19203
+ } else if (lda < Math.max(1, n)) {
19204
+ info = 9;
19205
+ }
19206
+ if (info !== 0) {
19207
+ xerbla("DSYR2 ", info);
19208
+ return;
19209
+ }
19210
+ if (n === 0 || alpha === ZERO9) return;
19211
+ const kx = incx > 0 ? 0 : -(n - 1) * incx;
19212
+ const ky = incy > 0 ? 0 : -(n - 1) * incy;
19213
+ let jx = kx;
19214
+ let jy = ky;
19215
+ if (uplo === UPPER) {
19216
+ for (let j = 1; j <= n; j++) {
19217
+ const xj = x[xOff + jx];
19218
+ const yj = y[yOff + jy];
19219
+ if (xj !== ZERO9 || yj !== ZERO9) {
19220
+ const temp1 = alpha * yj;
19221
+ const temp2 = alpha * xj;
19222
+ const aCol = aOff + (j - 1) * lda;
19223
+ let ix = kx;
19224
+ let iy = ky;
19225
+ for (let i = 1; i <= j; i++) {
19226
+ a[aCol + (i - 1)] += x[xOff + ix] * temp1 + y[yOff + iy] * temp2;
19227
+ ix += incx;
19228
+ iy += incy;
19229
+ }
19230
+ }
19231
+ jx += incx;
19232
+ jy += incy;
19233
+ }
19234
+ } else {
19235
+ for (let j = 1; j <= n; j++) {
19236
+ const xj = x[xOff + jx];
19237
+ const yj = y[yOff + jy];
19238
+ if (xj !== ZERO9 || yj !== ZERO9) {
19239
+ const temp1 = alpha * yj;
19240
+ const temp2 = alpha * xj;
19241
+ const aCol = aOff + (j - 1) * lda;
19242
+ let ix = jx;
19243
+ let iy = jy;
19244
+ for (let i = j; i <= n; i++) {
19245
+ a[aCol + (i - 1)] += x[xOff + ix] * temp1 + y[yOff + iy] * temp2;
19246
+ ix += incx;
19247
+ iy += incy;
19248
+ }
19249
+ }
19250
+ jx += incx;
19251
+ jy += incy;
19252
+ }
19253
+ }
19254
+ }
19255
+
19256
+ // src/ts-lapack/src/SRC/dsytd2.ts
19257
+ function dsytd2(uplo, n, a, aOff, lda, d, dOff, e, eOff, tau, tauOff) {
19258
+ const ONE10 = 1;
19259
+ const ZERO9 = 0;
19260
+ const HALF = 0.5;
19261
+ let info = 0;
19262
+ const upper = uplo === UPPER;
19263
+ if (!upper && uplo !== LOWER) {
19264
+ info = -1;
19265
+ } else if (n < 0) {
19266
+ info = -2;
19267
+ } else if (lda < Math.max(1, n)) {
19268
+ info = -4;
19269
+ }
19270
+ if (info !== 0) {
19271
+ xerbla("DSYTD2", -info);
19272
+ return info;
19273
+ }
19274
+ if (n <= 0) return 0;
19275
+ const A = (i, j) => aOff + (i - 1) + (j - 1) * lda;
19276
+ if (upper) {
19277
+ for (let i = n - 1; i >= 1; i--) {
19278
+ const r = dlarfg(i, a[A(i, i + 1)], a, A(1, i + 1), 1);
19279
+ a[A(i, i + 1)] = r.alpha;
19280
+ const taui = r.tau;
19281
+ e[eOff + (i - 1)] = a[A(i, i + 1)];
19282
+ if (taui !== ZERO9) {
19283
+ a[A(i, i + 1)] = ONE10;
19284
+ dsymv(
19285
+ uplo,
19286
+ i,
19287
+ taui,
19288
+ a,
19289
+ aOff,
19290
+ lda,
19291
+ a,
19292
+ A(1, i + 1),
19293
+ 1,
19294
+ ZERO9,
19295
+ tau,
19296
+ tauOff,
19297
+ 1
19298
+ );
19299
+ const alpha = -HALF * taui * ddot(i, tau, tauOff, 1, a, A(1, i + 1), 1);
19300
+ daxpy(i, alpha, a, A(1, i + 1), 1, tau, tauOff, 1);
19301
+ dsyr2(uplo, i, -ONE10, a, A(1, i + 1), 1, tau, tauOff, 1, a, aOff, lda);
19302
+ a[A(i, i + 1)] = e[eOff + (i - 1)];
19303
+ }
19304
+ d[dOff + i] = a[A(i + 1, i + 1)];
19305
+ tau[tauOff + (i - 1)] = taui;
19306
+ }
19307
+ d[dOff] = a[A(1, 1)];
19308
+ } else {
19309
+ for (let i = 1; i <= n - 1; i++) {
19310
+ const r = dlarfg(n - i, a[A(i + 1, i)], a, A(Math.min(i + 2, n), i), 1);
19311
+ a[A(i + 1, i)] = r.alpha;
19312
+ const taui = r.tau;
19313
+ e[eOff + (i - 1)] = a[A(i + 1, i)];
19314
+ if (taui !== ZERO9) {
19315
+ a[A(i + 1, i)] = ONE10;
19316
+ dsymv(
19317
+ uplo,
19318
+ n - i,
19319
+ taui,
19320
+ a,
19321
+ A(i + 1, i + 1),
19322
+ lda,
19323
+ a,
19324
+ A(i + 1, i),
19325
+ 1,
19326
+ ZERO9,
19327
+ tau,
19328
+ tauOff + (i - 1),
19329
+ 1
19330
+ );
19331
+ const alpha = -HALF * taui * ddot(n - i, tau, tauOff + (i - 1), 1, a, A(i + 1, i), 1);
19332
+ daxpy(n - i, alpha, a, A(i + 1, i), 1, tau, tauOff + (i - 1), 1);
19333
+ dsyr2(
19334
+ uplo,
19335
+ n - i,
19336
+ -ONE10,
19337
+ a,
19338
+ A(i + 1, i),
19339
+ 1,
19340
+ tau,
19341
+ tauOff + (i - 1),
19342
+ 1,
19343
+ a,
19344
+ A(i + 1, i + 1),
19345
+ lda
19346
+ );
19347
+ a[A(i + 1, i)] = e[eOff + (i - 1)];
19348
+ }
19349
+ d[dOff + (i - 1)] = a[A(i, i)];
19350
+ tau[tauOff + (i - 1)] = taui;
19351
+ }
19352
+ d[dOff + (n - 1)] = a[A(n, n)];
19353
+ }
19354
+ return 0;
19355
+ }
19356
+
19357
+ // src/ts-lapack/src/SRC/dorgtr.ts
19358
+ function dorgtr(uplo, n, a, aOff, lda, tau, tauOff) {
19359
+ const ONE10 = 1;
19360
+ const ZERO9 = 0;
19361
+ let info = 0;
19362
+ if (uplo !== LOWER) {
19363
+ info = -1;
19364
+ } else if (n < 0) {
19365
+ info = -2;
19366
+ } else if (lda < Math.max(1, n)) {
19367
+ info = -4;
19368
+ }
19369
+ if (info !== 0) {
19370
+ xerbla("DORGTR", -info);
19371
+ return info;
19372
+ }
19373
+ if (n === 0) return 0;
19374
+ const A = (i, j) => aOff + (i - 1) + (j - 1) * lda;
19375
+ for (let j = n; j >= 2; j--) {
19376
+ a[A(1, j)] = ZERO9;
19377
+ for (let i = j + 1; i <= n; i++) {
19378
+ a[A(i, j)] = a[A(i, j - 1)];
19379
+ }
19380
+ }
19381
+ a[A(1, 1)] = ONE10;
19382
+ for (let i = 2; i <= n; i++) {
19383
+ a[A(i, 1)] = ZERO9;
19384
+ }
19385
+ if (n > 1) {
19386
+ info = dorgqr(n - 1, n - 1, n - 1, a, A(2, 2), lda, tau, tauOff);
19387
+ }
19388
+ return info;
19389
+ }
19390
+
19391
+ // src/ts-lapack/src/SRC/dsyev.ts
19392
+ var NORM_MAX8 = 0;
19393
+ var TYPE_L2 = 1;
19394
+ function dsyev(wantz, uplo, n, a, aOff, lda, w, wOff) {
19395
+ const ONE10 = 1;
19396
+ const ZERO9 = 0;
19397
+ let info = 0;
19398
+ if (uplo !== LOWER) {
19399
+ info = -2;
19400
+ } else if (n < 0) {
19401
+ info = -3;
19402
+ } else if (lda < Math.max(1, n)) {
19403
+ info = -5;
19404
+ }
19405
+ if (info !== 0) {
19406
+ xerbla("DSYEV ", -info);
19407
+ return info;
19408
+ }
19409
+ if (n === 0) return 0;
19410
+ if (n === 1) {
19411
+ w[wOff] = a[aOff];
19412
+ if (wantz) a[aOff] = ONE10;
19413
+ return 0;
19414
+ }
19415
+ const safmin = dlamch(MACH_SFMIN);
19416
+ const eps2 = dlamch(MACH_PREC);
19417
+ const smlnum = safmin / eps2;
19418
+ const bignum = ONE10 / smlnum;
19419
+ const rmin = Math.sqrt(smlnum);
19420
+ const rmax = Math.sqrt(bignum);
19421
+ const work = allocFloat64Array(Math.max(1, 3 * n));
19422
+ const anrm = dlansy(NORM_MAX8, uplo, n, a, aOff, lda, work, 0);
19423
+ let iscale = 0;
19424
+ let sigma = ONE10;
19425
+ if (anrm > ZERO9 && anrm < rmin) {
19426
+ iscale = 1;
19427
+ sigma = rmin / anrm;
19428
+ } else if (anrm > rmax) {
19429
+ iscale = 1;
19430
+ sigma = rmax / anrm;
19431
+ }
19432
+ if (iscale === 1) dlascl(TYPE_L2, 0, 0, ONE10, sigma, n, n, a, aOff, lda);
19433
+ const e = allocFloat64Array(Math.max(1, n - 1));
19434
+ const tau = allocFloat64Array(Math.max(1, n - 1));
19435
+ dsytd2(uplo, n, a, aOff, lda, w, wOff, e, 0, tau, 0);
19436
+ if (!wantz) {
19437
+ info = dsteqr(COMPZ_N, n, w, wOff, e, 0, a, aOff, lda, work, 0);
19438
+ } else {
19439
+ const iinfo = dorgtr(uplo, n, a, aOff, lda, tau, 0);
19440
+ if (iinfo !== 0) return iinfo;
19441
+ info = dsteqr(COMPZ_V, n, w, wOff, e, 0, a, aOff, lda, work, 0);
19442
+ }
19443
+ if (iscale === 1) {
19444
+ const imax = info === 0 ? n : info - 1;
19445
+ dscal(imax, ONE10 / sigma, w, wOff, 1);
19446
+ }
19447
+ return info;
19448
+ }
19449
+
18093
19450
  // src/numbl-core/native/ts-lapack-bridge.ts
18094
19451
  function inv(data, n) {
18095
19452
  const a = allocFloat64Array(data);
@@ -18263,6 +19620,20 @@ function linsolve(A, m, n, B, nrhs) {
18263
19620
  return x;
18264
19621
  }
18265
19622
  }
19623
+ function eigSym(data, n, computeV) {
19624
+ const a = allocFloat64Array(data);
19625
+ const w = allocFloat64Array(n);
19626
+ const info = dsyev(computeV, LOWER, n, a, 0, n, w, 0);
19627
+ if (info !== 0) {
19628
+ throw new Error(
19629
+ info < 0 ? "eig: illegal argument passed to dsyev" : "QR algorithm failed to converge in dsyev"
19630
+ );
19631
+ }
19632
+ return computeV ? { w, V: a } : { w };
19633
+ }
19634
+ function eigHerm(dataRe, dataIm, n, computeV) {
19635
+ return eigHermTs(dataRe, dataIm, n, computeV);
19636
+ }
18266
19637
  function eig(data, n, computeVL, computeVR, balance) {
18267
19638
  const a = allocFloat64Array(data);
18268
19639
  const wr = allocFloat64Array(n);
@@ -19001,7 +20372,9 @@ var _bridge2 = {
19001
20372
  linsolve,
19002
20373
  linsolveComplex,
19003
20374
  eig,
20375
+ eigSym,
19004
20376
  eigComplex: eigComplexTs,
20377
+ eigHerm,
19005
20378
  lu,
19006
20379
  svd,
19007
20380
  chol,
@@ -21461,6 +22834,21 @@ function mMulSparse(a, b) {
21461
22834
  const m = a.m;
21462
22835
  const hasImag = isComplexSparse(a) || b.imag !== void 0;
21463
22836
  const result = allocFloat64Array(m * bCols);
22837
+ if (!hasImag) {
22838
+ const ir = a.ir, jc = a.jc, pr = a.pr, bd = b.data;
22839
+ for (let col = 0; col < bCols; col++) {
22840
+ const boff = col * bRows;
22841
+ const roff = col * m;
22842
+ for (let k = 0; k < a.n; k++) {
22843
+ const bk = bd[boff + k];
22844
+ if (bk === 0) continue;
22845
+ const end = jc[k + 1];
22846
+ for (let ka = jc[k]; ka < end; ka++)
22847
+ result[roff + ir[ka]] += pr[ka] * bk;
22848
+ }
22849
+ }
22850
+ return RTV.tensor(result, [m, bCols]);
22851
+ }
21464
22852
  const resultImag = hasImag ? allocFloat64Array(m * bCols) : void 0;
21465
22853
  for (let col = 0; col < bCols; col++) {
21466
22854
  for (let k = 0; k < a.n; k++) {
@@ -22580,6 +23968,707 @@ function sprintfFormat(fmt, args) {
22580
23968
  return result;
22581
23969
  }
22582
23970
 
23971
+ // src/numbl-core/helpers/warn.ts
23972
+ var sink = (msg) => console.warn("Warning: " + msg);
23973
+ function setWarningSink(fn) {
23974
+ sink = fn;
23975
+ }
23976
+ function emitWarning(msg) {
23977
+ sink(msg);
23978
+ }
23979
+
23980
+ // src/numbl-core/helpers/sparse-direct.ts
23981
+ var SINGULAR_WARNING = "Matrix is singular to working precision.";
23982
+ function denseToSparse(t) {
23983
+ const m = t.shape[0] ?? 1;
23984
+ const n = t.shape.length >= 2 ? t.shape[1] : 1;
23985
+ const irList = [];
23986
+ const prList = [];
23987
+ const piList = t.imag ? [] : void 0;
23988
+ const jc = new Int32Array(n + 1);
23989
+ for (let c = 0; c < n; c++) {
23990
+ jc[c] = irList.length;
23991
+ for (let r = 0; r < m; r++) {
23992
+ const idx = c * m + r;
23993
+ const re = t.data[idx];
23994
+ const im = t.imag ? t.imag[idx] : 0;
23995
+ if (re !== 0 || im !== 0) {
23996
+ irList.push(r);
23997
+ prList.push(re);
23998
+ if (piList) piList.push(im);
23999
+ }
24000
+ }
24001
+ }
24002
+ jc[n] = irList.length;
24003
+ return RTV.sparseMatrix(
24004
+ m,
24005
+ n,
24006
+ new Int32Array(irList),
24007
+ jc,
24008
+ allocFloat64Array(prList),
24009
+ piList ? allocFloat64Array(piList) : void 0
24010
+ );
24011
+ }
24012
+ function denseDataToSparse(data, m, n) {
24013
+ return denseToSparse(RTV.tensor(data, [m, n]));
24014
+ }
24015
+ function fromUnsortedColumns(m, n, ir, jc, pr) {
24016
+ return sparseTranspose(sparseTranspose(RTV.sparseMatrix(m, n, ir, jc, pr)));
24017
+ }
24018
+ function permutationMatrix(p2) {
24019
+ const n = p2.length;
24020
+ const ir = new Int32Array(n);
24021
+ const jc = new Int32Array(n + 1);
24022
+ const pr = allocFloat64Array(n);
24023
+ for (let k = 0; k < n; k++) jc[p2[k] + 1]++;
24024
+ for (let c = 0; c < n; c++) jc[c + 1] += jc[c];
24025
+ for (let k = 0; k < n; k++) {
24026
+ ir[jc[p2[k]]] = k;
24027
+ pr[jc[p2[k]]] = 1;
24028
+ }
24029
+ return RTV.sparseMatrix(n, n, ir, jc, pr);
24030
+ }
24031
+ function permVectorTensor(p2) {
24032
+ const d = allocFloat64Array(p2.length);
24033
+ for (let i = 0; i < p2.length; i++) d[i] = p2[i] + 1;
24034
+ return RTV.tensor(d, [1, p2.length]);
24035
+ }
24036
+ function invertPerm(p2) {
24037
+ const inv2 = new Int32Array(p2.length);
24038
+ for (let i = 0; i < p2.length; i++) inv2[p2[i]] = i;
24039
+ return inv2;
24040
+ }
24041
+ function sparsePermute(A, p2, q) {
24042
+ const pinv = invertPerm(p2);
24043
+ const nnz = A.jc[A.n];
24044
+ const ir = new Int32Array(nnz);
24045
+ const jc = new Int32Array(A.n + 1);
24046
+ const pr = allocFloat64Array(nnz);
24047
+ let pos = 0;
24048
+ for (let k = 0; k < A.n; k++) {
24049
+ jc[k] = pos;
24050
+ const j = q[k];
24051
+ for (let t = A.jc[j]; t < A.jc[j + 1]; t++) {
24052
+ ir[pos] = pinv[A.ir[t]];
24053
+ pr[pos] = A.pr[t];
24054
+ pos++;
24055
+ }
24056
+ }
24057
+ jc[A.n] = pos;
24058
+ return fromUnsortedColumns(A.m, A.n, ir, jc, pr);
24059
+ }
24060
+ function sparseKron(A, B) {
24061
+ const m = A.m, n = A.n, p2 = B.m, q = B.n;
24062
+ const nnz = A.jc[n] * B.jc[q];
24063
+ const ir = new Int32Array(nnz);
24064
+ const jc = new Int32Array(n * q + 1);
24065
+ const pr = allocFloat64Array(nnz);
24066
+ const cplx = A.pi !== void 0 || B.pi !== void 0;
24067
+ const pi2 = cplx ? allocFloat64Array(nnz) : void 0;
24068
+ let pos = 0;
24069
+ for (let ja = 0; ja < n; ja++) {
24070
+ for (let jb = 0; jb < q; jb++) {
24071
+ jc[ja * q + jb] = pos;
24072
+ for (let ka = A.jc[ja]; ka < A.jc[ja + 1]; ka++) {
24073
+ const rowBase = A.ir[ka] * p2;
24074
+ const aRe = A.pr[ka];
24075
+ const aIm = A.pi ? A.pi[ka] : 0;
24076
+ for (let kb = B.jc[jb]; kb < B.jc[jb + 1]; kb++) {
24077
+ ir[pos] = rowBase + B.ir[kb];
24078
+ const bRe = B.pr[kb];
24079
+ const bIm = B.pi ? B.pi[kb] : 0;
24080
+ pr[pos] = aRe * bRe - aIm * bIm;
24081
+ if (pi2) pi2[pos] = aRe * bIm + aIm * bRe;
24082
+ pos++;
24083
+ }
24084
+ }
24085
+ }
24086
+ }
24087
+ jc[n * q] = pos;
24088
+ return RTV.sparseMatrix(m * p2, n * q, ir, jc, pr, pi2);
24089
+ }
24090
+ function triangularInfo(S) {
24091
+ if (S._triInfo) return S._triInfo;
24092
+ const n = S.n;
24093
+ const ir = S.ir, jc = S.jc, pr = S.pr, pi2 = S.pi;
24094
+ const diagPos = new Int32Array(n).fill(-1);
24095
+ const diag2 = allocFloat64Array(n);
24096
+ let upper = true;
24097
+ let lower = true;
24098
+ for (let j = 0; j < n; j++) {
24099
+ const end = jc[j + 1];
24100
+ for (let k = jc[j]; k < end; k++) {
24101
+ const i = ir[k];
24102
+ if (i === j) {
24103
+ diagPos[j] = k;
24104
+ diag2[j] = pr[k];
24105
+ continue;
24106
+ }
24107
+ if (pr[k] === 0 && (!pi2 || pi2[k] === 0)) continue;
24108
+ if (i > j) upper = false;
24109
+ else lower = false;
24110
+ }
24111
+ }
24112
+ const info = { upper, lower, diagPos, diag: diag2 };
24113
+ S._triInfo = info;
24114
+ return info;
24115
+ }
24116
+ function sparseIsUpper(S) {
24117
+ return triangularInfo(S).upper;
24118
+ }
24119
+ function sparseIsLower(S) {
24120
+ return triangularInfo(S).lower;
24121
+ }
24122
+ function sparseIsSymmetric(S) {
24123
+ if (S.m !== S.n || S.pi) return false;
24124
+ const T = sparseTranspose(S);
24125
+ const nnz = S.jc[S.n];
24126
+ if (T.jc[T.n] !== nnz) return false;
24127
+ for (let j = 0; j <= S.n; j++) if (S.jc[j] !== T.jc[j]) return false;
24128
+ for (let k = 0; k < nnz; k++)
24129
+ if (S.ir[k] !== T.ir[k] || S.pr[k] !== T.pr[k]) return false;
24130
+ return true;
24131
+ }
24132
+ function sparseAt(S, i, j) {
24133
+ let lo = S.jc[j], hi = S.jc[j + 1] - 1;
24134
+ while (lo <= hi) {
24135
+ const mid = lo + hi >> 1;
24136
+ const r = S.ir[mid];
24137
+ if (r === i) return S.pr[mid];
24138
+ if (r < i) lo = mid + 1;
24139
+ else hi = mid - 1;
24140
+ }
24141
+ return 0;
24142
+ }
24143
+ function allDiagPositive(S) {
24144
+ for (let j = 0; j < S.n; j++) if (!(sparseAt(S, j, j) > 0)) return false;
24145
+ return true;
24146
+ }
24147
+ function sparseSolveUpper(R, B, nrhs) {
24148
+ const n = R.n;
24149
+ const { diagPos, diag: diag2 } = triangularInfo(R);
24150
+ const ir = R.ir, jc = R.jc, pr = R.pr;
24151
+ const x = allocFloat64Array(B);
24152
+ let singular = false;
24153
+ for (let j = 0; j < n; j++) if (diag2[j] === 0) singular = true;
24154
+ for (let c = 0; c < nrhs; c++) {
24155
+ const off = c * n;
24156
+ for (let j = n - 1; j >= 0; j--) {
24157
+ const xj = x[off + j] / diag2[j];
24158
+ x[off + j] = xj;
24159
+ if (xj === 0) continue;
24160
+ const dp = diagPos[j];
24161
+ const end = dp >= 0 ? dp : jc[j + 1];
24162
+ for (let k = jc[j]; k < end; k++) x[off + ir[k]] -= pr[k] * xj;
24163
+ }
24164
+ }
24165
+ return { x, singular };
24166
+ }
24167
+ function sparseSolveLower(L, B, nrhs) {
24168
+ const n = L.n;
24169
+ const { diagPos, diag: diag2 } = triangularInfo(L);
24170
+ const ir = L.ir, jc = L.jc, pr = L.pr;
24171
+ const x = allocFloat64Array(B);
24172
+ let singular = false;
24173
+ for (let j = 0; j < n; j++) if (diag2[j] === 0) singular = true;
24174
+ for (let c = 0; c < nrhs; c++) {
24175
+ const off = c * n;
24176
+ for (let j = 0; j < n; j++) {
24177
+ const xj = x[off + j] / diag2[j];
24178
+ x[off + j] = xj;
24179
+ if (xj === 0) continue;
24180
+ const dp = diagPos[j];
24181
+ const end = jc[j + 1];
24182
+ for (let k = dp >= 0 ? dp + 1 : jc[j]; k < end; k++)
24183
+ x[off + ir[k]] -= pr[k] * xj;
24184
+ }
24185
+ }
24186
+ return { x, singular };
24187
+ }
24188
+ function permuteRows(X, n, nrhs, p2) {
24189
+ const Y = allocFloat64Array(X.length);
24190
+ for (let c = 0; c < nrhs; c++) {
24191
+ const off = c * n;
24192
+ for (let k = 0; k < n; k++) Y[off + k] = X[off + p2[k]];
24193
+ }
24194
+ return Y;
24195
+ }
24196
+ function unpermuteRows(X, n, nrhs, p2) {
24197
+ const Y = allocFloat64Array(X.length);
24198
+ for (let c = 0; c < nrhs; c++) {
24199
+ const off = c * n;
24200
+ for (let k = 0; k < n; k++) Y[off + p2[k]] = X[off + k];
24201
+ }
24202
+ return Y;
24203
+ }
24204
+ function eliminationTree(A) {
24205
+ const n = A.n;
24206
+ const parent = new Int32Array(n).fill(-1);
24207
+ const ancestor = new Int32Array(n).fill(-1);
24208
+ for (let k = 0; k < n; k++) {
24209
+ for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
24210
+ let i = A.ir[p2];
24211
+ while (i !== -1 && i < k) {
24212
+ const inext = ancestor[i];
24213
+ ancestor[i] = k;
24214
+ if (inext === -1) parent[i] = k;
24215
+ i = inext;
24216
+ }
24217
+ }
24218
+ }
24219
+ return parent;
24220
+ }
24221
+ function etreeReach(A, k, parent, s, mark) {
24222
+ const n = A.n;
24223
+ let top = n;
24224
+ mark[k] = k;
24225
+ for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
24226
+ let i = A.ir[p2];
24227
+ if (i > k) continue;
24228
+ let len = 0;
24229
+ for (; mark[i] !== k; i = parent[i]) {
24230
+ s[len++] = i;
24231
+ mark[i] = k;
24232
+ }
24233
+ while (len > 0) s[--top] = s[--len];
24234
+ }
24235
+ return top;
24236
+ }
24237
+ function sparseChol(A) {
24238
+ const n = A.n;
24239
+ if (A.m !== n) throw new RuntimeError("chol: Matrix must be square.");
24240
+ const parent = eliminationTree(A);
24241
+ const s = new Int32Array(n);
24242
+ const mark = new Int32Array(n).fill(-1);
24243
+ const colCount = new Int32Array(n);
24244
+ for (let k = 0; k < n; k++) {
24245
+ const top = etreeReach(A, k, parent, s, mark);
24246
+ for (let t = top; t < n; t++) colCount[s[t]]++;
24247
+ colCount[k]++;
24248
+ }
24249
+ const Lp = new Int32Array(n + 1);
24250
+ for (let j = 0; j < n; j++) Lp[j + 1] = Lp[j] + colCount[j];
24251
+ const nnzL = Lp[n];
24252
+ const Li = new Int32Array(nnzL);
24253
+ const Lx = allocFloat64Array(nnzL);
24254
+ const c = new Int32Array(n);
24255
+ for (let j = 0; j < n; j++) c[j] = Lp[j];
24256
+ const x = allocFloat64Array(n);
24257
+ mark.fill(-1);
24258
+ for (let k = 0; k < n; k++) {
24259
+ const top = etreeReach(A, k, parent, s, mark);
24260
+ x[k] = 0;
24261
+ for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
24262
+ if (A.ir[p2] <= k) x[A.ir[p2]] = A.pr[p2];
24263
+ }
24264
+ let d = x[k];
24265
+ x[k] = 0;
24266
+ for (let t = top; t < n; t++) {
24267
+ const i = s[t];
24268
+ const lki = x[i] / Lx[Lp[i]];
24269
+ x[i] = 0;
24270
+ for (let p2 = Lp[i] + 1; p2 < c[i]; p2++) x[Li[p2]] -= Lx[p2] * lki;
24271
+ d -= lki * lki;
24272
+ const pos2 = c[i]++;
24273
+ Li[pos2] = k;
24274
+ Lx[pos2] = lki;
24275
+ }
24276
+ if (!(d > 0)) {
24277
+ for (let i = k + 1; i < n; i++) {
24278
+ const top2 = etreeReach(A, i, parent, s, mark);
24279
+ for (let p2 = A.jc[i]; p2 < A.jc[i + 1]; p2++)
24280
+ if (A.ir[p2] < k) x[A.ir[p2]] = A.pr[p2];
24281
+ for (let t = top2; t < n; t++) {
24282
+ const j = s[t];
24283
+ if (j >= k) {
24284
+ x[j] = 0;
24285
+ continue;
24286
+ }
24287
+ const lij = x[j] / Lx[Lp[j]];
24288
+ x[j] = 0;
24289
+ for (let p2 = Lp[j] + 1; p2 < c[j]; p2++) x[Li[p2]] -= Lx[p2] * lij;
24290
+ const pos2 = c[j]++;
24291
+ Li[pos2] = i;
24292
+ Lx[pos2] = lij;
24293
+ }
24294
+ }
24295
+ return { L: leadingColumns(n, k, Lp, Li, Lx, c), ok: false, p: k + 1 };
24296
+ }
24297
+ const pos = c[k]++;
24298
+ Li[pos] = k;
24299
+ Lx[pos] = Math.sqrt(d);
24300
+ }
24301
+ return { L: RTV.sparseMatrix(n, n, Li, Lp, Lx), ok: true, p: 0 };
24302
+ }
24303
+ function leadingColumns(n, k, Lp, Li, Lx, c) {
24304
+ let nnz = 0;
24305
+ for (let j = 0; j < k; j++) nnz += c[j] - Lp[j];
24306
+ const ir = new Int32Array(nnz);
24307
+ const pr = allocFloat64Array(nnz);
24308
+ const jc = new Int32Array(k + 1);
24309
+ let pos = 0;
24310
+ for (let j = 0; j < k; j++) {
24311
+ jc[j] = pos;
24312
+ for (let p2 = Lp[j]; p2 < c[j]; p2++) {
24313
+ ir[pos] = Li[p2];
24314
+ pr[pos] = Lx[p2];
24315
+ pos++;
24316
+ }
24317
+ }
24318
+ jc[k] = pos;
24319
+ return RTV.sparseMatrix(n, k, ir, jc, pr);
24320
+ }
24321
+ function sparseLu(A, q, tol) {
24322
+ const m = A.m, n = A.n;
24323
+ const kmin = Math.min(m, n);
24324
+ const Lp = [0];
24325
+ const Li = [];
24326
+ const Lx = [];
24327
+ const Up = [0];
24328
+ const Ui = [];
24329
+ const Ux = [];
24330
+ const pinv = new Int32Array(m).fill(-1);
24331
+ const x = allocFloat64Array(m);
24332
+ const xi = new Int32Array(m);
24333
+ const stack = new Int32Array(m);
24334
+ const pstack = new Int32Array(m);
24335
+ const mark = new Int32Array(m).fill(-1);
24336
+ let singular = false;
24337
+ for (let k = 0; k < n; k++) {
24338
+ const col = q ? q[k] : k;
24339
+ let top = m;
24340
+ for (let t = A.jc[col]; t < A.jc[col + 1]; t++) {
24341
+ const i0 = A.ir[t];
24342
+ if (mark[i0] === k) continue;
24343
+ let head = 0;
24344
+ stack[0] = i0;
24345
+ mark[i0] = k;
24346
+ pstack[i0] = pinv[i0] >= 0 ? Lp[pinv[i0]] : -1;
24347
+ while (head >= 0) {
24348
+ const j = stack[head];
24349
+ const J = pinv[j];
24350
+ let descended = false;
24351
+ if (J >= 0) {
24352
+ const end = Lp[J + 1];
24353
+ let p3 = pstack[j];
24354
+ for (; p3 < end; p3++) {
24355
+ const i = Li[p3];
24356
+ if (mark[i] !== k) {
24357
+ mark[i] = k;
24358
+ pstack[j] = p3 + 1;
24359
+ stack[++head] = i;
24360
+ pstack[i] = pinv[i] >= 0 ? Lp[pinv[i]] : -1;
24361
+ descended = true;
24362
+ break;
24363
+ }
24364
+ }
24365
+ if (descended) continue;
24366
+ }
24367
+ head--;
24368
+ xi[--top] = j;
24369
+ }
24370
+ }
24371
+ for (let t = A.jc[col]; t < A.jc[col + 1]; t++) x[A.ir[t]] = A.pr[t];
24372
+ for (let t = top; t < m; t++) {
24373
+ const j = xi[t];
24374
+ const J = pinv[j];
24375
+ if (J < 0) continue;
24376
+ const xj = x[j];
24377
+ if (xj === 0) continue;
24378
+ for (let p3 = Lp[J] + 1; p3 < Lp[J + 1]; p3++) x[Li[p3]] -= Lx[p3] * xj;
24379
+ }
24380
+ let ipiv = -1;
24381
+ let amax = -1;
24382
+ for (let t = top; t < m; t++) {
24383
+ const i = xi[t];
24384
+ if (pinv[i] >= 0) {
24385
+ Ui.push(pinv[i]);
24386
+ Ux.push(x[i]);
24387
+ } else {
24388
+ const a = Math.abs(x[i]);
24389
+ if (a > amax) {
24390
+ amax = a;
24391
+ ipiv = i;
24392
+ }
24393
+ }
24394
+ }
24395
+ if (k < kmin) {
24396
+ if (ipiv < 0 || amax === 0) {
24397
+ singular = true;
24398
+ if (ipiv < 0) {
24399
+ for (let i = 0; i < m; i++)
24400
+ if (pinv[i] < 0) {
24401
+ ipiv = i;
24402
+ break;
24403
+ }
24404
+ }
24405
+ } else if (col < m && pinv[col] < 0 && Math.abs(x[col]) >= tol * amax && x[col] !== 0) {
24406
+ ipiv = col;
24407
+ }
24408
+ const pivot = x[ipiv];
24409
+ if (!Number.isFinite(pivot)) singular = true;
24410
+ pinv[ipiv] = k;
24411
+ Ui.push(k);
24412
+ Ux.push(pivot);
24413
+ Li.push(ipiv);
24414
+ Lx.push(1);
24415
+ if (pivot !== 0 && Number.isFinite(pivot)) {
24416
+ for (let t = top; t < m; t++) {
24417
+ const i = xi[t];
24418
+ if (pinv[i] >= 0) continue;
24419
+ const v = x[i] / pivot;
24420
+ if (v !== 0) {
24421
+ Li.push(i);
24422
+ Lx.push(v);
24423
+ }
24424
+ }
24425
+ }
24426
+ Lp.push(Li.length);
24427
+ }
24428
+ Up.push(Ui.length);
24429
+ for (let t = top; t < m; t++) x[xi[t]] = 0;
24430
+ }
24431
+ let next = kmin;
24432
+ for (let i = 0; i < m; i++) if (pinv[i] < 0) pinv[i] = next++;
24433
+ const LiArr = new Int32Array(Li.length);
24434
+ for (let p3 = 0; p3 < Li.length; p3++) LiArr[p3] = pinv[Li[p3]];
24435
+ const L = fromUnsortedColumns(
24436
+ m,
24437
+ kmin,
24438
+ LiArr,
24439
+ new Int32Array(Lp),
24440
+ allocFloat64Array(Lx)
24441
+ );
24442
+ const U = fromUnsortedColumns(
24443
+ kmin,
24444
+ n,
24445
+ new Int32Array(Ui),
24446
+ new Int32Array(Up),
24447
+ allocFloat64Array(Ux)
24448
+ );
24449
+ const p2 = invertPerm(pinv);
24450
+ const qOut = q ? Int32Array.from(q) : identityPerm(n);
24451
+ return { L, U, p: p2, q: qOut, singular };
24452
+ }
24453
+ function identityPerm(n) {
24454
+ const p2 = new Int32Array(n);
24455
+ for (let i = 0; i < n; i++) p2[i] = i;
24456
+ return p2;
24457
+ }
24458
+ function symmetricAdjacency(A) {
24459
+ const n = Math.max(A.m, A.n);
24460
+ const adj = new Array(n);
24461
+ for (let i = 0; i < n; i++) adj[i] = /* @__PURE__ */ new Set();
24462
+ for (let j = 0; j < A.n; j++)
24463
+ for (let k = A.jc[j]; k < A.jc[j + 1]; k++) {
24464
+ const i = A.ir[k];
24465
+ if (i === j) continue;
24466
+ adj[i].add(j);
24467
+ adj[j].add(i);
24468
+ }
24469
+ return adj;
24470
+ }
24471
+ function minimumDegreeOrdering(A) {
24472
+ const adj = symmetricAdjacency(A);
24473
+ const n = adj.length;
24474
+ const perm = new Int32Array(n);
24475
+ if (n === 0) return perm;
24476
+ const head = new Int32Array(n + 1).fill(-1);
24477
+ const next = new Int32Array(n).fill(-1);
24478
+ const prev = new Int32Array(n).fill(-1);
24479
+ const deg = new Int32Array(n);
24480
+ const insert = (v) => {
24481
+ const d = deg[v];
24482
+ next[v] = head[d];
24483
+ prev[v] = -1;
24484
+ if (head[d] >= 0) prev[head[d]] = v;
24485
+ head[d] = v;
24486
+ };
24487
+ const remove = (v) => {
24488
+ const d = deg[v];
24489
+ if (prev[v] >= 0) next[prev[v]] = next[v];
24490
+ else head[d] = next[v];
24491
+ if (next[v] >= 0) prev[next[v]] = prev[v];
24492
+ };
24493
+ for (let v = 0; v < n; v++) {
24494
+ deg[v] = adj[v].size;
24495
+ insert(v);
24496
+ }
24497
+ let mind = 0;
24498
+ for (let step = 0; step < n; step++) {
24499
+ while (head[mind] < 0) mind++;
24500
+ const v = head[mind];
24501
+ remove(v);
24502
+ perm[step] = v;
24503
+ const nbrs = Array.from(adj[v]);
24504
+ for (const u of nbrs) adj[u].delete(v);
24505
+ for (let a = 0; a < nbrs.length; a++) {
24506
+ const u = nbrs[a];
24507
+ const su = adj[u];
24508
+ for (let b = a + 1; b < nbrs.length; b++) {
24509
+ const w = nbrs[b];
24510
+ if (!su.has(w)) {
24511
+ su.add(w);
24512
+ adj[w].add(u);
24513
+ }
24514
+ }
24515
+ }
24516
+ for (const u of nbrs) {
24517
+ remove(u);
24518
+ deg[u] = adj[u].size;
24519
+ insert(u);
24520
+ if (deg[u] < mind) mind = deg[u];
24521
+ }
24522
+ adj[v].clear();
24523
+ }
24524
+ return perm;
24525
+ }
24526
+ function reverseCuthillMcKee(A) {
24527
+ const adj = symmetricAdjacency(A);
24528
+ const n = adj.length;
24529
+ const nb = adj.map(
24530
+ (s) => Array.from(s).sort((a, b) => adj[a].size - adj[b].size || a - b)
24531
+ );
24532
+ const visited = new Uint8Array(n);
24533
+ const order = [];
24534
+ const bfsLevels = (start) => {
24535
+ const seen = new Uint8Array(n);
24536
+ let frontier = [start];
24537
+ seen[start] = 1;
24538
+ let levels = 0;
24539
+ let last = start;
24540
+ while (frontier.length > 0) {
24541
+ const nextF = [];
24542
+ for (const u of frontier)
24543
+ for (const w of nb[u])
24544
+ if (!seen[w]) {
24545
+ seen[w] = 1;
24546
+ nextF.push(w);
24547
+ }
24548
+ if (nextF.length === 0) {
24549
+ last = frontier.reduce((a, b) => adj[b].size < adj[a].size ? b : a);
24550
+ break;
24551
+ }
24552
+ frontier = nextF;
24553
+ levels++;
24554
+ }
24555
+ return { last, levels };
24556
+ };
24557
+ for (let s0 = 0; s0 < n; s0++) {
24558
+ if (visited[s0]) continue;
24559
+ let start = s0;
24560
+ let info = bfsLevels(start);
24561
+ for (let iter = 0; iter < 4; iter++) {
24562
+ const cand = bfsLevels(info.last);
24563
+ if (cand.levels > info.levels) {
24564
+ start = info.last;
24565
+ info = cand;
24566
+ } else {
24567
+ start = info.last;
24568
+ break;
24569
+ }
24570
+ }
24571
+ const queue = [start];
24572
+ visited[start] = 1;
24573
+ let qh = 0;
24574
+ while (qh < queue.length) {
24575
+ const u = queue[qh++];
24576
+ order.push(u);
24577
+ for (const w of nb[u])
24578
+ if (!visited[w]) {
24579
+ visited[w] = 1;
24580
+ queue.push(w);
24581
+ }
24582
+ }
24583
+ }
24584
+ const perm = new Int32Array(n);
24585
+ for (let i = 0; i < n; i++) perm[i] = order[n - 1 - i];
24586
+ return perm;
24587
+ }
24588
+ function ataPattern(A) {
24589
+ const At = sparseTranspose(A);
24590
+ const n = A.n;
24591
+ const marker = new Int32Array(n).fill(-1);
24592
+ const ir = [];
24593
+ const jc = new Int32Array(n + 1);
24594
+ for (let j = 0; j < n; j++) {
24595
+ jc[j] = ir.length;
24596
+ for (let k = A.jc[j]; k < A.jc[j + 1]; k++) {
24597
+ const row = A.ir[k];
24598
+ for (let t = At.jc[row]; t < At.jc[row + 1]; t++) {
24599
+ const i = At.ir[t];
24600
+ if (marker[i] !== j) {
24601
+ marker[i] = j;
24602
+ ir.push(i);
24603
+ }
24604
+ }
24605
+ }
24606
+ }
24607
+ jc[n] = ir.length;
24608
+ const pr = allocFloat64Array(ir.length).fill(1);
24609
+ return fromUnsortedColumns(n, n, new Int32Array(ir), jc, pr);
24610
+ }
24611
+ function columnOrdering(A) {
24612
+ return minimumDegreeOrdering(ataPattern(A));
24613
+ }
24614
+ var DENSE_FRACTION = 0.5;
24615
+ function sparseSolve(A, B, nrhs) {
24616
+ const n = A.n;
24617
+ if (A.m !== n || A.pi) return null;
24618
+ if (n === 0) return allocFloat64Array(0);
24619
+ const nnz = A.jc[n];
24620
+ if (nnz > DENSE_FRACTION * n * n && n > 8) return null;
24621
+ if (sparseIsUpper(A)) {
24622
+ const r = sparseSolveUpper(A, B, nrhs);
24623
+ if (r.singular) emitWarning(SINGULAR_WARNING);
24624
+ return r.x;
24625
+ }
24626
+ if (sparseIsLower(A)) {
24627
+ const r = sparseSolveLower(A, B, nrhs);
24628
+ if (r.singular) emitWarning(SINGULAR_WARNING);
24629
+ return r.x;
24630
+ }
24631
+ const perm = reverseCuthillMcKee(A);
24632
+ if (sparseIsSymmetric(A) && allDiagPositive(A)) {
24633
+ const Ap = sparsePermute(A, perm, perm);
24634
+ const ch = sparseChol(Ap);
24635
+ if (ch.ok) {
24636
+ const Lt = sparseTranspose(ch.L);
24637
+ const bp = permuteRows(B, n, nrhs, perm);
24638
+ const y = sparseSolveLower(ch.L, bp, nrhs).x;
24639
+ const z = sparseSolveUpper(Lt, y, nrhs).x;
24640
+ return unpermuteRows(z, n, nrhs, perm);
24641
+ }
24642
+ }
24643
+ const lu2 = sparseLu(A, perm, 1);
24644
+ return luSolve(lu2, B, nrhs);
24645
+ }
24646
+ function luSolve(lu2, B, nrhs) {
24647
+ const n = lu2.U.n;
24648
+ const pb = permuteRows(B, n, nrhs, lu2.p);
24649
+ const y = sparseSolveLower(lu2.L, pb, nrhs);
24650
+ const z = sparseSolveUpper(lu2.U, y.x, nrhs);
24651
+ if (lu2.singular || z.singular) emitWarning(SINGULAR_WARNING);
24652
+ return unpermuteRows(z.x, n, nrhs, lu2.q);
24653
+ }
24654
+ function luSolveTransposed(lu2, B, nrhs) {
24655
+ const n = lu2.U.n;
24656
+ const qb = permuteRows(B, n, nrhs, lu2.q);
24657
+ const y = sparseSolveLower(sparseTranspose(lu2.U), qb, nrhs);
24658
+ const z = sparseSolveUpper(sparseTranspose(lu2.L), y.x, nrhs);
24659
+ if (lu2.singular || y.singular) emitWarning(SINGULAR_WARNING);
24660
+ return unpermuteRows(z.x, n, nrhs, lu2.p);
24661
+ }
24662
+ function sparseInverse(A) {
24663
+ const n = A.n;
24664
+ if (A.m !== n) throw new RuntimeError("inv: matrix must be square");
24665
+ const I = allocFloat64Array(n * n);
24666
+ for (let i = 0; i < n; i++) I[i + i * n] = 1;
24667
+ const X = sparseSolve(A, I, n);
24668
+ if (X === null) throw new RuntimeError("inv: unsupported sparse matrix");
24669
+ return denseDataToSparse(X, n, n);
24670
+ }
24671
+
22583
24672
  // src/numbl-core/helpers/arithmetic.ts
22584
24673
  function toComplex(v) {
22585
24674
  if (isRuntimeComplexNumber(v)) return { re: v.re, im: v.im };
@@ -23170,6 +25259,12 @@ function mElemMul(a, b) {
23170
25259
  }
23171
25260
  function mDiv(a, b) {
23172
25261
  if (isRuntimeSparseMatrix(a) || isRuntimeSparseMatrix(b)) {
25262
+ if (isRuntimeSparseMatrix(a) && (isRuntimeNumber(b) || isRuntimeLogical(b) || isRuntimeComplexNumber(b) || isRuntimeTensor(b) && b.data.length === 1))
25263
+ return mElemDivSparse(a, b);
25264
+ if (isRuntimeSparseMatrix(b) && !(b.m === 1 && b.n === 1)) {
25265
+ const result = mLeftDiv(mConjugateTranspose(b), mConjugateTranspose(a));
25266
+ return mConjugateTranspose(result);
25267
+ }
23173
25268
  return mDiv(densify(a), densify(b));
23174
25269
  }
23175
25270
  if (isRuntimeTensor(a) && a.data.length === 1) a = unwrap1x1(a);
@@ -23225,8 +25320,50 @@ function mElemDiv(a, b) {
23225
25320
  }
23226
25321
  return binaryOp(a, b, (x, y) => x / y, BIN_OP_DIV);
23227
25322
  }
25323
+ function sparseLeftDiv(A, b) {
25324
+ if (A.pi) return null;
25325
+ if (A.m === 1 && A.n === 1) return null;
25326
+ let B;
25327
+ let rows, nrhs;
25328
+ const bSparse = isRuntimeSparseMatrix(b);
25329
+ if (isRuntimeSparseMatrix(b)) {
25330
+ if (b.pi) return null;
25331
+ const d = sparseToDense(b);
25332
+ B = d.data;
25333
+ rows = b.m;
25334
+ nrhs = b.n;
25335
+ } else if (isRuntimeTensor(b)) {
25336
+ if (b.imag) return null;
25337
+ [rows, nrhs] = tensorSize2D(b);
25338
+ B = b.data;
25339
+ } else if (isRuntimeNumber(b) || isRuntimeLogical(b)) {
25340
+ B = allocFloat64Array([toNumber(b)]);
25341
+ rows = 1;
25342
+ nrhs = 1;
25343
+ } else {
25344
+ return null;
25345
+ }
25346
+ if (rows !== A.m)
25347
+ throw new RuntimeError(
25348
+ `mldivide (\\): A is ${A.m}\xD7${A.n} but B has ${rows} rows`
25349
+ );
25350
+ if (A.m !== A.n) {
25351
+ emitWarning(
25352
+ "mldivide: sparse least-squares uses a dense factorization; the sparse matrix is converted to full."
25353
+ );
25354
+ return null;
25355
+ }
25356
+ const X = sparseSolve(A, B, nrhs);
25357
+ if (X === null) return null;
25358
+ if (bSparse) return denseDataToSparse(X, A.n, nrhs);
25359
+ return unwrap1x1(RTV.tensor(X, [A.n, nrhs]));
25360
+ }
23228
25361
  function mLeftDiv(a, b) {
23229
- if (isRuntimeSparseMatrix(a)) return mLeftDiv(densify(a), b);
25362
+ if (isRuntimeSparseMatrix(a)) {
25363
+ const r = sparseLeftDiv(a, b);
25364
+ if (r !== null) return r;
25365
+ return mLeftDiv(densify(a), densify(b));
25366
+ }
23230
25367
  if (isRuntimeSparseMatrix(b)) return mLeftDiv(a, densify(b));
23231
25368
  if (isRuntimeTensor(a) && a.data.length === 1) a = unwrap1x1(a);
23232
25369
  if (isRuntimeTensor(b) && b.data.length === 1) b = unwrap1x1(b);
@@ -32626,7 +34763,11 @@ function binop(op, a, b) {
32626
34763
  result = mElemDiv(mb, ma);
32627
34764
  break;
32628
34765
  }
32629
- const tensorA = isRuntimeSparseMatrix(ma) ? sparseToDense(ma) : ma;
34766
+ if (isRuntimeSparseMatrix(ma)) {
34767
+ result = mLeftDiv(ma, mb);
34768
+ break;
34769
+ }
34770
+ const tensorA = ma;
32630
34771
  const tensorB = isRuntimeNumber(mb) ? RTV.tensor(allocFloat64Array([mb]), [1, 1]) : isRuntimeSparseMatrix(mb) ? sparseToDense(mb) : mb;
32631
34772
  if (!isRuntimeTensor(tensorA) || !isRuntimeTensor(tensorB))
32632
34773
  throw new RuntimeError(
@@ -40039,6 +42180,24 @@ defineBuiltin({
40039
42180
  });
40040
42181
 
40041
42182
  // src/numbl-core/interpreter/builtins/linear-algebra.ts
42183
+ var SPARSE_TYPE = { kind: "sparse_matrix", isComplex: false };
42184
+ function toSparseOperand(v, name) {
42185
+ if (isRuntimeSparseMatrix(v)) return v;
42186
+ if (isRuntimeNumber(v) || typeof v === "boolean")
42187
+ return denseToSparse(RTV.tensor(allocFloat64Array([Number(v)]), [1, 1]));
42188
+ if (isRuntimeTensor(v)) return denseToSparse(v);
42189
+ throw new RuntimeError(`${name}: arguments must be numeric`);
42190
+ }
42191
+ function speyeSparse(n) {
42192
+ const ir = new Int32Array(n);
42193
+ const jc = new Int32Array(n + 1);
42194
+ const pr = allocFloat64Array(n).fill(1);
42195
+ for (let i = 0; i < n; i++) {
42196
+ ir[i] = i;
42197
+ jc[i + 1] = i + 1;
42198
+ }
42199
+ return RTV.sparseMatrix(n, n, ir, jc, pr);
42200
+ }
40042
42201
  function isNumericJitType(t) {
40043
42202
  return t.kind === "number" || t.kind === "boolean" || t.kind === "complex_or_number" || t.kind === "tensor" || t.kind === "sparse_matrix";
40044
42203
  }
@@ -40079,12 +42238,53 @@ function normApply(args) {
40079
42238
  const v = args[0];
40080
42239
  if (isRuntimeNumber(v)) return RTV.num(Math.abs(v));
40081
42240
  if (isRuntimeComplexNumber(v)) return RTV.num(Math.hypot(v.re, v.im));
40082
- if (isRuntimeSparseMatrix(v))
42241
+ if (isRuntimeSparseMatrix(v)) {
42242
+ const fast = sparseNormFast(v, args[1]);
42243
+ if (fast !== null) return RTV.num(fast);
40083
42244
  return normApply([sparseToDense(v), ...args.slice(1)]);
42245
+ }
40084
42246
  if (!isRuntimeTensor(v))
40085
42247
  throw new RuntimeError("norm: argument must be numeric");
40086
42248
  return normImplTensor(v, args);
40087
42249
  }
42250
+ function sparseNormFast(S, p2) {
42251
+ if (S.m === 1 || S.n === 1) return null;
42252
+ let kind = null;
42253
+ if (p2 === void 0) return null;
42254
+ if (isRuntimeNumber(p2)) {
42255
+ if (p2 === 1) kind = "one";
42256
+ else if (p2 === Infinity) kind = "inf";
42257
+ } else if (isRuntimeChar(p2) || isRuntimeString(p2)) {
42258
+ const s = parseStringArgLower(p2);
42259
+ if (s === "fro") kind = "fro";
42260
+ else if (s === "inf") kind = "inf";
42261
+ }
42262
+ if (kind === null) return null;
42263
+ const mag2 = (k) => S.pi ? Math.hypot(S.pr[k], S.pi[k]) : Math.abs(S.pr[k]);
42264
+ const nnz = S.jc[S.n];
42265
+ if (kind === "fro") {
42266
+ let sum2 = 0;
42267
+ for (let k = 0; k < nnz; k++) {
42268
+ const a = mag2(k);
42269
+ sum2 += a * a;
42270
+ }
42271
+ return Math.sqrt(sum2);
42272
+ }
42273
+ if (kind === "one") {
42274
+ let best2 = 0;
42275
+ for (let j = 0; j < S.n; j++) {
42276
+ let sum2 = 0;
42277
+ for (let k = S.jc[j]; k < S.jc[j + 1]; k++) sum2 += mag2(k);
42278
+ if (sum2 > best2) best2 = sum2;
42279
+ }
42280
+ return best2;
42281
+ }
42282
+ const rowSums = allocFloat64Array(S.m);
42283
+ for (let k = 0; k < nnz; k++) rowSums[S.ir[k]] += mag2(k);
42284
+ let best = 0;
42285
+ for (let i = 0; i < S.m; i++) if (rowSums[i] > best) best = rowSums[i];
42286
+ return best;
42287
+ }
40088
42288
  function scaledEuclid(magnitudes, count) {
40089
42289
  let scale = 0;
40090
42290
  let ssq = 1;
@@ -40709,11 +42909,18 @@ defineBuiltin({
40709
42909
  if (a.kind === "complex_or_number") return [COMPLEX_OR_NUM];
40710
42910
  if (a.kind === "tensor")
40711
42911
  return [{ kind: "tensor", isComplex: a.isComplex }];
42912
+ if (a.kind === "sparse_matrix")
42913
+ return [{ kind: "sparse_matrix", isComplex: a.isComplex }];
40712
42914
  return null;
40713
42915
  },
40714
- apply: (args) => {
42916
+ apply: function invApply(args) {
40715
42917
  if (args.length < 1) throw new RuntimeError("inv requires 1 argument");
40716
42918
  const A = args[0];
42919
+ if (isRuntimeSparseMatrix(A)) {
42920
+ if (!A.pi) return sparseInverse(A);
42921
+ const dense = invApply([sparseToDense(A)]);
42922
+ return isRuntimeTensor(dense) ? denseToSparse(dense) : dense;
42923
+ }
40717
42924
  if (isRuntimeComplexNumber(A)) {
40718
42925
  const { re, im } = A;
40719
42926
  if (re === 0 && im === 0)
@@ -41066,6 +43273,67 @@ registerIBuiltin({
41066
43273
  return { outputTypes: outs, apply: (args, n) => bandwidthApply(args, n) };
41067
43274
  }
41068
43275
  });
43276
+ function isTriangularValue(A, upper) {
43277
+ if (isRuntimeNumber(A) || isRuntimeComplexNumber(A)) return true;
43278
+ if (isRuntimeSparseMatrix(A))
43279
+ return upper ? sparseIsUpper(A) : sparseIsLower(A);
43280
+ if (isRuntimeTensor(A)) {
43281
+ if (A.shape.length > 2) return false;
43282
+ const [m, n] = tensorSize2D(A);
43283
+ for (let j = 0; j < n; j++)
43284
+ for (let i = 0; i < m; i++) {
43285
+ if (upper ? i <= j : i >= j) continue;
43286
+ const idx = colMajorIndex(i, j, m);
43287
+ if (A.data[idx] !== 0 || A.imag && A.imag[idx] !== 0) return false;
43288
+ }
43289
+ return true;
43290
+ }
43291
+ throw new RuntimeError("istriu: argument must be a numeric matrix");
43292
+ }
43293
+ for (const [name, upper] of [
43294
+ ["istriu", true],
43295
+ ["istril", false]
43296
+ ]) {
43297
+ registerIBuiltin({
43298
+ name,
43299
+ help: {
43300
+ signatures: [`tf = ${name}(A)`],
43301
+ description: `True if A is ${upper ? "upper" : "lower"} triangular (all entries ${upper ? "below" : "above"} the main diagonal are zero). Works for dense and sparse matrices.`
43302
+ },
43303
+ resolve: (argTypes, nargout) => {
43304
+ if (nargout > 1 || argTypes.length !== 1) return null;
43305
+ if (!isNumericJitType(argTypes[0])) return null;
43306
+ return {
43307
+ outputTypes: [{ kind: "boolean" }],
43308
+ apply: (args) => RTV.logical(isTriangularValue(args[0], upper))
43309
+ };
43310
+ }
43311
+ });
43312
+ }
43313
+ registerIBuiltin({
43314
+ name: "isbanded",
43315
+ help: {
43316
+ signatures: ["tf = isbanded(A, lower, upper)"],
43317
+ description: "True if A has lower bandwidth at most `lower` and upper bandwidth at most `upper`. Works for dense and sparse matrices."
43318
+ },
43319
+ resolve: (argTypes, nargout) => {
43320
+ if (nargout > 1 || argTypes.length !== 3) return null;
43321
+ if (!isNumericJitType(argTypes[0])) return null;
43322
+ return {
43323
+ outputTypes: [{ kind: "boolean" }],
43324
+ apply: (args) => {
43325
+ const lo = toNumber(args[1]);
43326
+ const up = toNumber(args[2]);
43327
+ if (lo < 0 || up < 0 || !Number.isInteger(lo) || !Number.isInteger(up))
43328
+ throw new RuntimeError(
43329
+ "isbanded: bandwidths must be nonnegative integers"
43330
+ );
43331
+ const [l, u] = computeBandwidth(args[0]);
43332
+ return RTV.logical(l <= lo && u <= up);
43333
+ }
43334
+ };
43335
+ }
43336
+ });
41069
43337
  function computeATA(A_data, m, n) {
41070
43338
  const result = allocFloat64Array(n * n);
41071
43339
  for (let j = 0; j < n; j++)
@@ -41434,19 +43702,59 @@ function qrPivotApply(A, m, n, k, econ) {
41434
43702
  registerIBuiltin({
41435
43703
  name: "lu",
41436
43704
  resolve: (argTypes, nargout) => {
41437
- if (nargout < 0 || nargout > 3) return null;
41438
- if (argTypes.length < 1 || argTypes.length > 2) return null;
43705
+ if (nargout < 0 || nargout > 4) return null;
43706
+ if (argTypes.length < 1 || argTypes.length > 3) return null;
41439
43707
  if (!isNumericJitType(argTypes[0])) return null;
41440
- const t = tensorType();
43708
+ const sparse = argTypes[0].kind === "sparse_matrix";
43709
+ if (!sparse && (nargout > 3 || argTypes.length > 2)) return null;
43710
+ const t = sparse ? SPARSE_TYPE : tensorType();
41441
43711
  const wrapped = (args, n) => withScratch(() => luApply(args, n));
41442
43712
  if (nargout <= 1) return { outputTypes: [t], apply: wrapped };
41443
43713
  if (nargout === 2) return { outputTypes: [t, t], apply: wrapped };
41444
- return { outputTypes: [t, t, t], apply: wrapped };
43714
+ if (nargout === 3) return { outputTypes: [t, t, t], apply: wrapped };
43715
+ return { outputTypes: [t, t, t, t], apply: wrapped };
41445
43716
  }
41446
43717
  });
43718
+ function sparseLuApply(S, args, nargout) {
43719
+ let outputForm = "matrix";
43720
+ let tol = nargout >= 4 ? 0.1 : 1;
43721
+ for (const opt of args.slice(1)) {
43722
+ if (isRuntimeNumber(opt)) {
43723
+ if (!(opt >= 0 && opt <= 1))
43724
+ throw new RuntimeError("lu: pivot threshold must be in [0, 1]");
43725
+ tol = opt;
43726
+ } else {
43727
+ const form = parseLuOutputForm(opt);
43728
+ if (form === null)
43729
+ throw new RuntimeError("lu: outputForm must be 'matrix' or 'vector'");
43730
+ outputForm = form;
43731
+ }
43732
+ }
43733
+ const q = nargout >= 4 ? columnOrdering(S) : null;
43734
+ const res = sparseLu(S, q, tol);
43735
+ const { L, U, p: p2 } = res;
43736
+ if (nargout <= 1) {
43737
+ return mSub(mAdd(L, U), speyeSparse(Math.min(S.m, S.n)));
43738
+ }
43739
+ if (nargout === 2) {
43740
+ const Lperm = sparsePermute(L, invertPerm(p2), identityPerm(L.n));
43741
+ return [Lperm, U];
43742
+ }
43743
+ const permOut = (perm) => outputForm === "vector" ? permVectorTensor(perm) : permutationMatrix(perm);
43744
+ if (nargout === 3) return [L, U, permOut(p2)];
43745
+ const Q = outputForm === "vector" ? permVectorTensor(res.q) : sparseTranspose(permutationMatrix(res.q));
43746
+ return [L, U, permOut(p2), Q];
43747
+ }
41447
43748
  function luApply(args, nargout) {
41448
43749
  if (args.length < 1)
41449
43750
  throw new RuntimeError("lu requires at least 1 argument");
43751
+ if (isRuntimeSparseMatrix(args[0]) && !args[0].pi)
43752
+ return sparseLuApply(args[0], args, nargout);
43753
+ if (isRuntimeSparseMatrix(args[0])) {
43754
+ const dense = luApply([sparseToDense(args[0]), ...args.slice(1)], nargout);
43755
+ const toSp = (v) => isRuntimeTensor(v) ? denseToSparse(v) : v;
43756
+ return Array.isArray(dense) ? dense.map(toSp) : toSp(dense);
43757
+ }
41450
43758
  const outputForm = args.length >= 2 ? parseLuOutputForm(args[1]) : "matrix";
41451
43759
  if (outputForm === null)
41452
43760
  throw new RuntimeError("lu: outputForm must be 'matrix' or 'vector'");
@@ -41565,7 +43873,7 @@ function ipivToPermVector(ipiv, m) {
41565
43873
  registerIBuiltin({
41566
43874
  name: "eig",
41567
43875
  resolve: (argTypes, nargout) => {
41568
- if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
43876
+ if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 4)
41569
43877
  return null;
41570
43878
  if (!isNumericJitType(argTypes[0])) return null;
41571
43879
  const c = tensorType(true);
@@ -41580,7 +43888,9 @@ function eigApply(args, nargout) {
41580
43888
  if (args.length < 1)
41581
43889
  throw new RuntimeError("eig requires at least 1 argument");
41582
43890
  const A = args[0];
41583
- const { balance, outputForm } = parseEigOptionsRuntime(args);
43891
+ const { B, balance, outputForm, algorithm } = parseEigOptionsRuntime(args);
43892
+ if (B !== void 0)
43893
+ return eigGeneralizedApply(A, B, nargout, outputForm, algorithm);
41584
43894
  if (isRuntimeNumber(A)) {
41585
43895
  const val = A;
41586
43896
  if (nargout <= 1) return RTV.num(val);
@@ -41597,6 +43907,10 @@ function eigApply(args, nargout) {
41597
43907
  const [m, n] = tensorSize2D(A);
41598
43908
  if (m !== n) throw new RuntimeError("eig: input must be a square matrix");
41599
43909
  const computeVL = nargout >= 3, computeVR = nargout >= 2;
43910
+ if (isExactlyHermitian(A, n)) {
43911
+ const symResult = eigSymmetricApply(A, n, nargout, outputForm);
43912
+ if (symResult) return symResult;
43913
+ }
41600
43914
  if (A.imag) {
41601
43915
  const bridge2 = getEffectiveBridge("eigComplex", "eigComplex");
41602
43916
  if (!bridge2.eigComplex)
@@ -41632,19 +43946,369 @@ function eigApply(args, nargout) {
41632
43946
  const Wout = computeVL && VL ? buildEigenvectorMatrix(VL, wi, n, hasComplex) : RTV.tensor(allocFloat64Array(n * n), [n, n]);
41633
43947
  return [Vout, Dout, Wout];
41634
43948
  }
43949
+ function isExactlyHermitian(A, n) {
43950
+ const re = A.data;
43951
+ const im = A.imag;
43952
+ for (let j = 0; j < n; j++) {
43953
+ if (im && im[j + j * n] !== 0) return false;
43954
+ const dj = re[j + j * n];
43955
+ if (Number.isNaN(dj)) return false;
43956
+ for (let i = j + 1; i < n; i++) {
43957
+ if (re[i + j * n] !== re[j + i * n]) return false;
43958
+ if (im && im[i + j * n] !== -im[j + i * n]) return false;
43959
+ }
43960
+ }
43961
+ return true;
43962
+ }
43963
+ function eigSymmetricApply(A, n, nargout, outputForm) {
43964
+ const computeV = nargout >= 2;
43965
+ let w;
43966
+ let VRe;
43967
+ let VIm;
43968
+ if (A.imag) {
43969
+ const bridge = getEffectiveBridge("eigHerm", "eigHerm");
43970
+ if (!bridge.eigHerm) return null;
43971
+ const r = bridge.eigHerm(toF64(A.data), toF64(A.imag), n, computeV);
43972
+ if (!r) return null;
43973
+ w = r.w;
43974
+ VRe = r.VRe;
43975
+ VIm = r.VIm;
43976
+ } else {
43977
+ const bridge = getEffectiveBridge("eigSym", "eigSym");
43978
+ if (!bridge.eigSym) return null;
43979
+ const r = bridge.eigSym(toF64(A.data), n, computeV);
43980
+ if (!r) return null;
43981
+ w = r.w;
43982
+ VRe = r.V;
43983
+ }
43984
+ if (nargout <= 1) return RTV.tensor(w, [n, 1]);
43985
+ const makeV = () => VRe ? maybeComplexTensor(
43986
+ allocFloat64Array(VRe),
43987
+ [n, n],
43988
+ VIm ? allocFloat64Array(VIm) : void 0
43989
+ ) : RTV.tensor(allocFloat64Array(n * n), [n, n]);
43990
+ const Vout = makeV();
43991
+ const Dout = outputForm === "vector" ? RTV.tensor(allocFloat64Array(w), [n, 1]) : buildDiagMatrix(w, void 0, n);
43992
+ if (nargout === 2) return [Vout, Dout];
43993
+ return [Vout, Dout, makeV()];
43994
+ }
41635
43995
  function parseEigOptionsRuntime(args) {
41636
- let balance = true, outputForm = "matrix";
41637
- for (let i = 1; i < args.length; i++) {
43996
+ let balance = true, outputForm = "matrix", algorithm = "auto";
43997
+ let B;
43998
+ let first = 1;
43999
+ if (args.length >= 2 && !isStringLikeArg(args[1])) {
44000
+ B = args[1];
44001
+ first = 2;
44002
+ }
44003
+ for (let i = first; i < args.length; i++) {
41638
44004
  const arg = args[i];
41639
- if (isRuntimeString(arg) || isRuntimeChar(arg)) {
41640
- const val = parseStringArgLower(arg);
41641
- if (val === "nobalance") balance = false;
41642
- else if (val === "balance") balance = true;
41643
- else if (val === "vector") outputForm = "vector";
41644
- else if (val === "matrix") outputForm = "matrix";
44005
+ if (!isStringLikeArg(arg))
44006
+ throw new RuntimeError(
44007
+ "eig: option arguments must be character vectors or strings"
44008
+ );
44009
+ const val = parseStringArgLower(arg);
44010
+ if (val === "nobalance") balance = false;
44011
+ else if (val === "balance") balance = true;
44012
+ else if (val === "vector") outputForm = "vector";
44013
+ else if (val === "matrix") outputForm = "matrix";
44014
+ else if (val === "chol" || val === "qz") algorithm = val;
44015
+ else throw new RuntimeError(`eig: unknown option '${val}'`);
44016
+ }
44017
+ if (algorithm !== "auto" && B === void 0)
44018
+ throw new RuntimeError(
44019
+ `eig: the '${algorithm}' algorithm applies only to eig(A, B)`
44020
+ );
44021
+ return { B, balance, outputForm, algorithm };
44022
+ }
44023
+ function isStringLikeArg(arg) {
44024
+ return isRuntimeString(arg) || isRuntimeChar(arg);
44025
+ }
44026
+ function toSplitSquare(v, name) {
44027
+ if (isRuntimeNumber(v))
44028
+ return { M: { re: allocFloat64Array([v]), im: null }, n: 1 };
44029
+ if (isRuntimeComplexNumber(v))
44030
+ return {
44031
+ M: { re: allocFloat64Array([v.re]), im: allocFloat64Array([v.im]) },
44032
+ n: 1
44033
+ };
44034
+ let t = v;
44035
+ if (isRuntimeSparseMatrix(t))
44036
+ t = sparseToDense(
44037
+ t
44038
+ );
44039
+ if (!isRuntimeTensor(t))
44040
+ throw new RuntimeError(`eig: ${name} must be a numeric matrix`);
44041
+ const [rows, cols] = tensorSize2D(t);
44042
+ if (rows !== cols)
44043
+ throw new RuntimeError(`eig: ${name} must be a square matrix`);
44044
+ return {
44045
+ M: { re: toF64(t.data), im: t.imag ? toF64(t.imag) : null },
44046
+ n: rows
44047
+ };
44048
+ }
44049
+ function splitIsHermitian(M, n) {
44050
+ for (let j = 0; j < n; j++) {
44051
+ if (M.im && M.im[j + j * n] !== 0) return false;
44052
+ if (Number.isNaN(M.re[j + j * n])) return false;
44053
+ for (let i = j + 1; i < n; i++) {
44054
+ if (M.re[i + j * n] !== M.re[j + i * n]) return false;
44055
+ if (M.im && M.im[i + j * n] !== -M.im[j + i * n]) return false;
44056
+ }
44057
+ }
44058
+ return true;
44059
+ }
44060
+ function eigGeneralizedApply(Aval, Bval, nargout, outputForm, algorithm) {
44061
+ const { M: A, n } = toSplitSquare(Aval, "A");
44062
+ const { M: B, n: nB } = toSplitSquare(Bval, "B");
44063
+ if (n !== nB) throw new RuntimeError("eig: A and B must be the same size");
44064
+ if (algorithm !== "qz" && splitIsHermitian(A, n) && splitIsHermitian(B, n)) {
44065
+ const R = choleskyFactor(B, n);
44066
+ if (R) return eigSymmetricDefinite(A, R, n, nargout, outputForm);
44067
+ if (algorithm === "chol")
44068
+ throw new RuntimeError(
44069
+ "eig: the 'chol' algorithm requires B to be symmetric positive definite"
44070
+ );
44071
+ }
44072
+ return eigGeneralizedQz(A, B, n, nargout, outputForm);
44073
+ }
44074
+ function choleskyFactor(B, n) {
44075
+ if (B.im) {
44076
+ const bridge2 = getEffectiveBridge("cholComplex", "cholComplex");
44077
+ if (!bridge2.cholComplex) return null;
44078
+ const r2 = bridge2.cholComplex(B.re, B.im, n, true);
44079
+ if (!r2 || r2.info !== 0) return null;
44080
+ return { re: r2.RRe, im: r2.RIm };
44081
+ }
44082
+ const bridge = getEffectiveBridge("chol", "chol");
44083
+ if (!bridge.chol) return null;
44084
+ const r = bridge.chol(B.re, n, true);
44085
+ if (!r || r.info !== 0) return null;
44086
+ return { re: r.R, im: null };
44087
+ }
44088
+ function eigSymmetricDefinite(A, R, n, nargout, outputForm) {
44089
+ const complex = !!(A.im || R.im);
44090
+ const Y = solveLeftConjTransposeUpper(R, A, n, complex);
44091
+ const C = solveRightUpper(Y, R, n, complex);
44092
+ symmetrizeInPlace(C, n);
44093
+ const computeV = nargout >= 2;
44094
+ let w;
44095
+ let SRe;
44096
+ let SIm;
44097
+ if (complex) {
44098
+ const bridge = getEffectiveBridge("eigHerm", "eigHerm");
44099
+ if (!bridge.eigHerm)
44100
+ throw new RuntimeError("eig: Hermitian eig bridge not available");
44101
+ const r = bridge.eigHerm(
44102
+ C.re,
44103
+ C.im ?? allocFloat64Array(n * n),
44104
+ n,
44105
+ computeV
44106
+ );
44107
+ w = r.w;
44108
+ SRe = r.VRe;
44109
+ SIm = r.VIm;
44110
+ } else {
44111
+ const bridge = getEffectiveBridge("eigSym", "eigSym");
44112
+ if (!bridge.eigSym)
44113
+ throw new RuntimeError("eig: symmetric eig bridge not available");
44114
+ const r = bridge.eigSym(C.re, n, computeV);
44115
+ w = r.w;
44116
+ SRe = r.V;
44117
+ }
44118
+ if (nargout <= 1) return RTV.tensor(w, [n, 1]);
44119
+ const S = {
44120
+ re: SRe ?? allocFloat64Array(n * n),
44121
+ im: SIm ?? null
44122
+ };
44123
+ const V = SRe ? solveUpper(R, S, n, complex) : S;
44124
+ const makeV = () => maybeComplexTensor(
44125
+ allocFloat64Array(V.re),
44126
+ [n, n],
44127
+ V.im ? allocFloat64Array(V.im) : void 0
44128
+ );
44129
+ const Vout = makeV();
44130
+ const Dout = outputForm === "vector" ? RTV.tensor(allocFloat64Array(w), [n, 1]) : buildDiagMatrix(w, void 0, n);
44131
+ if (nargout === 2) return [Vout, Dout];
44132
+ return [Vout, Dout, makeV()];
44133
+ }
44134
+ function symmetrizeInPlace(M, n) {
44135
+ for (let j = 0; j < n; j++) {
44136
+ if (M.im) M.im[j + j * n] = 0;
44137
+ for (let i = j + 1; i < n; i++) {
44138
+ const a = (M.re[i + j * n] + M.re[j + i * n]) / 2;
44139
+ M.re[i + j * n] = a;
44140
+ M.re[j + i * n] = a;
44141
+ if (M.im) {
44142
+ const b = (M.im[i + j * n] - M.im[j + i * n]) / 2;
44143
+ M.im[i + j * n] = b;
44144
+ M.im[j + i * n] = -b;
44145
+ }
44146
+ }
44147
+ }
44148
+ }
44149
+ function solveLeftConjTransposeUpper(R, Bm, n, complex) {
44150
+ const X = {
44151
+ re: allocFloat64Array(n * n),
44152
+ im: complex ? allocFloat64Array(n * n) : null
44153
+ };
44154
+ for (let c = 0; c < n; c++) {
44155
+ for (let i = 0; i < n; i++) {
44156
+ let sr = Bm.re[i + c * n];
44157
+ let si = Bm.im ? Bm.im[i + c * n] : 0;
44158
+ for (let k = 0; k < i; k++) {
44159
+ const lr = R.re[k + i * n];
44160
+ const li = R.im ? -R.im[k + i * n] : 0;
44161
+ const xr = X.re[k + c * n];
44162
+ const xi = X.im ? X.im[k + c * n] : 0;
44163
+ sr -= lr * xr - li * xi;
44164
+ si -= lr * xi + li * xr;
44165
+ }
44166
+ const dr = R.re[i + i * n];
44167
+ const di = R.im ? -R.im[i + i * n] : 0;
44168
+ const [qr2, qi] = complexDivide2(sr, si, dr, di);
44169
+ X.re[i + c * n] = qr2;
44170
+ if (X.im) X.im[i + c * n] = qi;
44171
+ }
44172
+ }
44173
+ return X;
44174
+ }
44175
+ function solveRightUpper(Y, R, n, complex) {
44176
+ const C = {
44177
+ re: allocFloat64Array(n * n),
44178
+ im: complex ? allocFloat64Array(n * n) : null
44179
+ };
44180
+ for (let j = 0; j < n; j++) {
44181
+ for (let i = 0; i < n; i++) {
44182
+ let sr = Y.re[i + j * n];
44183
+ let si = Y.im ? Y.im[i + j * n] : 0;
44184
+ for (let k = 0; k < j; k++) {
44185
+ const cr = C.re[i + k * n];
44186
+ const ci = C.im ? C.im[i + k * n] : 0;
44187
+ const rr = R.re[k + j * n];
44188
+ const ri = R.im ? R.im[k + j * n] : 0;
44189
+ sr -= cr * rr - ci * ri;
44190
+ si -= cr * ri + ci * rr;
44191
+ }
44192
+ const dr = R.re[j + j * n];
44193
+ const di = R.im ? R.im[j + j * n] : 0;
44194
+ const [qr2, qi] = complexDivide2(sr, si, dr, di);
44195
+ C.re[i + j * n] = qr2;
44196
+ if (C.im) C.im[i + j * n] = qi;
44197
+ }
44198
+ }
44199
+ return C;
44200
+ }
44201
+ function solveUpper(R, S, n, complex) {
44202
+ const V = {
44203
+ re: allocFloat64Array(n * n),
44204
+ im: complex ? allocFloat64Array(n * n) : null
44205
+ };
44206
+ for (let c = 0; c < n; c++) {
44207
+ for (let i = n - 1; i >= 0; i--) {
44208
+ let sr = S.re[i + c * n];
44209
+ let si = S.im ? S.im[i + c * n] : 0;
44210
+ for (let k = i + 1; k < n; k++) {
44211
+ const rr = R.re[i + k * n];
44212
+ const ri = R.im ? R.im[i + k * n] : 0;
44213
+ const vr = V.re[k + c * n];
44214
+ const vi = V.im ? V.im[k + c * n] : 0;
44215
+ sr -= rr * vr - ri * vi;
44216
+ si -= rr * vi + ri * vr;
44217
+ }
44218
+ const dr = R.re[i + i * n];
44219
+ const di = R.im ? R.im[i + i * n] : 0;
44220
+ const [qr2, qi] = complexDivide2(sr, si, dr, di);
44221
+ V.re[i + c * n] = qr2;
44222
+ if (V.im) V.im[i + c * n] = qi;
44223
+ }
44224
+ }
44225
+ return V;
44226
+ }
44227
+ function complexDivide2(ar, ai, br, bi) {
44228
+ if (bi === 0) return [ar / br, ai / br];
44229
+ if (Math.abs(br) >= Math.abs(bi)) {
44230
+ const r2 = bi / br;
44231
+ const t2 = br + bi * r2;
44232
+ return [(ar + ai * r2) / t2, (ai - ar * r2) / t2];
44233
+ }
44234
+ const r = br / bi;
44235
+ const t = br * r + bi;
44236
+ return [(ar * r + ai) / t, (ai * r - ar) / t];
44237
+ }
44238
+ function eigGeneralizedQz(A, B, n, nargout, outputForm) {
44239
+ const computeEigvecs = nargout >= 2;
44240
+ const wr = allocFloat64Array(n);
44241
+ const wi = allocFloat64Array(n);
44242
+ let V = null;
44243
+ let W = null;
44244
+ if (A.im || B.im) {
44245
+ const bridge = getEffectiveBridge("qzComplex", "qzComplex");
44246
+ if (!bridge.qzComplex) throw generalizedUnsupported();
44247
+ const r = bridge.qzComplex(
44248
+ A.re,
44249
+ A.im ?? allocFloat64Array(n * n),
44250
+ B.re,
44251
+ B.im ?? allocFloat64Array(n * n),
44252
+ n,
44253
+ computeEigvecs
44254
+ );
44255
+ if (!r) throw new RuntimeError("eig: complex QZ failed");
44256
+ for (let i = 0; i < n; i++) {
44257
+ const [qr2, qi] = complexDivide2(
44258
+ r.alphaRe[i],
44259
+ r.alphaIm[i],
44260
+ r.betaRe[i],
44261
+ r.betaIm[i]
44262
+ );
44263
+ wr[i] = qr2;
44264
+ wi[i] = qi;
44265
+ }
44266
+ if (computeEigvecs) {
44267
+ if (!r.VRe || !r.VIm || !r.WRe || !r.WIm)
44268
+ throw new RuntimeError(
44269
+ "eig: failed to compute generalized eigenvectors"
44270
+ );
44271
+ V = maybeComplexTensor(
44272
+ allocFloat64Array(r.VRe),
44273
+ [n, n],
44274
+ allocFloat64Array(r.VIm)
44275
+ );
44276
+ W = maybeComplexTensor(
44277
+ allocFloat64Array(r.WRe),
44278
+ [n, n],
44279
+ allocFloat64Array(r.WIm)
44280
+ );
44281
+ }
44282
+ } else {
44283
+ const bridge = getEffectiveBridge("qz", "qz");
44284
+ if (!bridge.qz) throw generalizedUnsupported();
44285
+ const r = bridge.qz(A.re, B.re, n, computeEigvecs);
44286
+ if (!r) throw new RuntimeError("eig: real QZ failed");
44287
+ let hasComplex = false;
44288
+ for (let i = 0; i < n; i++) {
44289
+ const beta = r.beta[i];
44290
+ wr[i] = r.alphar[i] / beta;
44291
+ wi[i] = r.alphai[i] === 0 && beta === 0 ? 0 : r.alphai[i] / beta;
44292
+ if (r.alphai[i] !== 0) hasComplex = true;
44293
+ }
44294
+ if (computeEigvecs) {
44295
+ if (!r.V || !r.W)
44296
+ throw new RuntimeError(
44297
+ "eig: failed to compute generalized eigenvectors"
44298
+ );
44299
+ V = buildEigenvectorMatrix(r.V, r.alphai, n, hasComplex);
44300
+ W = buildEigenvectorMatrix(r.W, r.alphai, n, hasComplex);
41645
44301
  }
41646
44302
  }
41647
- return { balance, outputForm };
44303
+ if (nargout <= 1) return maybeComplexTensor(wr, [n, 1], wi);
44304
+ const Dout = outputForm === "vector" ? maybeComplexTensor(wr, [n, 1], wi) : buildDiagMatrix(wr, wi, n);
44305
+ if (nargout === 2) return [V, Dout];
44306
+ return [V, Dout, W];
44307
+ }
44308
+ function generalizedUnsupported() {
44309
+ return new RuntimeError(
44310
+ "eig: the generalized eigenvalue problem eig(A, B) with a non symmetric-definite pencil requires the native LAPACK addon"
44311
+ );
41648
44312
  }
41649
44313
  registerIBuiltin({
41650
44314
  name: "chol",
@@ -41652,13 +44316,31 @@ registerIBuiltin({
41652
44316
  if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
41653
44317
  return null;
41654
44318
  if (!isNumericJitType(argTypes[0])) return null;
41655
- const t = tensorType();
44319
+ const t = argTypes[0].kind === "sparse_matrix" ? SPARSE_TYPE : tensorType();
41656
44320
  const wrapped = (args, n) => withScratch(() => cholApply(args, n));
41657
44321
  if (nargout <= 1) return { outputTypes: [t], apply: wrapped };
41658
44322
  if (nargout === 2) return { outputTypes: [t, NUM], apply: wrapped };
41659
44323
  return { outputTypes: [t, NUM, t], apply: wrapped };
41660
44324
  }
41661
44325
  });
44326
+ function sparseCholApply(S, upper, outputForm, nargout) {
44327
+ if (S.m !== S.n) throw new RuntimeError("chol: Matrix must be square.");
44328
+ const n = S.n;
44329
+ const perm = nargout >= 3 ? minimumDegreeOrdering(S) : identityPerm(n);
44330
+ const A = nargout >= 3 ? sparsePermute(S, perm, perm) : S;
44331
+ const res = sparseChol(A);
44332
+ const R = upper ? sparseTranspose(res.L) : res.L;
44333
+ const permOut = () => outputForm === "vector" ? permVectorTensor(perm) : permutationMatrix(invertPerm(perm));
44334
+ if (!res.ok) {
44335
+ if (nargout < 2)
44336
+ throw new RuntimeError("chol: Matrix must be positive definite.");
44337
+ if (nargout >= 3) return [R, RTV.num(res.p), permOut()];
44338
+ return [R, RTV.num(res.p)];
44339
+ }
44340
+ if (nargout >= 3) return [R, RTV.num(0), permOut()];
44341
+ if (nargout === 2) return [R, RTV.num(0)];
44342
+ return R;
44343
+ }
41662
44344
  function cholApply(args, nargout) {
41663
44345
  if (args.length < 1)
41664
44346
  throw new RuntimeError("chol requires at least 1 argument");
@@ -41666,10 +44348,9 @@ function cholApply(args, nargout) {
41666
44348
  const inputIsSparse = isRuntimeSparseMatrix(A);
41667
44349
  if (nargout >= 3 && !inputIsSparse)
41668
44350
  throw new RuntimeError("Third output only available for sparse matrices.");
41669
- if (inputIsSparse)
41670
- A = sparseToDense(
41671
- A
41672
- );
44351
+ const sparseInput = isRuntimeSparseMatrix(A) && !A.pi ? A : null;
44352
+ if (inputIsSparse && !sparseInput)
44353
+ A = sparseToDense(A);
41673
44354
  let triangle = "upper";
41674
44355
  let outputForm = "matrix";
41675
44356
  if (args.length === 2) {
@@ -41688,6 +44369,8 @@ function cholApply(args, nargout) {
41688
44369
  outputForm = form;
41689
44370
  }
41690
44371
  const upper = triangle === "upper";
44372
+ if (sparseInput)
44373
+ return sparseCholApply(sparseInput, upper, outputForm, nargout);
41691
44374
  if (isRuntimeNumber(A)) {
41692
44375
  const val = A;
41693
44376
  if (val <= 0) {
@@ -42105,15 +44788,28 @@ defineBuiltin({
42105
44788
  if (nargout > 1 || argTypes.length !== 2) return null;
42106
44789
  if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
42107
44790
  return null;
44791
+ if (argTypes.some((t) => t.kind === "sparse_matrix"))
44792
+ return [
44793
+ {
44794
+ kind: "sparse_matrix",
44795
+ isComplex: argTypes.some(
44796
+ (t) => t.kind === "sparse_matrix" && t.isComplex
44797
+ )
44798
+ }
44799
+ ];
42108
44800
  return [tensorType()];
42109
44801
  },
42110
44802
  apply: (args) => {
42111
44803
  if (args.length !== 2)
42112
44804
  throw new RuntimeError("kron requires 2 arguments");
44805
+ if (isRuntimeSparseMatrix(args[0]) || isRuntimeSparseMatrix(args[1]))
44806
+ return sparseKron(
44807
+ toSparseOperand(args[0], "kron"),
44808
+ toSparseOperand(args[1], "kron")
44809
+ );
42113
44810
  const coerce = (v) => {
42114
44811
  if (isRuntimeNumber(v))
42115
44812
  return RTV.tensor(allocFloat64Array([v]), [1, 1]);
42116
- if (isRuntimeSparseMatrix(v)) return sparseToDense(v);
42117
44813
  if (isRuntimeTensor(v)) return v;
42118
44814
  throw new RuntimeError("kron: arguments must be numeric");
42119
44815
  };
@@ -49876,6 +52572,585 @@ registerIBuiltin({
49876
52572
  }
49877
52573
  });
49878
52574
 
52575
+ // src/numbl-core/interpreter/builtins/sparse-solvers.ts
52576
+ function toSparseArg(v, name) {
52577
+ if (isRuntimeSparseMatrix(v)) return v;
52578
+ if (isRuntimeTensor(v)) return denseToSparse(v);
52579
+ if (isRuntimeNumber(v))
52580
+ return denseToSparse(RTV.tensor(allocFloat64Array([v]), [1, 1]));
52581
+ if (isRuntimeLogical(v))
52582
+ return denseToSparse(RTV.tensor(allocFloat64Array([v ? 1 : 0]), [1, 1]));
52583
+ throw new RuntimeError(`${name}: argument must be a numeric matrix`);
52584
+ }
52585
+ var ROW_VECTOR = { kind: "tensor", isComplex: false };
52586
+ registerIBuiltin({
52587
+ name: "symrcm",
52588
+ help: {
52589
+ signatures: ["p = symrcm(A)"],
52590
+ description: "Reverse Cuthill-McKee ordering of the pattern of A + A'. A(p,p) tends to have a smaller bandwidth than A."
52591
+ },
52592
+ resolve: (argTypes, nargout) => {
52593
+ if (argTypes.length !== 1 || nargout > 1) return null;
52594
+ return {
52595
+ outputTypes: [ROW_VECTOR],
52596
+ apply: (args) => permVectorTensor(reverseCuthillMcKee(toSparseArg(args[0], "symrcm")))
52597
+ };
52598
+ }
52599
+ });
52600
+ registerIBuiltin({
52601
+ name: "amd",
52602
+ help: {
52603
+ signatures: ["p = amd(A)"],
52604
+ description: "Minimum degree ordering of the pattern of A + A'. chol(A(p,p)) tends to be sparser than chol(A). numbl uses an exact minimum degree ordering, so p can differ from MATLAB's approximate minimum degree permutation."
52605
+ },
52606
+ resolve: (argTypes, nargout) => {
52607
+ if (argTypes.length < 1 || argTypes.length > 2 || nargout > 1) return null;
52608
+ return {
52609
+ outputTypes: [ROW_VECTOR],
52610
+ apply: (args) => permVectorTensor(minimumDegreeOrdering(toSparseArg(args[0], "amd")))
52611
+ };
52612
+ }
52613
+ });
52614
+ registerIBuiltin({
52615
+ name: "colamd",
52616
+ help: {
52617
+ signatures: ["p = colamd(A)"],
52618
+ description: "Column ordering for LU: minimum degree ordering of the pattern of A'*A. lu(A(:,p)) tends to produce sparser factors than lu(A)."
52619
+ },
52620
+ resolve: (argTypes, nargout) => {
52621
+ if (argTypes.length < 1 || argTypes.length > 2 || nargout > 1) return null;
52622
+ return {
52623
+ outputTypes: [ROW_VECTOR],
52624
+ apply: (args) => permVectorTensor(columnOrdering(toSparseArg(args[0], "colamd")))
52625
+ };
52626
+ }
52627
+ });
52628
+ function sampleDistinct(total, k) {
52629
+ if (k >= total) {
52630
+ const all2 = new Int32Array(total);
52631
+ for (let i = 0; i < total; i++) all2[i] = i;
52632
+ return all2;
52633
+ }
52634
+ let picked;
52635
+ if (k > total / 3) {
52636
+ const idx = new Int32Array(total);
52637
+ for (let i = 0; i < total; i++) idx[i] = i;
52638
+ for (let i = 0; i < k; i++) {
52639
+ const j = i + Math.floor(rngRandom() * (total - i));
52640
+ const t = idx[i];
52641
+ idx[i] = idx[j];
52642
+ idx[j] = t;
52643
+ }
52644
+ picked = idx.slice(0, k);
52645
+ } else {
52646
+ const set = /* @__PURE__ */ new Set();
52647
+ while (set.size < k) set.add(Math.floor(rngRandom() * total));
52648
+ picked = Int32Array.from(set);
52649
+ }
52650
+ return picked.sort();
52651
+ }
52652
+ function sparseFromLinearIndices(m, n, idx, gen) {
52653
+ const nnz = idx.length;
52654
+ const ir = new Int32Array(nnz);
52655
+ const jc = new Int32Array(n + 1);
52656
+ const pr = allocFloat64Array(nnz);
52657
+ for (let k = 0; k < nnz; k++) {
52658
+ const col = Math.floor(idx[k] / m);
52659
+ ir[k] = idx[k] - col * m;
52660
+ jc[col + 1]++;
52661
+ pr[k] = gen();
52662
+ }
52663
+ for (let c = 0; c < n; c++) jc[c + 1] += jc[c];
52664
+ return RTV.sparseMatrix(m, n, ir, jc, pr);
52665
+ }
52666
+ function registerSprand(name, gen) {
52667
+ registerIBuiltin({
52668
+ name,
52669
+ help: {
52670
+ signatures: [`R = ${name}(m, n, density)`, `R = ${name}(S)`],
52671
+ description: `Random m-by-n sparse matrix with approximately density*m*n ` + (name === "sprand" ? "uniformly" : "normally") + ` distributed nonzeros, or a matrix with the pattern of S and random values.`
52672
+ },
52673
+ resolve: (argTypes, nargout) => {
52674
+ if (nargout > 1) return null;
52675
+ if (argTypes.length !== 1 && argTypes.length < 3) return null;
52676
+ return {
52677
+ outputTypes: [{ kind: "sparse_matrix", isComplex: false }],
52678
+ apply: (args) => {
52679
+ if (args.length === 1) {
52680
+ const S = toSparseArg(args[0], name);
52681
+ const pr = allocFloat64Array(S.pr.length);
52682
+ for (let k2 = 0; k2 < pr.length; k2++) pr[k2] = gen();
52683
+ return RTV.sparseMatrix(
52684
+ S.m,
52685
+ S.n,
52686
+ new Int32Array(S.ir),
52687
+ new Int32Array(S.jc),
52688
+ pr
52689
+ );
52690
+ }
52691
+ if (args.length > 3)
52692
+ throw new RuntimeError(
52693
+ `${name}: the reciprocal-condition form ${name}(m, n, density, rc) is not supported`
52694
+ );
52695
+ const m = Math.round(toNumber(args[0]));
52696
+ const n = Math.round(toNumber(args[1]));
52697
+ const density = toNumber(args[2]);
52698
+ if (!(density >= 0 && density <= 1))
52699
+ throw new RuntimeError(`${name}: density must be in [0, 1]`);
52700
+ const total = m * n;
52701
+ const k = Math.min(total, Math.round(density * total));
52702
+ return sparseFromLinearIndices(m, n, sampleDistinct(total, k), gen);
52703
+ }
52704
+ };
52705
+ }
52706
+ });
52707
+ }
52708
+ registerSprand("sprand", rngRandom);
52709
+ registerSprand("sprandn", boxMullerRandom);
52710
+ registerIBuiltin({
52711
+ name: "sprandsym",
52712
+ help: {
52713
+ signatures: ["R = sprandsym(n, density)", "R = sprandsym(S)"],
52714
+ description: "Symmetric random n-by-n sparse matrix with approximately density*n*n normally distributed nonzeros, or a symmetric matrix with the pattern of the lower triangle of S."
52715
+ },
52716
+ resolve: (argTypes, nargout) => {
52717
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2) return null;
52718
+ return {
52719
+ outputTypes: [{ kind: "sparse_matrix", isComplex: false }],
52720
+ apply: (args) => {
52721
+ let n;
52722
+ let lowerIdx;
52723
+ if (args.length === 1) {
52724
+ const S = toSparseArg(args[0], "sprandsym");
52725
+ if (S.m !== S.n)
52726
+ throw new RuntimeError("sprandsym: S must be square");
52727
+ n = S.n;
52728
+ const idx = [];
52729
+ for (let j = 0; j < n; j++)
52730
+ for (let k = S.jc[j]; k < S.jc[j + 1]; k++)
52731
+ if (S.ir[k] >= j) idx.push(j * n + S.ir[k]);
52732
+ lowerIdx = Int32Array.from(idx);
52733
+ } else {
52734
+ n = Math.round(toNumber(args[0]));
52735
+ const density = toNumber(args[1]);
52736
+ if (!(density >= 0 && density <= 1))
52737
+ throw new RuntimeError("sprandsym: density must be in [0, 1]");
52738
+ const tri = n * (n + 1) / 2;
52739
+ const k = Math.min(tri, Math.round(density * n * n / 2));
52740
+ const triIdx = sampleDistinct(tri, k);
52741
+ const lin = [];
52742
+ for (let t = 0; t < triIdx.length; t++) {
52743
+ let r = triIdx[t];
52744
+ let col = 0;
52745
+ while (r >= n - col) {
52746
+ r -= n - col;
52747
+ col++;
52748
+ }
52749
+ lin.push(col * n + col + r);
52750
+ }
52751
+ lowerIdx = Int32Array.from(lin).sort();
52752
+ }
52753
+ const lower = sparseFromLinearIndices(n, n, lowerIdx, boxMullerRandom);
52754
+ const Lt = sparseTranspose(lower);
52755
+ const dense = sparseToDense(lower).data;
52756
+ const denseT = sparseToDense(Lt).data;
52757
+ for (let i = 0; i < dense.length; i++) dense[i] += denseT[i];
52758
+ for (let i = 0; i < n; i++) dense[i + i * n] /= 2;
52759
+ return denseDataToSparse(dense, n, n);
52760
+ }
52761
+ };
52762
+ }
52763
+ });
52764
+ var DEC_CLASS = "decomposition";
52765
+ function isDecomposition(v) {
52766
+ return isRuntimeClassInstance(v) && v.className === DEC_CLASS;
52767
+ }
52768
+ function permFromField(d, name) {
52769
+ const t = d.fields.get(name);
52770
+ if (t === void 0 || !isRuntimeTensor(t))
52771
+ throw new RuntimeError("decomposition: corrupt");
52772
+ const p2 = new Int32Array(t.data.length);
52773
+ for (let i = 0; i < p2.length; i++) p2[i] = t.data[i] - 1;
52774
+ return p2;
52775
+ }
52776
+ function sparseField(d, name) {
52777
+ const v = d.fields.get(name);
52778
+ if (v === void 0 || !isRuntimeSparseMatrix(v))
52779
+ throw new RuntimeError("decomposition: corrupt");
52780
+ return v;
52781
+ }
52782
+ function charField(d, name) {
52783
+ const v = d.fields.get(name);
52784
+ if (v === void 0) throw new RuntimeError("decomposition: corrupt");
52785
+ return parseStringArgLower(v);
52786
+ }
52787
+ function diagRatio(S) {
52788
+ let lo = Infinity;
52789
+ let hi = 0;
52790
+ for (let j = 0; j < S.n; j++) {
52791
+ let d = 0;
52792
+ for (let k = S.jc[j]; k < S.jc[j + 1]; k++)
52793
+ if (S.ir[k] === j) {
52794
+ d = Math.abs(S.pr[k]);
52795
+ break;
52796
+ }
52797
+ if (d < lo) lo = d;
52798
+ if (d > hi) hi = d;
52799
+ }
52800
+ if (S.n === 0) return 1;
52801
+ return hi === 0 ? 0 : lo / hi;
52802
+ }
52803
+ function denseLuFactors(data, n) {
52804
+ const bridge = getEffectiveBridge("lu", "lu");
52805
+ if (!bridge?.lu) throw new RuntimeError("decomposition: LU unavailable");
52806
+ const { LU, ipiv } = bridge.lu(toF64(data), n, n);
52807
+ const perm = new Int32Array(n);
52808
+ for (let i = 0; i < n; i++) perm[i] = i;
52809
+ for (let i = 0; i < ipiv.length; i++) {
52810
+ const j = ipiv[i] - 1;
52811
+ if (j !== i) {
52812
+ const t = perm[i];
52813
+ perm[i] = perm[j];
52814
+ perm[j] = t;
52815
+ }
52816
+ }
52817
+ const L = allocFloat64Array(n * n);
52818
+ const U = allocFloat64Array(n * n);
52819
+ let singular = false;
52820
+ for (let j = 0; j < n; j++) {
52821
+ L[j + j * n] = 1;
52822
+ for (let i = j + 1; i < n; i++) L[i + j * n] = LU[i + j * n];
52823
+ for (let i = 0; i <= j; i++) U[i + j * n] = LU[i + j * n];
52824
+ if (U[j + j * n] === 0) singular = true;
52825
+ }
52826
+ return {
52827
+ L: denseDataToSparse(L, n, n),
52828
+ U: denseDataToSparse(U, n, n),
52829
+ p: perm,
52830
+ q: identityPerm(n),
52831
+ singular
52832
+ };
52833
+ }
52834
+ function denseCholLower(data, n) {
52835
+ const bridge = getEffectiveBridge("chol", "chol");
52836
+ if (!bridge?.chol) throw new RuntimeError("decomposition: chol unavailable");
52837
+ const { R, info } = bridge.chol(toF64(data), n, false);
52838
+ if (info > 0) return null;
52839
+ return denseDataToSparse(R, n, n);
52840
+ }
52841
+ function denseIsTriangular(data, n, upper) {
52842
+ for (let j = 0; j < n; j++)
52843
+ for (let i = 0; i < n; i++) {
52844
+ if (upper ? i <= j : i >= j) continue;
52845
+ if (data[i + j * n] !== 0) return false;
52846
+ }
52847
+ return true;
52848
+ }
52849
+ registerIBuiltin({
52850
+ name: "decomposition",
52851
+ help: {
52852
+ signatures: [
52853
+ "dA = decomposition(A)",
52854
+ "dA = decomposition(A, type)",
52855
+ "dA = decomposition(A, 'triangular', 'upper' | 'lower')",
52856
+ "x = dA \\ b",
52857
+ "x = b / dA"
52858
+ ],
52859
+ description: "Factor a square matrix once and reuse the factors: dA \\ b and b / dA solve with the stored factorization. type is 'auto' (default), 'chol', 'lu', or 'triangular'; other MATLAB types fall back to LU. Sparse matrices use the sparse Cholesky / LU with a fill-reducing ordering. Properties: MatrixSize, Type, Datatype, IsReal, IsConjugateTransposed, ScaleFactor, CheckCondition."
52860
+ },
52861
+ resolve: (argTypes, nargout) => {
52862
+ if (argTypes.length < 1 || nargout > 1) return null;
52863
+ return {
52864
+ outputTypes: [{ kind: "unknown" }],
52865
+ apply: (args) => buildDecomposition(args)
52866
+ };
52867
+ }
52868
+ });
52869
+ function buildDecomposition(args) {
52870
+ const A = args[0];
52871
+ let type = "auto";
52872
+ let triangle = null;
52873
+ let checkCondition = true;
52874
+ let luTol = 1;
52875
+ let i = 1;
52876
+ const isStr = (v) => isRuntimeChar(v) || isRuntimeString(v);
52877
+ while (i < args.length) {
52878
+ const a = args[i];
52879
+ if (!isStr(a))
52880
+ throw new RuntimeError("decomposition: options must be strings");
52881
+ const s = parseStringArgLower(a);
52882
+ if (s === "upper" || s === "lower") {
52883
+ triangle = s;
52884
+ i++;
52885
+ continue;
52886
+ }
52887
+ if (s === "checkcondition" || s === "ranktolerance" || s === "banddensity" || s === "ldlpivottolerance" || s === "lupivottolerance") {
52888
+ if (i + 1 >= args.length)
52889
+ throw new RuntimeError(`decomposition: missing value for '${s}'`);
52890
+ const v = args[i + 1];
52891
+ if (s === "checkcondition") checkCondition = toNumber(v) !== 0;
52892
+ if (s === "lupivottolerance") luTol = toNumber(v);
52893
+ i += 2;
52894
+ continue;
52895
+ }
52896
+ if (i === 1) {
52897
+ type = s;
52898
+ i++;
52899
+ continue;
52900
+ }
52901
+ throw new RuntimeError(`decomposition: unknown option '${s}'`);
52902
+ }
52903
+ const known = [
52904
+ "auto",
52905
+ "chol",
52906
+ "lu",
52907
+ "triangular",
52908
+ "ldl",
52909
+ "qr",
52910
+ "banded",
52911
+ "diagonal",
52912
+ "permutedtriangular",
52913
+ "hessenberg",
52914
+ "cod"
52915
+ ];
52916
+ if (!known.includes(type))
52917
+ throw new RuntimeError(
52918
+ `decomposition: unknown decomposition type '${type}'`
52919
+ );
52920
+ let S = null;
52921
+ let dense = null;
52922
+ let n;
52923
+ if (isRuntimeSparseMatrix(A)) {
52924
+ if (A.pi)
52925
+ throw new RuntimeError(
52926
+ "decomposition: complex matrices are not supported"
52927
+ );
52928
+ if (A.m !== A.n)
52929
+ throw new RuntimeError(
52930
+ "decomposition: only square matrices are supported"
52931
+ );
52932
+ S = A;
52933
+ n = A.n;
52934
+ } else if (isRuntimeTensor(A) || isRuntimeNumber(A)) {
52935
+ const t = isRuntimeNumber(A) ? RTV.tensor(allocFloat64Array([A]), [1, 1]) : A;
52936
+ if (t.imag)
52937
+ throw new RuntimeError(
52938
+ "decomposition: complex matrices are not supported"
52939
+ );
52940
+ const [m, nn] = tensorSize2D(t);
52941
+ if (m !== nn)
52942
+ throw new RuntimeError(
52943
+ "decomposition: only square matrices are supported"
52944
+ );
52945
+ n = nn;
52946
+ dense = t.data;
52947
+ } else {
52948
+ throw new RuntimeError("decomposition: A must be a numeric matrix");
52949
+ }
52950
+ const fields = /* @__PURE__ */ new Map();
52951
+ const setCommon = (typeName, rc) => {
52952
+ fields.set("MatrixSize", RTV.tensor(allocFloat64Array([n, n]), [1, 2]));
52953
+ fields.set("Type", RTV.char(typeName));
52954
+ fields.set("Datatype", RTV.char("double"));
52955
+ fields.set("IsReal", RTV.logical(true));
52956
+ fields.set("IsConjugateTransposed", RTV.logical(false));
52957
+ fields.set("ScaleFactor", RTV.num(1));
52958
+ fields.set("CheckCondition", RTV.logical(checkCondition));
52959
+ fields.set("_rcond", RTV.num(rc));
52960
+ };
52961
+ const storeTriangular = (T, upper) => {
52962
+ fields.set("_kind", RTV.char("triangular"));
52963
+ fields.set("_T", T);
52964
+ fields.set("_upper", RTV.logical(upper));
52965
+ setCommon("triangular", diagRatio(T));
52966
+ };
52967
+ const storeChol = (L, p2) => {
52968
+ fields.set("_kind", RTV.char("chol"));
52969
+ fields.set("_L", L);
52970
+ fields.set("_Lt", sparseTranspose(L));
52971
+ fields.set("_p", permVectorTensor(p2));
52972
+ setCommon("chol", diagRatio(L) ** 2);
52973
+ };
52974
+ const storeLu = (lu3) => {
52975
+ fields.set("_kind", RTV.char("lu"));
52976
+ fields.set("_L", lu3.L);
52977
+ fields.set("_U", lu3.U);
52978
+ fields.set("_p", permVectorTensor(lu3.p));
52979
+ fields.set("_q", permVectorTensor(lu3.q));
52980
+ setCommon(type === "auto" || type === "lu" ? "lu" : type, diagRatio(lu3.U));
52981
+ };
52982
+ const upperOk = S ? sparseIsUpper(S) : denseIsTriangular(dense, n, true);
52983
+ const lowerOk = S ? sparseIsLower(S) : denseIsTriangular(dense, n, false);
52984
+ if (type === "triangular" || type === "auto" && (upperOk || lowerOk)) {
52985
+ let upper;
52986
+ if (triangle) upper = triangle === "upper";
52987
+ else if (upperOk) upper = true;
52988
+ else if (lowerOk) upper = false;
52989
+ else throw new RuntimeError("decomposition: matrix is not triangular");
52990
+ const T = S ?? denseDataToSparse(dense, n, n);
52991
+ storeTriangular(T, upper);
52992
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
52993
+ }
52994
+ const symmetric = S !== null && sparseIsSymmetric(S);
52995
+ if (type === "chol" || type === "auto" && symmetric) {
52996
+ if (S) {
52997
+ const perm = minimumDegreeOrdering(S);
52998
+ const res = sparseChol(sparsePermute(S, perm, perm));
52999
+ if (res.ok) {
53000
+ storeChol(res.L, perm);
53001
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
53002
+ }
53003
+ } else {
53004
+ const L = denseCholLower(dense, n);
53005
+ if (L) {
53006
+ storeChol(L, identityPerm(n));
53007
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
53008
+ }
53009
+ }
53010
+ if (type === "chol")
53011
+ throw new RuntimeError(
53012
+ "Cholesky decomposition requires the input matrix to be positive definite."
53013
+ );
53014
+ }
53015
+ const lu2 = S ? sparseLu(S, columnOrdering(S), luTol) : denseLuFactors(dense, n);
53016
+ if (lu2.singular) emitWarning(SINGULAR_WARNING);
53017
+ storeLu(lu2);
53018
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
53019
+ }
53020
+ function decompositionRcond(d) {
53021
+ const rc = d.fields.get("_rcond");
53022
+ return typeof rc === "number" ? rc : 1;
53023
+ }
53024
+ registerIBuiltin({
53025
+ name: "isIllConditioned",
53026
+ help: {
53027
+ signatures: ["tf = isIllConditioned(dA)"],
53028
+ description: "True if the matrix stored in a decomposition object is ill conditioned (reciprocal condition estimate below eps)."
53029
+ },
53030
+ resolve: (argTypes, nargout) => {
53031
+ if (argTypes.length !== 1 || nargout > 1) return null;
53032
+ return {
53033
+ outputTypes: [{ kind: "boolean" }],
53034
+ apply: (args) => {
53035
+ if (!isDecomposition(args[0]))
53036
+ throw new RuntimeError(
53037
+ "isIllConditioned: argument must be a decomposition object"
53038
+ );
53039
+ return RTV.logical(decompositionRcond(args[0]) < Number.EPSILON);
53040
+ }
53041
+ };
53042
+ }
53043
+ });
53044
+ function decompositionSolve(d, B, n, nrhs, transposed) {
53045
+ if (d.fields.get("CheckCondition") === true) {
53046
+ const rc = decompositionRcond(d);
53047
+ if (rc < Number.EPSILON)
53048
+ emitWarning(
53049
+ `Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = ${rc.toExponential(6)}.`
53050
+ );
53051
+ }
53052
+ const kind = charField(d, "_kind");
53053
+ if (kind === "triangular") {
53054
+ let T = sparseField(d, "_T");
53055
+ let upper = d.fields.get("_upper") === true;
53056
+ if (transposed) {
53057
+ T = sparseTranspose(T);
53058
+ upper = !upper;
53059
+ }
53060
+ const r = upper ? sparseSolveUpper(T, B, nrhs) : sparseSolveLower(T, B, nrhs);
53061
+ if (r.singular) emitWarning(SINGULAR_WARNING);
53062
+ return r.x;
53063
+ }
53064
+ if (kind === "chol") {
53065
+ const L = sparseField(d, "_L");
53066
+ const p2 = permFromField(d, "_p");
53067
+ const bp = allocFloat64Array(B.length);
53068
+ for (let c = 0; c < nrhs; c++)
53069
+ for (let k = 0; k < n; k++) bp[c * n + k] = B[c * n + p2[k]];
53070
+ const y = sparseSolveLower(L, bp, nrhs).x;
53071
+ const z = sparseSolveUpper(sparseField(d, "_Lt"), y, nrhs).x;
53072
+ const x = allocFloat64Array(B.length);
53073
+ for (let c = 0; c < nrhs; c++)
53074
+ for (let k = 0; k < n; k++) x[c * n + p2[k]] = z[c * n + k];
53075
+ return x;
53076
+ }
53077
+ const lu2 = {
53078
+ L: sparseField(d, "_L"),
53079
+ U: sparseField(d, "_U"),
53080
+ p: permFromField(d, "_p"),
53081
+ q: permFromField(d, "_q"),
53082
+ singular: false
53083
+ };
53084
+ return transposed ? luSolveTransposed(lu2, B, nrhs) : luSolve(lu2, B, nrhs);
53085
+ }
53086
+ function rhsData(v) {
53087
+ if (isRuntimeSparseMatrix(v)) {
53088
+ if (v.pi)
53089
+ throw new RuntimeError(
53090
+ "decomposition: complex operands are not supported"
53091
+ );
53092
+ return { data: sparseToDense(v).data, m: v.m, n: v.n };
53093
+ }
53094
+ if (isRuntimeTensor(v)) {
53095
+ if (v.imag)
53096
+ throw new RuntimeError(
53097
+ "decomposition: complex operands are not supported"
53098
+ );
53099
+ const [m, n] = tensorSize2D(v);
53100
+ return { data: v.data, m, n };
53101
+ }
53102
+ if (isRuntimeNumber(v) || isRuntimeLogical(v))
53103
+ return { data: allocFloat64Array([toNumber(v)]), m: 1, n: 1 };
53104
+ throw new RuntimeError("decomposition: operand must be numeric");
53105
+ }
53106
+ function tryDecompositionDivide(name, a, b) {
53107
+ if (name === "mldivide") {
53108
+ if (!isDecomposition(a)) {
53109
+ if (isDecomposition(b))
53110
+ throw new RuntimeError(
53111
+ "decomposition: a decomposition object can only be the left operand of \\"
53112
+ );
53113
+ return void 0;
53114
+ }
53115
+ const n2 = toNumber(permSize(a));
53116
+ const rhs2 = rhsData(b);
53117
+ if (rhs2.m !== n2)
53118
+ throw new RuntimeError(
53119
+ `mldivide (\\): A is ${n2}\xD7${n2} but B has ${rhs2.m} rows`
53120
+ );
53121
+ const x2 = decompositionSolve(a, rhs2.data, n2, rhs2.n, false);
53122
+ return RTV.tensor(x2, [n2, rhs2.n]);
53123
+ }
53124
+ if (!isDecomposition(b)) {
53125
+ if (isDecomposition(a))
53126
+ throw new RuntimeError(
53127
+ "decomposition: a decomposition object can only be the right operand of /"
53128
+ );
53129
+ return void 0;
53130
+ }
53131
+ const n = toNumber(permSize(b));
53132
+ const rhs = rhsData(a);
53133
+ if (rhs.n !== n)
53134
+ throw new RuntimeError(
53135
+ `mrdivide (/): A is ${n}\xD7${n} but B has ${rhs.n} columns`
53136
+ );
53137
+ const nrhs = rhs.m;
53138
+ const Bt = allocFloat64Array(n * nrhs);
53139
+ for (let c = 0; c < nrhs; c++)
53140
+ for (let k = 0; k < n; k++) Bt[c * n + k] = rhs.data[c + k * nrhs];
53141
+ const xt = decompositionSolve(b, Bt, n, nrhs, true);
53142
+ const x = allocFloat64Array(n * nrhs);
53143
+ for (let c = 0; c < nrhs; c++)
53144
+ for (let k = 0; k < n; k++) x[c + k * nrhs] = xt[c * n + k];
53145
+ return RTV.tensor(x, [nrhs, n]);
53146
+ }
53147
+ function permSize(d) {
53148
+ const ms = d.fields.get("MatrixSize");
53149
+ if (ms === void 0 || !isRuntimeTensor(ms))
53150
+ throw new RuntimeError("decomposition: corrupt");
53151
+ return ms.data[0];
53152
+ }
53153
+
49879
53154
  // src/numbl-core/interpreter/builtins/graph.ts
49880
53155
  function isGraph(v) {
49881
53156
  return isRuntimeClassInstance(v) && v.className === "graph";
@@ -51660,6 +54935,10 @@ for (const [name, op] of opMap) {
51660
54935
  apply: (args) => {
51661
54936
  const dt = tryDatetimeDurationBinop(name, args[0], args[1]);
51662
54937
  if (dt !== void 0) return dt;
54938
+ if (name === "mldivide" || name === "mrdivide") {
54939
+ const dec = tryDecompositionDivide(name, args[0], args[1]);
54940
+ if (dec !== void 0) return dec;
54941
+ }
51663
54942
  return op(args[0], args[1]);
51664
54943
  }
51665
54944
  };
@@ -53524,7 +56803,7 @@ var H = {
53524
56803
  },
53525
56804
  inv: {
53526
56805
  signatures: ["B = inv(A)"],
53527
- description: "Matrix inverse."
56806
+ description: "Matrix inverse. A sparse A gives a sparse B (computed by sparse LU); prefer A \\ b for solving systems."
53528
56807
  },
53529
56808
  expm: {
53530
56809
  signatures: ["Y = expm(X)"],
@@ -53535,8 +56814,15 @@ var H = {
53535
56814
  description: "Sum of diagonal elements."
53536
56815
  },
53537
56816
  eig: {
53538
- signatures: ["E = eig(A)", "[V, D] = eig(A)", "[V, D, W] = eig(A)"],
53539
- description: "Eigenvalues and eigenvectors of square matrix. With three outputs, W contains left eigenvectors."
56817
+ signatures: [
56818
+ "E = eig(A)",
56819
+ "[V, D] = eig(A)",
56820
+ "[V, D, W] = eig(A)",
56821
+ "E = eig(A, B)",
56822
+ "[V, D] = eig(A, B)",
56823
+ "eig(A, ..., 'vector' | 'matrix' | 'nobalance' | 'chol' | 'qz')"
56824
+ ],
56825
+ description: "Eigenvalues and eigenvectors of a square matrix. With three outputs, W contains left eigenvectors. Symmetric (Hermitian) input gives real eigenvalues in ascending order and an orthonormal eigenvector basis. eig(A, B) solves the generalized problem A*v = lambda*B*v; for a symmetric-definite pencil V is normalized so that V'*B*V = I."
53540
56826
  },
53541
56827
  eigs: {
53542
56828
  signatures: [
@@ -53559,8 +56845,15 @@ var H = {
53559
56845
  description: "Singular value decomposition."
53560
56846
  },
53561
56847
  lu: {
53562
- signatures: ["Y = lu(A)", "[L, U] = lu(A)", "[L, U, P] = lu(A)"],
53563
- description: "LU factorization. With 2 outputs, L includes the permutation. With 3, P is a permutation matrix."
56848
+ signatures: [
56849
+ "Y = lu(A)",
56850
+ "[L, U] = lu(A)",
56851
+ "[L, U, P] = lu(A)",
56852
+ "[L, U, P] = lu(A, 'vector')",
56853
+ "[L, U, P, Q] = lu(S)",
56854
+ "[L, U, P, Q] = lu(S, thresh)"
56855
+ ],
56856
+ description: "LU factorization. With 2 outputs, L includes the permutation. With 3, P is a permutation matrix (or a row vector with 'vector'). Sparse S returns sparse factors from a left-looking LU with threshold partial pivoting; with 4 outputs, Q is a fill-reducing column permutation and P*S*Q = L*U."
53564
56857
  },
53565
56858
  qr: {
53566
56859
  signatures: [
@@ -53572,8 +56865,14 @@ var H = {
53572
56865
  description: "QR factorization. With 3 outputs, E is a column permutation matrix (or vector in economy mode)."
53573
56866
  },
53574
56867
  chol: {
53575
- signatures: ["R = chol(A)", "[R, P] = chol(A)"],
53576
- description: "Cholesky factorization. A must be symmetric positive definite. With 2 outputs, P is 0 on success."
56868
+ signatures: [
56869
+ "R = chol(A)",
56870
+ "L = chol(A, 'lower')",
56871
+ "[R, p] = chol(A)",
56872
+ "[R, p, P] = chol(S)",
56873
+ "[R, p, q] = chol(S, 'vector')"
56874
+ ],
56875
+ description: "Cholesky factorization with R'*R = A, reading only the upper triangle. A must be symmetric positive definite; with 2 outputs, p is 0 on success and otherwise the failing column (no error). Sparse S returns a sparse factor; with 3 outputs, P is a fill-reducing permutation with R'*R = P'*S*P."
53577
56876
  },
53578
56877
  rank: {
53579
56878
  signatures: ["K = rank(A)", "K = rank(A, TOL)"],
@@ -53601,7 +56900,7 @@ var H = {
53601
56900
  },
53602
56901
  kron: {
53603
56902
  signatures: ["K = kron(A, B)"],
53604
- description: "Kronecker tensor product."
56903
+ description: "Kronecker tensor product. If either operand is sparse, K is sparse with nnz(A)*nnz(B) entries."
53605
56904
  },
53606
56905
  linsolve: {
53607
56906
  signatures: ["X = linsolve(A, B)"],
@@ -62560,6 +65859,7 @@ var Runtime = class _Runtime {
62560
65859
  if (options.cancelSAB) {
62561
65860
  this.cancelFlag = new Int32Array(options.cancelSAB);
62562
65861
  }
65862
+ setWarningSink((msg) => this.output("Warning: " + msg + "\n"));
62563
65863
  this.initBuiltins();
62564
65864
  }
62565
65865
  outputLines = [];
@@ -65210,9 +68510,9 @@ function analyzeLoop(stmt) {
65210
68510
  };
65211
68511
  }
65212
68512
  function collectReadsFromSiblings(stmts, startIdx, out) {
65213
- const sink = /* @__PURE__ */ new Set();
68513
+ const sink2 = /* @__PURE__ */ new Set();
65214
68514
  for (let i = startIdx; i < stmts.length; i++) {
65215
- walkStmt2(stmts[i], sink, out);
68515
+ walkStmt2(stmts[i], sink2, out);
65216
68516
  }
65217
68517
  }
65218
68518
  function walkStmts(stmts, assigned, referenced) {
@@ -70091,14 +73391,6 @@ end
70091
73391
  name: "+matlab/+internal/+math/blkdiag.m",
70092
73392
  source: "function B = blkdiag(varargin)\n B = builtin('blkdiag', varargin{:});\nend\n"
70093
73393
  },
70094
- {
70095
- name: "decomposition.m",
70096
- source: "classdef decomposition\n properties\n A\n checkCondition\n isIllCond\n end\n methods\n function obj = decomposition(A, varargin)\n obj.A = A;\n obj.checkCondition = true;\n for i = 1:2:length(varargin)\n if strcmpi(varargin{i}, 'CheckCondition')\n obj.checkCondition = varargin{i+1};\n end\n end\n if obj.checkCondition\n obj.isIllCond = (rcond(A) < eps);\n else\n obj.isIllCond = false;\n end\n end\n function x = mldivide(obj, b)\n x = obj.A \\ b;\n end\n end\nend\n"
70097
- },
70098
- {
70099
- name: "isIllConditioned.m",
70100
- source: "function result = isIllConditioned(dA)\n result = dA.isIllCond;\nend\n"
70101
- },
70102
73394
  {
70103
73395
  name: "uihtml.m",
70104
73396
  source: "classdef uihtml < handle\n %UIHTML Create an HTML UI component (numbl subset).\n % H = UIHTML('HTMLSource', HTML) renders the self-contained HTML string\n % HTML in the figure pane. An optional leading parent argument (e.g. a\n % figure) is accepted and ignored. Supported name-value options:\n % HTMLSource, Data, Position.\n %\n % H = UIHTML('HTMLSource', HTML, 'Data', X) also sends X into the page.\n % Mirroring MATLAB, X is encoded with jsonencode, parsed in the page with\n % JSON.parse, and set on the JavaScript `htmlComponent.Data` object,\n % firing any \"DataChanged\" listener registered in the page's\n % `function setup(htmlComponent)`. To update the data after construction,\n % set H.Data and call show(H) (numbl re-renders the component):\n %\n % h = uihtml('HTMLSource', html, 'Data', struct('n', 1));\n % h.Data = struct('n', 2);\n % show(h);\n %\n % numbl currently supports HTMLSource given as an HTML markup string (a\n % single self-contained document). HTML file paths and supporting files\n % are not yet supported.\n %\n % The reverse channel (page -> MATLAB) is supported for the IDE:\n % HTMLEventReceivedFcn fires when JS calls\n % htmlComponent.sendEventToMATLAB(name,data); inside the callback use\n % sendEventToHTMLSource(src,name,data) to send back to the page.\n % DataChangedFcn fires when JS sets htmlComponent.Data. Register callbacks\n % at construction (name-value) since numbl renders at construction.\n properties\n HTMLSource = ''\n Data = []\n Position = [100 100 100 100]\n HTMLEventReceivedFcn = []\n DataChangedFcn = []\n end\n methods\n function obj = uihtml(varargin)\n args = varargin;\n % Ignore an optional leading parent argument (anything that is not\n % a name-value name string).\n if numel(args) >= 1 && ~(ischar(args{1}) || isstring(args{1}))\n args = args(2:end);\n end\n for i = 1:2:numel(args) - 1\n name = args{i};\n val = args{i + 1};\n if strcmpi(name, 'HTMLSource')\n obj.HTMLSource = val;\n elseif strcmpi(name, 'Data')\n obj.Data = val;\n elseif strcmpi(name, 'Position')\n obj.Position = val;\n elseif strcmpi(name, 'HTMLEventReceivedFcn')\n obj.HTMLEventReceivedFcn = val;\n elseif strcmpi(name, 'DataChangedFcn')\n obj.DataChangedFcn = val;\n end\n end\n render(obj);\n end\n\n function show(obj)\n render(obj);\n end\n\n function render(obj)\n if isempty(obj.HTMLSource)\n return;\n end\n if isempty(obj.Data)\n id = drawuihtml(obj.HTMLSource);\n else\n id = drawuihtml(obj.HTMLSource, jsonencode(obj.Data));\n end\n if ~isempty(obj.HTMLEventReceivedFcn)\n registeruihtmlcallback(id, 'HTMLEventReceived', ...\n obj.HTMLEventReceivedFcn);\n end\n if ~isempty(obj.DataChangedFcn)\n registeruihtmlcallback(id, 'DataChanged', obj.DataChangedFcn);\n end\n end\n end\nend\n"
@@ -79316,7 +82608,7 @@ function cCos(z) {
79316
82608
  im: -Math.sin(z.re) * Math.sinh(z.im)
79317
82609
  };
79318
82610
  }
79319
- function cdiv2(a, b) {
82611
+ function cdiv3(a, b) {
79320
82612
  if (Math.abs(b.re) >= Math.abs(b.im)) {
79321
82613
  const r2 = b.im / b.re;
79322
82614
  const den2 = b.re + r2 * b.im;
@@ -79327,7 +82619,7 @@ function cdiv2(a, b) {
79327
82619
  return { re: (a.re * r + a.im) / den, im: (a.im * r - a.re) / den };
79328
82620
  }
79329
82621
  function cTan(z) {
79330
- return cdiv2(cSin(z), cCos(z));
82622
+ return cdiv3(cSin(z), cCos(z));
79331
82623
  }
79332
82624
  function cSinh(z) {
79333
82625
  return {
@@ -79349,7 +82641,7 @@ function cAtan(z) {
79349
82641
  const iz = { re: -z.im, im: z.re };
79350
82642
  const num = { re: 1 - iz.re, im: -iz.im };
79351
82643
  const den = { re: 1 + iz.re, im: iz.im };
79352
- const q = cdiv2(num, den);
82644
+ const q = cdiv3(num, den);
79353
82645
  const l = cLog(q);
79354
82646
  return { re: -l.im / 2, im: l.re / 2 };
79355
82647
  }