@danielsimonjr/mathts-functions 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9930,7 +9930,143 @@ function substitute(expr, vars) {
9930
9930
  }
9931
9931
  return result;
9932
9932
  }
9933
+ function isNearInt(c) {
9934
+ return Math.abs(c - Math.round(c)) < 1e-7;
9935
+ }
9936
+ function polyToDense(p) {
9937
+ let maxPow = 0;
9938
+ for (const t of p) maxPow = Math.max(maxPow, t.powers[0] ?? 0);
9939
+ const dense = new Array(maxPow + 1).fill(0);
9940
+ for (const t of p) dense[t.powers[0]] += t.coeff;
9941
+ return trimPoly(dense);
9942
+ }
9943
+ function denseToPoly(coeffs) {
9944
+ return coeffs.map((coeff, i) => ({ coeff, powers: [i] })).filter((t) => Math.abs(t.coeff) > 1e-10);
9945
+ }
9946
+ function divisorsOf(n) {
9947
+ const m = Math.abs(Math.round(n)) || 1;
9948
+ const divs = [];
9949
+ for (let i = 1; i <= m; i++) if (m % i === 0) divs.push(i);
9950
+ return divs;
9951
+ }
9952
+ function ratReduce(r) {
9953
+ let { n, d } = r;
9954
+ if (d < 0) {
9955
+ n = -n;
9956
+ d = -d;
9957
+ }
9958
+ const g = gcdNum(Math.abs(n), Math.abs(d)) || 1;
9959
+ return { n: n / g, d: d / g };
9960
+ }
9961
+ function ratPolyval(coeffs, r) {
9962
+ let acc = { n: 0, d: 1 };
9963
+ for (let i = coeffs.length - 1; i >= 0; i--) {
9964
+ acc = ratReduce({
9965
+ n: acc.n * r.n + coeffs[i] * acc.d * r.d,
9966
+ d: acc.d * r.d
9967
+ });
9968
+ }
9969
+ return acc;
9970
+ }
9971
+ function findRationalLinearFactors(poly) {
9972
+ let cur = trimPoly(poly.map((c) => Math.round(c)));
9973
+ const roots = [];
9974
+ let repeated = false;
9975
+ const hasRoot = (r) => roots.some((x) => x.n === r.n && x.d === r.d);
9976
+ for (; ; ) {
9977
+ const deg = cur.length - 1;
9978
+ if (deg < 1) break;
9979
+ if (cur[0] === 0) {
9980
+ const r = { n: 0, d: 1 };
9981
+ if (hasRoot(r)) repeated = true;
9982
+ roots.push(r);
9983
+ cur = trimPoly(cur.slice(1));
9984
+ continue;
9985
+ }
9986
+ const ps = divisorsOf(cur[0]);
9987
+ const qs = divisorsOf(cur[cur.length - 1]);
9988
+ let found = null;
9989
+ let quotient = null;
9990
+ outer: for (const q of qs) {
9991
+ for (const pAbs of ps) {
9992
+ for (const sign3 of [1, -1]) {
9993
+ const candidate = ratReduce({ n: sign3 * pAbs, d: q });
9994
+ const divisor = trimPoly([-candidate.n, candidate.d]);
9995
+ const rem = polynomialRemainder(cur, divisor);
9996
+ if (rem.length === 1 && Math.abs(rem[0]) < 1e-6) {
9997
+ found = candidate;
9998
+ quotient = polynomialQuotient(cur, divisor).map((c) => Math.round(c * 1e6) / 1e6);
9999
+ break outer;
10000
+ }
10001
+ }
10002
+ }
10003
+ }
10004
+ if (!found || !quotient) break;
10005
+ if (hasRoot(found)) repeated = true;
10006
+ roots.push(found);
10007
+ cur = trimPoly(quotient);
10008
+ }
10009
+ return { roots, remainder: cur, repeated };
10010
+ }
10011
+ function formatLinearFactor(r, varName) {
10012
+ const base = r.d === 1 ? varName : `${r.d}*${varName}`;
10013
+ if (r.n === 0) return `(${base})`;
10014
+ return r.n > 0 ? `(${base} - ${r.n})` : `(${base} + ${-r.n})`;
10015
+ }
10016
+ function formatPartialTerm(a, root2, varName) {
10017
+ const rootExpr = root2.d === 1 ? root2.n === 0 ? varName : root2.n > 0 ? `${varName} - ${root2.n}` : `${varName} + ${-root2.n}` : `${varName} - ${root2.n}/${root2.d}`;
10018
+ const denomExpr = a.d === 1 ? `(${rootExpr})` : `(${a.d}*(${rootExpr}))`;
10019
+ if (a.n === 1) return `1/${denomExpr}`;
10020
+ if (a.n === -1) return `-1/${denomExpr}`;
10021
+ return `${a.n}/${denomExpr}`;
10022
+ }
10023
+ function splitTopLevelSum(expr) {
10024
+ const s = expr.replace(/\s+/g, "");
10025
+ const terms = [];
10026
+ let depth = 0;
10027
+ let start = 0;
10028
+ for (let i = 0; i < s.length; i++) {
10029
+ const c = s[i];
10030
+ if (c === "(") depth++;
10031
+ else if (c === ")") depth--;
10032
+ else if (depth === 0 && (c === "+" || c === "-") && i > start) {
10033
+ const prev = s[i - 1];
10034
+ if (!/[*/^(+-]/.test(prev)) {
10035
+ terms.push(s.slice(start, i));
10036
+ start = i;
10037
+ }
10038
+ }
10039
+ }
10040
+ terms.push(s.slice(start));
10041
+ return terms.filter((t) => t !== "");
10042
+ }
10043
+ function splitProductChain(term) {
10044
+ const nums = [];
10045
+ const dens = [];
10046
+ let depth = 0;
10047
+ let start = 0;
10048
+ let op = "*";
10049
+ for (let i = 0; i <= term.length; i++) {
10050
+ const c = term[i];
10051
+ if (c === "(") depth++;
10052
+ else if (c === ")") depth--;
10053
+ if (depth === 0 && (c === "*" || c === "/" || i === term.length)) {
10054
+ const piece = term.slice(start, i).trim();
10055
+ if (piece !== "") (op === "*" ? nums : dens).push(piece);
10056
+ if (i < term.length) op = c;
10057
+ start = i + 1;
10058
+ }
10059
+ }
10060
+ return { nums, dens };
10061
+ }
9933
10062
  function expand(expr) {
10063
+ const univariateVars = variables(expr);
10064
+ if (univariateVars.length === 1) {
10065
+ try {
10066
+ return polyToString(polyFromExpression(expr, univariateVars), univariateVars);
10067
+ } catch {
10068
+ }
10069
+ }
9934
10070
  let result = expr;
9935
10071
  result = result.replace(/\(([^()]+)\)\^2/g, "($1)*($1)");
9936
10072
  const splitTerms = (factor2) => factor2.replace(/\s*-\s*/g, " + -").split(/\s*\+\s*/).map((t) => t.trim()).filter((t) => t !== "");
@@ -9951,6 +10087,27 @@ function expand(expr) {
9951
10087
  return result;
9952
10088
  }
9953
10089
  function factor(expr) {
10090
+ const univariateVars = variables(expr);
10091
+ if (univariateVars.length === 1) {
10092
+ try {
10093
+ const v = univariateVars[0];
10094
+ const dense = polyToDense(polyFromExpression(expr, [v]));
10095
+ if (degree(dense) >= 2 && dense.every(isNearInt)) {
10096
+ const intDense = dense.map((c) => Math.round(c));
10097
+ const { roots, remainder } = findRationalLinearFactors(intDense);
10098
+ if (roots.length > 0) {
10099
+ const factors = roots.map((r) => formatLinearFactor(r, v));
10100
+ if (degree(remainder) >= 1) {
10101
+ factors.push(`(${polyToString(denseToPoly(remainder), [v])})`);
10102
+ } else if (remainder[0] !== 1) {
10103
+ factors.unshift(String(remainder[0]));
10104
+ }
10105
+ return factors.join("*");
10106
+ }
10107
+ }
10108
+ } catch {
10109
+ }
10110
+ }
9954
10111
  const normalized = expr.replace(/\s*-\s*/g, " + -");
9955
10112
  const terms = normalized.split(/\s*\+\s*/).filter((t) => t.trim() !== "");
9956
10113
  if (terms.length < 2) return expr;
@@ -10027,6 +10184,49 @@ function collect(expr, variable) {
10027
10184
  function cancel(expr) {
10028
10185
  const sameMatch = expr.match(/^\s*\(([^()]+)\)\s*\/\s*\(\s*\1\s*\)\s*$/);
10029
10186
  if (sameMatch && sameMatch[1].trim().length > 0) return "1";
10187
+ const univariateVars = variables(expr);
10188
+ if (univariateVars.length === 1) {
10189
+ try {
10190
+ const v = univariateVars[0];
10191
+ const cleaned = expr.replace(/\s+/g, "");
10192
+ const topTerms = splitTopLevelSum(cleaned);
10193
+ if (topTerms.length === 1) {
10194
+ const { nums, dens } = splitProductChain(topTerms[0]);
10195
+ if (dens.length > 0) {
10196
+ const numStr = nums.length ? nums.join("*") : "1";
10197
+ const denStr = dens.join("*");
10198
+ const N = polyToDense(polyFromExpression(numStr, [v]));
10199
+ const D = polyToDense(polyFromExpression(denStr, [v]));
10200
+ if (N.every(isNearInt) && D.every(isNearInt)) {
10201
+ const Nint = N.map((c) => Math.round(c));
10202
+ const Dint = D.map((c) => Math.round(c));
10203
+ const g = polynomialGCD(Nint, Dint);
10204
+ if (degree(g) >= 1) {
10205
+ let Nq = polynomialQuotient(Nint, g).map((c) => Math.round(c * 1e6) / 1e6);
10206
+ let Dq = polynomialQuotient(Dint, g).map((c) => Math.round(c * 1e6) / 1e6);
10207
+ let contentGcd = 0;
10208
+ for (const c of [...Nq, ...Dq]) contentGcd = gcdNum(contentGcd, Math.round(c));
10209
+ if (contentGcd > 1) {
10210
+ Nq = Nq.map((c) => c / contentGcd);
10211
+ Dq = Dq.map((c) => c / contentGcd);
10212
+ }
10213
+ if (Dq[Dq.length - 1] < 0) {
10214
+ Nq = Nq.map((c) => -c);
10215
+ Dq = Dq.map((c) => -c);
10216
+ }
10217
+ if (degree(Dq) === 0) {
10218
+ const c = Dq[0];
10219
+ if (c !== 1) Nq = Nq.map((x) => x / c);
10220
+ return polyToString(denseToPoly(Nq), [v]);
10221
+ }
10222
+ return `(${polyToString(denseToPoly(Nq), [v])})/(${polyToString(denseToPoly(Dq), [v])})`;
10223
+ }
10224
+ }
10225
+ }
10226
+ }
10227
+ } catch {
10228
+ }
10229
+ }
10030
10230
  const fracMatch = expr.match(/^\s*(-?\d+)\s*\/\s*(-?\d+)\s*$/);
10031
10231
  if (fracMatch) {
10032
10232
  const num2 = parseInt(fracMatch[1], 10);
@@ -10053,6 +10253,25 @@ function cancel(expr) {
10053
10253
  return expr;
10054
10254
  }
10055
10255
  function together(expr) {
10256
+ const univariateVars = variables(expr);
10257
+ if (univariateVars.length === 1) {
10258
+ try {
10259
+ const v = univariateVars[0];
10260
+ const terms = splitTopLevelSum(expr).map(splitProductChain);
10261
+ const denParts = terms.flatMap((t) => t.dens);
10262
+ if (denParts.length > 0) {
10263
+ const denominatorStr = denParts.map((d) => `(${d})`).join("*");
10264
+ const numeratorExpr = terms.map((t, i) => {
10265
+ const otherDens = terms.flatMap((t2, j) => j === i ? [] : t2.dens);
10266
+ const parts = [...t.nums, ...otherDens].map((p) => `(${p})`);
10267
+ return parts.length ? parts.join("*") : "1";
10268
+ }).join(" + ");
10269
+ const numeratorStr = polyToString(polyFromExpression(numeratorExpr, [v]), [v]);
10270
+ return `(${numeratorStr})/(${denominatorStr})`;
10271
+ }
10272
+ } catch {
10273
+ }
10274
+ }
10056
10275
  const match = expr.match(/^\s*(-?\d+)\s*\/\s*(-?\d+)\s*\+\s*(-?\d+)\s*\/\s*(-?\d+)\s*$/);
10057
10276
  if (match) {
10058
10277
  const a = parseInt(match[1], 10);
@@ -10067,6 +10286,52 @@ function together(expr) {
10067
10286
  return expr;
10068
10287
  }
10069
10288
  function apart(expr) {
10289
+ const univariateVars = variables(expr);
10290
+ if (univariateVars.length === 1) {
10291
+ try {
10292
+ const v = univariateVars[0];
10293
+ const topTerms = splitTopLevelSum(expr);
10294
+ if (topTerms.length === 1) {
10295
+ const { nums, dens } = splitProductChain(topTerms[0]);
10296
+ if (dens.length > 0) {
10297
+ const numStr = nums.length ? nums.join("*") : "1";
10298
+ const denStr = dens.join("*");
10299
+ const N = polyToDense(polyFromExpression(numStr, [v]));
10300
+ const D = polyToDense(polyFromExpression(denStr, [v]));
10301
+ if (degree(D) >= 1 && N.every(isNearInt) && D.every(isNearInt)) {
10302
+ let Nint = N.map((c) => Math.round(c));
10303
+ const Dint = D.map((c) => Math.round(c));
10304
+ let quotientPrefix = "";
10305
+ if (degree(Nint) >= degree(Dint)) {
10306
+ const q = polynomialQuotient(Nint, Dint);
10307
+ const r = polynomialRemainder(Nint, Dint);
10308
+ if (degree(r) === 0 && r[0] === 0) {
10309
+ return polyToString(denseToPoly(q), [v]);
10310
+ }
10311
+ quotientPrefix = `${polyToString(denseToPoly(q), [v])} + `;
10312
+ Nint = r.map((c) => Math.round(c));
10313
+ }
10314
+ const { roots, remainder, repeated } = findRationalLinearFactors(Dint);
10315
+ if (!repeated && degree(remainder) === 0 && roots.length === degree(Dint)) {
10316
+ const Dprime = polyder(Dint);
10317
+ const termStrs = roots.map((root2) => {
10318
+ const nAtRoot = ratPolyval(Nint, root2);
10319
+ const dAtRoot = ratPolyval(Dprime, root2);
10320
+ if (dAtRoot.n === 0) throw new Error("apart: derivative vanished at root");
10321
+ const a = ratReduce({
10322
+ n: nAtRoot.n * dAtRoot.d,
10323
+ d: nAtRoot.d * dAtRoot.n
10324
+ });
10325
+ return formatPartialTerm(a, root2, v);
10326
+ });
10327
+ return (quotientPrefix + termStrs.join(" + ")).replace(/\+ -/g, "- ");
10328
+ }
10329
+ }
10330
+ }
10331
+ }
10332
+ } catch {
10333
+ }
10334
+ }
10070
10335
  const match = expr.match(/^\s*(-?\d+)\s*\/\s*(-?\d+)\s*$/);
10071
10336
  if (match) {
10072
10337
  const num2 = parseInt(match[1], 10);
@@ -12731,15 +12996,15 @@ function solveODESystem(f, y0, tspan, opts) {
12731
12996
  function stiffODESolver(f, y0, tspan) {
12732
12997
  return rosenbrockSolve((t, y) => f(t, y), tspan, y0, { tol: 1e-7 });
12733
12998
  }
12734
- function solveBVP(f, bc, mesh) {
12735
- const n = 2;
12999
+ function solveBVP(f, bc, mesh, y0Guess = [0, 0]) {
13000
+ const n = y0Guess.length;
12736
13001
  const tspan = [mesh[0], mesh[mesh.length - 1]];
12737
13002
  function shoot(guess) {
12738
13003
  const sol = solveODESystem(f, guess, tspan, { dt: (tspan[1] - tspan[0]) / 50 });
12739
13004
  const yf = sol.y[sol.y.length - 1];
12740
13005
  return bc(guess, yf);
12741
13006
  }
12742
- const s = new Array(n).fill(0);
13007
+ const s = y0Guess.slice();
12743
13008
  const delta = 1e-7;
12744
13009
  for (let iter = 0; iter < 50; iter++) {
12745
13010
  const r = shoot(s);
@@ -15496,6 +15761,71 @@ var logisticPDF = (x, mu = 0, s = 1) => {
15496
15761
  var logisticCDF = (x, mu = 0, s = 1) => 1 / (1 + Math.exp(-(x - mu) / s));
15497
15762
  var logisticQuantile = (p, mu = 0, s = 1) => mu + s * Math.log(p / (1 - p));
15498
15763
 
15764
+ // src/stats/inference-extra.ts
15765
+ function chi2Contingency(table, opts = {}) {
15766
+ const rows = table.length;
15767
+ if (rows < 2) throw new Error("chi2Contingency: table needs at least 2 rows");
15768
+ const cols = table[0].length;
15769
+ if (cols < 2) throw new Error("chi2Contingency: table needs at least 2 columns");
15770
+ for (const row2 of table) {
15771
+ if (row2.length !== cols) throw new Error("chi2Contingency: table must be rectangular");
15772
+ }
15773
+ const rowTotals = new Array(rows).fill(0);
15774
+ const colTotals = new Array(cols).fill(0);
15775
+ let total = 0;
15776
+ for (let i = 0; i < rows; i++) {
15777
+ for (let j = 0; j < cols; j++) {
15778
+ const v = table[i][j];
15779
+ rowTotals[i] += v;
15780
+ colTotals[j] += v;
15781
+ total += v;
15782
+ }
15783
+ }
15784
+ if (total <= 0) throw new Error("chi2Contingency: table sum must be positive");
15785
+ const expected = Array.from({ length: rows }, () => new Array(cols).fill(0));
15786
+ const applyCorrection = rows === 2 && cols === 2 && opts.correction !== false;
15787
+ let chi2 = 0;
15788
+ for (let i = 0; i < rows; i++) {
15789
+ for (let j = 0; j < cols; j++) {
15790
+ const e = rowTotals[i] * colTotals[j] / total;
15791
+ expected[i][j] = e;
15792
+ if (e <= 0) continue;
15793
+ const o = table[i][j];
15794
+ const diff2 = applyCorrection ? Math.max(0, Math.abs(o - e) - 0.5) : o - e;
15795
+ chi2 += diff2 * diff2 / e;
15796
+ }
15797
+ }
15798
+ const dof = (rows - 1) * (cols - 1);
15799
+ const pValue = 1 - chiSquaredCDF(chi2, dof);
15800
+ const cramersV = Math.sqrt(chi2 / (total * Math.min(rows - 1, cols - 1)));
15801
+ return { chi2, pValue, dof, expected, cramersV };
15802
+ }
15803
+ function multipleTest(pValues, method) {
15804
+ const n = pValues.length;
15805
+ if (n === 0) return [];
15806
+ if (method === "bonferroni") {
15807
+ return pValues.map((p) => Math.min(1, p * n));
15808
+ }
15809
+ const order = pValues.map((_, i) => i).sort((a, b) => pValues[a] - pValues[b]);
15810
+ const adjusted = new Array(n);
15811
+ if (method === "holm") {
15812
+ let running2 = 0;
15813
+ for (let rank2 = 0; rank2 < n; rank2++) {
15814
+ const idx = order[rank2];
15815
+ running2 = Math.max(running2, (n - rank2) * pValues[idx]);
15816
+ adjusted[idx] = Math.min(1, running2);
15817
+ }
15818
+ return adjusted;
15819
+ }
15820
+ let running = 1;
15821
+ for (let rank2 = n - 1; rank2 >= 0; rank2--) {
15822
+ const idx = order[rank2];
15823
+ running = Math.min(running, n / (rank2 + 1) * pValues[idx]);
15824
+ adjusted[idx] = Math.min(1, running);
15825
+ }
15826
+ return adjusted;
15827
+ }
15828
+
15499
15829
  // src/typed/hypothesis.ts
15500
15830
  var HYPOTHESIS_THRESHOLD = 4096;
15501
15831
  function _makeMulberry322(seed) {
@@ -16365,7 +16695,7 @@ function _median(arr10) {
16365
16695
  const m = n >> 1;
16366
16696
  return n % 2 === 1 ? s[m] : (s[m - 1] + s[m]) / 2;
16367
16697
  }
16368
- function leveneTest(groups, center2 = "median") {
16698
+ function leveneTest(groups, center3 = "median") {
16369
16699
  const k = groups.length;
16370
16700
  if (k < 2) throw new Error("leveneTest: need at least 2 groups");
16371
16701
  let N = 0;
@@ -16374,7 +16704,7 @@ function leveneTest(groups, center2 = "median") {
16374
16704
  N += g.length;
16375
16705
  }
16376
16706
  const z = groups.map((g) => {
16377
- const c = center2 === "median" ? _median(g) : _mean(g);
16707
+ const c = center3 === "median" ? _median(g) : _mean(g);
16378
16708
  return g.map((x) => Math.abs(x - c));
16379
16709
  });
16380
16710
  const allZ = [];
@@ -16596,27 +16926,7 @@ function anova2(data) {
16596
16926
  };
16597
16927
  }
16598
16928
  function multipleComparison(pValues, method = "bh") {
16599
- const m = pValues.length;
16600
- if (m === 0) return [];
16601
- if (method === "bonferroni") return pValues.map((p) => Math.min(p * m, 1));
16602
- const order = pValues.map((_, i) => i).sort((i, j) => pValues[i] - pValues[j]);
16603
- const out = new Array(m);
16604
- if (method === "holm") {
16605
- let running = 0;
16606
- for (let rank2 = 0; rank2 < m; rank2++) {
16607
- const idx = order[rank2];
16608
- running = Math.max(running, (m - rank2) * pValues[idx]);
16609
- out[idx] = Math.min(running, 1);
16610
- }
16611
- } else {
16612
- let prev = 1;
16613
- for (let rank2 = m - 1; rank2 >= 0; rank2--) {
16614
- const idx = order[rank2];
16615
- prev = Math.min(prev, pValues[idx] * m / (rank2 + 1));
16616
- out[idx] = Math.min(prev, 1);
16617
- }
16618
- }
16619
- return out;
16929
+ return multipleTest(pValues, method);
16620
16930
  }
16621
16931
  function meanCI(data, confidence = 0.95) {
16622
16932
  const n = data.length;
@@ -23175,7 +23485,7 @@ var dependencies92 = ["typed", "matrix", "flatten", "size"];
23175
23485
  var createMatrixFromColumns = /* @__PURE__ */ factory(
23176
23486
  name92,
23177
23487
  dependencies92,
23178
- ({ typed: typed3, matrix: matrix2, flatten: flatten4, size: size2 }) => {
23488
+ ({ typed: typed3, matrix: matrix2, flatten: flatten5, size: size2 }) => {
23179
23489
  return typed3(name92, {
23180
23490
  // Single variadic handler for arrays, matrices, and mixed types
23181
23491
  "...": function(arr10) {
@@ -23212,7 +23522,7 @@ var createMatrixFromColumns = /* @__PURE__ */ factory(
23212
23522
  "The vectors had different length: " + (N | 0) + " \u2260 " + (colLength | 0)
23213
23523
  );
23214
23524
  }
23215
- const f = flatten4(col);
23525
+ const f = flatten5(col);
23216
23526
  for (let i = 0; i < N; i++) {
23217
23527
  result[i].push(f[i]);
23218
23528
  }
@@ -23244,7 +23554,7 @@ var dependencies93 = ["typed", "matrix", "flatten", "size"];
23244
23554
  var createMatrixFromRows = /* @__PURE__ */ factory(
23245
23555
  name93,
23246
23556
  dependencies93,
23247
- ({ typed: typed3, matrix: matrix2, flatten: flatten4, size: size2 }) => {
23557
+ ({ typed: typed3, matrix: matrix2, flatten: flatten5, size: size2 }) => {
23248
23558
  return typed3(name93, {
23249
23559
  // Single variadic handler for arrays, matrices, and mixed types
23250
23560
  "...": function(arr10) {
@@ -23278,7 +23588,7 @@ var createMatrixFromRows = /* @__PURE__ */ factory(
23278
23588
  "The vectors had different length: " + (N | 0) + " \u2260 " + (rowLength | 0)
23279
23589
  );
23280
23590
  }
23281
- result.push(flatten4(row2));
23591
+ result.push(flatten5(row2));
23282
23592
  }
23283
23593
  return result;
23284
23594
  }
@@ -32299,13 +32609,13 @@ var createUtil = /* @__PURE__ */ factory(
32299
32609
  }
32300
32610
  return merged;
32301
32611
  }
32302
- function flatten4(node, context = defaultContext) {
32612
+ function flatten5(node, context = defaultContext) {
32303
32613
  if (!node.args || node.args.length === 0) {
32304
32614
  return;
32305
32615
  }
32306
32616
  node.args = allChildren(node, context);
32307
32617
  for (let i = 0; i < node.args.length; i++) {
32308
- flatten4(node.args[i], context);
32618
+ flatten5(node.args[i], context);
32309
32619
  }
32310
32620
  }
32311
32621
  function allChildren(node, context) {
@@ -32385,7 +32695,7 @@ var createUtil = /* @__PURE__ */ factory(
32385
32695
  isCommutative,
32386
32696
  isAssociative,
32387
32697
  mergeContext,
32388
- flatten: flatten4,
32698
+ flatten: flatten5,
32389
32699
  allChildren,
32390
32700
  unflattenr,
32391
32701
  unflattenl,
@@ -35420,7 +35730,7 @@ var createIntersect = /* @__PURE__ */ factory(
35420
35730
  subtract: subtract3,
35421
35731
  smaller: smaller2,
35422
35732
  equalScalar: equalScalar3,
35423
- flatten: flatten4,
35733
+ flatten: flatten5,
35424
35734
  isZero: isZero2,
35425
35735
  isNumeric: isNumeric2
35426
35736
  }) => {
@@ -35512,7 +35822,7 @@ var createIntersect = /* @__PURE__ */ factory(
35512
35822
  if (arr10.length === 1 && Array.isArray(arr10[0])) return arr10[0];
35513
35823
  if (arr10.length > 1 && Array.isArray(arr10[0])) {
35514
35824
  if (arr10.every((el) => Array.isArray(el) && el.length === 1))
35515
- return flatten4(arr10);
35825
+ return flatten5(arr10);
35516
35826
  }
35517
35827
  return arr10;
35518
35828
  }
@@ -37310,7 +37620,7 @@ function flattenToFloat648(matrix2, rows, cols) {
37310
37620
  function createComplexEigs({
37311
37621
  addScalar: addScalar2,
37312
37622
  subtract: subtract3,
37313
- flatten: flatten4,
37623
+ flatten: flatten5,
37314
37624
  multiply: multiply2,
37315
37625
  multiplyScalar: multiplyScalar2,
37316
37626
  divideScalar: divideScalar2,
@@ -37639,7 +37949,7 @@ function createComplexEigs({
37639
37949
  solutions = solutions.map(
37640
37950
  (v) => multiply2(correction, v)
37641
37951
  );
37642
- vectors.push(...solutions.map((v) => ({ value: lambda, vector: flatten4(v) })));
37952
+ vectors.push(...solutions.map((v) => ({ value: lambda, vector: flatten5(v) })));
37643
37953
  }
37644
37954
  return vectors;
37645
37955
  }
@@ -38184,7 +38494,7 @@ var createEigs = /* @__PURE__ */ factory(
38184
38494
  add: add3,
38185
38495
  larger: larger2,
38186
38496
  column: _column,
38187
- flatten: flatten4,
38497
+ flatten: flatten5,
38188
38498
  number: number2,
38189
38499
  complex: complex3,
38190
38500
  sqrt: sqrt2,
@@ -38220,7 +38530,7 @@ var createEigs = /* @__PURE__ */ factory(
38220
38530
  subtract: subtract3,
38221
38531
  multiply: multiply2,
38222
38532
  multiplyScalar: multiplyScalar2,
38223
- flatten: flatten4,
38533
+ flatten: flatten5,
38224
38534
  divideScalar: divideScalar2,
38225
38535
  sqrt: sqrt2,
38226
38536
  abs: abs2,
@@ -38868,7 +39178,7 @@ var createSimplify = /* @__PURE__ */ factory(
38868
39178
  isCommutative,
38869
39179
  isAssociative,
38870
39180
  mergeContext,
38871
- flatten: flatten4,
39181
+ flatten: flatten5,
38872
39182
  unflattenr,
38873
39183
  unflattenl,
38874
39184
  createMakeNodeFunction,
@@ -39180,7 +39490,7 @@ var createSimplify = /* @__PURE__ */ factory(
39180
39490
  );
39181
39491
  const expandsym = _getExpandPlaceholderSymbol();
39182
39492
  const expandedL = makeNode([newRule.l, expandsym]);
39183
- flatten4(expandedL, context);
39493
+ flatten5(expandedL, context);
39184
39494
  unflattenr(expandedL, context);
39185
39495
  newRule.expanded = {
39186
39496
  l: expandedL,
@@ -39267,7 +39577,7 @@ var createSimplify = /* @__PURE__ */ factory(
39267
39577
  if (debug)
39268
39578
  rulestr = builtRules[i].name;
39269
39579
  } else {
39270
- flatten4(res, options.context);
39580
+ flatten5(res, options.context);
39271
39581
  res = applyRule(res, builtRules[i], options.context);
39272
39582
  if (debug) {
39273
39583
  rulestr = `${builtRules[i].l.toString()} -> ${builtRules[i].r.toString()}`;
@@ -45474,7 +45784,7 @@ function hessian(f, x, h = 1e-4) {
45474
45784
  }
45475
45785
 
45476
45786
  // src/index.ts
45477
- import { svd as svd3 } from "@danielsimonjr/mathts-matrix";
45787
+ import { svd as svd4 } from "@danielsimonjr/mathts-matrix";
45478
45788
 
45479
45789
  // src/linalg-svd-extra.ts
45480
45790
  import { svd as svd2 } from "@danielsimonjr/mathts-matrix";
@@ -46776,6 +47086,87 @@ function minimizeScalar(f, opts) {
46776
47086
  return { x, fval: fx };
46777
47087
  }
46778
47088
 
47089
+ // src/numeric/interpn.ts
47090
+ function flattenND(values, shape) {
47091
+ const total = shape.reduce((a, b) => a * b, 1);
47092
+ const flat = new Float64Array(total);
47093
+ let pos = 0;
47094
+ function walk(v, depth) {
47095
+ if (depth === shape.length) {
47096
+ if (typeof v !== "number") {
47097
+ throw new Error(
47098
+ `interpn: values is nested deeper than grids.length (${shape.length} dimensions)`
47099
+ );
47100
+ }
47101
+ flat[pos++] = v;
47102
+ return;
47103
+ }
47104
+ if (!Array.isArray(v) || v.length !== shape[depth]) {
47105
+ const gotLen = Array.isArray(v) ? v.length : "scalar";
47106
+ throw new Error(
47107
+ `interpn: values shape mismatch at dimension ${depth} (expected length ${shape[depth]}, got ${gotLen})`
47108
+ );
47109
+ }
47110
+ for (const item of v) walk(item, depth + 1);
47111
+ }
47112
+ walk(values, 0);
47113
+ return flat;
47114
+ }
47115
+ function locateOnAxis(grid, x) {
47116
+ const n = grid.length;
47117
+ if (x < grid[0] || x > grid[n - 1]) {
47118
+ throw new Error(`interpn: query value ${x} is out of bounds [${grid[0]}, ${grid[n - 1]}]`);
47119
+ }
47120
+ if (n === 1) return { i: 0, t: 0 };
47121
+ let lo = 0;
47122
+ let hi = n - 1;
47123
+ while (hi - lo > 1) {
47124
+ const mid = lo + hi >> 1;
47125
+ if (grid[mid] <= x) lo = mid;
47126
+ else hi = mid;
47127
+ }
47128
+ const denom = grid[lo + 1] - grid[lo];
47129
+ const t = denom === 0 ? 0 : (x - grid[lo]) / denom;
47130
+ return { i: lo, t };
47131
+ }
47132
+ function interpn(grids, values, query) {
47133
+ if (grids.length === 0) throw new Error("interpn: at least one grid axis is required");
47134
+ for (const grid of grids) {
47135
+ if (grid.length < 2) throw new Error("interpn: each grid axis needs at least 2 points");
47136
+ for (let i = 1; i < grid.length; i++) {
47137
+ if (!(grid[i] > grid[i - 1])) {
47138
+ throw new Error("interpn: each grid axis must be strictly increasing");
47139
+ }
47140
+ }
47141
+ }
47142
+ const dims = grids.length;
47143
+ const shape = grids.map((g) => g.length);
47144
+ const flat = flattenND(values, shape);
47145
+ const strides = new Array(dims);
47146
+ strides[dims - 1] = 1;
47147
+ for (let d = dims - 2; d >= 0; d--) strides[d] = strides[d + 1] * shape[d + 1];
47148
+ const numCorners = 1 << dims;
47149
+ return query.map((q) => {
47150
+ if (q.length !== dims) {
47151
+ throw new Error(`interpn: query point has ${q.length} coordinates, expected ${dims}`);
47152
+ }
47153
+ const locs = grids.map((g, d) => locateOnAxis(g, q[d]));
47154
+ let result = 0;
47155
+ for (let corner = 0; corner < numCorners; corner++) {
47156
+ let weight = 1;
47157
+ let flatIndex = 0;
47158
+ for (let d = 0; d < dims; d++) {
47159
+ const bit = corner >> d & 1;
47160
+ const { i, t } = locs[d];
47161
+ weight *= bit ? t : 1 - t;
47162
+ flatIndex += (i + bit) * strides[d];
47163
+ }
47164
+ if (weight !== 0) result += weight * flat[flatIndex];
47165
+ }
47166
+ return result;
47167
+ });
47168
+ }
47169
+
46779
47170
  // src/timeseries-extra.ts
46780
47171
  var arr4 = (x) => Array.isArray(x) ? x : Array.from(x);
46781
47172
  var mean4 = (x) => mean(x);
@@ -47661,71 +48052,6 @@ function gaussianKDE(samples, opts = {}) {
47661
48052
  return { evaluate: evaluate3, bandwidth };
47662
48053
  }
47663
48054
 
47664
- // src/stats/inference-extra.ts
47665
- function chi2Contingency(table, opts = {}) {
47666
- const rows = table.length;
47667
- if (rows < 2) throw new Error("chi2Contingency: table needs at least 2 rows");
47668
- const cols = table[0].length;
47669
- if (cols < 2) throw new Error("chi2Contingency: table needs at least 2 columns");
47670
- for (const row2 of table) {
47671
- if (row2.length !== cols) throw new Error("chi2Contingency: table must be rectangular");
47672
- }
47673
- const rowTotals = new Array(rows).fill(0);
47674
- const colTotals = new Array(cols).fill(0);
47675
- let total = 0;
47676
- for (let i = 0; i < rows; i++) {
47677
- for (let j = 0; j < cols; j++) {
47678
- const v = table[i][j];
47679
- rowTotals[i] += v;
47680
- colTotals[j] += v;
47681
- total += v;
47682
- }
47683
- }
47684
- if (total <= 0) throw new Error("chi2Contingency: table sum must be positive");
47685
- const expected = Array.from({ length: rows }, () => new Array(cols).fill(0));
47686
- const applyCorrection = rows === 2 && cols === 2 && opts.correction !== false;
47687
- let chi2 = 0;
47688
- for (let i = 0; i < rows; i++) {
47689
- for (let j = 0; j < cols; j++) {
47690
- const e = rowTotals[i] * colTotals[j] / total;
47691
- expected[i][j] = e;
47692
- if (e <= 0) continue;
47693
- const o = table[i][j];
47694
- const diff2 = applyCorrection ? Math.max(0, Math.abs(o - e) - 0.5) : o - e;
47695
- chi2 += diff2 * diff2 / e;
47696
- }
47697
- }
47698
- const dof = (rows - 1) * (cols - 1);
47699
- const pValue = 1 - chiSquaredCDF(chi2, dof);
47700
- const cramersV = Math.sqrt(chi2 / (total * Math.min(rows - 1, cols - 1)));
47701
- return { chi2, pValue, dof, expected, cramersV };
47702
- }
47703
- function multipleTest(pValues, method) {
47704
- const n = pValues.length;
47705
- if (n === 0) return [];
47706
- if (method === "bonferroni") {
47707
- return pValues.map((p) => Math.min(1, p * n));
47708
- }
47709
- const order = pValues.map((_, i) => i).sort((a, b) => pValues[a] - pValues[b]);
47710
- const adjusted = new Array(n);
47711
- if (method === "holm") {
47712
- let running2 = 0;
47713
- for (let rank2 = 0; rank2 < n; rank2++) {
47714
- const idx = order[rank2];
47715
- running2 = Math.max(running2, (n - rank2) * pValues[idx]);
47716
- adjusted[idx] = Math.min(1, running2);
47717
- }
47718
- return adjusted;
47719
- }
47720
- let running = 1;
47721
- for (let rank2 = n - 1; rank2 >= 0; rank2--) {
47722
- const idx = order[rank2];
47723
- running = Math.min(running, n / (rank2 + 1) * pValues[idx]);
47724
- adjusted[idx] = Math.min(1, running);
47725
- }
47726
- return adjusted;
47727
- }
47728
-
47729
48055
  // src/stats/fit-distribution.ts
47730
48056
  var LOG_2PI = Math.log(2 * Math.PI);
47731
48057
  function meanOf(data) {
@@ -49239,9 +49565,9 @@ function waverec(coeffs, wavelet = "haar") {
49239
49565
  function rickerWavelet(points, scale3) {
49240
49566
  const amplitude = 2 / (Math.sqrt(3 * scale3) * Math.pow(Math.PI, 0.25));
49241
49567
  const out = new Array(points);
49242
- const center2 = (points - 1) / 2;
49568
+ const center3 = (points - 1) / 2;
49243
49569
  for (let i = 0; i < points; i++) {
49244
- const t = (i - center2) / scale3;
49570
+ const t = (i - center3) / scale3;
49245
49571
  const t2 = t * t;
49246
49572
  out[i] = amplitude * (1 - t2) * Math.exp(-t2 / 2);
49247
49573
  }
@@ -49250,9 +49576,9 @@ function rickerWavelet(points, scale3) {
49250
49576
  function morletWavelet(points, scale3) {
49251
49577
  const norm4 = 1 / (Math.sqrt(scale3) * Math.pow(Math.PI, 0.25));
49252
49578
  const out = new Array(points);
49253
- const center2 = (points - 1) / 2;
49579
+ const center3 = (points - 1) / 2;
49254
49580
  for (let i = 0; i < points; i++) {
49255
- const t = (i - center2) / scale3;
49581
+ const t = (i - center3) / scale3;
49256
49582
  out[i] = norm4 * Math.cos(5 * t) * Math.exp(-(t * t) / 2);
49257
49583
  }
49258
49584
  return out;
@@ -49532,6 +49858,170 @@ function quaternionToRotationMatrix(q) {
49532
49858
  ];
49533
49859
  }
49534
49860
 
49861
+ // src/geometry/geometry-extra.ts
49862
+ import { svd as svd3 } from "@danielsimonjr/mathts-matrix";
49863
+ function dot42(a, b) {
49864
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
49865
+ }
49866
+ function quaternionInverse(q) {
49867
+ const magSq = dot42(q, q);
49868
+ if (magSq === 0) throw new Error("quaternionInverse: zero-magnitude quaternion");
49869
+ return quaternionConjugate(q).map((v) => v / magSq);
49870
+ }
49871
+ function quaternionSlerp(q1, q2, t) {
49872
+ const a = q1;
49873
+ let b = q2;
49874
+ let d = dot42(a, b);
49875
+ if (d < 0) {
49876
+ d = -d;
49877
+ b = b.map((v) => -v);
49878
+ }
49879
+ const DOT_THRESHOLD = 0.9995;
49880
+ if (d > DOT_THRESHOLD) {
49881
+ const lerp = a.map((v, i) => v + t * (b[i] - v));
49882
+ const m = Math.sqrt(dot42(lerp, lerp)) || 1;
49883
+ return lerp.map((v) => v / m);
49884
+ }
49885
+ const clamped = d > 1 ? 1 : d < -1 ? -1 : d;
49886
+ const theta0 = Math.acos(clamped);
49887
+ const theta = theta0 * t;
49888
+ const sinTheta0 = Math.sin(theta0);
49889
+ const sinTheta = Math.sin(theta);
49890
+ const s0 = Math.cos(theta) - d * sinTheta / sinTheta0;
49891
+ const s1 = sinTheta / sinTheta0;
49892
+ return a.map((v, i) => s0 * v + s1 * b[i]);
49893
+ }
49894
+ function quaternionToEuler(q) {
49895
+ const [w, x, y, z] = q;
49896
+ const roll = Math.atan2(2 * (w * x + y * z), 1 - 2 * (x * x + y * y));
49897
+ const sinp = 2 * (w * y - z * x);
49898
+ const pitch = Math.asin(sinp > 1 ? 1 : sinp < -1 ? -1 : sinp);
49899
+ const yaw = Math.atan2(2 * (w * z + x * y), 1 - 2 * (y * y + z * z));
49900
+ return [roll, pitch, yaw];
49901
+ }
49902
+ function boundingBox(points) {
49903
+ if (points.length === 0) throw new Error("boundingBox: requires at least one point");
49904
+ const dims = points[0].length;
49905
+ const min2 = points[0].slice();
49906
+ const max2 = points[0].slice();
49907
+ for (let i = 1; i < points.length; i++) {
49908
+ const p = points[i];
49909
+ for (let d = 0; d < dims; d++) {
49910
+ if (p[d] < min2[d]) min2[d] = p[d];
49911
+ if (p[d] > max2[d]) max2[d] = p[d];
49912
+ }
49913
+ }
49914
+ return { min: min2, max: max2 };
49915
+ }
49916
+ function columnMean(A) {
49917
+ const n = A.length;
49918
+ const d = A[0]?.length ?? 0;
49919
+ const mean7 = new Array(d).fill(0);
49920
+ for (const row2 of A) {
49921
+ for (let j = 0; j < d; j++) mean7[j] += row2[j] / n;
49922
+ }
49923
+ return mean7;
49924
+ }
49925
+ function center2(A, mean7) {
49926
+ return A.map((row2) => row2.map((v, j) => v - mean7[j]));
49927
+ }
49928
+ function frobeniusNorm(A) {
49929
+ let sum3 = 0;
49930
+ for (const row2 of A) for (const v of row2) sum3 += v * v;
49931
+ return Math.sqrt(sum3);
49932
+ }
49933
+ function matTranspose(A) {
49934
+ const rows = A.length;
49935
+ const cols = A[0]?.length ?? 0;
49936
+ const T = Array.from({ length: cols }, () => new Array(rows).fill(0));
49937
+ for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) T[j][i] = A[i][j];
49938
+ return T;
49939
+ }
49940
+ function matMul2(A, B) {
49941
+ const rows = A.length;
49942
+ const inner = B.length;
49943
+ const cols = B[0]?.length ?? 0;
49944
+ const C = Array.from({ length: rows }, () => new Array(cols).fill(0));
49945
+ for (let i = 0; i < rows; i++) {
49946
+ for (let k = 0; k < inner; k++) {
49947
+ const a = A[i][k];
49948
+ if (a === 0) continue;
49949
+ for (let j = 0; j < cols; j++) C[i][j] += a * B[k][j];
49950
+ }
49951
+ }
49952
+ return C;
49953
+ }
49954
+ function procrustes(A, B) {
49955
+ if (A.length !== B.length || A.length === 0) {
49956
+ throw new Error("procrustes: A and B must have the same non-zero number of rows");
49957
+ }
49958
+ const A0raw = center2(A, columnMean(A));
49959
+ const B0raw = center2(B, columnMean(B));
49960
+ const nA = frobeniusNorm(A0raw) || 1;
49961
+ const nB = frobeniusNorm(B0raw) || 1;
49962
+ const A0 = A0raw.map((row2) => row2.map((v) => v / nA));
49963
+ const B0 = B0raw.map((row2) => row2.map((v) => v / nB));
49964
+ const M = matMul2(matTranspose(A0), B0);
49965
+ const { U, S, V } = svd3(M);
49966
+ const R = matMul2(V, matTranspose(U));
49967
+ const scale3 = S.reduce((s, v) => s + v, 0);
49968
+ const transformed = matMul2(B0, R).map((row2) => row2.map((v) => v * scale3));
49969
+ let disparity = 0;
49970
+ for (let i = 0; i < A0.length; i++) {
49971
+ for (let j = 0; j < A0[i].length; j++) {
49972
+ const diff2 = A0[i][j] - transformed[i][j];
49973
+ disparity += diff2 * diff2;
49974
+ }
49975
+ }
49976
+ return { R, scale: scale3, disparity };
49977
+ }
49978
+ function euclideanDist(a, b) {
49979
+ let sum3 = 0;
49980
+ for (let i = 0; i < a.length; i++) {
49981
+ const d = a[i] - b[i];
49982
+ sum3 += d * d;
49983
+ }
49984
+ return Math.sqrt(sum3);
49985
+ }
49986
+ function kdTreeKNN(points, query, k) {
49987
+ const ranked = points.map((p, i) => ({ i, d: euclideanDist(p, query) }));
49988
+ ranked.sort((a, b) => a.d - b.d);
49989
+ return ranked.slice(0, Math.max(0, Math.min(k, ranked.length))).map((e) => e.i);
49990
+ }
49991
+ function kdTreeRadius(points, query, r) {
49992
+ const result = [];
49993
+ for (let i = 0; i < points.length; i++) {
49994
+ if (euclideanDist(points[i], query) <= r) result.push(i);
49995
+ }
49996
+ return result;
49997
+ }
49998
+ function flatten4(arr10) {
49999
+ const result = [];
50000
+ const stack = [...arr10];
50001
+ while (stack.length > 0) {
50002
+ const item = stack.shift();
50003
+ if (Array.isArray(item)) {
50004
+ stack.unshift(...item);
50005
+ } else {
50006
+ result.push(item);
50007
+ }
50008
+ }
50009
+ return result;
50010
+ }
50011
+ function setIsSuperset(a, b) {
50012
+ return setIsSubset(b, a);
50013
+ }
50014
+ function setEqual(a, b) {
50015
+ return setIsSubset(a, b) && setIsSubset(b, a);
50016
+ }
50017
+ function setDisjoint(a, b) {
50018
+ const flatA = flatten4(a);
50019
+ for (const elem of flatA) {
50020
+ if (setMultiplicity(elem, b) > 0) return false;
50021
+ }
50022
+ return true;
50023
+ }
50024
+
49535
50025
  // src/stats/inference-extra2.ts
49536
50026
  var TWO_PI = 2 * Math.PI;
49537
50027
  function noncentralChi2CDF(x, df, nc) {
@@ -49807,6 +50297,475 @@ function rootsLegendre(n) {
49807
50297
  weights.reverse();
49808
50298
  return { nodes, weights };
49809
50299
  }
50300
+
50301
+ // src/graph/traversal-centrality.ts
50302
+ function bfs(adj, start) {
50303
+ const n = adj.length;
50304
+ if (start < 0 || start >= n) {
50305
+ throw new Error("bfs: start out of bounds");
50306
+ }
50307
+ const visited = new Array(n).fill(false);
50308
+ const order = [];
50309
+ const queue = [start];
50310
+ visited[start] = true;
50311
+ while (queue.length > 0) {
50312
+ const u = queue.shift();
50313
+ order.push(u);
50314
+ for (let v = 0; v < n; v++) {
50315
+ if (!visited[v] && Number.isFinite(adj[u][v]) && adj[u][v] !== 0) {
50316
+ visited[v] = true;
50317
+ queue.push(v);
50318
+ }
50319
+ }
50320
+ }
50321
+ return order;
50322
+ }
50323
+ function dfs(adj, start) {
50324
+ const n = adj.length;
50325
+ if (start < 0 || start >= n) {
50326
+ throw new Error("dfs: start out of bounds");
50327
+ }
50328
+ const visited = new Array(n).fill(false);
50329
+ const order = [];
50330
+ function visit(u) {
50331
+ visited[u] = true;
50332
+ order.push(u);
50333
+ for (let v = 0; v < n; v++) {
50334
+ if (!visited[v] && Number.isFinite(adj[u][v]) && adj[u][v] !== 0) {
50335
+ visit(v);
50336
+ }
50337
+ }
50338
+ }
50339
+ visit(start);
50340
+ return order;
50341
+ }
50342
+ function _hasWeightedEdge(w) {
50343
+ return Number.isFinite(w) && w !== 0;
50344
+ }
50345
+ function floydWarshall(adj) {
50346
+ const n = adj.length;
50347
+ const dist = Array.from({ length: n }, () => new Array(n).fill(Infinity));
50348
+ for (let i = 0; i < n; i++) {
50349
+ dist[i][i] = 0;
50350
+ for (let j = 0; j < n; j++) {
50351
+ if (i !== j && _hasWeightedEdge(adj[i][j])) {
50352
+ dist[i][j] = adj[i][j];
50353
+ }
50354
+ }
50355
+ }
50356
+ for (let k = 0; k < n; k++) {
50357
+ for (let i = 0; i < n; i++) {
50358
+ if (dist[i][k] === Infinity) continue;
50359
+ for (let j = 0; j < n; j++) {
50360
+ const throughK = dist[i][k] + dist[k][j];
50361
+ if (throughK < dist[i][j]) {
50362
+ dist[i][j] = throughK;
50363
+ }
50364
+ }
50365
+ }
50366
+ }
50367
+ return dist;
50368
+ }
50369
+ function bellmanFord(adj, source) {
50370
+ const n = adj.length;
50371
+ if (source < 0 || source >= n) {
50372
+ throw new Error("bellmanFord: source out of bounds");
50373
+ }
50374
+ const dist = new Array(n).fill(Infinity);
50375
+ dist[source] = 0;
50376
+ const edges = [];
50377
+ for (let u = 0; u < n; u++) {
50378
+ for (let v = 0; v < n; v++) {
50379
+ if (u !== v && _hasWeightedEdge(adj[u][v])) {
50380
+ edges.push([u, v, adj[u][v]]);
50381
+ }
50382
+ }
50383
+ }
50384
+ for (let i = 0; i < n - 1; i++) {
50385
+ let changed = false;
50386
+ for (const [u, v, w] of edges) {
50387
+ if (dist[u] !== Infinity && dist[u] + w < dist[v]) {
50388
+ dist[v] = dist[u] + w;
50389
+ changed = true;
50390
+ }
50391
+ }
50392
+ if (!changed) break;
50393
+ }
50394
+ let hasNegativeCycle = false;
50395
+ for (const [u, v, w] of edges) {
50396
+ if (dist[u] !== Infinity && dist[u] + w < dist[v]) {
50397
+ hasNegativeCycle = true;
50398
+ break;
50399
+ }
50400
+ }
50401
+ return { dist, hasNegativeCycle };
50402
+ }
50403
+ function closenessCentrality(adj) {
50404
+ const n = adj.length;
50405
+ const dist = floydWarshall(adj);
50406
+ const result = new Array(n).fill(0);
50407
+ for (let u = 0; u < n; u++) {
50408
+ let sum3 = 0;
50409
+ let reachable = 0;
50410
+ for (let v = 0; v < n; v++) {
50411
+ if (v === u) continue;
50412
+ if (dist[v][u] < Infinity) {
50413
+ sum3 += dist[v][u];
50414
+ reachable++;
50415
+ }
50416
+ }
50417
+ if (reachable === 0 || sum3 === 0) {
50418
+ result[u] = 0;
50419
+ continue;
50420
+ }
50421
+ const r = reachable + 1;
50422
+ result[u] = (r - 1 === n - 1 ? 1 : (r - 1) / (n - 1)) * ((r - 1) / sum3);
50423
+ }
50424
+ return result;
50425
+ }
50426
+ function harmonicCentrality(adj) {
50427
+ const n = adj.length;
50428
+ const dist = floydWarshall(adj);
50429
+ const result = new Array(n).fill(0);
50430
+ for (let u = 0; u < n; u++) {
50431
+ let sum3 = 0;
50432
+ for (let v = 0; v < n; v++) {
50433
+ if (v === u) continue;
50434
+ if (dist[v][u] > 0 && dist[v][u] < Infinity) {
50435
+ sum3 += 1 / dist[v][u];
50436
+ }
50437
+ }
50438
+ result[u] = sum3;
50439
+ }
50440
+ return result;
50441
+ }
50442
+
50443
+ // src/graph/optimization.ts
50444
+ function _bfsResidual(residual, source, sink) {
50445
+ const n = residual.length;
50446
+ const parent = new Array(n).fill(-1);
50447
+ const visited = new Array(n).fill(false);
50448
+ visited[source] = true;
50449
+ const queue = [source];
50450
+ while (queue.length > 0) {
50451
+ const u = queue.shift();
50452
+ if (u === sink) return parent;
50453
+ for (let v = 0; v < n; v++) {
50454
+ if (!visited[v] && residual[u][v] > 0) {
50455
+ visited[v] = true;
50456
+ parent[v] = u;
50457
+ queue.push(v);
50458
+ }
50459
+ }
50460
+ }
50461
+ return visited[sink] ? parent : null;
50462
+ }
50463
+ function maxFlow(capacity, source, sink) {
50464
+ const n = capacity.length;
50465
+ if (source < 0 || source >= n || sink < 0 || sink >= n) {
50466
+ throw new Error("maxFlow: source or sink out of bounds");
50467
+ }
50468
+ const residual = capacity.map((row2) => row2.slice());
50469
+ const flow = Array.from({ length: n }, () => new Array(n).fill(0));
50470
+ let total = 0;
50471
+ if (source === sink) {
50472
+ return { maxFlow: 0, flow };
50473
+ }
50474
+ for (; ; ) {
50475
+ const parent = _bfsResidual(residual, source, sink);
50476
+ if (parent === null) break;
50477
+ let pathFlow = Infinity;
50478
+ for (let v = sink; v !== source; v = parent[v]) {
50479
+ const u = parent[v];
50480
+ pathFlow = Math.min(pathFlow, residual[u][v]);
50481
+ }
50482
+ for (let v = sink; v !== source; v = parent[v]) {
50483
+ const u = parent[v];
50484
+ residual[u][v] -= pathFlow;
50485
+ residual[v][u] += pathFlow;
50486
+ flow[u][v] += pathFlow;
50487
+ flow[v][u] -= pathFlow;
50488
+ }
50489
+ total += pathFlow;
50490
+ }
50491
+ return { maxFlow: total, flow };
50492
+ }
50493
+ function minCut(capacity, source, sink) {
50494
+ const n = capacity.length;
50495
+ if (source < 0 || source >= n || sink < 0 || sink >= n) {
50496
+ throw new Error("minCut: source or sink out of bounds");
50497
+ }
50498
+ const { maxFlow: value, flow } = maxFlow(capacity, source, sink);
50499
+ const residual = Array.from(
50500
+ { length: n },
50501
+ (_, i) => capacity[i].map((c, j) => c - flow[i][j])
50502
+ );
50503
+ const visited = new Array(n).fill(false);
50504
+ visited[source] = true;
50505
+ const queue = [source];
50506
+ while (queue.length > 0) {
50507
+ const u = queue.shift();
50508
+ for (let v = 0; v < n; v++) {
50509
+ if (!visited[v] && residual[u][v] > 0) {
50510
+ visited[v] = true;
50511
+ queue.push(v);
50512
+ }
50513
+ }
50514
+ }
50515
+ const s = [];
50516
+ const t = [];
50517
+ for (let i = 0; i < n; i++) {
50518
+ (visited[i] ? s : t).push(i);
50519
+ }
50520
+ return { value, partition: [s, t] };
50521
+ }
50522
+ function astar(adj, start, goal, heuristic) {
50523
+ const n = adj.length;
50524
+ if (start < 0 || start >= n || goal < 0 || goal >= n) {
50525
+ throw new Error("astar: start or goal out of bounds");
50526
+ }
50527
+ if (start === goal) {
50528
+ return { path: [start], cost: 0 };
50529
+ }
50530
+ const gScore = new Array(n).fill(Infinity);
50531
+ gScore[start] = 0;
50532
+ const cameFrom = new Array(n).fill(-1);
50533
+ const closed = new Array(n).fill(false);
50534
+ const open = [{ node: start, fScore: heuristic(start) }];
50535
+ while (open.length > 0) {
50536
+ let bestIdx = 0;
50537
+ for (let i = 1; i < open.length; i++) {
50538
+ if (open[i].fScore < open[bestIdx].fScore) bestIdx = i;
50539
+ }
50540
+ const { node: u } = open[bestIdx];
50541
+ open.splice(bestIdx, 1);
50542
+ if (closed[u]) continue;
50543
+ closed[u] = true;
50544
+ if (u === goal) break;
50545
+ for (let v = 0; v < n; v++) {
50546
+ if (closed[v] || !Number.isFinite(adj[u][v]) || adj[u][v] === 0) continue;
50547
+ const tentative = gScore[u] + adj[u][v];
50548
+ if (tentative < gScore[v]) {
50549
+ gScore[v] = tentative;
50550
+ cameFrom[v] = u;
50551
+ open.push({ node: v, fScore: tentative + heuristic(v) });
50552
+ }
50553
+ }
50554
+ }
50555
+ if (gScore[goal] === Infinity) {
50556
+ return { path: [], cost: Infinity };
50557
+ }
50558
+ const path = [];
50559
+ for (let v = goal; v !== -1; v = cameFrom[v]) {
50560
+ path.unshift(v);
50561
+ if (v === start) break;
50562
+ }
50563
+ return { path, cost: gScore[goal] };
50564
+ }
50565
+ function hungarian(cost) {
50566
+ const n = cost.length;
50567
+ if (n === 0) {
50568
+ return { assignment: [], cost: 0 };
50569
+ }
50570
+ for (const row2 of cost) {
50571
+ if (row2.length !== n) {
50572
+ throw new Error("hungarian: cost matrix must be square");
50573
+ }
50574
+ }
50575
+ const INF = Infinity;
50576
+ const u = new Array(n + 1).fill(0);
50577
+ const v = new Array(n + 1).fill(0);
50578
+ const a = new Array(n + 1).fill(0);
50579
+ const p = new Array(n + 1).fill(0);
50580
+ for (let i = 1; i <= n; i++) {
50581
+ a[0] = i;
50582
+ let j0 = 0;
50583
+ const minv = new Array(n + 1).fill(INF);
50584
+ const used = new Array(n + 1).fill(false);
50585
+ do {
50586
+ used[j0] = true;
50587
+ const i0 = a[j0];
50588
+ let delta = INF;
50589
+ let j1 = -1;
50590
+ for (let j = 1; j <= n; j++) {
50591
+ if (used[j]) continue;
50592
+ const cur = cost[i0 - 1][j - 1] - u[i0] - v[j];
50593
+ if (cur < minv[j]) {
50594
+ minv[j] = cur;
50595
+ p[j] = j0;
50596
+ }
50597
+ if (minv[j] < delta) {
50598
+ delta = minv[j];
50599
+ j1 = j;
50600
+ }
50601
+ }
50602
+ for (let j = 0; j <= n; j++) {
50603
+ if (used[j]) {
50604
+ u[a[j]] += delta;
50605
+ v[j] -= delta;
50606
+ } else {
50607
+ minv[j] -= delta;
50608
+ }
50609
+ }
50610
+ j0 = j1;
50611
+ } while (a[j0] !== 0);
50612
+ while (j0 !== 0) {
50613
+ const j1 = p[j0];
50614
+ a[j0] = a[j1];
50615
+ j0 = j1;
50616
+ }
50617
+ }
50618
+ const assignment = new Array(n).fill(-1);
50619
+ let totalCost = 0;
50620
+ for (let j = 1; j <= n; j++) {
50621
+ const i = a[j];
50622
+ if (i > 0) {
50623
+ assignment[i - 1] = j - 1;
50624
+ totalCost += cost[i - 1][j - 1];
50625
+ }
50626
+ }
50627
+ return { assignment, cost: totalCost };
50628
+ }
50629
+
50630
+ // src/numeric/interval.ts
50631
+ var EPS3 = Number.EPSILON;
50632
+ function outward(lo, hi) {
50633
+ const loOut = lo - Math.abs(lo) * EPS3 - Number.MIN_VALUE;
50634
+ const hiOut = hi + Math.abs(hi) * EPS3 + Number.MIN_VALUE;
50635
+ return new Interval(loOut, hiOut);
50636
+ }
50637
+ var Interval = class {
50638
+ lo;
50639
+ hi;
50640
+ constructor(lo, hi) {
50641
+ if (lo > hi) {
50642
+ throw new Error(`Interval: lo (${lo}) must be <= hi (${hi})`);
50643
+ }
50644
+ this.lo = lo;
50645
+ this.hi = hi;
50646
+ }
50647
+ /** `[this.lo + b.lo, this.hi + b.hi]`, outward-rounded. */
50648
+ add(b) {
50649
+ return outward(this.lo + b.lo, this.hi + b.hi);
50650
+ }
50651
+ /** `[this.lo - b.hi, this.hi - b.lo]`, outward-rounded. */
50652
+ sub(b) {
50653
+ return outward(this.lo - b.hi, this.hi - b.lo);
50654
+ }
50655
+ /**
50656
+ * Interval product: the min/max of all four endpoint products
50657
+ * (`lo*lo, lo*hi, hi*lo, hi*hi`), outward-rounded. Correct for any
50658
+ * combination of signs.
50659
+ */
50660
+ mul(b) {
50661
+ const p1 = this.lo * b.lo;
50662
+ const p2 = this.lo * b.hi;
50663
+ const p3 = this.hi * b.lo;
50664
+ const p4 = this.hi * b.hi;
50665
+ return outward(Math.min(p1, p2, p3, p4), Math.max(p1, p2, p3, p4));
50666
+ }
50667
+ /**
50668
+ * Interval quotient. Throws if `b` contains 0 (division would be
50669
+ * unbounded). Otherwise the min/max of the four endpoint quotients,
50670
+ * outward-rounded.
50671
+ */
50672
+ div(b) {
50673
+ if (b.contains(0)) {
50674
+ throw new Error("Interval.div: divisor interval contains zero");
50675
+ }
50676
+ const q1 = this.lo / b.lo;
50677
+ const q2 = this.lo / b.hi;
50678
+ const q3 = this.hi / b.lo;
50679
+ const q4 = this.hi / b.hi;
50680
+ return outward(Math.min(q1, q2, q3, q4), Math.max(q1, q2, q3, q4));
50681
+ }
50682
+ /** `[-this.hi, -this.lo]`, outward-rounded. */
50683
+ neg() {
50684
+ return outward(-this.hi, -this.lo);
50685
+ }
50686
+ /** `hi - lo`. */
50687
+ width() {
50688
+ return this.hi - this.lo;
50689
+ }
50690
+ /** `(lo + hi) / 2`. */
50691
+ mid() {
50692
+ return (this.lo + this.hi) / 2;
50693
+ }
50694
+ /** Whether the closed interval `[lo, hi]` contains the real number `x`. */
50695
+ contains(x) {
50696
+ return x >= this.lo && x <= this.hi;
50697
+ }
50698
+ /**
50699
+ * Square root, monotonic-increasing over `[0, +Infinity)`. Throws if the
50700
+ * interval contains negative values (real square root is undefined there).
50701
+ */
50702
+ sqrt() {
50703
+ if (this.lo < 0) {
50704
+ throw new Error("Interval.sqrt: interval contains negative values");
50705
+ }
50706
+ return outward(Math.sqrt(this.lo), Math.sqrt(this.hi));
50707
+ }
50708
+ /** Exponential, monotonic-increasing over all reals. */
50709
+ exp() {
50710
+ return outward(Math.exp(this.lo), Math.exp(this.hi));
50711
+ }
50712
+ /**
50713
+ * Natural log, monotonic-increasing over `(0, +Infinity)`. Throws if the
50714
+ * interval is not strictly positive.
50715
+ */
50716
+ log() {
50717
+ if (this.lo <= 0) {
50718
+ throw new Error("Interval.log: interval must be strictly positive");
50719
+ }
50720
+ return outward(Math.log(this.lo), Math.log(this.hi));
50721
+ }
50722
+ /**
50723
+ * Integer power `x^n`, monotonic-aware:
50724
+ * - `n` odd: `x^n` is monotonic-increasing over all reals, so the result is
50725
+ * `[lo^n, hi^n]`.
50726
+ * - `n` even, interval entirely non-negative: monotonic-increasing, so
50727
+ * `[lo^n, hi^n]`.
50728
+ * - `n` even, interval entirely non-positive: monotonic-decreasing (in
50729
+ * magnitude, toward zero), so `[hi^n, lo^n]`.
50730
+ * - `n` even, interval spans zero: the minimum is `0` (attained at `x=0`)
50731
+ * and the maximum is `max(|lo|, |hi|)^n`.
50732
+ * - `n` negative: computed as the reciprocal of `pow(-n)`; throws if that
50733
+ * positive-power interval contains zero (division by zero).
50734
+ * - `n = 0`: `[1, 1]` for every interval.
50735
+ *
50736
+ * Throws if `n` is not an integer.
50737
+ */
50738
+ pow(n) {
50739
+ if (!Number.isInteger(n)) {
50740
+ throw new Error("Interval.pow: exponent must be an integer");
50741
+ }
50742
+ if (n === 0) {
50743
+ return outward(1, 1);
50744
+ }
50745
+ if (n < 0) {
50746
+ const positivePow = this.pow(-n);
50747
+ if (positivePow.contains(0)) {
50748
+ throw new Error("Interval.pow: cannot invert an interval containing zero");
50749
+ }
50750
+ return outward(1 / positivePow.hi, 1 / positivePow.lo);
50751
+ }
50752
+ const isOdd = n % 2 !== 0;
50753
+ if (isOdd) {
50754
+ return outward(this.lo ** n, this.hi ** n);
50755
+ }
50756
+ if (this.lo >= 0) {
50757
+ return outward(this.lo ** n, this.hi ** n);
50758
+ }
50759
+ if (this.hi <= 0) {
50760
+ return outward(this.hi ** n, this.lo ** n);
50761
+ }
50762
+ const maxAbs = Math.max(Math.abs(this.lo), Math.abs(this.hi));
50763
+ return outward(0, maxAbs ** n);
50764
+ }
50765
+ };
50766
+ function interval(lo, hi) {
50767
+ return new Interval(lo, hi);
50768
+ }
49810
50769
  export {
49811
50770
  ARRAY_WORKER_THRESHOLD,
49812
50771
  CAS_BATCH_THRESHOLD,
@@ -49818,6 +50777,7 @@ export {
49818
50777
  GPU_ELEMENTWISE_OPS,
49819
50778
  GPU_MIN_ELEMENTS2 as GPU_MIN_ELEMENTS,
49820
50779
  GPU_REDUCE_OPS,
50780
+ Interval,
49821
50781
  WASM_INTERP_THRESHOLD,
49822
50782
  abs,
49823
50783
  acf,
@@ -49848,6 +50808,7 @@ export {
49848
50808
  asin,
49849
50809
  asinh,
49850
50810
  assume,
50811
+ astar,
49851
50812
  asymptotic,
49852
50813
  atan,
49853
50814
  atan2,
@@ -49859,6 +50820,7 @@ export {
49859
50820
  bartlettPSD,
49860
50821
  bartlettTest,
49861
50822
  bellNumbers,
50823
+ bellmanFord,
49862
50824
  bernoulli,
49863
50825
  bernoulliPMF,
49864
50826
  besselI,
@@ -49878,6 +50840,7 @@ export {
49878
50840
  betweennessCentrality,
49879
50841
  bezierCurve,
49880
50842
  bfgs,
50843
+ bfs,
49881
50844
  bicgstab,
49882
50845
  bigint,
49883
50846
  bignumber,
@@ -49895,6 +50858,7 @@ export {
49895
50858
  boltzmann,
49896
50859
  boolean,
49897
50860
  bootstrapCI,
50861
+ boundingBox,
49898
50862
  bspline,
49899
50863
  butter,
49900
50864
  buttord,
@@ -49941,6 +50905,7 @@ export {
49941
50905
  classicalElectronRadius,
49942
50906
  clearAssumptions,
49943
50907
  clone3 as clone,
50908
+ closenessCentrality,
49944
50909
  cochranQ,
49945
50910
  coefficientList,
49946
50911
  coherence,
@@ -50026,6 +50991,7 @@ export {
50026
50991
  det,
50027
50992
  detrend,
50028
50993
  deuteronMass,
50994
+ dfs,
50029
50995
  diag,
50030
50996
  diff,
50031
50997
  differences,
@@ -50192,6 +51158,7 @@ export {
50192
51158
  fix,
50193
51159
  flatten3 as flatten,
50194
51160
  floor,
51161
+ floydWarshall,
50195
51162
  forEach,
50196
51163
  format4 as format,
50197
51164
  fourier,
@@ -50246,6 +51213,7 @@ export {
50246
51213
  groupDelay,
50247
51214
  gumbelDist,
50248
51215
  halley,
51216
+ harmonicCentrality,
50249
51217
  harmonicNumber,
50250
51218
  hartreeEnergy,
50251
51219
  hasNumericValue,
@@ -50261,6 +51229,7 @@ export {
50261
51229
  histogram,
50262
51230
  hmean,
50263
51231
  hotellingT2,
51232
+ hungarian,
50264
51233
  hyp0f1,
50265
51234
  hyp1f1,
50266
51235
  hyp2f1,
@@ -50281,10 +51250,12 @@ export {
50281
51250
  initializeStatistics,
50282
51251
  integerDigits,
50283
51252
  integrate,
51253
+ interpn,
50284
51254
  interpolate,
50285
51255
  intersect,
50286
51256
  intersectLines2D,
50287
51257
  intersectSegments2D,
51258
+ interval,
50288
51259
  inv,
50289
51260
  invFourier,
50290
51261
  invGaussDist,
@@ -50318,7 +51289,9 @@ export {
50318
51289
  josephson,
50319
51290
  jsDivergence,
50320
51291
  kdTree,
51292
+ kdTreeKNN,
50321
51293
  kdTreeNearest,
51294
+ kdTreeRadius,
50322
51295
  kendallTau,
50323
51296
  kendallTauTest,
50324
51297
  kendalltau,
@@ -50410,6 +51383,7 @@ export {
50410
51383
  matrixSqrtm,
50411
51384
  matvec,
50412
51385
  max,
51386
+ maxFlow,
50413
51387
  maxSelect,
50414
51388
  maximize,
50415
51389
  mcnemar,
@@ -50419,6 +51393,7 @@ export {
50419
51393
  median,
50420
51394
  medianSelect,
50421
51395
  min,
51396
+ minCut,
50422
51397
  minSelect,
50423
51398
  minimalPolynomial,
50424
51399
  minimize,
@@ -50562,6 +51537,7 @@ export {
50562
51537
  primitiveRoot,
50563
51538
  principalComponentAnalysis,
50564
51539
  print,
51540
+ procrustes,
50565
51541
  prod,
50566
51542
  projectVector,
50567
51543
  proportionCI,
@@ -50575,9 +51551,12 @@ export {
50575
51551
  quantumOfCirculation,
50576
51552
  quaternionConjugate,
50577
51553
  quaternionFromAxisAngle,
51554
+ quaternionInverse,
50578
51555
  quaternionMultiply,
50579
51556
  quaternionNormalize,
50580
51557
  quaternionRotate,
51558
+ quaternionSlerp,
51559
+ quaternionToEuler,
50581
51560
  quaternionToRotationMatrix,
50582
51561
  quickSelect,
50583
51562
  qz,
@@ -50634,9 +51613,12 @@ export {
50634
51613
  seriesCoefficient,
50635
51614
  setCartesian,
50636
51615
  setDifference,
51616
+ setDisjoint,
50637
51617
  setDistinct,
51618
+ setEqual,
50638
51619
  setIntersect,
50639
51620
  setIsSubset,
51621
+ setIsSuperset,
50640
51622
  setMultiplicity,
50641
51623
  setPowerset,
50642
51624
  setSize,
@@ -50707,7 +51689,7 @@ export {
50707
51689
  subtractScalar,
50708
51690
  sum,
50709
51691
  summation,
50710
- svd3 as svd,
51692
+ svd4 as svd,
50711
51693
  sylvester,
50712
51694
  symbolicEqual,
50713
51695
  symbolicIntegral,