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-cli/cli.js CHANGED
@@ -940,6 +940,9 @@ var RuntimeSparseMatrix = class extends Refcounted {
940
940
  jc;
941
941
  pr;
942
942
  pi;
943
+ /** Lazily computed by triangularInfo(); valid because sparse matrices are
944
+ * never mutated in place (indexed assignment builds a new matrix). */
945
+ _triInfo = void 0;
943
946
  constructor(m, n, ir, jc, pr, pi2) {
944
947
  super();
945
948
  this.m = m;
@@ -975,7 +978,7 @@ var RuntimeDictionary = class extends Refcounted {
975
978
  };
976
979
 
977
980
  // src/numbl-core/native/lapack-bridge.ts
978
- var NATIVE_ADDON_EXPECTED_VERSION = 8;
981
+ var NATIVE_ADDON_EXPECTED_VERSION = 9;
979
982
  var _bridge = null;
980
983
  function setLapackBridge(bridge) {
981
984
  _bridge = bridge;
@@ -3844,6 +3847,21 @@ function mMulSparse(a, b) {
3844
3847
  const m = a.m;
3845
3848
  const hasImag = isComplexSparse(a) || b.imag !== void 0;
3846
3849
  const result = allocFloat64Array(m * bCols);
3850
+ if (!hasImag) {
3851
+ const ir = a.ir, jc = a.jc, pr = a.pr, bd = b.data;
3852
+ for (let col = 0; col < bCols; col++) {
3853
+ const boff = col * bRows;
3854
+ const roff = col * m;
3855
+ for (let k = 0; k < a.n; k++) {
3856
+ const bk = bd[boff + k];
3857
+ if (bk === 0) continue;
3858
+ const end = jc[k + 1];
3859
+ for (let ka = jc[k]; ka < end; ka++)
3860
+ result[roff + ir[ka]] += pr[ka] * bk;
3861
+ }
3862
+ }
3863
+ return RTV.tensor(result, [m, bCols]);
3864
+ }
3847
3865
  const resultImag = hasImag ? allocFloat64Array(m * bCols) : void 0;
3848
3866
  for (let col = 0; col < bCols; col++) {
3849
3867
  for (let k = 0; k < a.n; k++) {
@@ -4087,6 +4105,8 @@ var PIVOT_T = 1;
4087
4105
  var PIVOT_B = 2;
4088
4106
  var DIRECT_F = 0;
4089
4107
  var DIRECT_B = 1;
4108
+ var SORT_INC = 0;
4109
+ var SORT_DEC = 1;
4090
4110
  var VECT_Q = 0;
4091
4111
  var VECT_P = 1;
4092
4112
 
@@ -20693,6 +20713,1357 @@ function eigComplexTs(dataRe, dataIm, n, computeVL, computeVR) {
20693
20713
  return result;
20694
20714
  }
20695
20715
 
20716
+ // src/ts-lapack/src/SRC/dlanst.ts
20717
+ var NORM_MAX5 = 0;
20718
+ var NORM_ONE2 = 1;
20719
+ var NORM_INF2 = 2;
20720
+ var NORM_FRO2 = 3;
20721
+ function dlanst(norm2, n, d, dOff, e, eOff) {
20722
+ let anorm = 0;
20723
+ if (n <= 0) {
20724
+ anorm = 0;
20725
+ } else if (norm2 === NORM_MAX5) {
20726
+ anorm = Math.abs(d[dOff + (n - 1)]);
20727
+ for (let i = 1; i <= n - 1; i++) {
20728
+ let sum2 = Math.abs(d[dOff + (i - 1)]);
20729
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
20730
+ sum2 = Math.abs(e[eOff + (i - 1)]);
20731
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
20732
+ }
20733
+ } else if (norm2 === NORM_ONE2 || norm2 === NORM_INF2) {
20734
+ if (n === 1) {
20735
+ anorm = Math.abs(d[dOff]);
20736
+ } else {
20737
+ anorm = Math.abs(d[dOff]) + Math.abs(e[eOff]);
20738
+ let sum2 = Math.abs(e[eOff + (n - 2)]) + Math.abs(d[dOff + (n - 1)]);
20739
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
20740
+ for (let i = 2; i <= n - 1; i++) {
20741
+ sum2 = Math.abs(d[dOff + (i - 1)]) + Math.abs(e[eOff + (i - 1)]) + Math.abs(e[eOff + (i - 2)]);
20742
+ if (anorm < sum2 || Number.isNaN(sum2)) anorm = sum2;
20743
+ }
20744
+ }
20745
+ } else if (norm2 === NORM_FRO2) {
20746
+ const scale = { val: 0 };
20747
+ const sum2 = { val: 1 };
20748
+ if (n > 1) {
20749
+ dlassq(n - 1, e, eOff, 1, scale, sum2);
20750
+ sum2.val = 2 * sum2.val;
20751
+ }
20752
+ dlassq(n, d, dOff, 1, scale, sum2);
20753
+ anorm = scale.val * Math.sqrt(sum2.val);
20754
+ }
20755
+ return anorm;
20756
+ }
20757
+
20758
+ // src/ts-lapack/src/SRC/dlae2.ts
20759
+ function dlae2(a, b, c) {
20760
+ const ONE10 = 1;
20761
+ const TWO = 2;
20762
+ const HALF = 0.5;
20763
+ const sm = a + c;
20764
+ const df = a - c;
20765
+ const adf = Math.abs(df);
20766
+ const tb = b + b;
20767
+ const ab = Math.abs(tb);
20768
+ let acmx, acmn;
20769
+ if (Math.abs(a) > Math.abs(c)) {
20770
+ acmx = a;
20771
+ acmn = c;
20772
+ } else {
20773
+ acmx = c;
20774
+ acmn = a;
20775
+ }
20776
+ let rt;
20777
+ if (adf > ab) {
20778
+ rt = adf * Math.sqrt(ONE10 + (ab / adf) ** 2);
20779
+ } else if (adf < ab) {
20780
+ rt = ab * Math.sqrt(ONE10 + (adf / ab) ** 2);
20781
+ } else {
20782
+ rt = ab * Math.sqrt(TWO);
20783
+ }
20784
+ let rt1, rt2;
20785
+ if (sm < 0) {
20786
+ rt1 = HALF * (sm - rt);
20787
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
20788
+ } else if (sm > 0) {
20789
+ rt1 = HALF * (sm + rt);
20790
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
20791
+ } else {
20792
+ rt1 = HALF * rt;
20793
+ rt2 = -HALF * rt;
20794
+ }
20795
+ return { rt1, rt2 };
20796
+ }
20797
+
20798
+ // src/ts-lapack/src/SRC/dlaev2.ts
20799
+ function dlaev2(a, b, c) {
20800
+ const ONE10 = 1;
20801
+ const TWO = 2;
20802
+ const HALF = 0.5;
20803
+ const sm = a + c;
20804
+ const df = a - c;
20805
+ const adf = Math.abs(df);
20806
+ const tb = b + b;
20807
+ const ab = Math.abs(tb);
20808
+ let acmx, acmn;
20809
+ if (Math.abs(a) > Math.abs(c)) {
20810
+ acmx = a;
20811
+ acmn = c;
20812
+ } else {
20813
+ acmx = c;
20814
+ acmn = a;
20815
+ }
20816
+ let rt;
20817
+ if (adf > ab) {
20818
+ rt = adf * Math.sqrt(ONE10 + (ab / adf) ** 2);
20819
+ } else if (adf < ab) {
20820
+ rt = ab * Math.sqrt(ONE10 + (adf / ab) ** 2);
20821
+ } else {
20822
+ rt = ab * Math.sqrt(TWO);
20823
+ }
20824
+ let rt1, rt2, sgn1;
20825
+ if (sm < 0) {
20826
+ rt1 = HALF * (sm - rt);
20827
+ sgn1 = -1;
20828
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
20829
+ } else if (sm > 0) {
20830
+ rt1 = HALF * (sm + rt);
20831
+ sgn1 = 1;
20832
+ rt2 = acmx / rt1 * acmn - b / rt1 * b;
20833
+ } else {
20834
+ rt1 = HALF * rt;
20835
+ rt2 = -HALF * rt;
20836
+ sgn1 = 1;
20837
+ }
20838
+ let cs, sgn2;
20839
+ if (df >= 0) {
20840
+ cs = df + rt;
20841
+ sgn2 = 1;
20842
+ } else {
20843
+ cs = df - rt;
20844
+ sgn2 = -1;
20845
+ }
20846
+ let cs1, sn1;
20847
+ const acs = Math.abs(cs);
20848
+ if (acs > ab) {
20849
+ const ct = -tb / cs;
20850
+ sn1 = ONE10 / Math.sqrt(ONE10 + ct * ct);
20851
+ cs1 = ct * sn1;
20852
+ } else {
20853
+ if (ab === 0) {
20854
+ cs1 = ONE10;
20855
+ sn1 = 0;
20856
+ } else {
20857
+ const tn = -cs / tb;
20858
+ cs1 = ONE10 / Math.sqrt(ONE10 + tn * tn);
20859
+ sn1 = tn * cs1;
20860
+ }
20861
+ }
20862
+ if (sgn1 === sgn2) {
20863
+ const tn = cs1;
20864
+ cs1 = -sn1;
20865
+ sn1 = tn;
20866
+ }
20867
+ return { rt1, rt2, cs1, sn1 };
20868
+ }
20869
+
20870
+ // src/ts-lapack/src/SRC/dlasrt.ts
20871
+ function dlasrt(id, n, d, dOff) {
20872
+ const SELECT = 20;
20873
+ let info = 0;
20874
+ let dir = -1;
20875
+ if (id === SORT_DEC) {
20876
+ dir = 0;
20877
+ } else if (id === SORT_INC) {
20878
+ dir = 1;
20879
+ }
20880
+ if (dir === -1) {
20881
+ info = -1;
20882
+ } else if (n < 0) {
20883
+ info = -2;
20884
+ }
20885
+ if (info !== 0) {
20886
+ return info;
20887
+ }
20888
+ if (n <= 1) {
20889
+ return 0;
20890
+ }
20891
+ const stack1 = new Int32Array(33);
20892
+ const stack2 = new Int32Array(33);
20893
+ let stkpnt = 1;
20894
+ stack1[1] = 1;
20895
+ stack2[1] = n;
20896
+ while (stkpnt > 0) {
20897
+ const start = stack1[stkpnt];
20898
+ const endd = stack2[stkpnt];
20899
+ stkpnt--;
20900
+ if (endd - start <= SELECT && endd - start > 0) {
20901
+ if (dir === 0) {
20902
+ for (let i = start + 1; i <= endd; i++) {
20903
+ for (let j = i; j >= start + 1; j--) {
20904
+ if (d[dOff + (j - 1)] > d[dOff + (j - 2)]) {
20905
+ const dmnmx = d[dOff + (j - 1)];
20906
+ d[dOff + (j - 1)] = d[dOff + (j - 2)];
20907
+ d[dOff + (j - 2)] = dmnmx;
20908
+ } else {
20909
+ break;
20910
+ }
20911
+ }
20912
+ }
20913
+ } else {
20914
+ for (let i = start + 1; i <= endd; i++) {
20915
+ for (let j = i; j >= start + 1; j--) {
20916
+ if (d[dOff + (j - 1)] < d[dOff + (j - 2)]) {
20917
+ const dmnmx = d[dOff + (j - 1)];
20918
+ d[dOff + (j - 1)] = d[dOff + (j - 2)];
20919
+ d[dOff + (j - 2)] = dmnmx;
20920
+ } else {
20921
+ break;
20922
+ }
20923
+ }
20924
+ }
20925
+ }
20926
+ } else if (endd - start > SELECT) {
20927
+ const d1 = d[dOff + (start - 1)];
20928
+ const d2 = d[dOff + (endd - 1)];
20929
+ const ii = Math.trunc((start + endd) / 2);
20930
+ const d3 = d[dOff + (ii - 1)];
20931
+ let dmnmx;
20932
+ if (d1 < d2) {
20933
+ if (d3 < d1) {
20934
+ dmnmx = d1;
20935
+ } else if (d3 < d2) {
20936
+ dmnmx = d3;
20937
+ } else {
20938
+ dmnmx = d2;
20939
+ }
20940
+ } else {
20941
+ if (d3 < d2) {
20942
+ dmnmx = d2;
20943
+ } else if (d3 < d1) {
20944
+ dmnmx = d3;
20945
+ } else {
20946
+ dmnmx = d1;
20947
+ }
20948
+ }
20949
+ let i;
20950
+ let j;
20951
+ if (dir === 0) {
20952
+ i = start - 1;
20953
+ j = endd + 1;
20954
+ while (true) {
20955
+ do {
20956
+ j--;
20957
+ } while (d[dOff + (j - 1)] < dmnmx);
20958
+ do {
20959
+ i++;
20960
+ } while (d[dOff + (i - 1)] > dmnmx);
20961
+ if (i < j) {
20962
+ const tmp = d[dOff + (i - 1)];
20963
+ d[dOff + (i - 1)] = d[dOff + (j - 1)];
20964
+ d[dOff + (j - 1)] = tmp;
20965
+ } else {
20966
+ break;
20967
+ }
20968
+ }
20969
+ if (j - start > endd - j - 1) {
20970
+ stkpnt++;
20971
+ stack1[stkpnt] = start;
20972
+ stack2[stkpnt] = j;
20973
+ stkpnt++;
20974
+ stack1[stkpnt] = j + 1;
20975
+ stack2[stkpnt] = endd;
20976
+ } else {
20977
+ stkpnt++;
20978
+ stack1[stkpnt] = j + 1;
20979
+ stack2[stkpnt] = endd;
20980
+ stkpnt++;
20981
+ stack1[stkpnt] = start;
20982
+ stack2[stkpnt] = j;
20983
+ }
20984
+ } else {
20985
+ i = start - 1;
20986
+ j = endd + 1;
20987
+ while (true) {
20988
+ do {
20989
+ j--;
20990
+ } while (d[dOff + (j - 1)] > dmnmx);
20991
+ do {
20992
+ i++;
20993
+ } while (d[dOff + (i - 1)] < dmnmx);
20994
+ if (i < j) {
20995
+ const tmp = d[dOff + (i - 1)];
20996
+ d[dOff + (i - 1)] = d[dOff + (j - 1)];
20997
+ d[dOff + (j - 1)] = tmp;
20998
+ } else {
20999
+ break;
21000
+ }
21001
+ }
21002
+ if (j - start > endd - j - 1) {
21003
+ stkpnt++;
21004
+ stack1[stkpnt] = start;
21005
+ stack2[stkpnt] = j;
21006
+ stkpnt++;
21007
+ stack1[stkpnt] = j + 1;
21008
+ stack2[stkpnt] = endd;
21009
+ } else {
21010
+ stkpnt++;
21011
+ stack1[stkpnt] = j + 1;
21012
+ stack2[stkpnt] = endd;
21013
+ stkpnt++;
21014
+ stack1[stkpnt] = start;
21015
+ stack2[stkpnt] = j;
21016
+ }
21017
+ }
21018
+ }
21019
+ }
21020
+ return 0;
21021
+ }
21022
+
21023
+ // src/ts-lapack/src/SRC/dsteqr.ts
21024
+ var COMPZ_N = 0;
21025
+ var COMPZ_V = 1;
21026
+ var COMPZ_I = 2;
21027
+ var NORM_MAX6 = 0;
21028
+ var TYPE_G3 = 0;
21029
+ var UPLO_FULL2 = -1;
21030
+ function fsign6(a, b) {
21031
+ return b >= 0 ? Math.abs(a) : -Math.abs(a);
21032
+ }
21033
+ function dsteqr(compz, n, d, dOff, e, eOff, z, zOff, ldz, work, workOff) {
21034
+ const ZERO9 = 0;
21035
+ const ONE10 = 1;
21036
+ const TWO = 2;
21037
+ const THREE = 3;
21038
+ const MAXIT = 30;
21039
+ let info = 0;
21040
+ if (compz !== COMPZ_N && compz !== COMPZ_V && compz !== COMPZ_I) {
21041
+ info = -1;
21042
+ } else if (n < 0) {
21043
+ info = -2;
21044
+ } else if (ldz < 1 || compz > 0 && ldz < Math.max(1, n)) {
21045
+ info = -6;
21046
+ }
21047
+ if (info !== 0) {
21048
+ xerbla("DSTEQR", -info);
21049
+ return info;
21050
+ }
21051
+ if (n === 0) return 0;
21052
+ if (n === 1) {
21053
+ if (compz === COMPZ_I) z[zOff] = ONE10;
21054
+ return 0;
21055
+ }
21056
+ const D = (i) => dOff + (i - 1);
21057
+ const E = (i) => eOff + (i - 1);
21058
+ const Zc = (j) => zOff + (j - 1) * ldz;
21059
+ const W = (i) => workOff + (i - 1);
21060
+ const eps2 = dlamch(MACH_EPS);
21061
+ const eps22 = eps2 * eps2;
21062
+ const safmin = dlamch(MACH_SFMIN);
21063
+ const safmax = ONE10 / safmin;
21064
+ const ssfmax = Math.sqrt(safmax) / THREE;
21065
+ const ssfmin = Math.sqrt(safmin) / eps22;
21066
+ if (compz === COMPZ_I) dlaset(UPLO_FULL2, n, n, ZERO9, ONE10, z, zOff, ldz);
21067
+ const nmaxit = n * MAXIT;
21068
+ let jtot = 0;
21069
+ let l1 = 1;
21070
+ const nm1 = n - 1;
21071
+ let ordered = false;
21072
+ outer: for (; ; ) {
21073
+ if (l1 > n) {
21074
+ ordered = true;
21075
+ break outer;
21076
+ }
21077
+ if (l1 > 1) e[E(l1 - 1)] = ZERO9;
21078
+ let m = n;
21079
+ if (l1 <= nm1) {
21080
+ let split = false;
21081
+ for (m = l1; m <= nm1; m++) {
21082
+ const tst = Math.abs(e[E(m)]);
21083
+ if (tst === ZERO9) {
21084
+ split = true;
21085
+ break;
21086
+ }
21087
+ if (tst <= Math.sqrt(Math.abs(d[D(m)])) * Math.sqrt(Math.abs(d[D(m + 1)])) * eps2) {
21088
+ e[E(m)] = ZERO9;
21089
+ split = true;
21090
+ break;
21091
+ }
21092
+ }
21093
+ if (!split) m = n;
21094
+ }
21095
+ let l = l1;
21096
+ const lsv = l;
21097
+ let lend = m;
21098
+ const lendsv = lend;
21099
+ l1 = m + 1;
21100
+ if (lend === l) continue outer;
21101
+ const anorm = dlanst(NORM_MAX6, lend - l + 1, d, D(l), e, E(l));
21102
+ let iscale = 0;
21103
+ if (anorm === ZERO9) continue outer;
21104
+ if (anorm > ssfmax) {
21105
+ iscale = 1;
21106
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmax, lend - l + 1, 1, d, D(l), n);
21107
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmax, lend - l, 1, e, E(l), n);
21108
+ } else if (anorm < ssfmin) {
21109
+ iscale = 2;
21110
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmin, lend - l + 1, 1, d, D(l), n);
21111
+ dlascl(TYPE_G3, 0, 0, anorm, ssfmin, lend - l, 1, e, E(l), n);
21112
+ }
21113
+ if (Math.abs(d[D(lend)]) < Math.abs(d[D(l)])) {
21114
+ lend = lsv;
21115
+ l = lendsv;
21116
+ }
21117
+ if (lend > l) {
21118
+ ql: for (; ; ) {
21119
+ if (l !== lend) {
21120
+ let found = false;
21121
+ for (m = l; m <= lend - 1; m++) {
21122
+ const tst = Math.abs(e[E(m)]) ** 2;
21123
+ if (tst <= eps22 * Math.abs(d[D(m)]) * Math.abs(d[D(m + 1)]) + safmin) {
21124
+ found = true;
21125
+ break;
21126
+ }
21127
+ }
21128
+ if (!found) m = lend;
21129
+ } else {
21130
+ m = lend;
21131
+ }
21132
+ if (m < lend) e[E(m)] = ZERO9;
21133
+ let p2 = d[D(l)];
21134
+ if (m === l) {
21135
+ d[D(l)] = p2;
21136
+ l = l + 1;
21137
+ if (l <= lend) continue ql;
21138
+ break ql;
21139
+ }
21140
+ if (m === l + 1) {
21141
+ if (compz > 0) {
21142
+ const r2 = dlaev2(d[D(l)], e[E(l)], d[D(l + 1)]);
21143
+ work[W(l)] = r2.cs1;
21144
+ work[W(n - 1 + l)] = r2.sn1;
21145
+ dlasr(
21146
+ RIGHT,
21147
+ PIVOT_V,
21148
+ DIRECT_B,
21149
+ n,
21150
+ 2,
21151
+ work,
21152
+ W(l),
21153
+ work,
21154
+ W(n - 1 + l),
21155
+ z,
21156
+ Zc(l),
21157
+ ldz
21158
+ );
21159
+ d[D(l)] = r2.rt1;
21160
+ d[D(l + 1)] = r2.rt2;
21161
+ } else {
21162
+ const r2 = dlae2(d[D(l)], e[E(l)], d[D(l + 1)]);
21163
+ d[D(l)] = r2.rt1;
21164
+ d[D(l + 1)] = r2.rt2;
21165
+ }
21166
+ e[E(l)] = ZERO9;
21167
+ l = l + 2;
21168
+ if (l <= lend) continue ql;
21169
+ break ql;
21170
+ }
21171
+ if (jtot === nmaxit) break ql;
21172
+ jtot = jtot + 1;
21173
+ let g = (d[D(l + 1)] - p2) / (TWO * e[E(l)]);
21174
+ let r = dlapy2(g, ONE10);
21175
+ g = d[D(m)] - p2 + e[E(l)] / (g + fsign6(r, g));
21176
+ let s = ONE10;
21177
+ let c = ONE10;
21178
+ p2 = ZERO9;
21179
+ for (let i = m - 1; i >= l; i--) {
21180
+ const f = s * e[E(i)];
21181
+ const b = c * e[E(i)];
21182
+ const rot = dlartg(g, f);
21183
+ c = rot.cs;
21184
+ s = rot.sn;
21185
+ r = rot.r;
21186
+ if (i !== m - 1) e[E(i + 1)] = r;
21187
+ g = d[D(i + 1)] - p2;
21188
+ r = (d[D(i)] - g) * s + TWO * c * b;
21189
+ p2 = s * r;
21190
+ d[D(i + 1)] = g + p2;
21191
+ g = c * r - b;
21192
+ if (compz > 0) {
21193
+ work[W(i)] = c;
21194
+ work[W(n - 1 + i)] = -s;
21195
+ }
21196
+ }
21197
+ if (compz > 0) {
21198
+ const mm = m - l + 1;
21199
+ dlasr(
21200
+ RIGHT,
21201
+ PIVOT_V,
21202
+ DIRECT_B,
21203
+ n,
21204
+ mm,
21205
+ work,
21206
+ W(l),
21207
+ work,
21208
+ W(n - 1 + l),
21209
+ z,
21210
+ Zc(l),
21211
+ ldz
21212
+ );
21213
+ }
21214
+ d[D(l)] = d[D(l)] - p2;
21215
+ e[E(l)] = g;
21216
+ continue ql;
21217
+ }
21218
+ } else {
21219
+ qr: for (; ; ) {
21220
+ if (l !== lend) {
21221
+ let found = false;
21222
+ for (m = l; m >= lend + 1; m--) {
21223
+ const tst = Math.abs(e[E(m - 1)]) ** 2;
21224
+ if (tst <= eps22 * Math.abs(d[D(m)]) * Math.abs(d[D(m - 1)]) + safmin) {
21225
+ found = true;
21226
+ break;
21227
+ }
21228
+ }
21229
+ if (!found) m = lend;
21230
+ } else {
21231
+ m = lend;
21232
+ }
21233
+ if (m > lend) e[E(m - 1)] = ZERO9;
21234
+ let p2 = d[D(l)];
21235
+ if (m === l) {
21236
+ d[D(l)] = p2;
21237
+ l = l - 1;
21238
+ if (l >= lend) continue qr;
21239
+ break qr;
21240
+ }
21241
+ if (m === l - 1) {
21242
+ if (compz > 0) {
21243
+ const r2 = dlaev2(d[D(l - 1)], e[E(l - 1)], d[D(l)]);
21244
+ work[W(m)] = r2.cs1;
21245
+ work[W(n - 1 + m)] = r2.sn1;
21246
+ dlasr(
21247
+ RIGHT,
21248
+ PIVOT_V,
21249
+ DIRECT_F,
21250
+ n,
21251
+ 2,
21252
+ work,
21253
+ W(m),
21254
+ work,
21255
+ W(n - 1 + m),
21256
+ z,
21257
+ Zc(l - 1),
21258
+ ldz
21259
+ );
21260
+ d[D(l - 1)] = r2.rt1;
21261
+ d[D(l)] = r2.rt2;
21262
+ } else {
21263
+ const r2 = dlae2(d[D(l - 1)], e[E(l - 1)], d[D(l)]);
21264
+ d[D(l - 1)] = r2.rt1;
21265
+ d[D(l)] = r2.rt2;
21266
+ }
21267
+ e[E(l - 1)] = ZERO9;
21268
+ l = l - 2;
21269
+ if (l >= lend) continue qr;
21270
+ break qr;
21271
+ }
21272
+ if (jtot === nmaxit) break qr;
21273
+ jtot = jtot + 1;
21274
+ let g = (d[D(l - 1)] - p2) / (TWO * e[E(l - 1)]);
21275
+ let r = dlapy2(g, ONE10);
21276
+ g = d[D(m)] - p2 + e[E(l - 1)] / (g + fsign6(r, g));
21277
+ let s = ONE10;
21278
+ let c = ONE10;
21279
+ p2 = ZERO9;
21280
+ for (let i = m; i <= l - 1; i++) {
21281
+ const f = s * e[E(i)];
21282
+ const b = c * e[E(i)];
21283
+ const rot = dlartg(g, f);
21284
+ c = rot.cs;
21285
+ s = rot.sn;
21286
+ r = rot.r;
21287
+ if (i !== m) e[E(i - 1)] = r;
21288
+ g = d[D(i)] - p2;
21289
+ r = (d[D(i + 1)] - g) * s + TWO * c * b;
21290
+ p2 = s * r;
21291
+ d[D(i)] = g + p2;
21292
+ g = c * r - b;
21293
+ if (compz > 0) {
21294
+ work[W(i)] = c;
21295
+ work[W(n - 1 + i)] = s;
21296
+ }
21297
+ }
21298
+ if (compz > 0) {
21299
+ const mm = l - m + 1;
21300
+ dlasr(
21301
+ RIGHT,
21302
+ PIVOT_V,
21303
+ DIRECT_F,
21304
+ n,
21305
+ mm,
21306
+ work,
21307
+ W(m),
21308
+ work,
21309
+ W(n - 1 + m),
21310
+ z,
21311
+ Zc(m),
21312
+ ldz
21313
+ );
21314
+ }
21315
+ d[D(l)] = d[D(l)] - p2;
21316
+ e[E(l - 1)] = g;
21317
+ continue qr;
21318
+ }
21319
+ }
21320
+ if (iscale === 1) {
21321
+ dlascl(TYPE_G3, 0, 0, ssfmax, anorm, lendsv - lsv + 1, 1, d, D(lsv), n);
21322
+ dlascl(TYPE_G3, 0, 0, ssfmax, anorm, lendsv - lsv, 1, e, E(lsv), n);
21323
+ } else if (iscale === 2) {
21324
+ dlascl(TYPE_G3, 0, 0, ssfmin, anorm, lendsv - lsv + 1, 1, d, D(lsv), n);
21325
+ dlascl(TYPE_G3, 0, 0, ssfmin, anorm, lendsv - lsv, 1, e, E(lsv), n);
21326
+ }
21327
+ if (jtot < nmaxit) continue outer;
21328
+ for (let i = 1; i <= n - 1; i++) {
21329
+ if (e[E(i)] !== ZERO9) info = info + 1;
21330
+ }
21331
+ break outer;
21332
+ }
21333
+ if (!ordered) return info;
21334
+ if (compz === COMPZ_N) {
21335
+ const sortInfo = dlasrt(SORT_INC, n, d, dOff);
21336
+ if (sortInfo !== 0) return sortInfo;
21337
+ } else {
21338
+ for (let ii = 2; ii <= n; ii++) {
21339
+ const i = ii - 1;
21340
+ let k = i;
21341
+ let p2 = d[D(i)];
21342
+ for (let j = ii; j <= n; j++) {
21343
+ if (d[D(j)] < p2) {
21344
+ k = j;
21345
+ p2 = d[D(j)];
21346
+ }
21347
+ }
21348
+ if (k !== i) {
21349
+ d[D(k)] = d[D(i)];
21350
+ d[D(i)] = p2;
21351
+ dswap(n, z, Zc(i), 1, z, Zc(k), 1);
21352
+ }
21353
+ }
21354
+ }
21355
+ return info;
21356
+ }
21357
+
21358
+ // src/numbl-core/native/ts-lapack-eig-hermitian.ts
21359
+ var EPS2 = 2220446049250313e-31;
21360
+ var SAFMIN2 = 22250738585072014e-324;
21361
+ function dlapy3(x, y, z) {
21362
+ const w = Math.max(Math.abs(x), Math.abs(y), Math.abs(z));
21363
+ if (w === 0 || !Number.isFinite(w))
21364
+ return Math.abs(x) + Math.abs(y) + Math.abs(z);
21365
+ return w * Math.sqrt((x / w) ** 2 + (y / w) ** 2 + (z / w) ** 2);
21366
+ }
21367
+ function fsign7(mag2, s) {
21368
+ return s >= 0 ? Math.abs(mag2) : -Math.abs(mag2);
21369
+ }
21370
+ function cdiv2(ar, ai, br, bi) {
21371
+ if (Math.abs(br) >= Math.abs(bi)) {
21372
+ const r2 = bi / br;
21373
+ const t2 = br + bi * r2;
21374
+ return [(ar + ai * r2) / t2, (ai - ar * r2) / t2];
21375
+ }
21376
+ const r = br / bi;
21377
+ const t = br * r + bi;
21378
+ return [(ar * r + ai) / t, (ai * r - ar) / t];
21379
+ }
21380
+ function dznrm2(n, re, im, off, incx) {
21381
+ let scale = 0;
21382
+ let ssq = 1;
21383
+ for (let i = 0, k = off; i < n; i++, k += incx) {
21384
+ for (const v of [re[k], im[k]]) {
21385
+ if (v !== 0) {
21386
+ const a = Math.abs(v);
21387
+ if (scale < a) {
21388
+ ssq = 1 + ssq * (scale / a) ** 2;
21389
+ scale = a;
21390
+ } else {
21391
+ ssq += (a / scale) ** 2;
21392
+ }
21393
+ }
21394
+ }
21395
+ }
21396
+ return scale * Math.sqrt(ssq);
21397
+ }
21398
+ function zlarfg2(n, re, im, off, incx) {
21399
+ if (n <= 0) return { tauRe: 0, tauIm: 0 };
21400
+ let xnorm = dznrm2(n - 1, re, im, off + incx, incx);
21401
+ let alphr = re[off];
21402
+ let alphi = im[off];
21403
+ if (xnorm === 0 && alphi === 0) {
21404
+ return { tauRe: 0, tauIm: 0 };
21405
+ }
21406
+ let beta = -fsign7(dlapy3(alphr, alphi, xnorm), alphr);
21407
+ const safmin = SAFMIN2 / EPS2;
21408
+ const rsafmn = 1 / safmin;
21409
+ let knt = 0;
21410
+ if (Math.abs(beta) < safmin) {
21411
+ do {
21412
+ knt++;
21413
+ for (let i = 1, k = off + incx; i < n; i++, k += incx) {
21414
+ re[k] *= rsafmn;
21415
+ im[k] *= rsafmn;
21416
+ }
21417
+ beta *= rsafmn;
21418
+ alphi *= rsafmn;
21419
+ alphr *= rsafmn;
21420
+ } while (Math.abs(beta) < safmin && knt < 20);
21421
+ xnorm = dznrm2(n - 1, re, im, off + incx, incx);
21422
+ beta = -fsign7(dlapy3(alphr, alphi, xnorm), alphr);
21423
+ }
21424
+ const tauRe = (beta - alphr) / beta;
21425
+ const tauIm = -alphi / beta;
21426
+ const [sr, si] = cdiv2(1, 0, alphr - beta, alphi);
21427
+ for (let i = 1, k = off + incx; i < n; i++, k += incx) {
21428
+ const xr = re[k];
21429
+ const xi = im[k];
21430
+ re[k] = xr * sr - xi * si;
21431
+ im[k] = xr * si + xi * sr;
21432
+ }
21433
+ for (let j = 1; j <= knt; j++) beta *= safmin;
21434
+ re[off] = beta;
21435
+ im[off] = 0;
21436
+ return { tauRe, tauIm };
21437
+ }
21438
+ function zhemvLower(n, alphaRe, alphaIm, aRe, aIm, aOff, lda, xRe, xIm, xOff, yRe, yIm, yOff) {
21439
+ for (let i = 0; i < n; i++) {
21440
+ yRe[yOff + i] = 0;
21441
+ yIm[yOff + i] = 0;
21442
+ }
21443
+ for (let j = 0; j < n; j++) {
21444
+ const xjr = xRe[xOff + j];
21445
+ const xji = xIm[xOff + j];
21446
+ const t1r = alphaRe * xjr - alphaIm * xji;
21447
+ const t1i = alphaRe * xji + alphaIm * xjr;
21448
+ let t2r = 0;
21449
+ let t2i = 0;
21450
+ const col = aOff + j * lda;
21451
+ yRe[yOff + j] += t1r * aRe[col + j];
21452
+ yIm[yOff + j] += t1i * aRe[col + j];
21453
+ for (let i = j + 1; i < n; i++) {
21454
+ const ar = aRe[col + i];
21455
+ const ai = aIm[col + i];
21456
+ yRe[yOff + i] += t1r * ar - t1i * ai;
21457
+ yIm[yOff + i] += t1r * ai + t1i * ar;
21458
+ const xir = xRe[xOff + i];
21459
+ const xii = xIm[xOff + i];
21460
+ t2r += ar * xir + ai * xii;
21461
+ t2i += ar * xii - ai * xir;
21462
+ }
21463
+ yRe[yOff + j] += alphaRe * t2r - alphaIm * t2i;
21464
+ yIm[yOff + j] += alphaRe * t2i + alphaIm * t2r;
21465
+ }
21466
+ }
21467
+ function zher2LowerMinus(n, xRe, xIm, xOff, yRe, yIm, yOff, aRe, aIm, aOff, lda) {
21468
+ for (let j = 0; j < n; j++) {
21469
+ const xjr = xRe[xOff + j];
21470
+ const xji = xIm[xOff + j];
21471
+ const yjr = yRe[yOff + j];
21472
+ const yji = yIm[yOff + j];
21473
+ const col = aOff + j * lda;
21474
+ if (xjr !== 0 || xji !== 0 || yjr !== 0 || yji !== 0) {
21475
+ const t1r = -yjr;
21476
+ const t1i = yji;
21477
+ const t2r = -xjr;
21478
+ const t2i = xji;
21479
+ aRe[col + j] = aRe[col + j] + (xjr * t1r - xji * t1i) + (yjr * t2r - yji * t2i);
21480
+ aIm[col + j] = 0;
21481
+ for (let i = j + 1; i < n; i++) {
21482
+ const xir = xRe[xOff + i];
21483
+ const xii = xIm[xOff + i];
21484
+ const yir = yRe[yOff + i];
21485
+ const yii = yIm[yOff + i];
21486
+ aRe[col + i] += xir * t1r - xii * t1i + (yir * t2r - yii * t2i);
21487
+ aIm[col + i] += xir * t1i + xii * t1r + (yir * t2i + yii * t2r);
21488
+ }
21489
+ } else {
21490
+ aIm[col + j] = 0;
21491
+ }
21492
+ }
21493
+ }
21494
+ function zhetd2Lower(n, aRe, aIm, lda, d, e, tauRe, tauIm) {
21495
+ const wRe = allocFloat64Array(Math.max(1, n));
21496
+ const wIm = allocFloat64Array(Math.max(1, n));
21497
+ for (let i = 1; i <= n - 1; i++) {
21498
+ const off = i + (i - 1) * lda;
21499
+ const t = zlarfg2(n - i, aRe, aIm, off, 1);
21500
+ e[i - 1] = aRe[off];
21501
+ const taur = t.tauRe;
21502
+ const taui = t.tauIm;
21503
+ if (taur !== 0 || taui !== 0) {
21504
+ aRe[off] = 1;
21505
+ aIm[off] = 0;
21506
+ const m = n - i;
21507
+ const a11 = i + i * lda;
21508
+ zhemvLower(m, taur, taui, aRe, aIm, a11, lda, aRe, aIm, off, wRe, wIm, 0);
21509
+ let dr = 0;
21510
+ let di = 0;
21511
+ for (let k = 0; k < m; k++) {
21512
+ const vr = aRe[off + k];
21513
+ const vi = aIm[off + k];
21514
+ dr += wRe[k] * vr + wIm[k] * vi;
21515
+ di += wRe[k] * vi - wIm[k] * vr;
21516
+ }
21517
+ const ar = -0.5 * (taur * dr - taui * di);
21518
+ const ai = -0.5 * (taur * di + taui * dr);
21519
+ for (let k = 0; k < m; k++) {
21520
+ const vr = aRe[off + k];
21521
+ const vi = aIm[off + k];
21522
+ wRe[k] += ar * vr - ai * vi;
21523
+ wIm[k] += ar * vi + ai * vr;
21524
+ }
21525
+ zher2LowerMinus(m, aRe, aIm, off, wRe, wIm, 0, aRe, aIm, a11, lda);
21526
+ } else {
21527
+ const a11 = i + i * lda;
21528
+ aIm[a11] = 0;
21529
+ }
21530
+ aRe[off] = e[i - 1];
21531
+ aIm[off] = 0;
21532
+ d[i - 1] = aRe[i - 1 + (i - 1) * lda];
21533
+ tauRe[i - 1] = taur;
21534
+ tauIm[i - 1] = taui;
21535
+ }
21536
+ d[n - 1] = aRe[n - 1 + (n - 1) * lda];
21537
+ }
21538
+ function zungtrLower(n, aRe, aIm, lda, tauRe, tauIm) {
21539
+ for (let j = n; j >= 2; j--) {
21540
+ aRe[(j - 1) * lda] = 0;
21541
+ aIm[(j - 1) * lda] = 0;
21542
+ for (let i = j + 1; i <= n; i++) {
21543
+ aRe[i - 1 + (j - 1) * lda] = aRe[i - 1 + (j - 2) * lda];
21544
+ aIm[i - 1 + (j - 1) * lda] = aIm[i - 1 + (j - 2) * lda];
21545
+ }
21546
+ }
21547
+ aRe[0] = 1;
21548
+ aIm[0] = 0;
21549
+ for (let i = 2; i <= n; i++) {
21550
+ aRe[i - 1] = 0;
21551
+ aIm[i - 1] = 0;
21552
+ }
21553
+ if (n <= 1) return;
21554
+ const m = n - 1;
21555
+ const base = 1 + lda;
21556
+ const workRe = allocFloat64Array(Math.max(1, m));
21557
+ const workIm = allocFloat64Array(Math.max(1, m));
21558
+ for (let i = m; i >= 1; i--) {
21559
+ const vOff = base + (i - 1) + (i - 1) * lda;
21560
+ const tr = tauRe[i - 1];
21561
+ const ti = tauIm[i - 1];
21562
+ if (i < m) {
21563
+ aRe[vOff] = 1;
21564
+ aIm[vOff] = 0;
21565
+ const rows = m - i + 1;
21566
+ const cols = m - i;
21567
+ const cOff = base + (i - 1) + i * lda;
21568
+ for (let j = 0; j < cols; j++) {
21569
+ let sr = 0;
21570
+ let si = 0;
21571
+ for (let k = 0; k < rows; k++) {
21572
+ const cr = aRe[cOff + k + j * lda];
21573
+ const ci = aIm[cOff + k + j * lda];
21574
+ const vr = aRe[vOff + k];
21575
+ const vi = aIm[vOff + k];
21576
+ sr += cr * vr + ci * vi;
21577
+ si += cr * vi - ci * vr;
21578
+ }
21579
+ workRe[j] = sr;
21580
+ workIm[j] = si;
21581
+ }
21582
+ for (let j = 0; j < cols; j++) {
21583
+ const wr = workRe[j];
21584
+ const wi = -workIm[j];
21585
+ const fr = -(tr * wr - ti * wi);
21586
+ const fi = -(tr * wi + ti * wr);
21587
+ for (let k = 0; k < rows; k++) {
21588
+ const vr = aRe[vOff + k];
21589
+ const vi = aIm[vOff + k];
21590
+ aRe[cOff + k + j * lda] += fr * vr - fi * vi;
21591
+ aIm[cOff + k + j * lda] += fr * vi + fi * vr;
21592
+ }
21593
+ }
21594
+ }
21595
+ if (i < m) {
21596
+ for (let k = 1; k <= m - i; k++) {
21597
+ const vr = aRe[vOff + k];
21598
+ const vi = aIm[vOff + k];
21599
+ aRe[vOff + k] = -(tr * vr - ti * vi);
21600
+ aIm[vOff + k] = -(tr * vi + ti * vr);
21601
+ }
21602
+ }
21603
+ aRe[vOff] = 1 - tr;
21604
+ aIm[vOff] = -ti;
21605
+ for (let k = 1; k <= i - 1; k++) {
21606
+ aRe[base + (k - 1) + (i - 1) * lda] = 0;
21607
+ aIm[base + (k - 1) + (i - 1) * lda] = 0;
21608
+ }
21609
+ }
21610
+ }
21611
+ function eigHermTs(dataRe, dataIm, n, computeV) {
21612
+ const w = allocFloat64Array(n);
21613
+ if (n === 0)
21614
+ return { w, VRe: allocFloat64Array(0), VIm: allocFloat64Array(0) };
21615
+ if (n === 1) {
21616
+ w[0] = dataRe[0];
21617
+ if (!computeV) return { w };
21618
+ const VRe2 = allocFloat64Array(1);
21619
+ VRe2[0] = 1;
21620
+ return { w, VRe: VRe2, VIm: allocFloat64Array(1) };
21621
+ }
21622
+ const aRe = allocFloat64Array(dataRe);
21623
+ const aIm = allocFloat64Array(dataIm);
21624
+ const e = allocFloat64Array(Math.max(1, n - 1));
21625
+ const tauRe = allocFloat64Array(Math.max(1, n - 1));
21626
+ const tauIm = allocFloat64Array(Math.max(1, n - 1));
21627
+ zhetd2Lower(n, aRe, aIm, n, w, e, tauRe, tauIm);
21628
+ if (!computeV) {
21629
+ const work2 = allocFloat64Array(Math.max(1, 2 * n - 2));
21630
+ const dummy = allocFloat64Array(1);
21631
+ dsteqr(COMPZ_N, n, w, 0, e, 0, dummy, 0, 1, work2, 0);
21632
+ return { w };
21633
+ }
21634
+ zungtrLower(n, aRe, aIm, n, tauRe, tauIm);
21635
+ const S = allocFloat64Array(n * n);
21636
+ const work = allocFloat64Array(Math.max(1, 2 * n - 2));
21637
+ dsteqr(COMPZ_I, n, w, 0, e, 0, S, 0, n, work, 0);
21638
+ const VRe = allocFloat64Array(n * n);
21639
+ const VIm = allocFloat64Array(n * n);
21640
+ for (let j = 0; j < n; j++) {
21641
+ for (let k = 0; k < n; k++) {
21642
+ const s = S[k + j * n];
21643
+ if (s === 0) continue;
21644
+ for (let i = 0; i < n; i++) {
21645
+ VRe[i + j * n] += aRe[i + k * n] * s;
21646
+ VIm[i + j * n] += aIm[i + k * n] * s;
21647
+ }
21648
+ }
21649
+ }
21650
+ return { w, VRe, VIm };
21651
+ }
21652
+
21653
+ // src/ts-lapack/src/SRC/dlansy.ts
21654
+ var NORM_MAX7 = 0;
21655
+ var NORM_ONE3 = 1;
21656
+ var NORM_INF3 = 2;
21657
+ var NORM_FRO3 = 3;
21658
+ function dlansy(norm2, uplo, n, a, aOff, lda, work, workOff) {
21659
+ let value = 0;
21660
+ if (n === 0) {
21661
+ value = 0;
21662
+ } else if (norm2 === NORM_MAX7) {
21663
+ value = 0;
21664
+ if (uplo === UPPER) {
21665
+ for (let j = 1; j <= n; j++) {
21666
+ for (let i = 1; i <= j; i++) {
21667
+ const sum2 = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
21668
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
21669
+ }
21670
+ }
21671
+ } else {
21672
+ for (let j = 1; j <= n; j++) {
21673
+ for (let i = j; i <= n; i++) {
21674
+ const sum2 = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
21675
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
21676
+ }
21677
+ }
21678
+ }
21679
+ } else if (norm2 === NORM_ONE3 || norm2 === NORM_INF3) {
21680
+ value = 0;
21681
+ if (uplo === UPPER) {
21682
+ for (let j = 1; j <= n; j++) {
21683
+ let sum2 = 0;
21684
+ for (let i = 1; i <= j - 1; i++) {
21685
+ const absa = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
21686
+ sum2 += absa;
21687
+ work[workOff + (i - 1)] += absa;
21688
+ }
21689
+ work[workOff + (j - 1)] = sum2 + Math.abs(a[aOff + (j - 1) + (j - 1) * lda]);
21690
+ }
21691
+ for (let i = 1; i <= n; i++) {
21692
+ const sum2 = work[workOff + (i - 1)];
21693
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
21694
+ }
21695
+ } else {
21696
+ for (let i = 1; i <= n; i++) work[workOff + (i - 1)] = 0;
21697
+ for (let j = 1; j <= n; j++) {
21698
+ let sum2 = work[workOff + (j - 1)] + Math.abs(a[aOff + (j - 1) + (j - 1) * lda]);
21699
+ for (let i = j + 1; i <= n; i++) {
21700
+ const absa = Math.abs(a[aOff + (i - 1) + (j - 1) * lda]);
21701
+ sum2 += absa;
21702
+ work[workOff + (i - 1)] += absa;
21703
+ }
21704
+ if (value < sum2 || Number.isNaN(sum2)) value = sum2;
21705
+ }
21706
+ }
21707
+ } else if (norm2 === NORM_FRO3) {
21708
+ const scale = { val: 0 };
21709
+ const sum2 = { val: 1 };
21710
+ if (uplo === UPPER) {
21711
+ for (let j = 2; j <= n; j++) {
21712
+ dlassq(j - 1, a, aOff + (j - 1) * lda, 1, scale, sum2);
21713
+ }
21714
+ } else {
21715
+ for (let j = 1; j <= n - 1; j++) {
21716
+ dlassq(n - j, a, aOff + j + (j - 1) * lda, 1, scale, sum2);
21717
+ }
21718
+ }
21719
+ sum2.val = 2 * sum2.val;
21720
+ dlassq(n, a, aOff, lda + 1, scale, sum2);
21721
+ value = scale.val * Math.sqrt(sum2.val);
21722
+ }
21723
+ return value;
21724
+ }
21725
+
21726
+ // src/ts-lapack/src/BLAS/dsymv.ts
21727
+ function dsymv(uplo, n, alpha, a, aOff, lda, x, xOff, incx, beta, y, yOff, incy) {
21728
+ const ZERO9 = 0;
21729
+ const ONE10 = 1;
21730
+ let info = 0;
21731
+ if (uplo !== UPPER && uplo !== LOWER) {
21732
+ info = 1;
21733
+ } else if (n < 0) {
21734
+ info = 2;
21735
+ } else if (lda < Math.max(1, n)) {
21736
+ info = 5;
21737
+ } else if (incx === 0) {
21738
+ info = 7;
21739
+ } else if (incy === 0) {
21740
+ info = 10;
21741
+ }
21742
+ if (info !== 0) {
21743
+ xerbla("DSYMV ", info);
21744
+ return;
21745
+ }
21746
+ if (n === 0 || alpha === ZERO9 && beta === ONE10) return;
21747
+ const kx = incx > 0 ? 0 : -(n - 1) * incx;
21748
+ const ky = incy > 0 ? 0 : -(n - 1) * incy;
21749
+ if (beta !== ONE10) {
21750
+ let iy = ky;
21751
+ if (beta === ZERO9) {
21752
+ for (let i = 0; i < n; i++) {
21753
+ y[yOff + iy] = ZERO9;
21754
+ iy += incy;
21755
+ }
21756
+ } else {
21757
+ for (let i = 0; i < n; i++) {
21758
+ y[yOff + iy] *= beta;
21759
+ iy += incy;
21760
+ }
21761
+ }
21762
+ }
21763
+ if (alpha === ZERO9) return;
21764
+ if (uplo === UPPER) {
21765
+ let jx = kx;
21766
+ let jy = ky;
21767
+ for (let j = 1; j <= n; j++) {
21768
+ const temp1 = alpha * x[xOff + jx];
21769
+ let temp2 = ZERO9;
21770
+ const aCol = aOff + (j - 1) * lda;
21771
+ let ix = kx;
21772
+ let iy = ky;
21773
+ for (let i = 1; i <= j - 1; i++) {
21774
+ const aij = a[aCol + (i - 1)];
21775
+ y[yOff + iy] += temp1 * aij;
21776
+ temp2 += aij * x[xOff + ix];
21777
+ ix += incx;
21778
+ iy += incy;
21779
+ }
21780
+ y[yOff + jy] += temp1 * a[aCol + (j - 1)] + alpha * temp2;
21781
+ jx += incx;
21782
+ jy += incy;
21783
+ }
21784
+ } else {
21785
+ let jx = kx;
21786
+ let jy = ky;
21787
+ for (let j = 1; j <= n; j++) {
21788
+ const temp1 = alpha * x[xOff + jx];
21789
+ let temp2 = ZERO9;
21790
+ const aCol = aOff + (j - 1) * lda;
21791
+ y[yOff + jy] += temp1 * a[aCol + (j - 1)];
21792
+ let ix = jx;
21793
+ let iy = jy;
21794
+ for (let i = j + 1; i <= n; i++) {
21795
+ ix += incx;
21796
+ iy += incy;
21797
+ const aij = a[aCol + (i - 1)];
21798
+ y[yOff + iy] += temp1 * aij;
21799
+ temp2 += aij * x[xOff + ix];
21800
+ }
21801
+ y[yOff + jy] += alpha * temp2;
21802
+ jx += incx;
21803
+ jy += incy;
21804
+ }
21805
+ }
21806
+ }
21807
+
21808
+ // src/ts-lapack/src/BLAS/dsyr2.ts
21809
+ function dsyr2(uplo, n, alpha, x, xOff, incx, y, yOff, incy, a, aOff, lda) {
21810
+ const ZERO9 = 0;
21811
+ let info = 0;
21812
+ if (uplo !== UPPER && uplo !== LOWER) {
21813
+ info = 1;
21814
+ } else if (n < 0) {
21815
+ info = 2;
21816
+ } else if (incx === 0) {
21817
+ info = 5;
21818
+ } else if (incy === 0) {
21819
+ info = 7;
21820
+ } else if (lda < Math.max(1, n)) {
21821
+ info = 9;
21822
+ }
21823
+ if (info !== 0) {
21824
+ xerbla("DSYR2 ", info);
21825
+ return;
21826
+ }
21827
+ if (n === 0 || alpha === ZERO9) return;
21828
+ const kx = incx > 0 ? 0 : -(n - 1) * incx;
21829
+ const ky = incy > 0 ? 0 : -(n - 1) * incy;
21830
+ let jx = kx;
21831
+ let jy = ky;
21832
+ if (uplo === UPPER) {
21833
+ for (let j = 1; j <= n; j++) {
21834
+ const xj = x[xOff + jx];
21835
+ const yj = y[yOff + jy];
21836
+ if (xj !== ZERO9 || yj !== ZERO9) {
21837
+ const temp1 = alpha * yj;
21838
+ const temp2 = alpha * xj;
21839
+ const aCol = aOff + (j - 1) * lda;
21840
+ let ix = kx;
21841
+ let iy = ky;
21842
+ for (let i = 1; i <= j; i++) {
21843
+ a[aCol + (i - 1)] += x[xOff + ix] * temp1 + y[yOff + iy] * temp2;
21844
+ ix += incx;
21845
+ iy += incy;
21846
+ }
21847
+ }
21848
+ jx += incx;
21849
+ jy += incy;
21850
+ }
21851
+ } else {
21852
+ for (let j = 1; j <= n; j++) {
21853
+ const xj = x[xOff + jx];
21854
+ const yj = y[yOff + jy];
21855
+ if (xj !== ZERO9 || yj !== ZERO9) {
21856
+ const temp1 = alpha * yj;
21857
+ const temp2 = alpha * xj;
21858
+ const aCol = aOff + (j - 1) * lda;
21859
+ let ix = jx;
21860
+ let iy = jy;
21861
+ for (let i = j; i <= n; i++) {
21862
+ a[aCol + (i - 1)] += x[xOff + ix] * temp1 + y[yOff + iy] * temp2;
21863
+ ix += incx;
21864
+ iy += incy;
21865
+ }
21866
+ }
21867
+ jx += incx;
21868
+ jy += incy;
21869
+ }
21870
+ }
21871
+ }
21872
+
21873
+ // src/ts-lapack/src/SRC/dsytd2.ts
21874
+ function dsytd2(uplo, n, a, aOff, lda, d, dOff, e, eOff, tau, tauOff) {
21875
+ const ONE10 = 1;
21876
+ const ZERO9 = 0;
21877
+ const HALF = 0.5;
21878
+ let info = 0;
21879
+ const upper = uplo === UPPER;
21880
+ if (!upper && uplo !== LOWER) {
21881
+ info = -1;
21882
+ } else if (n < 0) {
21883
+ info = -2;
21884
+ } else if (lda < Math.max(1, n)) {
21885
+ info = -4;
21886
+ }
21887
+ if (info !== 0) {
21888
+ xerbla("DSYTD2", -info);
21889
+ return info;
21890
+ }
21891
+ if (n <= 0) return 0;
21892
+ const A = (i, j) => aOff + (i - 1) + (j - 1) * lda;
21893
+ if (upper) {
21894
+ for (let i = n - 1; i >= 1; i--) {
21895
+ const r = dlarfg(i, a[A(i, i + 1)], a, A(1, i + 1), 1);
21896
+ a[A(i, i + 1)] = r.alpha;
21897
+ const taui = r.tau;
21898
+ e[eOff + (i - 1)] = a[A(i, i + 1)];
21899
+ if (taui !== ZERO9) {
21900
+ a[A(i, i + 1)] = ONE10;
21901
+ dsymv(
21902
+ uplo,
21903
+ i,
21904
+ taui,
21905
+ a,
21906
+ aOff,
21907
+ lda,
21908
+ a,
21909
+ A(1, i + 1),
21910
+ 1,
21911
+ ZERO9,
21912
+ tau,
21913
+ tauOff,
21914
+ 1
21915
+ );
21916
+ const alpha = -HALF * taui * ddot(i, tau, tauOff, 1, a, A(1, i + 1), 1);
21917
+ daxpy(i, alpha, a, A(1, i + 1), 1, tau, tauOff, 1);
21918
+ dsyr2(uplo, i, -ONE10, a, A(1, i + 1), 1, tau, tauOff, 1, a, aOff, lda);
21919
+ a[A(i, i + 1)] = e[eOff + (i - 1)];
21920
+ }
21921
+ d[dOff + i] = a[A(i + 1, i + 1)];
21922
+ tau[tauOff + (i - 1)] = taui;
21923
+ }
21924
+ d[dOff] = a[A(1, 1)];
21925
+ } else {
21926
+ for (let i = 1; i <= n - 1; i++) {
21927
+ const r = dlarfg(n - i, a[A(i + 1, i)], a, A(Math.min(i + 2, n), i), 1);
21928
+ a[A(i + 1, i)] = r.alpha;
21929
+ const taui = r.tau;
21930
+ e[eOff + (i - 1)] = a[A(i + 1, i)];
21931
+ if (taui !== ZERO9) {
21932
+ a[A(i + 1, i)] = ONE10;
21933
+ dsymv(
21934
+ uplo,
21935
+ n - i,
21936
+ taui,
21937
+ a,
21938
+ A(i + 1, i + 1),
21939
+ lda,
21940
+ a,
21941
+ A(i + 1, i),
21942
+ 1,
21943
+ ZERO9,
21944
+ tau,
21945
+ tauOff + (i - 1),
21946
+ 1
21947
+ );
21948
+ const alpha = -HALF * taui * ddot(n - i, tau, tauOff + (i - 1), 1, a, A(i + 1, i), 1);
21949
+ daxpy(n - i, alpha, a, A(i + 1, i), 1, tau, tauOff + (i - 1), 1);
21950
+ dsyr2(
21951
+ uplo,
21952
+ n - i,
21953
+ -ONE10,
21954
+ a,
21955
+ A(i + 1, i),
21956
+ 1,
21957
+ tau,
21958
+ tauOff + (i - 1),
21959
+ 1,
21960
+ a,
21961
+ A(i + 1, i + 1),
21962
+ lda
21963
+ );
21964
+ a[A(i + 1, i)] = e[eOff + (i - 1)];
21965
+ }
21966
+ d[dOff + (i - 1)] = a[A(i, i)];
21967
+ tau[tauOff + (i - 1)] = taui;
21968
+ }
21969
+ d[dOff + (n - 1)] = a[A(n, n)];
21970
+ }
21971
+ return 0;
21972
+ }
21973
+
21974
+ // src/ts-lapack/src/SRC/dorgtr.ts
21975
+ function dorgtr(uplo, n, a, aOff, lda, tau, tauOff) {
21976
+ const ONE10 = 1;
21977
+ const ZERO9 = 0;
21978
+ let info = 0;
21979
+ if (uplo !== LOWER) {
21980
+ info = -1;
21981
+ } else if (n < 0) {
21982
+ info = -2;
21983
+ } else if (lda < Math.max(1, n)) {
21984
+ info = -4;
21985
+ }
21986
+ if (info !== 0) {
21987
+ xerbla("DORGTR", -info);
21988
+ return info;
21989
+ }
21990
+ if (n === 0) return 0;
21991
+ const A = (i, j) => aOff + (i - 1) + (j - 1) * lda;
21992
+ for (let j = n; j >= 2; j--) {
21993
+ a[A(1, j)] = ZERO9;
21994
+ for (let i = j + 1; i <= n; i++) {
21995
+ a[A(i, j)] = a[A(i, j - 1)];
21996
+ }
21997
+ }
21998
+ a[A(1, 1)] = ONE10;
21999
+ for (let i = 2; i <= n; i++) {
22000
+ a[A(i, 1)] = ZERO9;
22001
+ }
22002
+ if (n > 1) {
22003
+ info = dorgqr(n - 1, n - 1, n - 1, a, A(2, 2), lda, tau, tauOff);
22004
+ }
22005
+ return info;
22006
+ }
22007
+
22008
+ // src/ts-lapack/src/SRC/dsyev.ts
22009
+ var NORM_MAX8 = 0;
22010
+ var TYPE_L2 = 1;
22011
+ function dsyev(wantz, uplo, n, a, aOff, lda, w, wOff) {
22012
+ const ONE10 = 1;
22013
+ const ZERO9 = 0;
22014
+ let info = 0;
22015
+ if (uplo !== LOWER) {
22016
+ info = -2;
22017
+ } else if (n < 0) {
22018
+ info = -3;
22019
+ } else if (lda < Math.max(1, n)) {
22020
+ info = -5;
22021
+ }
22022
+ if (info !== 0) {
22023
+ xerbla("DSYEV ", -info);
22024
+ return info;
22025
+ }
22026
+ if (n === 0) return 0;
22027
+ if (n === 1) {
22028
+ w[wOff] = a[aOff];
22029
+ if (wantz) a[aOff] = ONE10;
22030
+ return 0;
22031
+ }
22032
+ const safmin = dlamch(MACH_SFMIN);
22033
+ const eps2 = dlamch(MACH_PREC);
22034
+ const smlnum = safmin / eps2;
22035
+ const bignum = ONE10 / smlnum;
22036
+ const rmin = Math.sqrt(smlnum);
22037
+ const rmax = Math.sqrt(bignum);
22038
+ const work = allocFloat64Array(Math.max(1, 3 * n));
22039
+ const anrm = dlansy(NORM_MAX8, uplo, n, a, aOff, lda, work, 0);
22040
+ let iscale = 0;
22041
+ let sigma = ONE10;
22042
+ if (anrm > ZERO9 && anrm < rmin) {
22043
+ iscale = 1;
22044
+ sigma = rmin / anrm;
22045
+ } else if (anrm > rmax) {
22046
+ iscale = 1;
22047
+ sigma = rmax / anrm;
22048
+ }
22049
+ if (iscale === 1) dlascl(TYPE_L2, 0, 0, ONE10, sigma, n, n, a, aOff, lda);
22050
+ const e = allocFloat64Array(Math.max(1, n - 1));
22051
+ const tau = allocFloat64Array(Math.max(1, n - 1));
22052
+ dsytd2(uplo, n, a, aOff, lda, w, wOff, e, 0, tau, 0);
22053
+ if (!wantz) {
22054
+ info = dsteqr(COMPZ_N, n, w, wOff, e, 0, a, aOff, lda, work, 0);
22055
+ } else {
22056
+ const iinfo = dorgtr(uplo, n, a, aOff, lda, tau, 0);
22057
+ if (iinfo !== 0) return iinfo;
22058
+ info = dsteqr(COMPZ_V, n, w, wOff, e, 0, a, aOff, lda, work, 0);
22059
+ }
22060
+ if (iscale === 1) {
22061
+ const imax = info === 0 ? n : info - 1;
22062
+ dscal(imax, ONE10 / sigma, w, wOff, 1);
22063
+ }
22064
+ return info;
22065
+ }
22066
+
20696
22067
  // src/numbl-core/native/ts-lapack-bridge.ts
20697
22068
  function inv(data, n) {
20698
22069
  const a = allocFloat64Array(data);
@@ -20866,6 +22237,20 @@ function linsolve(A, m, n, B, nrhs) {
20866
22237
  return x;
20867
22238
  }
20868
22239
  }
22240
+ function eigSym(data, n, computeV) {
22241
+ const a = allocFloat64Array(data);
22242
+ const w = allocFloat64Array(n);
22243
+ const info = dsyev(computeV, LOWER, n, a, 0, n, w, 0);
22244
+ if (info !== 0) {
22245
+ throw new Error(
22246
+ info < 0 ? "eig: illegal argument passed to dsyev" : "QR algorithm failed to converge in dsyev"
22247
+ );
22248
+ }
22249
+ return computeV ? { w, V: a } : { w };
22250
+ }
22251
+ function eigHerm(dataRe, dataIm, n, computeV) {
22252
+ return eigHermTs(dataRe, dataIm, n, computeV);
22253
+ }
20869
22254
  function eig(data, n, computeVL, computeVR, balance) {
20870
22255
  const a = allocFloat64Array(data);
20871
22256
  const wr = allocFloat64Array(n);
@@ -21604,7 +22989,9 @@ var _bridge2 = {
21604
22989
  linsolve,
21605
22990
  linsolveComplex,
21606
22991
  eig,
22992
+ eigSym,
21607
22993
  eigComplex: eigComplexTs,
22994
+ eigHerm,
21608
22995
  lu,
21609
22996
  svd,
21610
22997
  chol,
@@ -22053,6 +23440,7 @@ function formatClassInstance(v) {
22053
23440
  const lines = [` ${v.className} with properties:
22054
23441
  `];
22055
23442
  for (const [key, val] of v.fields) {
23443
+ if (key.startsWith("_")) continue;
22056
23444
  lines.push(` ${key}: ${displayValue(val)}`);
22057
23445
  }
22058
23446
  return lines.join("\n");
@@ -27756,6 +29144,707 @@ function sprintfFormat(fmt, args) {
27756
29144
  return result;
27757
29145
  }
27758
29146
 
29147
+ // src/numbl-core/helpers/warn.ts
29148
+ var sink = (msg) => console.warn("Warning: " + msg);
29149
+ function setWarningSink(fn) {
29150
+ sink = fn;
29151
+ }
29152
+ function emitWarning(msg) {
29153
+ sink(msg);
29154
+ }
29155
+
29156
+ // src/numbl-core/helpers/sparse-direct.ts
29157
+ var SINGULAR_WARNING = "Matrix is singular to working precision.";
29158
+ function denseToSparse(t) {
29159
+ const m = t.shape[0] ?? 1;
29160
+ const n = t.shape.length >= 2 ? t.shape[1] : 1;
29161
+ const irList = [];
29162
+ const prList = [];
29163
+ const piList = t.imag ? [] : void 0;
29164
+ const jc = new Int32Array(n + 1);
29165
+ for (let c = 0; c < n; c++) {
29166
+ jc[c] = irList.length;
29167
+ for (let r = 0; r < m; r++) {
29168
+ const idx = c * m + r;
29169
+ const re = t.data[idx];
29170
+ const im = t.imag ? t.imag[idx] : 0;
29171
+ if (re !== 0 || im !== 0) {
29172
+ irList.push(r);
29173
+ prList.push(re);
29174
+ if (piList) piList.push(im);
29175
+ }
29176
+ }
29177
+ }
29178
+ jc[n] = irList.length;
29179
+ return RTV.sparseMatrix(
29180
+ m,
29181
+ n,
29182
+ new Int32Array(irList),
29183
+ jc,
29184
+ allocFloat64Array(prList),
29185
+ piList ? allocFloat64Array(piList) : void 0
29186
+ );
29187
+ }
29188
+ function denseDataToSparse(data, m, n) {
29189
+ return denseToSparse(RTV.tensor(data, [m, n]));
29190
+ }
29191
+ function fromUnsortedColumns(m, n, ir, jc, pr) {
29192
+ return sparseTranspose(sparseTranspose(RTV.sparseMatrix(m, n, ir, jc, pr)));
29193
+ }
29194
+ function permutationMatrix(p2) {
29195
+ const n = p2.length;
29196
+ const ir = new Int32Array(n);
29197
+ const jc = new Int32Array(n + 1);
29198
+ const pr = allocFloat64Array(n);
29199
+ for (let k = 0; k < n; k++) jc[p2[k] + 1]++;
29200
+ for (let c = 0; c < n; c++) jc[c + 1] += jc[c];
29201
+ for (let k = 0; k < n; k++) {
29202
+ ir[jc[p2[k]]] = k;
29203
+ pr[jc[p2[k]]] = 1;
29204
+ }
29205
+ return RTV.sparseMatrix(n, n, ir, jc, pr);
29206
+ }
29207
+ function permVectorTensor(p2) {
29208
+ const d = allocFloat64Array(p2.length);
29209
+ for (let i = 0; i < p2.length; i++) d[i] = p2[i] + 1;
29210
+ return RTV.tensor(d, [1, p2.length]);
29211
+ }
29212
+ function invertPerm(p2) {
29213
+ const inv2 = new Int32Array(p2.length);
29214
+ for (let i = 0; i < p2.length; i++) inv2[p2[i]] = i;
29215
+ return inv2;
29216
+ }
29217
+ function sparsePermute(A, p2, q) {
29218
+ const pinv = invertPerm(p2);
29219
+ const nnz = A.jc[A.n];
29220
+ const ir = new Int32Array(nnz);
29221
+ const jc = new Int32Array(A.n + 1);
29222
+ const pr = allocFloat64Array(nnz);
29223
+ let pos = 0;
29224
+ for (let k = 0; k < A.n; k++) {
29225
+ jc[k] = pos;
29226
+ const j = q[k];
29227
+ for (let t = A.jc[j]; t < A.jc[j + 1]; t++) {
29228
+ ir[pos] = pinv[A.ir[t]];
29229
+ pr[pos] = A.pr[t];
29230
+ pos++;
29231
+ }
29232
+ }
29233
+ jc[A.n] = pos;
29234
+ return fromUnsortedColumns(A.m, A.n, ir, jc, pr);
29235
+ }
29236
+ function sparseKron(A, B) {
29237
+ const m = A.m, n = A.n, p2 = B.m, q = B.n;
29238
+ const nnz = A.jc[n] * B.jc[q];
29239
+ const ir = new Int32Array(nnz);
29240
+ const jc = new Int32Array(n * q + 1);
29241
+ const pr = allocFloat64Array(nnz);
29242
+ const cplx = A.pi !== void 0 || B.pi !== void 0;
29243
+ const pi2 = cplx ? allocFloat64Array(nnz) : void 0;
29244
+ let pos = 0;
29245
+ for (let ja = 0; ja < n; ja++) {
29246
+ for (let jb = 0; jb < q; jb++) {
29247
+ jc[ja * q + jb] = pos;
29248
+ for (let ka = A.jc[ja]; ka < A.jc[ja + 1]; ka++) {
29249
+ const rowBase = A.ir[ka] * p2;
29250
+ const aRe = A.pr[ka];
29251
+ const aIm = A.pi ? A.pi[ka] : 0;
29252
+ for (let kb = B.jc[jb]; kb < B.jc[jb + 1]; kb++) {
29253
+ ir[pos] = rowBase + B.ir[kb];
29254
+ const bRe = B.pr[kb];
29255
+ const bIm = B.pi ? B.pi[kb] : 0;
29256
+ pr[pos] = aRe * bRe - aIm * bIm;
29257
+ if (pi2) pi2[pos] = aRe * bIm + aIm * bRe;
29258
+ pos++;
29259
+ }
29260
+ }
29261
+ }
29262
+ }
29263
+ jc[n * q] = pos;
29264
+ return RTV.sparseMatrix(m * p2, n * q, ir, jc, pr, pi2);
29265
+ }
29266
+ function triangularInfo(S) {
29267
+ if (S._triInfo) return S._triInfo;
29268
+ const n = S.n;
29269
+ const ir = S.ir, jc = S.jc, pr = S.pr, pi2 = S.pi;
29270
+ const diagPos = new Int32Array(n).fill(-1);
29271
+ const diag2 = allocFloat64Array(n);
29272
+ let upper = true;
29273
+ let lower = true;
29274
+ for (let j = 0; j < n; j++) {
29275
+ const end = jc[j + 1];
29276
+ for (let k = jc[j]; k < end; k++) {
29277
+ const i = ir[k];
29278
+ if (i === j) {
29279
+ diagPos[j] = k;
29280
+ diag2[j] = pr[k];
29281
+ continue;
29282
+ }
29283
+ if (pr[k] === 0 && (!pi2 || pi2[k] === 0)) continue;
29284
+ if (i > j) upper = false;
29285
+ else lower = false;
29286
+ }
29287
+ }
29288
+ const info = { upper, lower, diagPos, diag: diag2 };
29289
+ S._triInfo = info;
29290
+ return info;
29291
+ }
29292
+ function sparseIsUpper(S) {
29293
+ return triangularInfo(S).upper;
29294
+ }
29295
+ function sparseIsLower(S) {
29296
+ return triangularInfo(S).lower;
29297
+ }
29298
+ function sparseIsSymmetric(S) {
29299
+ if (S.m !== S.n || S.pi) return false;
29300
+ const T = sparseTranspose(S);
29301
+ const nnz = S.jc[S.n];
29302
+ if (T.jc[T.n] !== nnz) return false;
29303
+ for (let j = 0; j <= S.n; j++) if (S.jc[j] !== T.jc[j]) return false;
29304
+ for (let k = 0; k < nnz; k++)
29305
+ if (S.ir[k] !== T.ir[k] || S.pr[k] !== T.pr[k]) return false;
29306
+ return true;
29307
+ }
29308
+ function sparseAt(S, i, j) {
29309
+ let lo = S.jc[j], hi = S.jc[j + 1] - 1;
29310
+ while (lo <= hi) {
29311
+ const mid = lo + hi >> 1;
29312
+ const r = S.ir[mid];
29313
+ if (r === i) return S.pr[mid];
29314
+ if (r < i) lo = mid + 1;
29315
+ else hi = mid - 1;
29316
+ }
29317
+ return 0;
29318
+ }
29319
+ function allDiagPositive(S) {
29320
+ for (let j = 0; j < S.n; j++) if (!(sparseAt(S, j, j) > 0)) return false;
29321
+ return true;
29322
+ }
29323
+ function sparseSolveUpper(R, B, nrhs) {
29324
+ const n = R.n;
29325
+ const { diagPos, diag: diag2 } = triangularInfo(R);
29326
+ const ir = R.ir, jc = R.jc, pr = R.pr;
29327
+ const x = allocFloat64Array(B);
29328
+ let singular = false;
29329
+ for (let j = 0; j < n; j++) if (diag2[j] === 0) singular = true;
29330
+ for (let c = 0; c < nrhs; c++) {
29331
+ const off = c * n;
29332
+ for (let j = n - 1; j >= 0; j--) {
29333
+ const xj = x[off + j] / diag2[j];
29334
+ x[off + j] = xj;
29335
+ if (xj === 0) continue;
29336
+ const dp = diagPos[j];
29337
+ const end = dp >= 0 ? dp : jc[j + 1];
29338
+ for (let k = jc[j]; k < end; k++) x[off + ir[k]] -= pr[k] * xj;
29339
+ }
29340
+ }
29341
+ return { x, singular };
29342
+ }
29343
+ function sparseSolveLower(L, B, nrhs) {
29344
+ const n = L.n;
29345
+ const { diagPos, diag: diag2 } = triangularInfo(L);
29346
+ const ir = L.ir, jc = L.jc, pr = L.pr;
29347
+ const x = allocFloat64Array(B);
29348
+ let singular = false;
29349
+ for (let j = 0; j < n; j++) if (diag2[j] === 0) singular = true;
29350
+ for (let c = 0; c < nrhs; c++) {
29351
+ const off = c * n;
29352
+ for (let j = 0; j < n; j++) {
29353
+ const xj = x[off + j] / diag2[j];
29354
+ x[off + j] = xj;
29355
+ if (xj === 0) continue;
29356
+ const dp = diagPos[j];
29357
+ const end = jc[j + 1];
29358
+ for (let k = dp >= 0 ? dp + 1 : jc[j]; k < end; k++)
29359
+ x[off + ir[k]] -= pr[k] * xj;
29360
+ }
29361
+ }
29362
+ return { x, singular };
29363
+ }
29364
+ function permuteRows(X, n, nrhs, p2) {
29365
+ const Y = allocFloat64Array(X.length);
29366
+ for (let c = 0; c < nrhs; c++) {
29367
+ const off = c * n;
29368
+ for (let k = 0; k < n; k++) Y[off + k] = X[off + p2[k]];
29369
+ }
29370
+ return Y;
29371
+ }
29372
+ function unpermuteRows(X, n, nrhs, p2) {
29373
+ const Y = allocFloat64Array(X.length);
29374
+ for (let c = 0; c < nrhs; c++) {
29375
+ const off = c * n;
29376
+ for (let k = 0; k < n; k++) Y[off + p2[k]] = X[off + k];
29377
+ }
29378
+ return Y;
29379
+ }
29380
+ function eliminationTree(A) {
29381
+ const n = A.n;
29382
+ const parent = new Int32Array(n).fill(-1);
29383
+ const ancestor = new Int32Array(n).fill(-1);
29384
+ for (let k = 0; k < n; k++) {
29385
+ for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
29386
+ let i = A.ir[p2];
29387
+ while (i !== -1 && i < k) {
29388
+ const inext = ancestor[i];
29389
+ ancestor[i] = k;
29390
+ if (inext === -1) parent[i] = k;
29391
+ i = inext;
29392
+ }
29393
+ }
29394
+ }
29395
+ return parent;
29396
+ }
29397
+ function etreeReach(A, k, parent, s, mark) {
29398
+ const n = A.n;
29399
+ let top = n;
29400
+ mark[k] = k;
29401
+ for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
29402
+ let i = A.ir[p2];
29403
+ if (i > k) continue;
29404
+ let len = 0;
29405
+ for (; mark[i] !== k; i = parent[i]) {
29406
+ s[len++] = i;
29407
+ mark[i] = k;
29408
+ }
29409
+ while (len > 0) s[--top] = s[--len];
29410
+ }
29411
+ return top;
29412
+ }
29413
+ function sparseChol(A) {
29414
+ const n = A.n;
29415
+ if (A.m !== n) throw new RuntimeError("chol: Matrix must be square.");
29416
+ const parent = eliminationTree(A);
29417
+ const s = new Int32Array(n);
29418
+ const mark = new Int32Array(n).fill(-1);
29419
+ const colCount = new Int32Array(n);
29420
+ for (let k = 0; k < n; k++) {
29421
+ const top = etreeReach(A, k, parent, s, mark);
29422
+ for (let t = top; t < n; t++) colCount[s[t]]++;
29423
+ colCount[k]++;
29424
+ }
29425
+ const Lp = new Int32Array(n + 1);
29426
+ for (let j = 0; j < n; j++) Lp[j + 1] = Lp[j] + colCount[j];
29427
+ const nnzL = Lp[n];
29428
+ const Li = new Int32Array(nnzL);
29429
+ const Lx = allocFloat64Array(nnzL);
29430
+ const c = new Int32Array(n);
29431
+ for (let j = 0; j < n; j++) c[j] = Lp[j];
29432
+ const x = allocFloat64Array(n);
29433
+ mark.fill(-1);
29434
+ for (let k = 0; k < n; k++) {
29435
+ const top = etreeReach(A, k, parent, s, mark);
29436
+ x[k] = 0;
29437
+ for (let p2 = A.jc[k]; p2 < A.jc[k + 1]; p2++) {
29438
+ if (A.ir[p2] <= k) x[A.ir[p2]] = A.pr[p2];
29439
+ }
29440
+ let d = x[k];
29441
+ x[k] = 0;
29442
+ for (let t = top; t < n; t++) {
29443
+ const i = s[t];
29444
+ const lki = x[i] / Lx[Lp[i]];
29445
+ x[i] = 0;
29446
+ for (let p2 = Lp[i] + 1; p2 < c[i]; p2++) x[Li[p2]] -= Lx[p2] * lki;
29447
+ d -= lki * lki;
29448
+ const pos2 = c[i]++;
29449
+ Li[pos2] = k;
29450
+ Lx[pos2] = lki;
29451
+ }
29452
+ if (!(d > 0)) {
29453
+ for (let i = k + 1; i < n; i++) {
29454
+ const top2 = etreeReach(A, i, parent, s, mark);
29455
+ for (let p2 = A.jc[i]; p2 < A.jc[i + 1]; p2++)
29456
+ if (A.ir[p2] < k) x[A.ir[p2]] = A.pr[p2];
29457
+ for (let t = top2; t < n; t++) {
29458
+ const j = s[t];
29459
+ if (j >= k) {
29460
+ x[j] = 0;
29461
+ continue;
29462
+ }
29463
+ const lij = x[j] / Lx[Lp[j]];
29464
+ x[j] = 0;
29465
+ for (let p2 = Lp[j] + 1; p2 < c[j]; p2++) x[Li[p2]] -= Lx[p2] * lij;
29466
+ const pos2 = c[j]++;
29467
+ Li[pos2] = i;
29468
+ Lx[pos2] = lij;
29469
+ }
29470
+ }
29471
+ return { L: leadingColumns(n, k, Lp, Li, Lx, c), ok: false, p: k + 1 };
29472
+ }
29473
+ const pos = c[k]++;
29474
+ Li[pos] = k;
29475
+ Lx[pos] = Math.sqrt(d);
29476
+ }
29477
+ return { L: RTV.sparseMatrix(n, n, Li, Lp, Lx), ok: true, p: 0 };
29478
+ }
29479
+ function leadingColumns(n, k, Lp, Li, Lx, c) {
29480
+ let nnz = 0;
29481
+ for (let j = 0; j < k; j++) nnz += c[j] - Lp[j];
29482
+ const ir = new Int32Array(nnz);
29483
+ const pr = allocFloat64Array(nnz);
29484
+ const jc = new Int32Array(k + 1);
29485
+ let pos = 0;
29486
+ for (let j = 0; j < k; j++) {
29487
+ jc[j] = pos;
29488
+ for (let p2 = Lp[j]; p2 < c[j]; p2++) {
29489
+ ir[pos] = Li[p2];
29490
+ pr[pos] = Lx[p2];
29491
+ pos++;
29492
+ }
29493
+ }
29494
+ jc[k] = pos;
29495
+ return RTV.sparseMatrix(n, k, ir, jc, pr);
29496
+ }
29497
+ function sparseLu(A, q, tol) {
29498
+ const m = A.m, n = A.n;
29499
+ const kmin = Math.min(m, n);
29500
+ const Lp = [0];
29501
+ const Li = [];
29502
+ const Lx = [];
29503
+ const Up = [0];
29504
+ const Ui = [];
29505
+ const Ux = [];
29506
+ const pinv = new Int32Array(m).fill(-1);
29507
+ const x = allocFloat64Array(m);
29508
+ const xi = new Int32Array(m);
29509
+ const stack = new Int32Array(m);
29510
+ const pstack = new Int32Array(m);
29511
+ const mark = new Int32Array(m).fill(-1);
29512
+ let singular = false;
29513
+ for (let k = 0; k < n; k++) {
29514
+ const col = q ? q[k] : k;
29515
+ let top = m;
29516
+ for (let t = A.jc[col]; t < A.jc[col + 1]; t++) {
29517
+ const i0 = A.ir[t];
29518
+ if (mark[i0] === k) continue;
29519
+ let head = 0;
29520
+ stack[0] = i0;
29521
+ mark[i0] = k;
29522
+ pstack[i0] = pinv[i0] >= 0 ? Lp[pinv[i0]] : -1;
29523
+ while (head >= 0) {
29524
+ const j = stack[head];
29525
+ const J = pinv[j];
29526
+ let descended = false;
29527
+ if (J >= 0) {
29528
+ const end = Lp[J + 1];
29529
+ let p3 = pstack[j];
29530
+ for (; p3 < end; p3++) {
29531
+ const i = Li[p3];
29532
+ if (mark[i] !== k) {
29533
+ mark[i] = k;
29534
+ pstack[j] = p3 + 1;
29535
+ stack[++head] = i;
29536
+ pstack[i] = pinv[i] >= 0 ? Lp[pinv[i]] : -1;
29537
+ descended = true;
29538
+ break;
29539
+ }
29540
+ }
29541
+ if (descended) continue;
29542
+ }
29543
+ head--;
29544
+ xi[--top] = j;
29545
+ }
29546
+ }
29547
+ for (let t = A.jc[col]; t < A.jc[col + 1]; t++) x[A.ir[t]] = A.pr[t];
29548
+ for (let t = top; t < m; t++) {
29549
+ const j = xi[t];
29550
+ const J = pinv[j];
29551
+ if (J < 0) continue;
29552
+ const xj = x[j];
29553
+ if (xj === 0) continue;
29554
+ for (let p3 = Lp[J] + 1; p3 < Lp[J + 1]; p3++) x[Li[p3]] -= Lx[p3] * xj;
29555
+ }
29556
+ let ipiv = -1;
29557
+ let amax = -1;
29558
+ for (let t = top; t < m; t++) {
29559
+ const i = xi[t];
29560
+ if (pinv[i] >= 0) {
29561
+ Ui.push(pinv[i]);
29562
+ Ux.push(x[i]);
29563
+ } else {
29564
+ const a = Math.abs(x[i]);
29565
+ if (a > amax) {
29566
+ amax = a;
29567
+ ipiv = i;
29568
+ }
29569
+ }
29570
+ }
29571
+ if (k < kmin) {
29572
+ if (ipiv < 0 || amax === 0) {
29573
+ singular = true;
29574
+ if (ipiv < 0) {
29575
+ for (let i = 0; i < m; i++)
29576
+ if (pinv[i] < 0) {
29577
+ ipiv = i;
29578
+ break;
29579
+ }
29580
+ }
29581
+ } else if (col < m && pinv[col] < 0 && Math.abs(x[col]) >= tol * amax && x[col] !== 0) {
29582
+ ipiv = col;
29583
+ }
29584
+ const pivot = x[ipiv];
29585
+ if (!Number.isFinite(pivot)) singular = true;
29586
+ pinv[ipiv] = k;
29587
+ Ui.push(k);
29588
+ Ux.push(pivot);
29589
+ Li.push(ipiv);
29590
+ Lx.push(1);
29591
+ if (pivot !== 0 && Number.isFinite(pivot)) {
29592
+ for (let t = top; t < m; t++) {
29593
+ const i = xi[t];
29594
+ if (pinv[i] >= 0) continue;
29595
+ const v = x[i] / pivot;
29596
+ if (v !== 0) {
29597
+ Li.push(i);
29598
+ Lx.push(v);
29599
+ }
29600
+ }
29601
+ }
29602
+ Lp.push(Li.length);
29603
+ }
29604
+ Up.push(Ui.length);
29605
+ for (let t = top; t < m; t++) x[xi[t]] = 0;
29606
+ }
29607
+ let next = kmin;
29608
+ for (let i = 0; i < m; i++) if (pinv[i] < 0) pinv[i] = next++;
29609
+ const LiArr = new Int32Array(Li.length);
29610
+ for (let p3 = 0; p3 < Li.length; p3++) LiArr[p3] = pinv[Li[p3]];
29611
+ const L = fromUnsortedColumns(
29612
+ m,
29613
+ kmin,
29614
+ LiArr,
29615
+ new Int32Array(Lp),
29616
+ allocFloat64Array(Lx)
29617
+ );
29618
+ const U = fromUnsortedColumns(
29619
+ kmin,
29620
+ n,
29621
+ new Int32Array(Ui),
29622
+ new Int32Array(Up),
29623
+ allocFloat64Array(Ux)
29624
+ );
29625
+ const p2 = invertPerm(pinv);
29626
+ const qOut = q ? Int32Array.from(q) : identityPerm(n);
29627
+ return { L, U, p: p2, q: qOut, singular };
29628
+ }
29629
+ function identityPerm(n) {
29630
+ const p2 = new Int32Array(n);
29631
+ for (let i = 0; i < n; i++) p2[i] = i;
29632
+ return p2;
29633
+ }
29634
+ function symmetricAdjacency(A) {
29635
+ const n = Math.max(A.m, A.n);
29636
+ const adj = new Array(n);
29637
+ for (let i = 0; i < n; i++) adj[i] = /* @__PURE__ */ new Set();
29638
+ for (let j = 0; j < A.n; j++)
29639
+ for (let k = A.jc[j]; k < A.jc[j + 1]; k++) {
29640
+ const i = A.ir[k];
29641
+ if (i === j) continue;
29642
+ adj[i].add(j);
29643
+ adj[j].add(i);
29644
+ }
29645
+ return adj;
29646
+ }
29647
+ function minimumDegreeOrdering(A) {
29648
+ const adj = symmetricAdjacency(A);
29649
+ const n = adj.length;
29650
+ const perm = new Int32Array(n);
29651
+ if (n === 0) return perm;
29652
+ const head = new Int32Array(n + 1).fill(-1);
29653
+ const next = new Int32Array(n).fill(-1);
29654
+ const prev = new Int32Array(n).fill(-1);
29655
+ const deg = new Int32Array(n);
29656
+ const insert = (v) => {
29657
+ const d = deg[v];
29658
+ next[v] = head[d];
29659
+ prev[v] = -1;
29660
+ if (head[d] >= 0) prev[head[d]] = v;
29661
+ head[d] = v;
29662
+ };
29663
+ const remove = (v) => {
29664
+ const d = deg[v];
29665
+ if (prev[v] >= 0) next[prev[v]] = next[v];
29666
+ else head[d] = next[v];
29667
+ if (next[v] >= 0) prev[next[v]] = prev[v];
29668
+ };
29669
+ for (let v = 0; v < n; v++) {
29670
+ deg[v] = adj[v].size;
29671
+ insert(v);
29672
+ }
29673
+ let mind = 0;
29674
+ for (let step = 0; step < n; step++) {
29675
+ while (head[mind] < 0) mind++;
29676
+ const v = head[mind];
29677
+ remove(v);
29678
+ perm[step] = v;
29679
+ const nbrs = Array.from(adj[v]);
29680
+ for (const u of nbrs) adj[u].delete(v);
29681
+ for (let a = 0; a < nbrs.length; a++) {
29682
+ const u = nbrs[a];
29683
+ const su = adj[u];
29684
+ for (let b = a + 1; b < nbrs.length; b++) {
29685
+ const w = nbrs[b];
29686
+ if (!su.has(w)) {
29687
+ su.add(w);
29688
+ adj[w].add(u);
29689
+ }
29690
+ }
29691
+ }
29692
+ for (const u of nbrs) {
29693
+ remove(u);
29694
+ deg[u] = adj[u].size;
29695
+ insert(u);
29696
+ if (deg[u] < mind) mind = deg[u];
29697
+ }
29698
+ adj[v].clear();
29699
+ }
29700
+ return perm;
29701
+ }
29702
+ function reverseCuthillMcKee(A) {
29703
+ const adj = symmetricAdjacency(A);
29704
+ const n = adj.length;
29705
+ const nb = adj.map(
29706
+ (s) => Array.from(s).sort((a, b) => adj[a].size - adj[b].size || a - b)
29707
+ );
29708
+ const visited = new Uint8Array(n);
29709
+ const order = [];
29710
+ const bfsLevels = (start) => {
29711
+ const seen = new Uint8Array(n);
29712
+ let frontier = [start];
29713
+ seen[start] = 1;
29714
+ let levels = 0;
29715
+ let last = start;
29716
+ while (frontier.length > 0) {
29717
+ const nextF = [];
29718
+ for (const u of frontier)
29719
+ for (const w of nb[u])
29720
+ if (!seen[w]) {
29721
+ seen[w] = 1;
29722
+ nextF.push(w);
29723
+ }
29724
+ if (nextF.length === 0) {
29725
+ last = frontier.reduce((a, b) => adj[b].size < adj[a].size ? b : a);
29726
+ break;
29727
+ }
29728
+ frontier = nextF;
29729
+ levels++;
29730
+ }
29731
+ return { last, levels };
29732
+ };
29733
+ for (let s0 = 0; s0 < n; s0++) {
29734
+ if (visited[s0]) continue;
29735
+ let start = s0;
29736
+ let info = bfsLevels(start);
29737
+ for (let iter = 0; iter < 4; iter++) {
29738
+ const cand = bfsLevels(info.last);
29739
+ if (cand.levels > info.levels) {
29740
+ start = info.last;
29741
+ info = cand;
29742
+ } else {
29743
+ start = info.last;
29744
+ break;
29745
+ }
29746
+ }
29747
+ const queue = [start];
29748
+ visited[start] = 1;
29749
+ let qh = 0;
29750
+ while (qh < queue.length) {
29751
+ const u = queue[qh++];
29752
+ order.push(u);
29753
+ for (const w of nb[u])
29754
+ if (!visited[w]) {
29755
+ visited[w] = 1;
29756
+ queue.push(w);
29757
+ }
29758
+ }
29759
+ }
29760
+ const perm = new Int32Array(n);
29761
+ for (let i = 0; i < n; i++) perm[i] = order[n - 1 - i];
29762
+ return perm;
29763
+ }
29764
+ function ataPattern(A) {
29765
+ const At = sparseTranspose(A);
29766
+ const n = A.n;
29767
+ const marker = new Int32Array(n).fill(-1);
29768
+ const ir = [];
29769
+ const jc = new Int32Array(n + 1);
29770
+ for (let j = 0; j < n; j++) {
29771
+ jc[j] = ir.length;
29772
+ for (let k = A.jc[j]; k < A.jc[j + 1]; k++) {
29773
+ const row = A.ir[k];
29774
+ for (let t = At.jc[row]; t < At.jc[row + 1]; t++) {
29775
+ const i = At.ir[t];
29776
+ if (marker[i] !== j) {
29777
+ marker[i] = j;
29778
+ ir.push(i);
29779
+ }
29780
+ }
29781
+ }
29782
+ }
29783
+ jc[n] = ir.length;
29784
+ const pr = allocFloat64Array(ir.length).fill(1);
29785
+ return fromUnsortedColumns(n, n, new Int32Array(ir), jc, pr);
29786
+ }
29787
+ function columnOrdering(A) {
29788
+ return minimumDegreeOrdering(ataPattern(A));
29789
+ }
29790
+ var DENSE_FRACTION = 0.5;
29791
+ function sparseSolve(A, B, nrhs) {
29792
+ const n = A.n;
29793
+ if (A.m !== n || A.pi) return null;
29794
+ if (n === 0) return allocFloat64Array(0);
29795
+ const nnz = A.jc[n];
29796
+ if (nnz > DENSE_FRACTION * n * n && n > 8) return null;
29797
+ if (sparseIsUpper(A)) {
29798
+ const r = sparseSolveUpper(A, B, nrhs);
29799
+ if (r.singular) emitWarning(SINGULAR_WARNING);
29800
+ return r.x;
29801
+ }
29802
+ if (sparseIsLower(A)) {
29803
+ const r = sparseSolveLower(A, B, nrhs);
29804
+ if (r.singular) emitWarning(SINGULAR_WARNING);
29805
+ return r.x;
29806
+ }
29807
+ const perm = reverseCuthillMcKee(A);
29808
+ if (sparseIsSymmetric(A) && allDiagPositive(A)) {
29809
+ const Ap = sparsePermute(A, perm, perm);
29810
+ const ch = sparseChol(Ap);
29811
+ if (ch.ok) {
29812
+ const Lt = sparseTranspose(ch.L);
29813
+ const bp = permuteRows(B, n, nrhs, perm);
29814
+ const y = sparseSolveLower(ch.L, bp, nrhs).x;
29815
+ const z = sparseSolveUpper(Lt, y, nrhs).x;
29816
+ return unpermuteRows(z, n, nrhs, perm);
29817
+ }
29818
+ }
29819
+ const lu2 = sparseLu(A, perm, 1);
29820
+ return luSolve(lu2, B, nrhs);
29821
+ }
29822
+ function luSolve(lu2, B, nrhs) {
29823
+ const n = lu2.U.n;
29824
+ const pb = permuteRows(B, n, nrhs, lu2.p);
29825
+ const y = sparseSolveLower(lu2.L, pb, nrhs);
29826
+ const z = sparseSolveUpper(lu2.U, y.x, nrhs);
29827
+ if (lu2.singular || z.singular) emitWarning(SINGULAR_WARNING);
29828
+ return unpermuteRows(z.x, n, nrhs, lu2.q);
29829
+ }
29830
+ function luSolveTransposed(lu2, B, nrhs) {
29831
+ const n = lu2.U.n;
29832
+ const qb = permuteRows(B, n, nrhs, lu2.q);
29833
+ const y = sparseSolveLower(sparseTranspose(lu2.U), qb, nrhs);
29834
+ const z = sparseSolveUpper(sparseTranspose(lu2.L), y.x, nrhs);
29835
+ if (lu2.singular || y.singular) emitWarning(SINGULAR_WARNING);
29836
+ return unpermuteRows(z.x, n, nrhs, lu2.p);
29837
+ }
29838
+ function sparseInverse(A) {
29839
+ const n = A.n;
29840
+ if (A.m !== n) throw new RuntimeError("inv: matrix must be square");
29841
+ const I = allocFloat64Array(n * n);
29842
+ for (let i = 0; i < n; i++) I[i + i * n] = 1;
29843
+ const X = sparseSolve(A, I, n);
29844
+ if (X === null) throw new RuntimeError("inv: unsupported sparse matrix");
29845
+ return denseDataToSparse(X, n, n);
29846
+ }
29847
+
27759
29848
  // src/numbl-core/helpers/arithmetic.ts
27760
29849
  function toComplex(v) {
27761
29850
  if (isRuntimeComplexNumber(v)) return { re: v.re, im: v.im };
@@ -28346,6 +30435,12 @@ function mElemMul(a, b) {
28346
30435
  }
28347
30436
  function mDiv(a, b) {
28348
30437
  if (isRuntimeSparseMatrix(a) || isRuntimeSparseMatrix(b)) {
30438
+ if (isRuntimeSparseMatrix(a) && (isRuntimeNumber(b) || isRuntimeLogical(b) || isRuntimeComplexNumber(b) || isRuntimeTensor(b) && b.data.length === 1))
30439
+ return mElemDivSparse(a, b);
30440
+ if (isRuntimeSparseMatrix(b) && !(b.m === 1 && b.n === 1)) {
30441
+ const result = mLeftDiv(mConjugateTranspose(b), mConjugateTranspose(a));
30442
+ return mConjugateTranspose(result);
30443
+ }
28349
30444
  return mDiv(densify(a), densify(b));
28350
30445
  }
28351
30446
  if (isRuntimeTensor(a) && a.data.length === 1) a = unwrap1x1(a);
@@ -28401,8 +30496,50 @@ function mElemDiv(a, b) {
28401
30496
  }
28402
30497
  return binaryOp(a, b, (x, y) => x / y, BIN_OP_DIV);
28403
30498
  }
30499
+ function sparseLeftDiv(A, b) {
30500
+ if (A.pi) return null;
30501
+ if (A.m === 1 && A.n === 1) return null;
30502
+ let B;
30503
+ let rows, nrhs;
30504
+ const bSparse = isRuntimeSparseMatrix(b);
30505
+ if (isRuntimeSparseMatrix(b)) {
30506
+ if (b.pi) return null;
30507
+ const d = sparseToDense(b);
30508
+ B = d.data;
30509
+ rows = b.m;
30510
+ nrhs = b.n;
30511
+ } else if (isRuntimeTensor(b)) {
30512
+ if (b.imag) return null;
30513
+ [rows, nrhs] = tensorSize2D(b);
30514
+ B = b.data;
30515
+ } else if (isRuntimeNumber(b) || isRuntimeLogical(b)) {
30516
+ B = allocFloat64Array([toNumber(b)]);
30517
+ rows = 1;
30518
+ nrhs = 1;
30519
+ } else {
30520
+ return null;
30521
+ }
30522
+ if (rows !== A.m)
30523
+ throw new RuntimeError(
30524
+ `mldivide (\\): A is ${A.m}\xD7${A.n} but B has ${rows} rows`
30525
+ );
30526
+ if (A.m !== A.n) {
30527
+ emitWarning(
30528
+ "mldivide: sparse least-squares uses a dense factorization; the sparse matrix is converted to full."
30529
+ );
30530
+ return null;
30531
+ }
30532
+ const X = sparseSolve(A, B, nrhs);
30533
+ if (X === null) return null;
30534
+ if (bSparse) return denseDataToSparse(X, A.n, nrhs);
30535
+ return unwrap1x1(RTV.tensor(X, [A.n, nrhs]));
30536
+ }
28404
30537
  function mLeftDiv(a, b) {
28405
- if (isRuntimeSparseMatrix(a)) return mLeftDiv(densify(a), b);
30538
+ if (isRuntimeSparseMatrix(a)) {
30539
+ const r = sparseLeftDiv(a, b);
30540
+ if (r !== null) return r;
30541
+ return mLeftDiv(densify(a), densify(b));
30542
+ }
28406
30543
  if (isRuntimeSparseMatrix(b)) return mLeftDiv(a, densify(b));
28407
30544
  if (isRuntimeTensor(a) && a.data.length === 1) a = unwrap1x1(a);
28408
30545
  if (isRuntimeTensor(b) && b.data.length === 1) b = unwrap1x1(b);
@@ -34326,7 +36463,11 @@ function binop(op, a, b) {
34326
36463
  result = mElemDiv(mb, ma);
34327
36464
  break;
34328
36465
  }
34329
- const tensorA = isRuntimeSparseMatrix(ma) ? sparseToDense(ma) : ma;
36466
+ if (isRuntimeSparseMatrix(ma)) {
36467
+ result = mLeftDiv(ma, mb);
36468
+ break;
36469
+ }
36470
+ const tensorA = ma;
34330
36471
  const tensorB = isRuntimeNumber(mb) ? RTV.tensor(allocFloat64Array([mb]), [1, 1]) : isRuntimeSparseMatrix(mb) ? sparseToDense(mb) : mb;
34331
36472
  if (!isRuntimeTensor(tensorA) || !isRuntimeTensor(tensorB))
34332
36473
  throw new RuntimeError(
@@ -38237,6 +40378,709 @@ function tryDatetimeDurationBinop(opName, a, b) {
38237
40378
  );
38238
40379
  }
38239
40380
 
40381
+ // src/numbl-core/helpers/prng.ts
40382
+ var _rngState = null;
40383
+ var _rngSeed = 0;
40384
+ var _bmSpare = null;
40385
+ function setRngShuffle() {
40386
+ _rngState = null;
40387
+ _rngSeed = 0;
40388
+ _bmSpare = null;
40389
+ }
40390
+ function setRngSeed(seed) {
40391
+ _rngSeed = seed;
40392
+ }
40393
+ function splitmix32(seed) {
40394
+ let s = seed | 0;
40395
+ return () => {
40396
+ s = s + 2654435769 | 0;
40397
+ let z = s;
40398
+ z = Math.imul(z ^ z >>> 16, 2246822507);
40399
+ z = Math.imul(z ^ z >>> 13, 3266489909);
40400
+ return (z ^ z >>> 16) >>> 0;
40401
+ };
40402
+ }
40403
+ function seedRng(seed) {
40404
+ _bmSpare = null;
40405
+ const sm = splitmix32(seed);
40406
+ _rngState = new Uint32Array([sm(), sm(), sm(), sm()]);
40407
+ if (_rngState[0] === 0 && _rngState[1] === 0 && _rngState[2] === 0 && _rngState[3] === 0) {
40408
+ _rngState[0] = 1;
40409
+ }
40410
+ }
40411
+ function xoshiro128ss() {
40412
+ const s = _rngState;
40413
+ const result = Math.imul(rotl(Math.imul(s[1], 5), 7), 9) >>> 0;
40414
+ const t = s[1] << 9;
40415
+ s[2] ^= s[0];
40416
+ s[3] ^= s[1];
40417
+ s[1] ^= s[2];
40418
+ s[0] ^= s[3];
40419
+ s[2] ^= t;
40420
+ s[3] = rotl(s[3], 11);
40421
+ return result;
40422
+ }
40423
+ function rotl(x, k) {
40424
+ return (x << k | x >>> 32 - k) >>> 0;
40425
+ }
40426
+ function rngRandom() {
40427
+ if (_rngState === null) return Math.random();
40428
+ return (xoshiro128ss() >>> 0) / 4294967296;
40429
+ }
40430
+ function boxMullerRandom() {
40431
+ if (_bmSpare !== null) {
40432
+ const s2 = _bmSpare;
40433
+ _bmSpare = null;
40434
+ return s2;
40435
+ }
40436
+ let u, v, s;
40437
+ do {
40438
+ u = 2 * rngRandom() - 1;
40439
+ v = 2 * rngRandom() - 1;
40440
+ s = u * u + v * v;
40441
+ } while (s >= 1 || s === 0);
40442
+ const mul = Math.sqrt(-2 * Math.log(s) / s);
40443
+ _bmSpare = v * mul;
40444
+ return u * mul;
40445
+ }
40446
+ function fillRandn(data) {
40447
+ if (_rngState !== null) {
40448
+ const bridge = getLapackBridge();
40449
+ if (bridge?.fillRandn) {
40450
+ const r = bridge.fillRandn(
40451
+ _rngState,
40452
+ data.length,
40453
+ _bmSpare ?? 0,
40454
+ _bmSpare !== null
40455
+ );
40456
+ _bmSpare = r.hasSpare ? r.spare : null;
40457
+ data.set(r.data);
40458
+ return;
40459
+ }
40460
+ }
40461
+ const n = data.length;
40462
+ let i = 0;
40463
+ if (_bmSpare !== null && i < n) {
40464
+ data[i++] = _bmSpare;
40465
+ _bmSpare = null;
40466
+ }
40467
+ for (; i + 1 < n; i += 2) {
40468
+ let u, v, s;
40469
+ do {
40470
+ u = 2 * rngRandom() - 1;
40471
+ v = 2 * rngRandom() - 1;
40472
+ s = u * u + v * v;
40473
+ } while (s >= 1 || s === 0);
40474
+ const mul = Math.sqrt(-2 * Math.log(s) / s);
40475
+ data[i] = u * mul;
40476
+ data[i + 1] = v * mul;
40477
+ }
40478
+ if (i < n) {
40479
+ data[i] = boxMullerRandom();
40480
+ }
40481
+ }
40482
+ function getRngStateStruct() {
40483
+ const stateArray = _rngState ? RTV.tensor(allocFloat64Array(Array.from(_rngState).map((v) => v)), [4, 1]) : RTV.tensor(allocFloat64Array(0), [0, 1]);
40484
+ return RTV.struct({
40485
+ Type: RTV.char("twister"),
40486
+ Seed: RTV.num(_rngSeed),
40487
+ State: stateArray
40488
+ });
40489
+ }
40490
+ function restoreRngState(s) {
40491
+ const seedField = s.fields.get("Seed");
40492
+ const stateField = s.fields.get("State");
40493
+ if (seedField === void 0 || stateField === void 0) {
40494
+ throw new RuntimeError("rng: invalid state structure");
40495
+ }
40496
+ _rngSeed = Math.round(toNumber(seedField));
40497
+ if (isRuntimeTensor(stateField) && stateField.data.length === 4) {
40498
+ _rngState = new Uint32Array(4);
40499
+ for (let i = 0; i < 4; i++) _rngState[i] = stateField.data[i] >>> 0;
40500
+ } else {
40501
+ _rngState = null;
40502
+ }
40503
+ }
40504
+
40505
+ // src/numbl-core/interpreter/builtins/sparse-solvers.ts
40506
+ function toSparseArg(v, name) {
40507
+ if (isRuntimeSparseMatrix(v)) return v;
40508
+ if (isRuntimeTensor(v)) return denseToSparse(v);
40509
+ if (isRuntimeNumber(v))
40510
+ return denseToSparse(RTV.tensor(allocFloat64Array([v]), [1, 1]));
40511
+ if (isRuntimeLogical(v))
40512
+ return denseToSparse(RTV.tensor(allocFloat64Array([v ? 1 : 0]), [1, 1]));
40513
+ throw new RuntimeError(`${name}: argument must be a numeric matrix`);
40514
+ }
40515
+ var ROW_VECTOR = { kind: "tensor", isComplex: false };
40516
+ registerIBuiltin({
40517
+ name: "symrcm",
40518
+ help: {
40519
+ signatures: ["p = symrcm(A)"],
40520
+ description: "Reverse Cuthill-McKee ordering of the pattern of A + A'. A(p,p) tends to have a smaller bandwidth than A."
40521
+ },
40522
+ resolve: (argTypes, nargout) => {
40523
+ if (argTypes.length !== 1 || nargout > 1) return null;
40524
+ return {
40525
+ outputTypes: [ROW_VECTOR],
40526
+ apply: (args) => permVectorTensor(reverseCuthillMcKee(toSparseArg(args[0], "symrcm")))
40527
+ };
40528
+ }
40529
+ });
40530
+ registerIBuiltin({
40531
+ name: "amd",
40532
+ help: {
40533
+ signatures: ["p = amd(A)"],
40534
+ 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."
40535
+ },
40536
+ resolve: (argTypes, nargout) => {
40537
+ if (argTypes.length < 1 || argTypes.length > 2 || nargout > 1) return null;
40538
+ return {
40539
+ outputTypes: [ROW_VECTOR],
40540
+ apply: (args) => permVectorTensor(minimumDegreeOrdering(toSparseArg(args[0], "amd")))
40541
+ };
40542
+ }
40543
+ });
40544
+ registerIBuiltin({
40545
+ name: "colamd",
40546
+ help: {
40547
+ signatures: ["p = colamd(A)"],
40548
+ 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)."
40549
+ },
40550
+ resolve: (argTypes, nargout) => {
40551
+ if (argTypes.length < 1 || argTypes.length > 2 || nargout > 1) return null;
40552
+ return {
40553
+ outputTypes: [ROW_VECTOR],
40554
+ apply: (args) => permVectorTensor(columnOrdering(toSparseArg(args[0], "colamd")))
40555
+ };
40556
+ }
40557
+ });
40558
+ function sampleDistinct(total, k) {
40559
+ if (k >= total) {
40560
+ const all2 = new Int32Array(total);
40561
+ for (let i = 0; i < total; i++) all2[i] = i;
40562
+ return all2;
40563
+ }
40564
+ let picked;
40565
+ if (k > total / 3) {
40566
+ const idx = new Int32Array(total);
40567
+ for (let i = 0; i < total; i++) idx[i] = i;
40568
+ for (let i = 0; i < k; i++) {
40569
+ const j = i + Math.floor(rngRandom() * (total - i));
40570
+ const t = idx[i];
40571
+ idx[i] = idx[j];
40572
+ idx[j] = t;
40573
+ }
40574
+ picked = idx.slice(0, k);
40575
+ } else {
40576
+ const set = /* @__PURE__ */ new Set();
40577
+ while (set.size < k) set.add(Math.floor(rngRandom() * total));
40578
+ picked = Int32Array.from(set);
40579
+ }
40580
+ return picked.sort();
40581
+ }
40582
+ function sparseFromLinearIndices(m, n, idx, gen) {
40583
+ const nnz = idx.length;
40584
+ const ir = new Int32Array(nnz);
40585
+ const jc = new Int32Array(n + 1);
40586
+ const pr = allocFloat64Array(nnz);
40587
+ for (let k = 0; k < nnz; k++) {
40588
+ const col = Math.floor(idx[k] / m);
40589
+ ir[k] = idx[k] - col * m;
40590
+ jc[col + 1]++;
40591
+ pr[k] = gen();
40592
+ }
40593
+ for (let c = 0; c < n; c++) jc[c + 1] += jc[c];
40594
+ return RTV.sparseMatrix(m, n, ir, jc, pr);
40595
+ }
40596
+ function registerSprand(name, gen) {
40597
+ registerIBuiltin({
40598
+ name,
40599
+ help: {
40600
+ signatures: [`R = ${name}(m, n, density)`, `R = ${name}(S)`],
40601
+ 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.`
40602
+ },
40603
+ resolve: (argTypes, nargout) => {
40604
+ if (nargout > 1) return null;
40605
+ if (argTypes.length !== 1 && argTypes.length < 3) return null;
40606
+ return {
40607
+ outputTypes: [{ kind: "sparse_matrix", isComplex: false }],
40608
+ apply: (args) => {
40609
+ if (args.length === 1) {
40610
+ const S = toSparseArg(args[0], name);
40611
+ const pr = allocFloat64Array(S.pr.length);
40612
+ for (let k2 = 0; k2 < pr.length; k2++) pr[k2] = gen();
40613
+ return RTV.sparseMatrix(
40614
+ S.m,
40615
+ S.n,
40616
+ new Int32Array(S.ir),
40617
+ new Int32Array(S.jc),
40618
+ pr
40619
+ );
40620
+ }
40621
+ if (args.length > 3)
40622
+ throw new RuntimeError(
40623
+ `${name}: the reciprocal-condition form ${name}(m, n, density, rc) is not supported`
40624
+ );
40625
+ const m = Math.round(toNumber(args[0]));
40626
+ const n = Math.round(toNumber(args[1]));
40627
+ const density = toNumber(args[2]);
40628
+ if (!(density >= 0 && density <= 1))
40629
+ throw new RuntimeError(`${name}: density must be in [0, 1]`);
40630
+ const total = m * n;
40631
+ const k = Math.min(total, Math.round(density * total));
40632
+ return sparseFromLinearIndices(m, n, sampleDistinct(total, k), gen);
40633
+ }
40634
+ };
40635
+ }
40636
+ });
40637
+ }
40638
+ registerSprand("sprand", rngRandom);
40639
+ registerSprand("sprandn", boxMullerRandom);
40640
+ registerIBuiltin({
40641
+ name: "sprandsym",
40642
+ help: {
40643
+ signatures: ["R = sprandsym(n, density)", "R = sprandsym(S)"],
40644
+ 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."
40645
+ },
40646
+ resolve: (argTypes, nargout) => {
40647
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2) return null;
40648
+ return {
40649
+ outputTypes: [{ kind: "sparse_matrix", isComplex: false }],
40650
+ apply: (args) => {
40651
+ let n;
40652
+ let lowerIdx;
40653
+ if (args.length === 1) {
40654
+ const S = toSparseArg(args[0], "sprandsym");
40655
+ if (S.m !== S.n)
40656
+ throw new RuntimeError("sprandsym: S must be square");
40657
+ n = S.n;
40658
+ const idx = [];
40659
+ for (let j = 0; j < n; j++)
40660
+ for (let k = S.jc[j]; k < S.jc[j + 1]; k++)
40661
+ if (S.ir[k] >= j) idx.push(j * n + S.ir[k]);
40662
+ lowerIdx = Int32Array.from(idx);
40663
+ } else {
40664
+ n = Math.round(toNumber(args[0]));
40665
+ const density = toNumber(args[1]);
40666
+ if (!(density >= 0 && density <= 1))
40667
+ throw new RuntimeError("sprandsym: density must be in [0, 1]");
40668
+ const tri = n * (n + 1) / 2;
40669
+ const k = Math.min(tri, Math.round(density * n * n / 2));
40670
+ const triIdx = sampleDistinct(tri, k);
40671
+ const lin = [];
40672
+ for (let t = 0; t < triIdx.length; t++) {
40673
+ let r = triIdx[t];
40674
+ let col = 0;
40675
+ while (r >= n - col) {
40676
+ r -= n - col;
40677
+ col++;
40678
+ }
40679
+ lin.push(col * n + col + r);
40680
+ }
40681
+ lowerIdx = Int32Array.from(lin).sort();
40682
+ }
40683
+ const lower = sparseFromLinearIndices(n, n, lowerIdx, boxMullerRandom);
40684
+ const Lt = sparseTranspose(lower);
40685
+ const dense = sparseToDense(lower).data;
40686
+ const denseT = sparseToDense(Lt).data;
40687
+ for (let i = 0; i < dense.length; i++) dense[i] += denseT[i];
40688
+ for (let i = 0; i < n; i++) dense[i + i * n] /= 2;
40689
+ return denseDataToSparse(dense, n, n);
40690
+ }
40691
+ };
40692
+ }
40693
+ });
40694
+ var DEC_CLASS = "decomposition";
40695
+ function isDecomposition(v) {
40696
+ return isRuntimeClassInstance(v) && v.className === DEC_CLASS;
40697
+ }
40698
+ function permFromField(d, name) {
40699
+ const t = d.fields.get(name);
40700
+ if (t === void 0 || !isRuntimeTensor(t))
40701
+ throw new RuntimeError("decomposition: corrupt");
40702
+ const p2 = new Int32Array(t.data.length);
40703
+ for (let i = 0; i < p2.length; i++) p2[i] = t.data[i] - 1;
40704
+ return p2;
40705
+ }
40706
+ function sparseField(d, name) {
40707
+ const v = d.fields.get(name);
40708
+ if (v === void 0 || !isRuntimeSparseMatrix(v))
40709
+ throw new RuntimeError("decomposition: corrupt");
40710
+ return v;
40711
+ }
40712
+ function charField(d, name) {
40713
+ const v = d.fields.get(name);
40714
+ if (v === void 0) throw new RuntimeError("decomposition: corrupt");
40715
+ return parseStringArgLower(v);
40716
+ }
40717
+ function diagRatio(S) {
40718
+ let lo = Infinity;
40719
+ let hi = 0;
40720
+ for (let j = 0; j < S.n; j++) {
40721
+ let d = 0;
40722
+ for (let k = S.jc[j]; k < S.jc[j + 1]; k++)
40723
+ if (S.ir[k] === j) {
40724
+ d = Math.abs(S.pr[k]);
40725
+ break;
40726
+ }
40727
+ if (d < lo) lo = d;
40728
+ if (d > hi) hi = d;
40729
+ }
40730
+ if (S.n === 0) return 1;
40731
+ return hi === 0 ? 0 : lo / hi;
40732
+ }
40733
+ function denseLuFactors(data, n) {
40734
+ const bridge = getEffectiveBridge("lu", "lu");
40735
+ if (!bridge?.lu) throw new RuntimeError("decomposition: LU unavailable");
40736
+ const { LU, ipiv } = bridge.lu(toF64(data), n, n);
40737
+ const perm = new Int32Array(n);
40738
+ for (let i = 0; i < n; i++) perm[i] = i;
40739
+ for (let i = 0; i < ipiv.length; i++) {
40740
+ const j = ipiv[i] - 1;
40741
+ if (j !== i) {
40742
+ const t = perm[i];
40743
+ perm[i] = perm[j];
40744
+ perm[j] = t;
40745
+ }
40746
+ }
40747
+ const L = allocFloat64Array(n * n);
40748
+ const U = allocFloat64Array(n * n);
40749
+ let singular = false;
40750
+ for (let j = 0; j < n; j++) {
40751
+ L[j + j * n] = 1;
40752
+ for (let i = j + 1; i < n; i++) L[i + j * n] = LU[i + j * n];
40753
+ for (let i = 0; i <= j; i++) U[i + j * n] = LU[i + j * n];
40754
+ if (U[j + j * n] === 0) singular = true;
40755
+ }
40756
+ return {
40757
+ L: denseDataToSparse(L, n, n),
40758
+ U: denseDataToSparse(U, n, n),
40759
+ p: perm,
40760
+ q: identityPerm(n),
40761
+ singular
40762
+ };
40763
+ }
40764
+ function denseCholLower(data, n) {
40765
+ const bridge = getEffectiveBridge("chol", "chol");
40766
+ if (!bridge?.chol) throw new RuntimeError("decomposition: chol unavailable");
40767
+ const { R, info } = bridge.chol(toF64(data), n, false);
40768
+ if (info > 0) return null;
40769
+ return denseDataToSparse(R, n, n);
40770
+ }
40771
+ function denseIsTriangular(data, n, upper) {
40772
+ for (let j = 0; j < n; j++)
40773
+ for (let i = 0; i < n; i++) {
40774
+ if (upper ? i <= j : i >= j) continue;
40775
+ if (data[i + j * n] !== 0) return false;
40776
+ }
40777
+ return true;
40778
+ }
40779
+ registerIBuiltin({
40780
+ name: "decomposition",
40781
+ help: {
40782
+ signatures: [
40783
+ "dA = decomposition(A)",
40784
+ "dA = decomposition(A, type)",
40785
+ "dA = decomposition(A, 'triangular', 'upper' | 'lower')",
40786
+ "x = dA \\ b",
40787
+ "x = b / dA"
40788
+ ],
40789
+ 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."
40790
+ },
40791
+ resolve: (argTypes, nargout) => {
40792
+ if (argTypes.length < 1 || nargout > 1) return null;
40793
+ return {
40794
+ outputTypes: [{ kind: "unknown" }],
40795
+ apply: (args) => buildDecomposition(args)
40796
+ };
40797
+ }
40798
+ });
40799
+ function buildDecomposition(args) {
40800
+ const A = args[0];
40801
+ let type = "auto";
40802
+ let triangle = null;
40803
+ let checkCondition = true;
40804
+ let luTol = 1;
40805
+ let i = 1;
40806
+ const isStr = (v) => isRuntimeChar(v) || isRuntimeString(v);
40807
+ while (i < args.length) {
40808
+ const a = args[i];
40809
+ if (!isStr(a))
40810
+ throw new RuntimeError("decomposition: options must be strings");
40811
+ const s = parseStringArgLower(a);
40812
+ if (s === "upper" || s === "lower") {
40813
+ triangle = s;
40814
+ i++;
40815
+ continue;
40816
+ }
40817
+ if (s === "checkcondition" || s === "ranktolerance" || s === "banddensity" || s === "ldlpivottolerance" || s === "lupivottolerance") {
40818
+ if (i + 1 >= args.length)
40819
+ throw new RuntimeError(`decomposition: missing value for '${s}'`);
40820
+ const v = args[i + 1];
40821
+ if (s === "checkcondition") checkCondition = toNumber(v) !== 0;
40822
+ if (s === "lupivottolerance") luTol = toNumber(v);
40823
+ i += 2;
40824
+ continue;
40825
+ }
40826
+ if (i === 1) {
40827
+ type = s;
40828
+ i++;
40829
+ continue;
40830
+ }
40831
+ throw new RuntimeError(`decomposition: unknown option '${s}'`);
40832
+ }
40833
+ const known = [
40834
+ "auto",
40835
+ "chol",
40836
+ "lu",
40837
+ "triangular",
40838
+ "ldl",
40839
+ "qr",
40840
+ "banded",
40841
+ "diagonal",
40842
+ "permutedtriangular",
40843
+ "hessenberg",
40844
+ "cod"
40845
+ ];
40846
+ if (!known.includes(type))
40847
+ throw new RuntimeError(
40848
+ `decomposition: unknown decomposition type '${type}'`
40849
+ );
40850
+ let S = null;
40851
+ let dense = null;
40852
+ let n;
40853
+ if (isRuntimeSparseMatrix(A)) {
40854
+ if (A.pi)
40855
+ throw new RuntimeError(
40856
+ "decomposition: complex matrices are not supported"
40857
+ );
40858
+ if (A.m !== A.n)
40859
+ throw new RuntimeError(
40860
+ "decomposition: only square matrices are supported"
40861
+ );
40862
+ S = A;
40863
+ n = A.n;
40864
+ } else if (isRuntimeTensor(A) || isRuntimeNumber(A)) {
40865
+ const t = isRuntimeNumber(A) ? RTV.tensor(allocFloat64Array([A]), [1, 1]) : A;
40866
+ if (t.imag)
40867
+ throw new RuntimeError(
40868
+ "decomposition: complex matrices are not supported"
40869
+ );
40870
+ const [m, nn] = tensorSize2D(t);
40871
+ if (m !== nn)
40872
+ throw new RuntimeError(
40873
+ "decomposition: only square matrices are supported"
40874
+ );
40875
+ n = nn;
40876
+ dense = t.data;
40877
+ } else {
40878
+ throw new RuntimeError("decomposition: A must be a numeric matrix");
40879
+ }
40880
+ const fields = /* @__PURE__ */ new Map();
40881
+ const setCommon = (typeName, rc) => {
40882
+ fields.set("MatrixSize", RTV.tensor(allocFloat64Array([n, n]), [1, 2]));
40883
+ fields.set("Type", RTV.char(typeName));
40884
+ fields.set("Datatype", RTV.char("double"));
40885
+ fields.set("IsReal", RTV.logical(true));
40886
+ fields.set("IsConjugateTransposed", RTV.logical(false));
40887
+ fields.set("ScaleFactor", RTV.num(1));
40888
+ fields.set("CheckCondition", RTV.logical(checkCondition));
40889
+ fields.set("_rcond", RTV.num(rc));
40890
+ };
40891
+ const storeTriangular = (T, upper) => {
40892
+ fields.set("_kind", RTV.char("triangular"));
40893
+ fields.set("_T", T);
40894
+ fields.set("_upper", RTV.logical(upper));
40895
+ setCommon("triangular", diagRatio(T));
40896
+ };
40897
+ const storeChol = (L, p2) => {
40898
+ fields.set("_kind", RTV.char("chol"));
40899
+ fields.set("_L", L);
40900
+ fields.set("_Lt", sparseTranspose(L));
40901
+ fields.set("_p", permVectorTensor(p2));
40902
+ setCommon("chol", diagRatio(L) ** 2);
40903
+ };
40904
+ const storeLu = (lu3) => {
40905
+ fields.set("_kind", RTV.char("lu"));
40906
+ fields.set("_L", lu3.L);
40907
+ fields.set("_U", lu3.U);
40908
+ fields.set("_p", permVectorTensor(lu3.p));
40909
+ fields.set("_q", permVectorTensor(lu3.q));
40910
+ setCommon(type === "auto" || type === "lu" ? "lu" : type, diagRatio(lu3.U));
40911
+ };
40912
+ const upperOk = S ? sparseIsUpper(S) : denseIsTriangular(dense, n, true);
40913
+ const lowerOk = S ? sparseIsLower(S) : denseIsTriangular(dense, n, false);
40914
+ if (type === "triangular" || type === "auto" && (upperOk || lowerOk)) {
40915
+ let upper;
40916
+ if (triangle) upper = triangle === "upper";
40917
+ else if (upperOk) upper = true;
40918
+ else if (lowerOk) upper = false;
40919
+ else throw new RuntimeError("decomposition: matrix is not triangular");
40920
+ const T = S ?? denseDataToSparse(dense, n, n);
40921
+ storeTriangular(T, upper);
40922
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
40923
+ }
40924
+ const symmetric = S !== null && sparseIsSymmetric(S);
40925
+ if (type === "chol" || type === "auto" && symmetric) {
40926
+ if (S) {
40927
+ const perm = minimumDegreeOrdering(S);
40928
+ const res = sparseChol(sparsePermute(S, perm, perm));
40929
+ if (res.ok) {
40930
+ storeChol(res.L, perm);
40931
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
40932
+ }
40933
+ } else {
40934
+ const L = denseCholLower(dense, n);
40935
+ if (L) {
40936
+ storeChol(L, identityPerm(n));
40937
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
40938
+ }
40939
+ }
40940
+ if (type === "chol")
40941
+ throw new RuntimeError(
40942
+ "Cholesky decomposition requires the input matrix to be positive definite."
40943
+ );
40944
+ }
40945
+ const lu2 = S ? sparseLu(S, columnOrdering(S), luTol) : denseLuFactors(dense, n);
40946
+ if (lu2.singular) emitWarning(SINGULAR_WARNING);
40947
+ storeLu(lu2);
40948
+ return new RuntimeClassInstance(DEC_CLASS, fields, false);
40949
+ }
40950
+ function decompositionRcond(d) {
40951
+ const rc = d.fields.get("_rcond");
40952
+ return typeof rc === "number" ? rc : 1;
40953
+ }
40954
+ registerIBuiltin({
40955
+ name: "isIllConditioned",
40956
+ help: {
40957
+ signatures: ["tf = isIllConditioned(dA)"],
40958
+ description: "True if the matrix stored in a decomposition object is ill conditioned (reciprocal condition estimate below eps)."
40959
+ },
40960
+ resolve: (argTypes, nargout) => {
40961
+ if (argTypes.length !== 1 || nargout > 1) return null;
40962
+ return {
40963
+ outputTypes: [{ kind: "boolean" }],
40964
+ apply: (args) => {
40965
+ if (!isDecomposition(args[0]))
40966
+ throw new RuntimeError(
40967
+ "isIllConditioned: argument must be a decomposition object"
40968
+ );
40969
+ return RTV.logical(decompositionRcond(args[0]) < Number.EPSILON);
40970
+ }
40971
+ };
40972
+ }
40973
+ });
40974
+ function decompositionSolve(d, B, n, nrhs, transposed) {
40975
+ if (d.fields.get("CheckCondition") === true) {
40976
+ const rc = decompositionRcond(d);
40977
+ if (rc < Number.EPSILON)
40978
+ emitWarning(
40979
+ `Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = ${rc.toExponential(6)}.`
40980
+ );
40981
+ }
40982
+ const kind = charField(d, "_kind");
40983
+ if (kind === "triangular") {
40984
+ let T = sparseField(d, "_T");
40985
+ let upper = d.fields.get("_upper") === true;
40986
+ if (transposed) {
40987
+ T = sparseTranspose(T);
40988
+ upper = !upper;
40989
+ }
40990
+ const r = upper ? sparseSolveUpper(T, B, nrhs) : sparseSolveLower(T, B, nrhs);
40991
+ if (r.singular) emitWarning(SINGULAR_WARNING);
40992
+ return r.x;
40993
+ }
40994
+ if (kind === "chol") {
40995
+ const L = sparseField(d, "_L");
40996
+ const p2 = permFromField(d, "_p");
40997
+ const bp = allocFloat64Array(B.length);
40998
+ for (let c = 0; c < nrhs; c++)
40999
+ for (let k = 0; k < n; k++) bp[c * n + k] = B[c * n + p2[k]];
41000
+ const y = sparseSolveLower(L, bp, nrhs).x;
41001
+ const z = sparseSolveUpper(sparseField(d, "_Lt"), y, nrhs).x;
41002
+ const x = allocFloat64Array(B.length);
41003
+ for (let c = 0; c < nrhs; c++)
41004
+ for (let k = 0; k < n; k++) x[c * n + p2[k]] = z[c * n + k];
41005
+ return x;
41006
+ }
41007
+ const lu2 = {
41008
+ L: sparseField(d, "_L"),
41009
+ U: sparseField(d, "_U"),
41010
+ p: permFromField(d, "_p"),
41011
+ q: permFromField(d, "_q"),
41012
+ singular: false
41013
+ };
41014
+ return transposed ? luSolveTransposed(lu2, B, nrhs) : luSolve(lu2, B, nrhs);
41015
+ }
41016
+ function rhsData(v) {
41017
+ if (isRuntimeSparseMatrix(v)) {
41018
+ if (v.pi)
41019
+ throw new RuntimeError(
41020
+ "decomposition: complex operands are not supported"
41021
+ );
41022
+ return { data: sparseToDense(v).data, m: v.m, n: v.n };
41023
+ }
41024
+ if (isRuntimeTensor(v)) {
41025
+ if (v.imag)
41026
+ throw new RuntimeError(
41027
+ "decomposition: complex operands are not supported"
41028
+ );
41029
+ const [m, n] = tensorSize2D(v);
41030
+ return { data: v.data, m, n };
41031
+ }
41032
+ if (isRuntimeNumber(v) || isRuntimeLogical(v))
41033
+ return { data: allocFloat64Array([toNumber(v)]), m: 1, n: 1 };
41034
+ throw new RuntimeError("decomposition: operand must be numeric");
41035
+ }
41036
+ function tryDecompositionDivide(name, a, b) {
41037
+ if (name === "mldivide") {
41038
+ if (!isDecomposition(a)) {
41039
+ if (isDecomposition(b))
41040
+ throw new RuntimeError(
41041
+ "decomposition: a decomposition object can only be the left operand of \\"
41042
+ );
41043
+ return void 0;
41044
+ }
41045
+ const n2 = toNumber(permSize(a));
41046
+ const rhs2 = rhsData(b);
41047
+ if (rhs2.m !== n2)
41048
+ throw new RuntimeError(
41049
+ `mldivide (\\): A is ${n2}\xD7${n2} but B has ${rhs2.m} rows`
41050
+ );
41051
+ const x2 = decompositionSolve(a, rhs2.data, n2, rhs2.n, false);
41052
+ return RTV.tensor(x2, [n2, rhs2.n]);
41053
+ }
41054
+ if (!isDecomposition(b)) {
41055
+ if (isDecomposition(a))
41056
+ throw new RuntimeError(
41057
+ "decomposition: a decomposition object can only be the right operand of /"
41058
+ );
41059
+ return void 0;
41060
+ }
41061
+ const n = toNumber(permSize(b));
41062
+ const rhs = rhsData(a);
41063
+ if (rhs.n !== n)
41064
+ throw new RuntimeError(
41065
+ `mrdivide (/): A is ${n}\xD7${n} but B has ${rhs.n} columns`
41066
+ );
41067
+ const nrhs = rhs.m;
41068
+ const Bt = allocFloat64Array(n * nrhs);
41069
+ for (let c = 0; c < nrhs; c++)
41070
+ for (let k = 0; k < n; k++) Bt[c * n + k] = rhs.data[c + k * nrhs];
41071
+ const xt = decompositionSolve(b, Bt, n, nrhs, true);
41072
+ const x = allocFloat64Array(n * nrhs);
41073
+ for (let c = 0; c < nrhs; c++)
41074
+ for (let k = 0; k < n; k++) x[c + k * nrhs] = xt[c * n + k];
41075
+ return RTV.tensor(x, [nrhs, n]);
41076
+ }
41077
+ function permSize(d) {
41078
+ const ms = d.fields.get("MatrixSize");
41079
+ if (ms === void 0 || !isRuntimeTensor(ms))
41080
+ throw new RuntimeError("decomposition: corrupt");
41081
+ return ms.data[0];
41082
+ }
41083
+
38240
41084
  // src/numbl-core/interpreter/builtins/array-construction.ts
38241
41085
  function isClassNameType(t) {
38242
41086
  return t.kind === "char" || t.kind === "string";
@@ -38812,6 +41656,10 @@ for (const [name, op] of opMap) {
38812
41656
  apply: (args) => {
38813
41657
  const dt = tryDatetimeDurationBinop(name, args[0], args[1]);
38814
41658
  if (dt !== void 0) return dt;
41659
+ if (name === "mldivide" || name === "mrdivide") {
41660
+ const dec = tryDecompositionDivide(name, args[0], args[1]);
41661
+ if (dec !== void 0) return dec;
41662
+ }
38815
41663
  return op(args[0], args[1]);
38816
41664
  }
38817
41665
  };
@@ -44288,6 +47136,7 @@ var Runtime = class _Runtime {
44288
47136
  if (options.cancelSAB) {
44289
47137
  this.cancelFlag = new Int32Array(options.cancelSAB);
44290
47138
  }
47139
+ setWarningSink((msg) => this.output("Warning: " + msg + "\n"));
44291
47140
  this.initBuiltins();
44292
47141
  }
44293
47142
  outputLines = [];
@@ -51463,6 +54312,24 @@ defineBuiltin({
51463
54312
  });
51464
54313
 
51465
54314
  // src/numbl-core/interpreter/builtins/linear-algebra.ts
54315
+ var SPARSE_TYPE = { kind: "sparse_matrix", isComplex: false };
54316
+ function toSparseOperand(v, name) {
54317
+ if (isRuntimeSparseMatrix(v)) return v;
54318
+ if (isRuntimeNumber(v) || typeof v === "boolean")
54319
+ return denseToSparse(RTV.tensor(allocFloat64Array([Number(v)]), [1, 1]));
54320
+ if (isRuntimeTensor(v)) return denseToSparse(v);
54321
+ throw new RuntimeError(`${name}: arguments must be numeric`);
54322
+ }
54323
+ function speyeSparse(n) {
54324
+ const ir = new Int32Array(n);
54325
+ const jc = new Int32Array(n + 1);
54326
+ const pr = allocFloat64Array(n).fill(1);
54327
+ for (let i = 0; i < n; i++) {
54328
+ ir[i] = i;
54329
+ jc[i + 1] = i + 1;
54330
+ }
54331
+ return RTV.sparseMatrix(n, n, ir, jc, pr);
54332
+ }
51466
54333
  function isNumericJitType(t) {
51467
54334
  return t.kind === "number" || t.kind === "boolean" || t.kind === "complex_or_number" || t.kind === "tensor" || t.kind === "sparse_matrix";
51468
54335
  }
@@ -51503,12 +54370,53 @@ function normApply(args) {
51503
54370
  const v = args[0];
51504
54371
  if (isRuntimeNumber(v)) return RTV.num(Math.abs(v));
51505
54372
  if (isRuntimeComplexNumber(v)) return RTV.num(Math.hypot(v.re, v.im));
51506
- if (isRuntimeSparseMatrix(v))
54373
+ if (isRuntimeSparseMatrix(v)) {
54374
+ const fast = sparseNormFast(v, args[1]);
54375
+ if (fast !== null) return RTV.num(fast);
51507
54376
  return normApply([sparseToDense(v), ...args.slice(1)]);
54377
+ }
51508
54378
  if (!isRuntimeTensor(v))
51509
54379
  throw new RuntimeError("norm: argument must be numeric");
51510
54380
  return normImplTensor(v, args);
51511
54381
  }
54382
+ function sparseNormFast(S, p2) {
54383
+ if (S.m === 1 || S.n === 1) return null;
54384
+ let kind = null;
54385
+ if (p2 === void 0) return null;
54386
+ if (isRuntimeNumber(p2)) {
54387
+ if (p2 === 1) kind = "one";
54388
+ else if (p2 === Infinity) kind = "inf";
54389
+ } else if (isRuntimeChar(p2) || isRuntimeString(p2)) {
54390
+ const s = parseStringArgLower(p2);
54391
+ if (s === "fro") kind = "fro";
54392
+ else if (s === "inf") kind = "inf";
54393
+ }
54394
+ if (kind === null) return null;
54395
+ const mag2 = (k) => S.pi ? Math.hypot(S.pr[k], S.pi[k]) : Math.abs(S.pr[k]);
54396
+ const nnz = S.jc[S.n];
54397
+ if (kind === "fro") {
54398
+ let sum2 = 0;
54399
+ for (let k = 0; k < nnz; k++) {
54400
+ const a = mag2(k);
54401
+ sum2 += a * a;
54402
+ }
54403
+ return Math.sqrt(sum2);
54404
+ }
54405
+ if (kind === "one") {
54406
+ let best2 = 0;
54407
+ for (let j = 0; j < S.n; j++) {
54408
+ let sum2 = 0;
54409
+ for (let k = S.jc[j]; k < S.jc[j + 1]; k++) sum2 += mag2(k);
54410
+ if (sum2 > best2) best2 = sum2;
54411
+ }
54412
+ return best2;
54413
+ }
54414
+ const rowSums = allocFloat64Array(S.m);
54415
+ for (let k = 0; k < nnz; k++) rowSums[S.ir[k]] += mag2(k);
54416
+ let best = 0;
54417
+ for (let i = 0; i < S.m; i++) if (rowSums[i] > best) best = rowSums[i];
54418
+ return best;
54419
+ }
51512
54420
  function scaledEuclid(magnitudes, count) {
51513
54421
  let scale = 0;
51514
54422
  let ssq = 1;
@@ -52133,11 +55041,18 @@ defineBuiltin({
52133
55041
  if (a.kind === "complex_or_number") return [COMPLEX_OR_NUM];
52134
55042
  if (a.kind === "tensor")
52135
55043
  return [{ kind: "tensor", isComplex: a.isComplex }];
55044
+ if (a.kind === "sparse_matrix")
55045
+ return [{ kind: "sparse_matrix", isComplex: a.isComplex }];
52136
55046
  return null;
52137
55047
  },
52138
- apply: (args) => {
55048
+ apply: function invApply(args) {
52139
55049
  if (args.length < 1) throw new RuntimeError("inv requires 1 argument");
52140
55050
  const A = args[0];
55051
+ if (isRuntimeSparseMatrix(A)) {
55052
+ if (!A.pi) return sparseInverse(A);
55053
+ const dense = invApply([sparseToDense(A)]);
55054
+ return isRuntimeTensor(dense) ? denseToSparse(dense) : dense;
55055
+ }
52141
55056
  if (isRuntimeComplexNumber(A)) {
52142
55057
  const { re, im } = A;
52143
55058
  if (re === 0 && im === 0)
@@ -52490,6 +55405,67 @@ registerIBuiltin({
52490
55405
  return { outputTypes: outs, apply: (args, n) => bandwidthApply(args, n) };
52491
55406
  }
52492
55407
  });
55408
+ function isTriangularValue(A, upper) {
55409
+ if (isRuntimeNumber(A) || isRuntimeComplexNumber(A)) return true;
55410
+ if (isRuntimeSparseMatrix(A))
55411
+ return upper ? sparseIsUpper(A) : sparseIsLower(A);
55412
+ if (isRuntimeTensor(A)) {
55413
+ if (A.shape.length > 2) return false;
55414
+ const [m, n] = tensorSize2D(A);
55415
+ for (let j = 0; j < n; j++)
55416
+ for (let i = 0; i < m; i++) {
55417
+ if (upper ? i <= j : i >= j) continue;
55418
+ const idx = colMajorIndex(i, j, m);
55419
+ if (A.data[idx] !== 0 || A.imag && A.imag[idx] !== 0) return false;
55420
+ }
55421
+ return true;
55422
+ }
55423
+ throw new RuntimeError("istriu: argument must be a numeric matrix");
55424
+ }
55425
+ for (const [name, upper] of [
55426
+ ["istriu", true],
55427
+ ["istril", false]
55428
+ ]) {
55429
+ registerIBuiltin({
55430
+ name,
55431
+ help: {
55432
+ signatures: [`tf = ${name}(A)`],
55433
+ 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.`
55434
+ },
55435
+ resolve: (argTypes, nargout) => {
55436
+ if (nargout > 1 || argTypes.length !== 1) return null;
55437
+ if (!isNumericJitType(argTypes[0])) return null;
55438
+ return {
55439
+ outputTypes: [{ kind: "boolean" }],
55440
+ apply: (args) => RTV.logical(isTriangularValue(args[0], upper))
55441
+ };
55442
+ }
55443
+ });
55444
+ }
55445
+ registerIBuiltin({
55446
+ name: "isbanded",
55447
+ help: {
55448
+ signatures: ["tf = isbanded(A, lower, upper)"],
55449
+ description: "True if A has lower bandwidth at most `lower` and upper bandwidth at most `upper`. Works for dense and sparse matrices."
55450
+ },
55451
+ resolve: (argTypes, nargout) => {
55452
+ if (nargout > 1 || argTypes.length !== 3) return null;
55453
+ if (!isNumericJitType(argTypes[0])) return null;
55454
+ return {
55455
+ outputTypes: [{ kind: "boolean" }],
55456
+ apply: (args) => {
55457
+ const lo = toNumber(args[1]);
55458
+ const up = toNumber(args[2]);
55459
+ if (lo < 0 || up < 0 || !Number.isInteger(lo) || !Number.isInteger(up))
55460
+ throw new RuntimeError(
55461
+ "isbanded: bandwidths must be nonnegative integers"
55462
+ );
55463
+ const [l, u] = computeBandwidth(args[0]);
55464
+ return RTV.logical(l <= lo && u <= up);
55465
+ }
55466
+ };
55467
+ }
55468
+ });
52493
55469
  function computeATA(A_data, m, n) {
52494
55470
  const result = allocFloat64Array(n * n);
52495
55471
  for (let j = 0; j < n; j++)
@@ -52858,19 +55834,59 @@ function qrPivotApply(A, m, n, k, econ) {
52858
55834
  registerIBuiltin({
52859
55835
  name: "lu",
52860
55836
  resolve: (argTypes, nargout) => {
52861
- if (nargout < 0 || nargout > 3) return null;
52862
- if (argTypes.length < 1 || argTypes.length > 2) return null;
55837
+ if (nargout < 0 || nargout > 4) return null;
55838
+ if (argTypes.length < 1 || argTypes.length > 3) return null;
52863
55839
  if (!isNumericJitType(argTypes[0])) return null;
52864
- const t = tensorType();
55840
+ const sparse = argTypes[0].kind === "sparse_matrix";
55841
+ if (!sparse && (nargout > 3 || argTypes.length > 2)) return null;
55842
+ const t = sparse ? SPARSE_TYPE : tensorType();
52865
55843
  const wrapped = (args, n) => withScratch(() => luApply(args, n));
52866
55844
  if (nargout <= 1) return { outputTypes: [t], apply: wrapped };
52867
55845
  if (nargout === 2) return { outputTypes: [t, t], apply: wrapped };
52868
- return { outputTypes: [t, t, t], apply: wrapped };
55846
+ if (nargout === 3) return { outputTypes: [t, t, t], apply: wrapped };
55847
+ return { outputTypes: [t, t, t, t], apply: wrapped };
52869
55848
  }
52870
55849
  });
55850
+ function sparseLuApply(S, args, nargout) {
55851
+ let outputForm = "matrix";
55852
+ let tol = nargout >= 4 ? 0.1 : 1;
55853
+ for (const opt of args.slice(1)) {
55854
+ if (isRuntimeNumber(opt)) {
55855
+ if (!(opt >= 0 && opt <= 1))
55856
+ throw new RuntimeError("lu: pivot threshold must be in [0, 1]");
55857
+ tol = opt;
55858
+ } else {
55859
+ const form = parseLuOutputForm(opt);
55860
+ if (form === null)
55861
+ throw new RuntimeError("lu: outputForm must be 'matrix' or 'vector'");
55862
+ outputForm = form;
55863
+ }
55864
+ }
55865
+ const q = nargout >= 4 ? columnOrdering(S) : null;
55866
+ const res = sparseLu(S, q, tol);
55867
+ const { L, U, p: p2 } = res;
55868
+ if (nargout <= 1) {
55869
+ return mSub(mAdd(L, U), speyeSparse(Math.min(S.m, S.n)));
55870
+ }
55871
+ if (nargout === 2) {
55872
+ const Lperm = sparsePermute(L, invertPerm(p2), identityPerm(L.n));
55873
+ return [Lperm, U];
55874
+ }
55875
+ const permOut = (perm) => outputForm === "vector" ? permVectorTensor(perm) : permutationMatrix(perm);
55876
+ if (nargout === 3) return [L, U, permOut(p2)];
55877
+ const Q = outputForm === "vector" ? permVectorTensor(res.q) : sparseTranspose(permutationMatrix(res.q));
55878
+ return [L, U, permOut(p2), Q];
55879
+ }
52871
55880
  function luApply(args, nargout) {
52872
55881
  if (args.length < 1)
52873
55882
  throw new RuntimeError("lu requires at least 1 argument");
55883
+ if (isRuntimeSparseMatrix(args[0]) && !args[0].pi)
55884
+ return sparseLuApply(args[0], args, nargout);
55885
+ if (isRuntimeSparseMatrix(args[0])) {
55886
+ const dense = luApply([sparseToDense(args[0]), ...args.slice(1)], nargout);
55887
+ const toSp = (v) => isRuntimeTensor(v) ? denseToSparse(v) : v;
55888
+ return Array.isArray(dense) ? dense.map(toSp) : toSp(dense);
55889
+ }
52874
55890
  const outputForm = args.length >= 2 ? parseLuOutputForm(args[1]) : "matrix";
52875
55891
  if (outputForm === null)
52876
55892
  throw new RuntimeError("lu: outputForm must be 'matrix' or 'vector'");
@@ -52989,7 +56005,7 @@ function ipivToPermVector(ipiv, m) {
52989
56005
  registerIBuiltin({
52990
56006
  name: "eig",
52991
56007
  resolve: (argTypes, nargout) => {
52992
- if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
56008
+ if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 4)
52993
56009
  return null;
52994
56010
  if (!isNumericJitType(argTypes[0])) return null;
52995
56011
  const c = tensorType(true);
@@ -53004,7 +56020,9 @@ function eigApply(args, nargout) {
53004
56020
  if (args.length < 1)
53005
56021
  throw new RuntimeError("eig requires at least 1 argument");
53006
56022
  const A = args[0];
53007
- const { balance, outputForm } = parseEigOptionsRuntime(args);
56023
+ const { B, balance, outputForm, algorithm } = parseEigOptionsRuntime(args);
56024
+ if (B !== void 0)
56025
+ return eigGeneralizedApply(A, B, nargout, outputForm, algorithm);
53008
56026
  if (isRuntimeNumber(A)) {
53009
56027
  const val = A;
53010
56028
  if (nargout <= 1) return RTV.num(val);
@@ -53021,6 +56039,10 @@ function eigApply(args, nargout) {
53021
56039
  const [m, n] = tensorSize2D(A);
53022
56040
  if (m !== n) throw new RuntimeError("eig: input must be a square matrix");
53023
56041
  const computeVL = nargout >= 3, computeVR = nargout >= 2;
56042
+ if (isExactlyHermitian(A, n)) {
56043
+ const symResult = eigSymmetricApply(A, n, nargout, outputForm);
56044
+ if (symResult) return symResult;
56045
+ }
53024
56046
  if (A.imag) {
53025
56047
  const bridge2 = getEffectiveBridge("eigComplex", "eigComplex");
53026
56048
  if (!bridge2.eigComplex)
@@ -53056,19 +56078,369 @@ function eigApply(args, nargout) {
53056
56078
  const Wout = computeVL && VL ? buildEigenvectorMatrix(VL, wi, n, hasComplex) : RTV.tensor(allocFloat64Array(n * n), [n, n]);
53057
56079
  return [Vout, Dout, Wout];
53058
56080
  }
56081
+ function isExactlyHermitian(A, n) {
56082
+ const re = A.data;
56083
+ const im = A.imag;
56084
+ for (let j = 0; j < n; j++) {
56085
+ if (im && im[j + j * n] !== 0) return false;
56086
+ const dj = re[j + j * n];
56087
+ if (Number.isNaN(dj)) return false;
56088
+ for (let i = j + 1; i < n; i++) {
56089
+ if (re[i + j * n] !== re[j + i * n]) return false;
56090
+ if (im && im[i + j * n] !== -im[j + i * n]) return false;
56091
+ }
56092
+ }
56093
+ return true;
56094
+ }
56095
+ function eigSymmetricApply(A, n, nargout, outputForm) {
56096
+ const computeV = nargout >= 2;
56097
+ let w;
56098
+ let VRe;
56099
+ let VIm;
56100
+ if (A.imag) {
56101
+ const bridge = getEffectiveBridge("eigHerm", "eigHerm");
56102
+ if (!bridge.eigHerm) return null;
56103
+ const r = bridge.eigHerm(toF64(A.data), toF64(A.imag), n, computeV);
56104
+ if (!r) return null;
56105
+ w = r.w;
56106
+ VRe = r.VRe;
56107
+ VIm = r.VIm;
56108
+ } else {
56109
+ const bridge = getEffectiveBridge("eigSym", "eigSym");
56110
+ if (!bridge.eigSym) return null;
56111
+ const r = bridge.eigSym(toF64(A.data), n, computeV);
56112
+ if (!r) return null;
56113
+ w = r.w;
56114
+ VRe = r.V;
56115
+ }
56116
+ if (nargout <= 1) return RTV.tensor(w, [n, 1]);
56117
+ const makeV = () => VRe ? maybeComplexTensor(
56118
+ allocFloat64Array(VRe),
56119
+ [n, n],
56120
+ VIm ? allocFloat64Array(VIm) : void 0
56121
+ ) : RTV.tensor(allocFloat64Array(n * n), [n, n]);
56122
+ const Vout = makeV();
56123
+ const Dout = outputForm === "vector" ? RTV.tensor(allocFloat64Array(w), [n, 1]) : buildDiagMatrix(w, void 0, n);
56124
+ if (nargout === 2) return [Vout, Dout];
56125
+ return [Vout, Dout, makeV()];
56126
+ }
53059
56127
  function parseEigOptionsRuntime(args) {
53060
- let balance = true, outputForm = "matrix";
53061
- for (let i = 1; i < args.length; i++) {
56128
+ let balance = true, outputForm = "matrix", algorithm = "auto";
56129
+ let B;
56130
+ let first = 1;
56131
+ if (args.length >= 2 && !isStringLikeArg(args[1])) {
56132
+ B = args[1];
56133
+ first = 2;
56134
+ }
56135
+ for (let i = first; i < args.length; i++) {
53062
56136
  const arg = args[i];
53063
- if (isRuntimeString(arg) || isRuntimeChar(arg)) {
53064
- const val = parseStringArgLower(arg);
53065
- if (val === "nobalance") balance = false;
53066
- else if (val === "balance") balance = true;
53067
- else if (val === "vector") outputForm = "vector";
53068
- else if (val === "matrix") outputForm = "matrix";
56137
+ if (!isStringLikeArg(arg))
56138
+ throw new RuntimeError(
56139
+ "eig: option arguments must be character vectors or strings"
56140
+ );
56141
+ const val = parseStringArgLower(arg);
56142
+ if (val === "nobalance") balance = false;
56143
+ else if (val === "balance") balance = true;
56144
+ else if (val === "vector") outputForm = "vector";
56145
+ else if (val === "matrix") outputForm = "matrix";
56146
+ else if (val === "chol" || val === "qz") algorithm = val;
56147
+ else throw new RuntimeError(`eig: unknown option '${val}'`);
56148
+ }
56149
+ if (algorithm !== "auto" && B === void 0)
56150
+ throw new RuntimeError(
56151
+ `eig: the '${algorithm}' algorithm applies only to eig(A, B)`
56152
+ );
56153
+ return { B, balance, outputForm, algorithm };
56154
+ }
56155
+ function isStringLikeArg(arg) {
56156
+ return isRuntimeString(arg) || isRuntimeChar(arg);
56157
+ }
56158
+ function toSplitSquare(v, name) {
56159
+ if (isRuntimeNumber(v))
56160
+ return { M: { re: allocFloat64Array([v]), im: null }, n: 1 };
56161
+ if (isRuntimeComplexNumber(v))
56162
+ return {
56163
+ M: { re: allocFloat64Array([v.re]), im: allocFloat64Array([v.im]) },
56164
+ n: 1
56165
+ };
56166
+ let t = v;
56167
+ if (isRuntimeSparseMatrix(t))
56168
+ t = sparseToDense(
56169
+ t
56170
+ );
56171
+ if (!isRuntimeTensor(t))
56172
+ throw new RuntimeError(`eig: ${name} must be a numeric matrix`);
56173
+ const [rows, cols] = tensorSize2D(t);
56174
+ if (rows !== cols)
56175
+ throw new RuntimeError(`eig: ${name} must be a square matrix`);
56176
+ return {
56177
+ M: { re: toF64(t.data), im: t.imag ? toF64(t.imag) : null },
56178
+ n: rows
56179
+ };
56180
+ }
56181
+ function splitIsHermitian(M, n) {
56182
+ for (let j = 0; j < n; j++) {
56183
+ if (M.im && M.im[j + j * n] !== 0) return false;
56184
+ if (Number.isNaN(M.re[j + j * n])) return false;
56185
+ for (let i = j + 1; i < n; i++) {
56186
+ if (M.re[i + j * n] !== M.re[j + i * n]) return false;
56187
+ if (M.im && M.im[i + j * n] !== -M.im[j + i * n]) return false;
56188
+ }
56189
+ }
56190
+ return true;
56191
+ }
56192
+ function eigGeneralizedApply(Aval, Bval, nargout, outputForm, algorithm) {
56193
+ const { M: A, n } = toSplitSquare(Aval, "A");
56194
+ const { M: B, n: nB } = toSplitSquare(Bval, "B");
56195
+ if (n !== nB) throw new RuntimeError("eig: A and B must be the same size");
56196
+ if (algorithm !== "qz" && splitIsHermitian(A, n) && splitIsHermitian(B, n)) {
56197
+ const R = choleskyFactor(B, n);
56198
+ if (R) return eigSymmetricDefinite(A, R, n, nargout, outputForm);
56199
+ if (algorithm === "chol")
56200
+ throw new RuntimeError(
56201
+ "eig: the 'chol' algorithm requires B to be symmetric positive definite"
56202
+ );
56203
+ }
56204
+ return eigGeneralizedQz(A, B, n, nargout, outputForm);
56205
+ }
56206
+ function choleskyFactor(B, n) {
56207
+ if (B.im) {
56208
+ const bridge2 = getEffectiveBridge("cholComplex", "cholComplex");
56209
+ if (!bridge2.cholComplex) return null;
56210
+ const r2 = bridge2.cholComplex(B.re, B.im, n, true);
56211
+ if (!r2 || r2.info !== 0) return null;
56212
+ return { re: r2.RRe, im: r2.RIm };
56213
+ }
56214
+ const bridge = getEffectiveBridge("chol", "chol");
56215
+ if (!bridge.chol) return null;
56216
+ const r = bridge.chol(B.re, n, true);
56217
+ if (!r || r.info !== 0) return null;
56218
+ return { re: r.R, im: null };
56219
+ }
56220
+ function eigSymmetricDefinite(A, R, n, nargout, outputForm) {
56221
+ const complex = !!(A.im || R.im);
56222
+ const Y = solveLeftConjTransposeUpper(R, A, n, complex);
56223
+ const C = solveRightUpper(Y, R, n, complex);
56224
+ symmetrizeInPlace(C, n);
56225
+ const computeV = nargout >= 2;
56226
+ let w;
56227
+ let SRe;
56228
+ let SIm;
56229
+ if (complex) {
56230
+ const bridge = getEffectiveBridge("eigHerm", "eigHerm");
56231
+ if (!bridge.eigHerm)
56232
+ throw new RuntimeError("eig: Hermitian eig bridge not available");
56233
+ const r = bridge.eigHerm(
56234
+ C.re,
56235
+ C.im ?? allocFloat64Array(n * n),
56236
+ n,
56237
+ computeV
56238
+ );
56239
+ w = r.w;
56240
+ SRe = r.VRe;
56241
+ SIm = r.VIm;
56242
+ } else {
56243
+ const bridge = getEffectiveBridge("eigSym", "eigSym");
56244
+ if (!bridge.eigSym)
56245
+ throw new RuntimeError("eig: symmetric eig bridge not available");
56246
+ const r = bridge.eigSym(C.re, n, computeV);
56247
+ w = r.w;
56248
+ SRe = r.V;
56249
+ }
56250
+ if (nargout <= 1) return RTV.tensor(w, [n, 1]);
56251
+ const S = {
56252
+ re: SRe ?? allocFloat64Array(n * n),
56253
+ im: SIm ?? null
56254
+ };
56255
+ const V = SRe ? solveUpper(R, S, n, complex) : S;
56256
+ const makeV = () => maybeComplexTensor(
56257
+ allocFloat64Array(V.re),
56258
+ [n, n],
56259
+ V.im ? allocFloat64Array(V.im) : void 0
56260
+ );
56261
+ const Vout = makeV();
56262
+ const Dout = outputForm === "vector" ? RTV.tensor(allocFloat64Array(w), [n, 1]) : buildDiagMatrix(w, void 0, n);
56263
+ if (nargout === 2) return [Vout, Dout];
56264
+ return [Vout, Dout, makeV()];
56265
+ }
56266
+ function symmetrizeInPlace(M, n) {
56267
+ for (let j = 0; j < n; j++) {
56268
+ if (M.im) M.im[j + j * n] = 0;
56269
+ for (let i = j + 1; i < n; i++) {
56270
+ const a = (M.re[i + j * n] + M.re[j + i * n]) / 2;
56271
+ M.re[i + j * n] = a;
56272
+ M.re[j + i * n] = a;
56273
+ if (M.im) {
56274
+ const b = (M.im[i + j * n] - M.im[j + i * n]) / 2;
56275
+ M.im[i + j * n] = b;
56276
+ M.im[j + i * n] = -b;
56277
+ }
56278
+ }
56279
+ }
56280
+ }
56281
+ function solveLeftConjTransposeUpper(R, Bm, n, complex) {
56282
+ const X = {
56283
+ re: allocFloat64Array(n * n),
56284
+ im: complex ? allocFloat64Array(n * n) : null
56285
+ };
56286
+ for (let c = 0; c < n; c++) {
56287
+ for (let i = 0; i < n; i++) {
56288
+ let sr = Bm.re[i + c * n];
56289
+ let si = Bm.im ? Bm.im[i + c * n] : 0;
56290
+ for (let k = 0; k < i; k++) {
56291
+ const lr = R.re[k + i * n];
56292
+ const li = R.im ? -R.im[k + i * n] : 0;
56293
+ const xr = X.re[k + c * n];
56294
+ const xi = X.im ? X.im[k + c * n] : 0;
56295
+ sr -= lr * xr - li * xi;
56296
+ si -= lr * xi + li * xr;
56297
+ }
56298
+ const dr = R.re[i + i * n];
56299
+ const di = R.im ? -R.im[i + i * n] : 0;
56300
+ const [qr2, qi] = complexDivide2(sr, si, dr, di);
56301
+ X.re[i + c * n] = qr2;
56302
+ if (X.im) X.im[i + c * n] = qi;
56303
+ }
56304
+ }
56305
+ return X;
56306
+ }
56307
+ function solveRightUpper(Y, R, n, complex) {
56308
+ const C = {
56309
+ re: allocFloat64Array(n * n),
56310
+ im: complex ? allocFloat64Array(n * n) : null
56311
+ };
56312
+ for (let j = 0; j < n; j++) {
56313
+ for (let i = 0; i < n; i++) {
56314
+ let sr = Y.re[i + j * n];
56315
+ let si = Y.im ? Y.im[i + j * n] : 0;
56316
+ for (let k = 0; k < j; k++) {
56317
+ const cr = C.re[i + k * n];
56318
+ const ci = C.im ? C.im[i + k * n] : 0;
56319
+ const rr = R.re[k + j * n];
56320
+ const ri = R.im ? R.im[k + j * n] : 0;
56321
+ sr -= cr * rr - ci * ri;
56322
+ si -= cr * ri + ci * rr;
56323
+ }
56324
+ const dr = R.re[j + j * n];
56325
+ const di = R.im ? R.im[j + j * n] : 0;
56326
+ const [qr2, qi] = complexDivide2(sr, si, dr, di);
56327
+ C.re[i + j * n] = qr2;
56328
+ if (C.im) C.im[i + j * n] = qi;
56329
+ }
56330
+ }
56331
+ return C;
56332
+ }
56333
+ function solveUpper(R, S, n, complex) {
56334
+ const V = {
56335
+ re: allocFloat64Array(n * n),
56336
+ im: complex ? allocFloat64Array(n * n) : null
56337
+ };
56338
+ for (let c = 0; c < n; c++) {
56339
+ for (let i = n - 1; i >= 0; i--) {
56340
+ let sr = S.re[i + c * n];
56341
+ let si = S.im ? S.im[i + c * n] : 0;
56342
+ for (let k = i + 1; k < n; k++) {
56343
+ const rr = R.re[i + k * n];
56344
+ const ri = R.im ? R.im[i + k * n] : 0;
56345
+ const vr = V.re[k + c * n];
56346
+ const vi = V.im ? V.im[k + c * n] : 0;
56347
+ sr -= rr * vr - ri * vi;
56348
+ si -= rr * vi + ri * vr;
56349
+ }
56350
+ const dr = R.re[i + i * n];
56351
+ const di = R.im ? R.im[i + i * n] : 0;
56352
+ const [qr2, qi] = complexDivide2(sr, si, dr, di);
56353
+ V.re[i + c * n] = qr2;
56354
+ if (V.im) V.im[i + c * n] = qi;
56355
+ }
56356
+ }
56357
+ return V;
56358
+ }
56359
+ function complexDivide2(ar, ai, br, bi) {
56360
+ if (bi === 0) return [ar / br, ai / br];
56361
+ if (Math.abs(br) >= Math.abs(bi)) {
56362
+ const r2 = bi / br;
56363
+ const t2 = br + bi * r2;
56364
+ return [(ar + ai * r2) / t2, (ai - ar * r2) / t2];
56365
+ }
56366
+ const r = br / bi;
56367
+ const t = br * r + bi;
56368
+ return [(ar * r + ai) / t, (ai * r - ar) / t];
56369
+ }
56370
+ function eigGeneralizedQz(A, B, n, nargout, outputForm) {
56371
+ const computeEigvecs = nargout >= 2;
56372
+ const wr = allocFloat64Array(n);
56373
+ const wi = allocFloat64Array(n);
56374
+ let V = null;
56375
+ let W = null;
56376
+ if (A.im || B.im) {
56377
+ const bridge = getEffectiveBridge("qzComplex", "qzComplex");
56378
+ if (!bridge.qzComplex) throw generalizedUnsupported();
56379
+ const r = bridge.qzComplex(
56380
+ A.re,
56381
+ A.im ?? allocFloat64Array(n * n),
56382
+ B.re,
56383
+ B.im ?? allocFloat64Array(n * n),
56384
+ n,
56385
+ computeEigvecs
56386
+ );
56387
+ if (!r) throw new RuntimeError("eig: complex QZ failed");
56388
+ for (let i = 0; i < n; i++) {
56389
+ const [qr2, qi] = complexDivide2(
56390
+ r.alphaRe[i],
56391
+ r.alphaIm[i],
56392
+ r.betaRe[i],
56393
+ r.betaIm[i]
56394
+ );
56395
+ wr[i] = qr2;
56396
+ wi[i] = qi;
56397
+ }
56398
+ if (computeEigvecs) {
56399
+ if (!r.VRe || !r.VIm || !r.WRe || !r.WIm)
56400
+ throw new RuntimeError(
56401
+ "eig: failed to compute generalized eigenvectors"
56402
+ );
56403
+ V = maybeComplexTensor(
56404
+ allocFloat64Array(r.VRe),
56405
+ [n, n],
56406
+ allocFloat64Array(r.VIm)
56407
+ );
56408
+ W = maybeComplexTensor(
56409
+ allocFloat64Array(r.WRe),
56410
+ [n, n],
56411
+ allocFloat64Array(r.WIm)
56412
+ );
56413
+ }
56414
+ } else {
56415
+ const bridge = getEffectiveBridge("qz", "qz");
56416
+ if (!bridge.qz) throw generalizedUnsupported();
56417
+ const r = bridge.qz(A.re, B.re, n, computeEigvecs);
56418
+ if (!r) throw new RuntimeError("eig: real QZ failed");
56419
+ let hasComplex = false;
56420
+ for (let i = 0; i < n; i++) {
56421
+ const beta = r.beta[i];
56422
+ wr[i] = r.alphar[i] / beta;
56423
+ wi[i] = r.alphai[i] === 0 && beta === 0 ? 0 : r.alphai[i] / beta;
56424
+ if (r.alphai[i] !== 0) hasComplex = true;
56425
+ }
56426
+ if (computeEigvecs) {
56427
+ if (!r.V || !r.W)
56428
+ throw new RuntimeError(
56429
+ "eig: failed to compute generalized eigenvectors"
56430
+ );
56431
+ V = buildEigenvectorMatrix(r.V, r.alphai, n, hasComplex);
56432
+ W = buildEigenvectorMatrix(r.W, r.alphai, n, hasComplex);
53069
56433
  }
53070
56434
  }
53071
- return { balance, outputForm };
56435
+ if (nargout <= 1) return maybeComplexTensor(wr, [n, 1], wi);
56436
+ const Dout = outputForm === "vector" ? maybeComplexTensor(wr, [n, 1], wi) : buildDiagMatrix(wr, wi, n);
56437
+ if (nargout === 2) return [V, Dout];
56438
+ return [V, Dout, W];
56439
+ }
56440
+ function generalizedUnsupported() {
56441
+ return new RuntimeError(
56442
+ "eig: the generalized eigenvalue problem eig(A, B) with a non symmetric-definite pencil requires the native LAPACK addon"
56443
+ );
53072
56444
  }
53073
56445
  registerIBuiltin({
53074
56446
  name: "chol",
@@ -53076,13 +56448,31 @@ registerIBuiltin({
53076
56448
  if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
53077
56449
  return null;
53078
56450
  if (!isNumericJitType(argTypes[0])) return null;
53079
- const t = tensorType();
56451
+ const t = argTypes[0].kind === "sparse_matrix" ? SPARSE_TYPE : tensorType();
53080
56452
  const wrapped = (args, n) => withScratch(() => cholApply(args, n));
53081
56453
  if (nargout <= 1) return { outputTypes: [t], apply: wrapped };
53082
56454
  if (nargout === 2) return { outputTypes: [t, NUM], apply: wrapped };
53083
56455
  return { outputTypes: [t, NUM, t], apply: wrapped };
53084
56456
  }
53085
56457
  });
56458
+ function sparseCholApply(S, upper, outputForm, nargout) {
56459
+ if (S.m !== S.n) throw new RuntimeError("chol: Matrix must be square.");
56460
+ const n = S.n;
56461
+ const perm = nargout >= 3 ? minimumDegreeOrdering(S) : identityPerm(n);
56462
+ const A = nargout >= 3 ? sparsePermute(S, perm, perm) : S;
56463
+ const res = sparseChol(A);
56464
+ const R = upper ? sparseTranspose(res.L) : res.L;
56465
+ const permOut = () => outputForm === "vector" ? permVectorTensor(perm) : permutationMatrix(invertPerm(perm));
56466
+ if (!res.ok) {
56467
+ if (nargout < 2)
56468
+ throw new RuntimeError("chol: Matrix must be positive definite.");
56469
+ if (nargout >= 3) return [R, RTV.num(res.p), permOut()];
56470
+ return [R, RTV.num(res.p)];
56471
+ }
56472
+ if (nargout >= 3) return [R, RTV.num(0), permOut()];
56473
+ if (nargout === 2) return [R, RTV.num(0)];
56474
+ return R;
56475
+ }
53086
56476
  function cholApply(args, nargout) {
53087
56477
  if (args.length < 1)
53088
56478
  throw new RuntimeError("chol requires at least 1 argument");
@@ -53090,10 +56480,9 @@ function cholApply(args, nargout) {
53090
56480
  const inputIsSparse = isRuntimeSparseMatrix(A);
53091
56481
  if (nargout >= 3 && !inputIsSparse)
53092
56482
  throw new RuntimeError("Third output only available for sparse matrices.");
53093
- if (inputIsSparse)
53094
- A = sparseToDense(
53095
- A
53096
- );
56483
+ const sparseInput = isRuntimeSparseMatrix(A) && !A.pi ? A : null;
56484
+ if (inputIsSparse && !sparseInput)
56485
+ A = sparseToDense(A);
53097
56486
  let triangle = "upper";
53098
56487
  let outputForm = "matrix";
53099
56488
  if (args.length === 2) {
@@ -53112,6 +56501,8 @@ function cholApply(args, nargout) {
53112
56501
  outputForm = form;
53113
56502
  }
53114
56503
  const upper = triangle === "upper";
56504
+ if (sparseInput)
56505
+ return sparseCholApply(sparseInput, upper, outputForm, nargout);
53115
56506
  if (isRuntimeNumber(A)) {
53116
56507
  const val = A;
53117
56508
  if (val <= 0) {
@@ -53529,15 +56920,28 @@ defineBuiltin({
53529
56920
  if (nargout > 1 || argTypes.length !== 2) return null;
53530
56921
  if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
53531
56922
  return null;
56923
+ if (argTypes.some((t) => t.kind === "sparse_matrix"))
56924
+ return [
56925
+ {
56926
+ kind: "sparse_matrix",
56927
+ isComplex: argTypes.some(
56928
+ (t) => t.kind === "sparse_matrix" && t.isComplex
56929
+ )
56930
+ }
56931
+ ];
53532
56932
  return [tensorType()];
53533
56933
  },
53534
56934
  apply: (args) => {
53535
56935
  if (args.length !== 2)
53536
56936
  throw new RuntimeError("kron requires 2 arguments");
56937
+ if (isRuntimeSparseMatrix(args[0]) || isRuntimeSparseMatrix(args[1]))
56938
+ return sparseKron(
56939
+ toSparseOperand(args[0], "kron"),
56940
+ toSparseOperand(args[1], "kron")
56941
+ );
53537
56942
  const coerce = (v) => {
53538
56943
  if (isRuntimeNumber(v))
53539
56944
  return RTV.tensor(allocFloat64Array([v]), [1, 1]);
53540
- if (isRuntimeSparseMatrix(v)) return sparseToDense(v);
53541
56945
  if (isRuntimeTensor(v)) return v;
53542
56946
  throw new RuntimeError("kron: arguments must be numeric");
53543
56947
  };
@@ -59444,130 +62848,6 @@ registerIBuiltin({
59444
62848
  }
59445
62849
  });
59446
62850
 
59447
- // src/numbl-core/helpers/prng.ts
59448
- var _rngState = null;
59449
- var _rngSeed = 0;
59450
- var _bmSpare = null;
59451
- function setRngShuffle() {
59452
- _rngState = null;
59453
- _rngSeed = 0;
59454
- _bmSpare = null;
59455
- }
59456
- function setRngSeed(seed) {
59457
- _rngSeed = seed;
59458
- }
59459
- function splitmix32(seed) {
59460
- let s = seed | 0;
59461
- return () => {
59462
- s = s + 2654435769 | 0;
59463
- let z = s;
59464
- z = Math.imul(z ^ z >>> 16, 2246822507);
59465
- z = Math.imul(z ^ z >>> 13, 3266489909);
59466
- return (z ^ z >>> 16) >>> 0;
59467
- };
59468
- }
59469
- function seedRng(seed) {
59470
- _bmSpare = null;
59471
- const sm = splitmix32(seed);
59472
- _rngState = new Uint32Array([sm(), sm(), sm(), sm()]);
59473
- if (_rngState[0] === 0 && _rngState[1] === 0 && _rngState[2] === 0 && _rngState[3] === 0) {
59474
- _rngState[0] = 1;
59475
- }
59476
- }
59477
- function xoshiro128ss() {
59478
- const s = _rngState;
59479
- const result = Math.imul(rotl(Math.imul(s[1], 5), 7), 9) >>> 0;
59480
- const t = s[1] << 9;
59481
- s[2] ^= s[0];
59482
- s[3] ^= s[1];
59483
- s[1] ^= s[2];
59484
- s[0] ^= s[3];
59485
- s[2] ^= t;
59486
- s[3] = rotl(s[3], 11);
59487
- return result;
59488
- }
59489
- function rotl(x, k) {
59490
- return (x << k | x >>> 32 - k) >>> 0;
59491
- }
59492
- function rngRandom() {
59493
- if (_rngState === null) return Math.random();
59494
- return (xoshiro128ss() >>> 0) / 4294967296;
59495
- }
59496
- function boxMullerRandom() {
59497
- if (_bmSpare !== null) {
59498
- const s2 = _bmSpare;
59499
- _bmSpare = null;
59500
- return s2;
59501
- }
59502
- let u, v, s;
59503
- do {
59504
- u = 2 * rngRandom() - 1;
59505
- v = 2 * rngRandom() - 1;
59506
- s = u * u + v * v;
59507
- } while (s >= 1 || s === 0);
59508
- const mul = Math.sqrt(-2 * Math.log(s) / s);
59509
- _bmSpare = v * mul;
59510
- return u * mul;
59511
- }
59512
- function fillRandn(data) {
59513
- if (_rngState !== null) {
59514
- const bridge = getLapackBridge();
59515
- if (bridge?.fillRandn) {
59516
- const r = bridge.fillRandn(
59517
- _rngState,
59518
- data.length,
59519
- _bmSpare ?? 0,
59520
- _bmSpare !== null
59521
- );
59522
- _bmSpare = r.hasSpare ? r.spare : null;
59523
- data.set(r.data);
59524
- return;
59525
- }
59526
- }
59527
- const n = data.length;
59528
- let i = 0;
59529
- if (_bmSpare !== null && i < n) {
59530
- data[i++] = _bmSpare;
59531
- _bmSpare = null;
59532
- }
59533
- for (; i + 1 < n; i += 2) {
59534
- let u, v, s;
59535
- do {
59536
- u = 2 * rngRandom() - 1;
59537
- v = 2 * rngRandom() - 1;
59538
- s = u * u + v * v;
59539
- } while (s >= 1 || s === 0);
59540
- const mul = Math.sqrt(-2 * Math.log(s) / s);
59541
- data[i] = u * mul;
59542
- data[i + 1] = v * mul;
59543
- }
59544
- if (i < n) {
59545
- data[i] = boxMullerRandom();
59546
- }
59547
- }
59548
- function getRngStateStruct() {
59549
- const stateArray = _rngState ? RTV.tensor(allocFloat64Array(Array.from(_rngState).map((v) => v)), [4, 1]) : RTV.tensor(allocFloat64Array(0), [0, 1]);
59550
- return RTV.struct({
59551
- Type: RTV.char("twister"),
59552
- Seed: RTV.num(_rngSeed),
59553
- State: stateArray
59554
- });
59555
- }
59556
- function restoreRngState(s) {
59557
- const seedField = s.fields.get("Seed");
59558
- const stateField = s.fields.get("State");
59559
- if (seedField === void 0 || stateField === void 0) {
59560
- throw new RuntimeError("rng: invalid state structure");
59561
- }
59562
- _rngSeed = Math.round(toNumber(seedField));
59563
- if (isRuntimeTensor(stateField) && stateField.data.length === 4) {
59564
- _rngState = new Uint32Array(4);
59565
- for (let i = 0; i < 4; i++) _rngState[i] = stateField.data[i] >>> 0;
59566
- } else {
59567
- _rngState = null;
59568
- }
59569
- }
59570
-
59571
62851
  // src/numbl-core/interpreter/builtins/prng.ts
59572
62852
  function parseShapeArgs3(rawArgs) {
59573
62853
  const args = stripClassNameArgs(rawArgs);
@@ -63317,7 +66597,7 @@ var H = {
63317
66597
  },
63318
66598
  inv: {
63319
66599
  signatures: ["B = inv(A)"],
63320
- description: "Matrix inverse."
66600
+ description: "Matrix inverse. A sparse A gives a sparse B (computed by sparse LU); prefer A \\ b for solving systems."
63321
66601
  },
63322
66602
  expm: {
63323
66603
  signatures: ["Y = expm(X)"],
@@ -63328,8 +66608,15 @@ var H = {
63328
66608
  description: "Sum of diagonal elements."
63329
66609
  },
63330
66610
  eig: {
63331
- signatures: ["E = eig(A)", "[V, D] = eig(A)", "[V, D, W] = eig(A)"],
63332
- description: "Eigenvalues and eigenvectors of square matrix. With three outputs, W contains left eigenvectors."
66611
+ signatures: [
66612
+ "E = eig(A)",
66613
+ "[V, D] = eig(A)",
66614
+ "[V, D, W] = eig(A)",
66615
+ "E = eig(A, B)",
66616
+ "[V, D] = eig(A, B)",
66617
+ "eig(A, ..., 'vector' | 'matrix' | 'nobalance' | 'chol' | 'qz')"
66618
+ ],
66619
+ 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."
63333
66620
  },
63334
66621
  eigs: {
63335
66622
  signatures: [
@@ -63352,8 +66639,15 @@ var H = {
63352
66639
  description: "Singular value decomposition."
63353
66640
  },
63354
66641
  lu: {
63355
- signatures: ["Y = lu(A)", "[L, U] = lu(A)", "[L, U, P] = lu(A)"],
63356
- description: "LU factorization. With 2 outputs, L includes the permutation. With 3, P is a permutation matrix."
66642
+ signatures: [
66643
+ "Y = lu(A)",
66644
+ "[L, U] = lu(A)",
66645
+ "[L, U, P] = lu(A)",
66646
+ "[L, U, P] = lu(A, 'vector')",
66647
+ "[L, U, P, Q] = lu(S)",
66648
+ "[L, U, P, Q] = lu(S, thresh)"
66649
+ ],
66650
+ 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."
63357
66651
  },
63358
66652
  qr: {
63359
66653
  signatures: [
@@ -63365,8 +66659,14 @@ var H = {
63365
66659
  description: "QR factorization. With 3 outputs, E is a column permutation matrix (or vector in economy mode)."
63366
66660
  },
63367
66661
  chol: {
63368
- signatures: ["R = chol(A)", "[R, P] = chol(A)"],
63369
- description: "Cholesky factorization. A must be symmetric positive definite. With 2 outputs, P is 0 on success."
66662
+ signatures: [
66663
+ "R = chol(A)",
66664
+ "L = chol(A, 'lower')",
66665
+ "[R, p] = chol(A)",
66666
+ "[R, p, P] = chol(S)",
66667
+ "[R, p, q] = chol(S, 'vector')"
66668
+ ],
66669
+ 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."
63370
66670
  },
63371
66671
  rank: {
63372
66672
  signatures: ["K = rank(A)", "K = rank(A, TOL)"],
@@ -63394,7 +66694,7 @@ var H = {
63394
66694
  },
63395
66695
  kron: {
63396
66696
  signatures: ["K = kron(A, B)"],
63397
- description: "Kronecker tensor product."
66697
+ description: "Kronecker tensor product. If either operand is sparse, K is sparse with nnz(A)*nnz(B) entries."
63398
66698
  },
63399
66699
  linsolve: {
63400
66700
  signatures: ["X = linsolve(A, B)"],
@@ -64800,7 +68100,7 @@ function getSourceLine(getSource, file, line) {
64800
68100
  }
64801
68101
 
64802
68102
  // src/numbl-core/version.ts
64803
- var NUMBL_VERSION = "0.4.19";
68103
+ var NUMBL_VERSION = "0.4.21";
64804
68104
 
64805
68105
  // src/cli-repl.ts
64806
68106
  import { createInterface } from "readline";
@@ -66024,9 +69324,9 @@ function analyzeLoop(stmt) {
66024
69324
  };
66025
69325
  }
66026
69326
  function collectReadsFromSiblings(stmts, startIdx, out) {
66027
- const sink = /* @__PURE__ */ new Set();
69327
+ const sink2 = /* @__PURE__ */ new Set();
66028
69328
  for (let i = startIdx; i < stmts.length; i++) {
66029
- walkStmt2(stmts[i], sink, out);
69329
+ walkStmt2(stmts[i], sink2, out);
66030
69330
  }
66031
69331
  }
66032
69332
  function walkStmts(stmts, assigned, referenced) {
@@ -70905,14 +74205,6 @@ end
70905
74205
  name: "+matlab/+internal/+math/blkdiag.m",
70906
74206
  source: "function B = blkdiag(varargin)\n B = builtin('blkdiag', varargin{:});\nend\n"
70907
74207
  },
70908
- {
70909
- name: "decomposition.m",
70910
- 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"
70911
- },
70912
- {
70913
- name: "isIllConditioned.m",
70914
- source: "function result = isIllConditioned(dA)\n result = dA.isIllCond;\nend\n"
70915
- },
70916
74208
  {
70917
74209
  name: "uihtml.m",
70918
74210
  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"
@@ -80231,7 +83523,7 @@ function cCos(z) {
80231
83523
  im: -Math.sin(z.re) * Math.sinh(z.im)
80232
83524
  };
80233
83525
  }
80234
- function cdiv2(a, b) {
83526
+ function cdiv3(a, b) {
80235
83527
  if (Math.abs(b.re) >= Math.abs(b.im)) {
80236
83528
  const r2 = b.im / b.re;
80237
83529
  const den2 = b.re + r2 * b.im;
@@ -80242,7 +83534,7 @@ function cdiv2(a, b) {
80242
83534
  return { re: (a.re * r + a.im) / den, im: (a.im * r - a.re) / den };
80243
83535
  }
80244
83536
  function cTan(z) {
80245
- return cdiv2(cSin(z), cCos(z));
83537
+ return cdiv3(cSin(z), cCos(z));
80246
83538
  }
80247
83539
  function cSinh(z) {
80248
83540
  return {
@@ -80264,7 +83556,7 @@ function cAtan(z) {
80264
83556
  const iz = { re: -z.im, im: z.re };
80265
83557
  const num = { re: 1 - iz.re, im: -iz.im };
80266
83558
  const den = { re: 1 + iz.re, im: iz.im };
80267
- const q = cdiv2(num, den);
83559
+ const q = cdiv3(num, den);
80268
83560
  const l = cLog(q);
80269
83561
  return { re: -l.im / 2, im: l.re / 2 };
80270
83562
  }