numbl 0.4.2 → 0.4.3
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-cli/cli.js +1120 -34
- package/dist-lib/graphics/axisLimits.d.ts +23 -0
- package/dist-lib/graphics/figuresReducer.d.ts +73 -0
- package/dist-lib/graphics/types.d.ts +17 -0
- package/dist-lib/lib.js +1119 -33
- package/dist-lib/numbl-core/helpers/eigs-select.d.ts +25 -0
- package/dist-lib/numbl-core/runtime/axisCommand.d.ts +34 -0
- package/dist-lib/numbl-core/runtime/runtime.d.ts +5 -0
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-plot-viewer/assets/index-ClpZQuMR.js +4426 -0
- package/dist-plot-viewer/index.html +1 -1
- package/dist-site-viewer/assets/index-CgKjTQT7.js +4748 -0
- package/dist-site-viewer/assets/{numbl-worker-B18l6dfh.js → numbl-worker-DarsHbBe.js} +125 -125
- package/dist-site-viewer/index.html +1 -1
- package/package.json +1 -1
- package/dist-plot-viewer/assets/index-DfxsWeyf.js +0 -4426
- package/dist-site-viewer/assets/index-D0XGPdHU.js +0 -4748
package/dist-lib/lib.js
CHANGED
|
@@ -19452,9 +19452,9 @@ function airyAllComplex(zr, zi) {
|
|
|
19452
19452
|
sfpi += m3k * tfi;
|
|
19453
19453
|
sgpr += (m3k + 1) * tgr;
|
|
19454
19454
|
sgpi += (m3k + 1) * tgi;
|
|
19455
|
-
const
|
|
19455
|
+
const mag2 = Math.abs(tfr) + Math.abs(tfi) + Math.abs(tgr) + Math.abs(tgi);
|
|
19456
19456
|
const ref = Math.abs(sfr) + Math.abs(sfi) + Math.abs(sgr) + Math.abs(sgi) + 1e-300;
|
|
19457
|
-
if (
|
|
19457
|
+
if (mag2 < 1e-16 * ref) break;
|
|
19458
19458
|
}
|
|
19459
19459
|
const gr = zr * sgr - zi * sgi;
|
|
19460
19460
|
const gi = zr * sgi + zi * sgr;
|
|
@@ -22329,8 +22329,8 @@ function sinpi(x) {
|
|
|
22329
22329
|
return Math.sin(Math.PI * x);
|
|
22330
22330
|
}
|
|
22331
22331
|
function negRealPow(negBase, exponent) {
|
|
22332
|
-
const
|
|
22333
|
-
return { re:
|
|
22332
|
+
const mag2 = Math.pow(-negBase, exponent);
|
|
22333
|
+
return { re: mag2 * cospi(exponent), im: mag2 * sinpi(exponent) };
|
|
22334
22334
|
}
|
|
22335
22335
|
function mPow(a, b) {
|
|
22336
22336
|
if (isComplexOrMixed(a, b)) {
|
|
@@ -29285,9 +29285,9 @@ function complexSqrt(re, im) {
|
|
|
29285
29285
|
if (re >= 0) return { re: Math.sqrt(re), im: 0 };
|
|
29286
29286
|
return { re: 0, im: Math.sqrt(-re) };
|
|
29287
29287
|
}
|
|
29288
|
-
const
|
|
29289
|
-
if (
|
|
29290
|
-
const r = Math.sqrt(
|
|
29288
|
+
const mag2 = Math.hypot(re, im);
|
|
29289
|
+
if (mag2 === 0) return { re: 0, im: 0 };
|
|
29290
|
+
const r = Math.sqrt(mag2);
|
|
29291
29291
|
const angle2 = Math.atan2(im, re) / 2;
|
|
29292
29292
|
return { re: r * Math.cos(angle2), im: r * Math.sin(angle2) };
|
|
29293
29293
|
}
|
|
@@ -29335,9 +29335,9 @@ defineBuiltin({
|
|
|
29335
29335
|
)
|
|
29336
29336
|
});
|
|
29337
29337
|
registerUnary("sign", Math.sign, (re, im) => {
|
|
29338
|
-
const
|
|
29339
|
-
if (
|
|
29340
|
-
return { re: re /
|
|
29338
|
+
const mag2 = Math.hypot(re, im);
|
|
29339
|
+
if (mag2 === 0) return { re: 0, im: 0 };
|
|
29340
|
+
return { re: re / mag2, im: im / mag2 };
|
|
29341
29341
|
});
|
|
29342
29342
|
function registerRounding(name, fn) {
|
|
29343
29343
|
defineBuiltin({
|
|
@@ -34070,10 +34070,10 @@ function sortTensor(v, dim, descend, nargout) {
|
|
|
34070
34070
|
const dimSize = shape[dimIdx];
|
|
34071
34071
|
let cmpFlatIdx;
|
|
34072
34072
|
if (im && !im.every((x) => x === 0)) {
|
|
34073
|
-
const
|
|
34073
|
+
const mag2 = (i) => Math.sqrt(re[i] * re[i] + im[i] * im[i]);
|
|
34074
34074
|
const phase = (i) => Math.atan2(im[i], re[i]);
|
|
34075
34075
|
cmpFlatIdx = (a, b) => {
|
|
34076
|
-
const diff2 =
|
|
34076
|
+
const diff2 = mag2(a) - mag2(b);
|
|
34077
34077
|
if (diff2 !== 0) return descend ? -diff2 : diff2;
|
|
34078
34078
|
const pDiff = phase(a) - phase(b);
|
|
34079
34079
|
return descend ? -pDiff : pDiff;
|
|
@@ -35501,9 +35501,9 @@ function invComplexJS(dataRe, dataIm, n) {
|
|
|
35501
35501
|
let maxRow = col;
|
|
35502
35502
|
let maxMag = augRe[col * 2 * n + col] ** 2 + augIm[col * 2 * n + col] ** 2;
|
|
35503
35503
|
for (let row = col + 1; row < n; row++) {
|
|
35504
|
-
const
|
|
35505
|
-
if (
|
|
35506
|
-
maxMag =
|
|
35504
|
+
const mag2 = augRe[row * 2 * n + col] ** 2 + augIm[row * 2 * n + col] ** 2;
|
|
35505
|
+
if (mag2 > maxMag) {
|
|
35506
|
+
maxMag = mag2;
|
|
35507
35507
|
maxRow = row;
|
|
35508
35508
|
}
|
|
35509
35509
|
}
|
|
@@ -35548,6 +35548,88 @@ function invComplexJS(dataRe, dataIm, n) {
|
|
|
35548
35548
|
}
|
|
35549
35549
|
return { re: resultRe, im: resultIm };
|
|
35550
35550
|
}
|
|
35551
|
+
defineBuiltin({
|
|
35552
|
+
name: "expm",
|
|
35553
|
+
cases: [
|
|
35554
|
+
{
|
|
35555
|
+
match: (argTypes, nargout) => {
|
|
35556
|
+
if (argTypes.length !== 1 || nargout > 1) return null;
|
|
35557
|
+
if (!isNumericJitType(argTypes[0])) return null;
|
|
35558
|
+
const a = argTypes[0];
|
|
35559
|
+
if (a.kind === "number" || a.kind === "boolean") return [NUM];
|
|
35560
|
+
if (a.kind === "complex_or_number") return [COMPLEX_OR_NUM];
|
|
35561
|
+
if (a.kind === "tensor")
|
|
35562
|
+
return [{ kind: "tensor", isComplex: a.isComplex }];
|
|
35563
|
+
return null;
|
|
35564
|
+
},
|
|
35565
|
+
apply: (args) => expmApply(args)
|
|
35566
|
+
}
|
|
35567
|
+
]
|
|
35568
|
+
});
|
|
35569
|
+
function expmApply(args) {
|
|
35570
|
+
if (args.length !== 1) throw new RuntimeError("expm requires 1 argument");
|
|
35571
|
+
const A = args[0];
|
|
35572
|
+
if (isRuntimeNumber(A)) return RTV.num(Math.exp(A));
|
|
35573
|
+
if (isRuntimeComplexNumber(A)) {
|
|
35574
|
+
const ex = Math.exp(A.re);
|
|
35575
|
+
return RTV.complex(ex * Math.cos(A.im), ex * Math.sin(A.im));
|
|
35576
|
+
}
|
|
35577
|
+
if (!isRuntimeTensor(A))
|
|
35578
|
+
throw new RuntimeError("expm: argument must be a numeric matrix");
|
|
35579
|
+
const [m, n] = tensorSize2D(A);
|
|
35580
|
+
if (m !== n) throw new RuntimeError("expm: input must be a square matrix");
|
|
35581
|
+
if (n === 0) return A;
|
|
35582
|
+
if (n === 1) {
|
|
35583
|
+
const ex = Math.exp(A.data[0]);
|
|
35584
|
+
if (A.imag)
|
|
35585
|
+
return RTV.tensor(
|
|
35586
|
+
Float64Array.of(ex * Math.cos(A.imag[0])),
|
|
35587
|
+
[1, 1],
|
|
35588
|
+
Float64Array.of(ex * Math.sin(A.imag[0]))
|
|
35589
|
+
);
|
|
35590
|
+
return RTV.tensor(Float64Array.of(ex), [1, 1]);
|
|
35591
|
+
}
|
|
35592
|
+
let s = 0;
|
|
35593
|
+
for (let scaled = matrixOneNorm(A, n); scaled > 0.5; scaled /= 2) s++;
|
|
35594
|
+
const As = mMul(A, RTV.num(Math.pow(2, -s)));
|
|
35595
|
+
const q = 6;
|
|
35596
|
+
const I = identityTensor(n);
|
|
35597
|
+
let c = 0.5;
|
|
35598
|
+
let E = mAdd(I, mMul(As, RTV.num(c)));
|
|
35599
|
+
let D = mSub(I, mMul(As, RTV.num(c)));
|
|
35600
|
+
let X = As;
|
|
35601
|
+
let plus2 = true;
|
|
35602
|
+
for (let k = 2; k <= q; k++) {
|
|
35603
|
+
c = c * (q - k + 1) / (k * (2 * q - k + 1));
|
|
35604
|
+
X = mMul(As, X);
|
|
35605
|
+
const cX = mMul(X, RTV.num(c));
|
|
35606
|
+
E = mAdd(E, cX);
|
|
35607
|
+
D = plus2 ? mAdd(D, cX) : mSub(D, cX);
|
|
35608
|
+
plus2 = !plus2;
|
|
35609
|
+
}
|
|
35610
|
+
let R = mLeftDiv(D, E);
|
|
35611
|
+
for (let i = 0; i < s; i++) R = mMul(R, R);
|
|
35612
|
+
return R;
|
|
35613
|
+
}
|
|
35614
|
+
function matrixOneNorm(A, n) {
|
|
35615
|
+
const re = A.data;
|
|
35616
|
+
const im = A.imag;
|
|
35617
|
+
let maxSum = 0;
|
|
35618
|
+
for (let j = 0; j < n; j++) {
|
|
35619
|
+
let colSum = 0;
|
|
35620
|
+
for (let i = 0; i < n; i++) {
|
|
35621
|
+
const idx = i + j * n;
|
|
35622
|
+
colSum += im ? Math.hypot(re[idx], im[idx]) : Math.abs(re[idx]);
|
|
35623
|
+
}
|
|
35624
|
+
if (colSum > maxSum) maxSum = colSum;
|
|
35625
|
+
}
|
|
35626
|
+
return maxSum;
|
|
35627
|
+
}
|
|
35628
|
+
function identityTensor(n) {
|
|
35629
|
+
const data = allocFloat64Array(n * n);
|
|
35630
|
+
for (let i = 0; i < n; i++) data[i + i * n] = 1;
|
|
35631
|
+
return RTV.tensor(data, [n, n]);
|
|
35632
|
+
}
|
|
35551
35633
|
registerIBuiltin({
|
|
35552
35634
|
name: "svd",
|
|
35553
35635
|
resolve: (argTypes, nargout) => {
|
|
@@ -37074,8 +37156,8 @@ function isFiberConjugateSymmetric(re, im) {
|
|
|
37074
37156
|
if (N <= 1) return Math.abs(im[0]) < 1e-14;
|
|
37075
37157
|
let maxMag = 0;
|
|
37076
37158
|
for (let i = 0; i < N; i++) {
|
|
37077
|
-
const
|
|
37078
|
-
if (
|
|
37159
|
+
const mag2 = Math.abs(re[i]) + Math.abs(im[i]);
|
|
37160
|
+
if (mag2 > maxMag) maxMag = mag2;
|
|
37079
37161
|
}
|
|
37080
37162
|
const tol = Math.max(1e-14, maxMag * 1e-12);
|
|
37081
37163
|
if (Math.abs(im[0]) > tol) return false;
|
|
@@ -45645,6 +45727,10 @@ var H = {
|
|
|
45645
45727
|
signatures: ["B = inv(A)"],
|
|
45646
45728
|
description: "Matrix inverse."
|
|
45647
45729
|
},
|
|
45730
|
+
expm: {
|
|
45731
|
+
signatures: ["Y = expm(X)"],
|
|
45732
|
+
description: "Matrix exponential of square matrix X (scaling-and-squaring Pad\xE9). Use exp for the element-wise exponential."
|
|
45733
|
+
},
|
|
45648
45734
|
trace: {
|
|
45649
45735
|
signatures: ["T = trace(A)"],
|
|
45650
45736
|
description: "Sum of diagonal elements."
|
|
@@ -45653,6 +45739,17 @@ var H = {
|
|
|
45653
45739
|
signatures: ["E = eig(A)", "[V, D] = eig(A)", "[V, D, W] = eig(A)"],
|
|
45654
45740
|
description: "Eigenvalues and eigenvectors of square matrix. With three outputs, W contains left eigenvectors."
|
|
45655
45741
|
},
|
|
45742
|
+
eigs: {
|
|
45743
|
+
signatures: [
|
|
45744
|
+
"d = eigs(A)",
|
|
45745
|
+
"d = eigs(A, k)",
|
|
45746
|
+
"d = eigs(A, k, sigma)",
|
|
45747
|
+
"d = eigs(A, B, ...)",
|
|
45748
|
+
"d = eigs(Afun, n, ...)",
|
|
45749
|
+
"[V, D, flag] = eigs(...)"
|
|
45750
|
+
],
|
|
45751
|
+
description: "Subset of k eigenvalues/eigenvectors (default 6). sigma selects which: 'largestabs' (default), 'smallestabs', 'largestreal', 'smallestreal', 'bothendsreal', 'largestimag', 'smallestimag', 'bothendsimag', or a scalar (eigenvalues closest to it). Supports the generalized problem A*V = B*V*D and a function handle Afun. Computed densely via eig, so convergence options are accepted but ignored and flag is always 0."
|
|
45752
|
+
},
|
|
45656
45753
|
svd: {
|
|
45657
45754
|
signatures: [
|
|
45658
45755
|
"S = svd(A)",
|
|
@@ -46454,6 +46551,17 @@ var H = {
|
|
|
46454
46551
|
signatures: ["colorbar", "colorbar(MODE)"],
|
|
46455
46552
|
description: "Display colorbar on current axes."
|
|
46456
46553
|
},
|
|
46554
|
+
axis: {
|
|
46555
|
+
signatures: [
|
|
46556
|
+
"axis([xmin xmax ymin ymax])",
|
|
46557
|
+
"axis STYLE",
|
|
46558
|
+
"axis MODE",
|
|
46559
|
+
"axis ij | xy",
|
|
46560
|
+
"axis on | off",
|
|
46561
|
+
"LIM = axis"
|
|
46562
|
+
],
|
|
46563
|
+
description: "Set or query axis limits, scaling, direction, and visibility. LIMITS is a 4-, 6-, or 8-element vector (inf bounds stay automatic). STYLE is tight | padded | fill | equal | image | square | vis3d | normal | tickaligned. MODE is manual | auto | 'auto x' | 'auto y' | 'auto z' (and xy combinations). 'ij' reverses the y-axis; 'off' hides the axes lines and background. LIM = axis returns the current limits."
|
|
46564
|
+
},
|
|
46457
46565
|
xlim: {
|
|
46458
46566
|
signatures: ["xlim(LIMITS)"],
|
|
46459
46567
|
description: "Set x-axis limits."
|
|
@@ -49627,6 +49735,134 @@ function stream2Call(args) {
|
|
|
49627
49735
|
return RTV.cell(cellData, [1, cellData.length]);
|
|
49628
49736
|
}
|
|
49629
49737
|
|
|
49738
|
+
// src/numbl-core/runtime/axisCommand.ts
|
|
49739
|
+
var STYLE_WORDS = /* @__PURE__ */ new Set([
|
|
49740
|
+
"tight",
|
|
49741
|
+
"padded",
|
|
49742
|
+
"fill",
|
|
49743
|
+
"equal",
|
|
49744
|
+
"image",
|
|
49745
|
+
"square",
|
|
49746
|
+
"vis3d",
|
|
49747
|
+
"normal",
|
|
49748
|
+
"tickaligned"
|
|
49749
|
+
]);
|
|
49750
|
+
var STYLE_RESETS_LIMITS = /* @__PURE__ */ new Set([
|
|
49751
|
+
"tight",
|
|
49752
|
+
"padded",
|
|
49753
|
+
"equal",
|
|
49754
|
+
"image",
|
|
49755
|
+
"tickaligned"
|
|
49756
|
+
]);
|
|
49757
|
+
var AUTO_AXIS_TOKENS = {
|
|
49758
|
+
auto: ["x", "y", "z"],
|
|
49759
|
+
"auto x": ["x"],
|
|
49760
|
+
"auto y": ["y"],
|
|
49761
|
+
"auto z": ["z"],
|
|
49762
|
+
"auto xy": ["x", "y"],
|
|
49763
|
+
"auto yx": ["x", "y"],
|
|
49764
|
+
"auto xz": ["x", "z"],
|
|
49765
|
+
"auto zx": ["x", "z"],
|
|
49766
|
+
"auto yz": ["y", "z"],
|
|
49767
|
+
"auto zy": ["y", "z"]
|
|
49768
|
+
};
|
|
49769
|
+
function isHandle(v) {
|
|
49770
|
+
return isRuntimeDummyHandle(v) || isRuntimeGraphicsHandle(v);
|
|
49771
|
+
}
|
|
49772
|
+
function numericValues(v) {
|
|
49773
|
+
if (isRuntimeTensor(v)) return Array.from(v.data);
|
|
49774
|
+
if (isRuntimeNumber(v)) return [v];
|
|
49775
|
+
if (isRuntimeLogical(v)) return [v ? 1 : 0];
|
|
49776
|
+
return null;
|
|
49777
|
+
}
|
|
49778
|
+
function bound(v) {
|
|
49779
|
+
return Number.isFinite(v) ? v : null;
|
|
49780
|
+
}
|
|
49781
|
+
function clearLimits(axes) {
|
|
49782
|
+
const instr = {
|
|
49783
|
+
type: "set_axis_limits"
|
|
49784
|
+
};
|
|
49785
|
+
if (axes.includes("x")) instr.xlim = "auto";
|
|
49786
|
+
if (axes.includes("y")) instr.ylim = "auto";
|
|
49787
|
+
if (axes.includes("z")) instr.zlim = "auto";
|
|
49788
|
+
return instr;
|
|
49789
|
+
}
|
|
49790
|
+
function applyAxisCommand(args, instructions, freezeLimits) {
|
|
49791
|
+
let i = 0;
|
|
49792
|
+
while (i < args.length && isHandle(args[i])) i++;
|
|
49793
|
+
let applied = false;
|
|
49794
|
+
const styles = [];
|
|
49795
|
+
for (; i < args.length; i++) {
|
|
49796
|
+
const arg = args[i];
|
|
49797
|
+
const nums = numericValues(arg);
|
|
49798
|
+
if (nums !== null) {
|
|
49799
|
+
applied = true;
|
|
49800
|
+
if (nums.length === 1) {
|
|
49801
|
+
instructions.push({ type: "set_axis_visible", value: nums[0] !== 0 });
|
|
49802
|
+
continue;
|
|
49803
|
+
}
|
|
49804
|
+
if (nums.length === 4 || nums.length === 6 || nums.length === 8) {
|
|
49805
|
+
const instr = {
|
|
49806
|
+
type: "set_axis_limits",
|
|
49807
|
+
xlim: [bound(nums[0]), bound(nums[1])],
|
|
49808
|
+
ylim: [bound(nums[2]), bound(nums[3])]
|
|
49809
|
+
};
|
|
49810
|
+
if (nums.length >= 6) instr.zlim = [bound(nums[4]), bound(nums[5])];
|
|
49811
|
+
instructions.push(instr);
|
|
49812
|
+
if (nums.length === 8 && Number.isFinite(nums[6]) && Number.isFinite(nums[7])) {
|
|
49813
|
+
instructions.push({ type: "set_caxis", limits: [nums[6], nums[7]] });
|
|
49814
|
+
}
|
|
49815
|
+
continue;
|
|
49816
|
+
}
|
|
49817
|
+
throw new RuntimeError(
|
|
49818
|
+
"axis: limit vector must have 4, 6, or 8 elements"
|
|
49819
|
+
);
|
|
49820
|
+
}
|
|
49821
|
+
const kw = toString(arg).trim().replace(/^["']|["']$/g, "").toLowerCase();
|
|
49822
|
+
applied = true;
|
|
49823
|
+
if (STYLE_WORDS.has(kw)) {
|
|
49824
|
+
styles.push(kw);
|
|
49825
|
+
if (STYLE_RESETS_LIMITS.has(kw)) {
|
|
49826
|
+
instructions.push(clearLimits(["x", "y", "z"]));
|
|
49827
|
+
}
|
|
49828
|
+
continue;
|
|
49829
|
+
}
|
|
49830
|
+
if (kw === "manual") {
|
|
49831
|
+
const lim = freezeLimits?.();
|
|
49832
|
+
if (lim && lim.length >= 4) {
|
|
49833
|
+
const instr = {
|
|
49834
|
+
type: "set_axis_limits",
|
|
49835
|
+
xlim: [lim[0], lim[1]],
|
|
49836
|
+
ylim: [lim[2], lim[3]]
|
|
49837
|
+
};
|
|
49838
|
+
if (lim.length >= 6) instr.zlim = [lim[4], lim[5]];
|
|
49839
|
+
instructions.push(instr);
|
|
49840
|
+
}
|
|
49841
|
+
continue;
|
|
49842
|
+
}
|
|
49843
|
+
if (kw in AUTO_AXIS_TOKENS) {
|
|
49844
|
+
instructions.push(clearLimits(AUTO_AXIS_TOKENS[kw]));
|
|
49845
|
+
continue;
|
|
49846
|
+
}
|
|
49847
|
+
if (kw === "xy" || kw === "ij") {
|
|
49848
|
+
instructions.push({
|
|
49849
|
+
type: "set_axis_ydir",
|
|
49850
|
+
dir: kw === "ij" ? "reverse" : "normal"
|
|
49851
|
+
});
|
|
49852
|
+
continue;
|
|
49853
|
+
}
|
|
49854
|
+
if (kw === "on" || kw === "off") {
|
|
49855
|
+
instructions.push({ type: "set_axis_visible", value: kw === "on" });
|
|
49856
|
+
continue;
|
|
49857
|
+
}
|
|
49858
|
+
throw new RuntimeError(`axis: unknown option '${kw}'`);
|
|
49859
|
+
}
|
|
49860
|
+
if (styles.length > 0) {
|
|
49861
|
+
instructions.push({ type: "set_axis", value: styles.join(" ") });
|
|
49862
|
+
}
|
|
49863
|
+
return applied;
|
|
49864
|
+
}
|
|
49865
|
+
|
|
49630
49866
|
// src/numbl-core/runtime/plotBuiltinDispatch.ts
|
|
49631
49867
|
function dispatchPlotBuiltin(name, args, instructions, state) {
|
|
49632
49868
|
switch (name) {
|
|
@@ -49815,10 +50051,7 @@ function dispatchPlotBuiltin(name, args, instructions, state) {
|
|
|
49815
50051
|
dispatchColormap(args, instructions);
|
|
49816
50052
|
return true;
|
|
49817
50053
|
case "axis": {
|
|
49818
|
-
|
|
49819
|
-
const val = toString(args[0]).replace(/^"|"$/g, "");
|
|
49820
|
-
plotInstr(instructions, { type: "set_axis", value: val });
|
|
49821
|
-
}
|
|
50054
|
+
applyAxisCommand(args, instructions);
|
|
49822
50055
|
return true;
|
|
49823
50056
|
}
|
|
49824
50057
|
case "caxis":
|
|
@@ -50513,6 +50746,85 @@ function quadgkAdaptive(integrand, a, b, opts = {}) {
|
|
|
50513
50746
|
};
|
|
50514
50747
|
}
|
|
50515
50748
|
|
|
50749
|
+
// src/numbl-core/helpers/eigs-select.ts
|
|
50750
|
+
var SIGMA_ALIASES = {
|
|
50751
|
+
lm: "largestabs",
|
|
50752
|
+
largestabs: "largestabs",
|
|
50753
|
+
sm: "smallestabs",
|
|
50754
|
+
smallestabs: "smallestabs",
|
|
50755
|
+
lr: "largestreal",
|
|
50756
|
+
la: "largestreal",
|
|
50757
|
+
largestreal: "largestreal",
|
|
50758
|
+
sr: "smallestreal",
|
|
50759
|
+
sa: "smallestreal",
|
|
50760
|
+
smallestreal: "smallestreal",
|
|
50761
|
+
be: "bothendsreal",
|
|
50762
|
+
bothendsreal: "bothendsreal",
|
|
50763
|
+
li: "largestimag",
|
|
50764
|
+
largestimag: "largestimag",
|
|
50765
|
+
si: "smallestimag",
|
|
50766
|
+
smallestimag: "smallestimag",
|
|
50767
|
+
bothendsimag: "bothendsimag"
|
|
50768
|
+
};
|
|
50769
|
+
function normalizeSigmaString(s) {
|
|
50770
|
+
return SIGMA_ALIASES[s.trim().toLowerCase()] ?? null;
|
|
50771
|
+
}
|
|
50772
|
+
var mag = (re, im) => Math.hypot(re, im);
|
|
50773
|
+
function sortedBy(n, key, descending) {
|
|
50774
|
+
const idx = Array.from({ length: n }, (_, i) => i);
|
|
50775
|
+
idx.sort((a, b) => {
|
|
50776
|
+
const ka = key(a);
|
|
50777
|
+
const kb = key(b);
|
|
50778
|
+
if (ka !== kb) return descending ? kb - ka : ka - kb;
|
|
50779
|
+
return a - b;
|
|
50780
|
+
});
|
|
50781
|
+
return idx;
|
|
50782
|
+
}
|
|
50783
|
+
function bothEnds(n, key, k) {
|
|
50784
|
+
const nHigh = Math.ceil(k / 2);
|
|
50785
|
+
const nLow = Math.floor(k / 2);
|
|
50786
|
+
const desc = sortedBy(n, key, true);
|
|
50787
|
+
const high = desc.slice(0, nHigh);
|
|
50788
|
+
const highSet = new Set(high);
|
|
50789
|
+
const low = [];
|
|
50790
|
+
for (let i = desc.length - 1; i >= 0 && low.length < nLow; i--) {
|
|
50791
|
+
if (!highSet.has(desc[i])) low.push(desc[i]);
|
|
50792
|
+
}
|
|
50793
|
+
return { high, low };
|
|
50794
|
+
}
|
|
50795
|
+
function selectEigsIndices(re, im, k, sigma) {
|
|
50796
|
+
const n = re.length;
|
|
50797
|
+
const kk = Math.max(0, Math.min(k, n));
|
|
50798
|
+
switch (sigma.kind) {
|
|
50799
|
+
case "largestabs":
|
|
50800
|
+
return sortedBy(n, (i) => mag(re[i], im[i]), true).slice(0, kk);
|
|
50801
|
+
case "smallestabs":
|
|
50802
|
+
return sortedBy(n, (i) => mag(re[i], im[i]), false).slice(0, kk);
|
|
50803
|
+
case "largestreal":
|
|
50804
|
+
return sortedBy(n, (i) => re[i], true).slice(0, kk);
|
|
50805
|
+
case "smallestreal":
|
|
50806
|
+
return sortedBy(n, (i) => re[i], false).slice(0, kk);
|
|
50807
|
+
case "largestimag":
|
|
50808
|
+
return sortedBy(n, (i) => im[i], true).slice(0, kk);
|
|
50809
|
+
case "smallestimag":
|
|
50810
|
+
return sortedBy(n, (i) => im[i], false).slice(0, kk);
|
|
50811
|
+
case "scalar": {
|
|
50812
|
+
const { re: sr, im: si } = sigma;
|
|
50813
|
+
return sortedBy(n, (i) => mag(re[i] - sr, im[i] - si), false).slice(0, kk);
|
|
50814
|
+
}
|
|
50815
|
+
case "bothendsreal": {
|
|
50816
|
+
const { high, low } = bothEnds(n, (i) => re[i], kk);
|
|
50817
|
+
return [...high, ...low].sort((a, b) => re[a] - re[b] || a - b);
|
|
50818
|
+
}
|
|
50819
|
+
case "bothendsimag": {
|
|
50820
|
+
const { high, low } = bothEnds(n, (i) => im[i], kk);
|
|
50821
|
+
return [...high, ...low].sort(
|
|
50822
|
+
(a, b) => Math.abs(im[b]) - Math.abs(im[a]) || a - b
|
|
50823
|
+
);
|
|
50824
|
+
}
|
|
50825
|
+
}
|
|
50826
|
+
}
|
|
50827
|
+
|
|
50516
50828
|
// src/numbl-core/runtime/specialBuiltinNames.ts
|
|
50517
50829
|
var SPECIAL_BUILTIN_NAMES = [
|
|
50518
50830
|
"help",
|
|
@@ -50631,6 +50943,7 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
50631
50943
|
"toc",
|
|
50632
50944
|
"quadgk",
|
|
50633
50945
|
"gmres",
|
|
50946
|
+
"eigs",
|
|
50634
50947
|
"onCleanup"
|
|
50635
50948
|
];
|
|
50636
50949
|
|
|
@@ -52008,6 +52321,9 @@ function registerSpecialBuiltins(rt) {
|
|
|
52008
52321
|
registerSpecial("gmres", (nargout, args) => {
|
|
52009
52322
|
return _gmresImpl(rt, nargout, args);
|
|
52010
52323
|
});
|
|
52324
|
+
registerSpecial("eigs", (nargout, args) => {
|
|
52325
|
+
return _eigsImpl(rt, nargout, args);
|
|
52326
|
+
});
|
|
52011
52327
|
registerSpecial("onCleanup", (_nargout, args) => {
|
|
52012
52328
|
if (args.length !== 1 || !isRuntimeFunction(args[0]))
|
|
52013
52329
|
throw new RuntimeError("onCleanup requires a function handle argument");
|
|
@@ -52015,6 +52331,271 @@ function registerSpecialBuiltins(rt) {
|
|
|
52015
52331
|
return RTV.classInstance("onCleanup", [], false);
|
|
52016
52332
|
});
|
|
52017
52333
|
}
|
|
52334
|
+
function eigsReIm(v) {
|
|
52335
|
+
if (isRuntimeNumber(v)) return { re: [v], im: [0] };
|
|
52336
|
+
if (isRuntimeComplexNumber(v)) return { re: [v.re], im: [v.im] };
|
|
52337
|
+
if (isRuntimeTensor(v)) {
|
|
52338
|
+
const re = Array.from(v.data);
|
|
52339
|
+
const im = v.imag ? Array.from(v.imag) : re.map(() => 0);
|
|
52340
|
+
return { re, im };
|
|
52341
|
+
}
|
|
52342
|
+
throw new RuntimeError("eigs: expected a numeric value");
|
|
52343
|
+
}
|
|
52344
|
+
function eigsAsTensor(v) {
|
|
52345
|
+
const rv = ensureRuntimeValue(v);
|
|
52346
|
+
if (isRuntimeTensor(rv)) return rv;
|
|
52347
|
+
if (isRuntimeNumber(rv))
|
|
52348
|
+
return RTV.tensor(allocFloat64Array([rv]), [1, 1]);
|
|
52349
|
+
if (isRuntimeComplexNumber(rv))
|
|
52350
|
+
return RTV.tensor(
|
|
52351
|
+
allocFloat64Array([rv.re]),
|
|
52352
|
+
[1, 1],
|
|
52353
|
+
allocFloat64Array([rv.im])
|
|
52354
|
+
);
|
|
52355
|
+
throw new RuntimeError("eigs: expected a numeric matrix");
|
|
52356
|
+
}
|
|
52357
|
+
function eigsMatrixSize(A) {
|
|
52358
|
+
if (isRuntimeNumber(A) || isRuntimeComplexNumber(A)) return 1;
|
|
52359
|
+
if (isRuntimeTensor(A)) {
|
|
52360
|
+
const rows = A.shape[0] ?? 1;
|
|
52361
|
+
const cols = A.shape[1] ?? 1;
|
|
52362
|
+
if (rows !== cols)
|
|
52363
|
+
throw new RuntimeError("eigs: input matrix must be square");
|
|
52364
|
+
return rows;
|
|
52365
|
+
}
|
|
52366
|
+
throw new RuntimeError("eigs: input must be a numeric matrix");
|
|
52367
|
+
}
|
|
52368
|
+
function eigsIsScalar(v) {
|
|
52369
|
+
return isRuntimeNumber(v) || isRuntimeComplexNumber(v) || isRuntimeTensor(v) && v.data.length === 1;
|
|
52370
|
+
}
|
|
52371
|
+
function eigsIsMatrixArg(v) {
|
|
52372
|
+
if (!isRuntimeTensor(v)) return false;
|
|
52373
|
+
if (v.data.length === 0) return true;
|
|
52374
|
+
const rows = v.shape[0] ?? 1;
|
|
52375
|
+
const cols = v.shape[1] ?? 1;
|
|
52376
|
+
return rows > 1 || cols > 1;
|
|
52377
|
+
}
|
|
52378
|
+
function eigsToBool(v) {
|
|
52379
|
+
if (isRuntimeLogical(v)) return v;
|
|
52380
|
+
if (isRuntimeNumber(v)) return v !== 0;
|
|
52381
|
+
if (isRuntimeTensor(v) && v.data.length >= 1) return v.data[0] !== 0;
|
|
52382
|
+
return false;
|
|
52383
|
+
}
|
|
52384
|
+
function eigsParseSigma(v) {
|
|
52385
|
+
if (isRuntimeString(v) || isRuntimeChar(v)) {
|
|
52386
|
+
const s = typeof v === "string" ? v : v.value;
|
|
52387
|
+
const kind = normalizeSigmaString(s);
|
|
52388
|
+
if (!kind) throw new RuntimeError(`eigs: unknown sigma option '${s}'`);
|
|
52389
|
+
return { kind };
|
|
52390
|
+
}
|
|
52391
|
+
let re;
|
|
52392
|
+
let im = 0;
|
|
52393
|
+
if (isRuntimeComplexNumber(v)) {
|
|
52394
|
+
re = v.re;
|
|
52395
|
+
im = v.im;
|
|
52396
|
+
} else if (isRuntimeNumber(v)) {
|
|
52397
|
+
re = v;
|
|
52398
|
+
} else if (isRuntimeTensor(v) && v.data.length >= 1) {
|
|
52399
|
+
re = v.data[0];
|
|
52400
|
+
im = v.imag ? v.imag[0] : 0;
|
|
52401
|
+
} else {
|
|
52402
|
+
throw new RuntimeError("eigs: invalid sigma argument");
|
|
52403
|
+
}
|
|
52404
|
+
if (re === 0 && im === 0) return { kind: "smallestabs" };
|
|
52405
|
+
return { kind: "scalar", re, im };
|
|
52406
|
+
}
|
|
52407
|
+
function eigsReconstructOperator(rt, afun, n) {
|
|
52408
|
+
const re = allocFloat64Array(n * n);
|
|
52409
|
+
const im = allocFloat64Array(n * n);
|
|
52410
|
+
let anyImag = false;
|
|
52411
|
+
for (let j = 0; j < n; j++) {
|
|
52412
|
+
const e = allocFloat64Array(n);
|
|
52413
|
+
e[j] = 1;
|
|
52414
|
+
const col = ensureRuntimeValue(
|
|
52415
|
+
rt.index(afun, [RTV.tensor(e, [n, 1])], 1)
|
|
52416
|
+
);
|
|
52417
|
+
const { re: cre, im: cim } = eigsReIm(col);
|
|
52418
|
+
for (let i = 0; i < n; i++) {
|
|
52419
|
+
re[j * n + i] = cre[i] ?? 0;
|
|
52420
|
+
im[j * n + i] = cim[i] ?? 0;
|
|
52421
|
+
if (im[j * n + i] !== 0) anyImag = true;
|
|
52422
|
+
}
|
|
52423
|
+
}
|
|
52424
|
+
return anyImag ? RTV.tensor(re, [n, n], im) : RTV.tensor(re, [n, n]);
|
|
52425
|
+
}
|
|
52426
|
+
function eigsRecoverAfunMatrix(rt, M, sigma, B, n) {
|
|
52427
|
+
if (sigma.kind === "smallestabs") {
|
|
52428
|
+
return eigsAsTensor(rt.dispatch("inv", 1, [M]));
|
|
52429
|
+
}
|
|
52430
|
+
if (sigma.kind === "scalar") {
|
|
52431
|
+
const base = eigsAsTensor(rt.dispatch("inv", 1, [M]));
|
|
52432
|
+
const shiftRe = allocFloat64Array(n * n);
|
|
52433
|
+
const shiftIm = allocFloat64Array(n * n);
|
|
52434
|
+
if (B && isRuntimeTensor(B)) {
|
|
52435
|
+
for (let i = 0; i < n * n; i++) {
|
|
52436
|
+
shiftRe[i] = (B.data[i] ?? 0) * sigma.re - (B.imag?.[i] ?? 0) * sigma.im;
|
|
52437
|
+
shiftIm[i] = (B.data[i] ?? 0) * sigma.im + (B.imag?.[i] ?? 0) * sigma.re;
|
|
52438
|
+
}
|
|
52439
|
+
} else {
|
|
52440
|
+
for (let d = 0; d < n; d++) {
|
|
52441
|
+
shiftRe[d * n + d] = sigma.re;
|
|
52442
|
+
shiftIm[d * n + d] = sigma.im;
|
|
52443
|
+
}
|
|
52444
|
+
}
|
|
52445
|
+
const shift = maybeComplexTensor(shiftRe, [n, n], shiftIm);
|
|
52446
|
+
return eigsAsTensor(rt.dispatch("plus", 1, [base, shift]));
|
|
52447
|
+
}
|
|
52448
|
+
return M;
|
|
52449
|
+
}
|
|
52450
|
+
function eigsReconstructCholesky(R, perm, n) {
|
|
52451
|
+
if (!isRuntimeTensor(R))
|
|
52452
|
+
throw new RuntimeError("eigs: Cholesky factor must be a matrix");
|
|
52453
|
+
const r = R.data;
|
|
52454
|
+
const rtr = allocFloat64Array(n * n);
|
|
52455
|
+
for (let i = 0; i < n; i++) {
|
|
52456
|
+
for (let j = 0; j < n; j++) {
|
|
52457
|
+
let s = 0;
|
|
52458
|
+
for (let kk = 0; kk < n; kk++) s += r[i * n + kk] * r[j * n + kk];
|
|
52459
|
+
rtr[j * n + i] = s;
|
|
52460
|
+
}
|
|
52461
|
+
}
|
|
52462
|
+
if (!perm) return RTV.tensor(rtr, [n, n]);
|
|
52463
|
+
const b = allocFloat64Array(n * n);
|
|
52464
|
+
for (let i = 0; i < n; i++) {
|
|
52465
|
+
for (let j = 0; j < n; j++) {
|
|
52466
|
+
const pi2 = (perm[i] ?? i + 1) - 1;
|
|
52467
|
+
const pj = (perm[j] ?? j + 1) - 1;
|
|
52468
|
+
b[pj * n + pi2] = rtr[j * n + i];
|
|
52469
|
+
}
|
|
52470
|
+
}
|
|
52471
|
+
return RTV.tensor(b, [n, n]);
|
|
52472
|
+
}
|
|
52473
|
+
function _eigsImpl(rt, nargout, args) {
|
|
52474
|
+
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
52475
|
+
if (margs.length < 1)
|
|
52476
|
+
throw new RuntimeError("eigs requires at least 1 argument");
|
|
52477
|
+
let afun = null;
|
|
52478
|
+
let A = null;
|
|
52479
|
+
let n;
|
|
52480
|
+
let pos;
|
|
52481
|
+
if (isRuntimeFunction(margs[0])) {
|
|
52482
|
+
afun = margs[0];
|
|
52483
|
+
if (margs.length < 2 || !eigsIsScalar(margs[1]))
|
|
52484
|
+
throw new RuntimeError(
|
|
52485
|
+
"eigs: a function handle must be followed by the matrix size n"
|
|
52486
|
+
);
|
|
52487
|
+
n = Math.floor(toNumber(margs[1]));
|
|
52488
|
+
pos = 2;
|
|
52489
|
+
} else {
|
|
52490
|
+
A = margs[0];
|
|
52491
|
+
n = eigsMatrixSize(A);
|
|
52492
|
+
pos = 1;
|
|
52493
|
+
}
|
|
52494
|
+
let B = null;
|
|
52495
|
+
if (pos < margs.length && eigsIsMatrixArg(margs[pos])) {
|
|
52496
|
+
const b = margs[pos];
|
|
52497
|
+
if (!(isRuntimeTensor(b) && b.data.length === 0)) B = b;
|
|
52498
|
+
pos++;
|
|
52499
|
+
}
|
|
52500
|
+
let kReq = null;
|
|
52501
|
+
if (pos < margs.length && eigsIsScalar(margs[pos])) {
|
|
52502
|
+
kReq = Math.max(1, Math.floor(toNumber(margs[pos])));
|
|
52503
|
+
pos++;
|
|
52504
|
+
}
|
|
52505
|
+
let sigma = { kind: "largestabs" };
|
|
52506
|
+
if (pos < margs.length) {
|
|
52507
|
+
const a = margs[pos];
|
|
52508
|
+
if (isRuntimeString(a) || isRuntimeChar(a)) {
|
|
52509
|
+
const s = typeof a === "string" ? a : a.value;
|
|
52510
|
+
if (normalizeSigmaString(s)) {
|
|
52511
|
+
sigma = eigsParseSigma(a);
|
|
52512
|
+
pos++;
|
|
52513
|
+
}
|
|
52514
|
+
} else if (eigsIsScalar(a)) {
|
|
52515
|
+
sigma = eigsParseSigma(a);
|
|
52516
|
+
pos++;
|
|
52517
|
+
}
|
|
52518
|
+
}
|
|
52519
|
+
let isCholesky = false;
|
|
52520
|
+
let cholPerm = null;
|
|
52521
|
+
const applyOption = (key, val) => {
|
|
52522
|
+
const lk = key.toLowerCase();
|
|
52523
|
+
if (lk === "ischolesky" || lk === "cholb") isCholesky = eigsToBool(val);
|
|
52524
|
+
else if (lk === "choleskypermutation" || lk === "permb") {
|
|
52525
|
+
if (isRuntimeTensor(val)) cholPerm = Array.from(val.data);
|
|
52526
|
+
}
|
|
52527
|
+
};
|
|
52528
|
+
while (pos < margs.length) {
|
|
52529
|
+
const a = margs[pos];
|
|
52530
|
+
if (isRuntimeStruct(a)) {
|
|
52531
|
+
for (const [key, val] of a.fields) applyOption(key, val);
|
|
52532
|
+
pos++;
|
|
52533
|
+
} else if (pos + 1 < margs.length) {
|
|
52534
|
+
applyOption(
|
|
52535
|
+
isRuntimeChar(margs[pos]) ? margs[pos].value : String(toString(margs[pos])),
|
|
52536
|
+
margs[pos + 1]
|
|
52537
|
+
);
|
|
52538
|
+
pos += 2;
|
|
52539
|
+
} else {
|
|
52540
|
+
break;
|
|
52541
|
+
}
|
|
52542
|
+
}
|
|
52543
|
+
const k = kReq == null ? Math.min(6, n) : Math.min(kReq, n);
|
|
52544
|
+
let actualA;
|
|
52545
|
+
if (afun) {
|
|
52546
|
+
const M = eigsReconstructOperator(rt, afun, n);
|
|
52547
|
+
actualA = eigsRecoverAfunMatrix(rt, M, sigma, B, n);
|
|
52548
|
+
} else {
|
|
52549
|
+
actualA = A;
|
|
52550
|
+
}
|
|
52551
|
+
let effective = actualA;
|
|
52552
|
+
if (B) {
|
|
52553
|
+
const Bmat = isCholesky ? eigsReconstructCholesky(B, cholPerm, n) : B;
|
|
52554
|
+
effective = eigsAsTensor(rt.dispatch("mldivide", 1, [Bmat, actualA]));
|
|
52555
|
+
}
|
|
52556
|
+
if (nargout <= 1) {
|
|
52557
|
+
const d = ensureRuntimeValue(rt.dispatch("eig", 1, [effective]));
|
|
52558
|
+
const { re: re2, im: im2 } = eigsReIm(d);
|
|
52559
|
+
const order2 = selectEigsIndices(re2, im2, k, sigma);
|
|
52560
|
+
const outRe = allocFloat64Array(order2.length);
|
|
52561
|
+
const outIm = allocFloat64Array(order2.length);
|
|
52562
|
+
for (let c = 0; c < order2.length; c++) {
|
|
52563
|
+
outRe[c] = re2[order2[c]];
|
|
52564
|
+
outIm[c] = im2[order2[c]];
|
|
52565
|
+
}
|
|
52566
|
+
return maybeComplexTensor(outRe, [order2.length, 1], outIm);
|
|
52567
|
+
}
|
|
52568
|
+
const res = rt.dispatch("eig", 2, [effective]);
|
|
52569
|
+
const Vall = eigsAsTensor(res[0]);
|
|
52570
|
+
const Dall = eigsAsTensor(res[1]);
|
|
52571
|
+
const p2 = Dall.shape[0] ?? 1;
|
|
52572
|
+
const vrows = Vall.shape[0] ?? p2;
|
|
52573
|
+
const re = [];
|
|
52574
|
+
const im = [];
|
|
52575
|
+
for (let j = 0; j < p2; j++) {
|
|
52576
|
+
re.push(Dall.data[j * p2 + j]);
|
|
52577
|
+
im.push(Dall.imag ? Dall.imag[j * p2 + j] : 0);
|
|
52578
|
+
}
|
|
52579
|
+
const order = selectEigsIndices(re, im, k, sigma);
|
|
52580
|
+
const kk = order.length;
|
|
52581
|
+
const Vre = allocFloat64Array(vrows * kk);
|
|
52582
|
+
const Vim = allocFloat64Array(vrows * kk);
|
|
52583
|
+
const Dre = allocFloat64Array(kk * kk);
|
|
52584
|
+
const Dim = allocFloat64Array(kk * kk);
|
|
52585
|
+
for (let c = 0; c < kk; c++) {
|
|
52586
|
+
const s = order[c];
|
|
52587
|
+
for (let r = 0; r < vrows; r++) {
|
|
52588
|
+
Vre[c * vrows + r] = Vall.data[s * vrows + r];
|
|
52589
|
+
if (Vall.imag) Vim[c * vrows + r] = Vall.imag[s * vrows + r];
|
|
52590
|
+
}
|
|
52591
|
+
Dre[c * kk + c] = re[s];
|
|
52592
|
+
Dim[c * kk + c] = im[s];
|
|
52593
|
+
}
|
|
52594
|
+
const V = maybeComplexTensor(Vre, [vrows, kk], Vim);
|
|
52595
|
+
const D = maybeComplexTensor(Dre, [kk, kk], Dim);
|
|
52596
|
+
if (nargout === 2) return [V, D];
|
|
52597
|
+
return [V, D, RTV.num(0)];
|
|
52598
|
+
}
|
|
52018
52599
|
function _ode45Impl(rt, nargout, args, tableau = dormandPrince45) {
|
|
52019
52600
|
const solverName = tableau.name;
|
|
52020
52601
|
if (args.length < 3)
|
|
@@ -54372,6 +54953,484 @@ function memberChainAssign(rt, base, names, rhs) {
|
|
|
54372
54953
|
return subsasgnFallback(rt, base, names, rhs);
|
|
54373
54954
|
}
|
|
54374
54955
|
|
|
54956
|
+
// src/graphics/figuresReducer.ts
|
|
54957
|
+
var defaultAxes = {
|
|
54958
|
+
holdOn: false,
|
|
54959
|
+
traces: [],
|
|
54960
|
+
plot3Traces: [],
|
|
54961
|
+
surfTraces: [],
|
|
54962
|
+
pcolorTraces: [],
|
|
54963
|
+
contourTraces: [],
|
|
54964
|
+
barTraces: [],
|
|
54965
|
+
barhTraces: [],
|
|
54966
|
+
bar3Traces: [],
|
|
54967
|
+
bar3hTraces: [],
|
|
54968
|
+
errorBarTraces: [],
|
|
54969
|
+
boxTraces: [],
|
|
54970
|
+
quiverTraces: [],
|
|
54971
|
+
quiver3Traces: [],
|
|
54972
|
+
areaTraces: [],
|
|
54973
|
+
areaBaseValue: 0
|
|
54974
|
+
};
|
|
54975
|
+
function getAxes(fig) {
|
|
54976
|
+
return fig.axes[fig.currentAxesIndex] || { ...defaultAxes };
|
|
54977
|
+
}
|
|
54978
|
+
function setAxes(fig, axes) {
|
|
54979
|
+
return {
|
|
54980
|
+
...fig,
|
|
54981
|
+
axes: { ...fig.axes, [fig.currentAxesIndex]: axes }
|
|
54982
|
+
};
|
|
54983
|
+
}
|
|
54984
|
+
var initialFiguresState = {
|
|
54985
|
+
currentHandle: 1,
|
|
54986
|
+
figs: {}
|
|
54987
|
+
};
|
|
54988
|
+
var defaultFigure = {
|
|
54989
|
+
currentAxesIndex: 1,
|
|
54990
|
+
axes: {}
|
|
54991
|
+
};
|
|
54992
|
+
function ensureFig(state) {
|
|
54993
|
+
return state.figs[state.currentHandle] || { ...defaultFigure };
|
|
54994
|
+
}
|
|
54995
|
+
function updateAxes(state, update) {
|
|
54996
|
+
const fig = ensureFig(state);
|
|
54997
|
+
const axes = getAxes(fig);
|
|
54998
|
+
return {
|
|
54999
|
+
...state,
|
|
55000
|
+
figs: {
|
|
55001
|
+
...state.figs,
|
|
55002
|
+
[state.currentHandle]: setAxes(fig, { ...axes, ...update })
|
|
55003
|
+
}
|
|
55004
|
+
};
|
|
55005
|
+
}
|
|
55006
|
+
function addTraces(state, update) {
|
|
55007
|
+
const fig = ensureFig(state);
|
|
55008
|
+
const axes = getAxes(fig);
|
|
55009
|
+
const hold = axes.holdOn;
|
|
55010
|
+
return {
|
|
55011
|
+
...state,
|
|
55012
|
+
figs: {
|
|
55013
|
+
...state.figs,
|
|
55014
|
+
[state.currentHandle]: setAxes(fig, {
|
|
55015
|
+
...axes,
|
|
55016
|
+
traces: update.traces ?? (hold ? axes.traces : []),
|
|
55017
|
+
plot3Traces: update.plot3Traces ?? (hold ? axes.plot3Traces : []),
|
|
55018
|
+
surfTraces: update.surfTraces ?? (hold ? axes.surfTraces : []),
|
|
55019
|
+
pcolorTraces: update.pcolorTraces ?? (hold ? axes.pcolorTraces : []),
|
|
55020
|
+
contourTraces: update.contourTraces ?? (hold ? axes.contourTraces : []),
|
|
55021
|
+
barTraces: update.barTraces ?? (hold ? axes.barTraces : []),
|
|
55022
|
+
barhTraces: update.barhTraces ?? (hold ? axes.barhTraces : []),
|
|
55023
|
+
bar3Traces: update.bar3Traces ?? (hold ? axes.bar3Traces : []),
|
|
55024
|
+
bar3hTraces: update.bar3hTraces ?? (hold ? axes.bar3hTraces : []),
|
|
55025
|
+
errorBarTraces: update.errorBarTraces ?? (hold ? axes.errorBarTraces : []),
|
|
55026
|
+
boxTraces: update.boxTraces ?? (hold ? axes.boxTraces : []),
|
|
55027
|
+
pieTrace: update.pieTrace ?? (hold ? axes.pieTrace : void 0),
|
|
55028
|
+
heatmapTrace: update.heatmapTrace ?? (hold ? axes.heatmapTrace : void 0),
|
|
55029
|
+
quiverTraces: update.quiverTraces ?? (hold ? axes.quiverTraces : []),
|
|
55030
|
+
quiver3Traces: update.quiver3Traces ?? (hold ? axes.quiver3Traces : []),
|
|
55031
|
+
areaTraces: update.areaTraces ?? (hold ? axes.areaTraces : []),
|
|
55032
|
+
areaBaseValue: update.areaBaseValue ?? axes.areaBaseValue,
|
|
55033
|
+
...update.imagescTrace !== void 0 ? { imagescTrace: update.imagescTrace } : {}
|
|
55034
|
+
})
|
|
55035
|
+
}
|
|
55036
|
+
};
|
|
55037
|
+
}
|
|
55038
|
+
var figuresReducer = (state, action) => {
|
|
55039
|
+
switch (action.type) {
|
|
55040
|
+
case "set_figure_handle":
|
|
55041
|
+
return { ...state, currentHandle: action.handle };
|
|
55042
|
+
case "set_hold":
|
|
55043
|
+
return updateAxes(state, { holdOn: action.value });
|
|
55044
|
+
case "plot": {
|
|
55045
|
+
const axes = getAxes(ensureFig(state));
|
|
55046
|
+
return addTraces(state, {
|
|
55047
|
+
traces: axes.holdOn ? [...axes.traces, ...action.traces] : [...action.traces]
|
|
55048
|
+
});
|
|
55049
|
+
}
|
|
55050
|
+
case "plot3": {
|
|
55051
|
+
const axes = getAxes(ensureFig(state));
|
|
55052
|
+
return addTraces(state, {
|
|
55053
|
+
plot3Traces: axes.holdOn ? [...axes.plot3Traces, ...action.traces] : [...action.traces]
|
|
55054
|
+
});
|
|
55055
|
+
}
|
|
55056
|
+
case "surf": {
|
|
55057
|
+
const axes = getAxes(ensureFig(state));
|
|
55058
|
+
return addTraces(state, {
|
|
55059
|
+
surfTraces: axes.holdOn ? [...axes.surfTraces, action.trace] : [action.trace]
|
|
55060
|
+
});
|
|
55061
|
+
}
|
|
55062
|
+
case "surface": {
|
|
55063
|
+
const axes = getAxes(ensureFig(state));
|
|
55064
|
+
return updateAxes(state, {
|
|
55065
|
+
surfTraces: [...axes.surfTraces, action.trace]
|
|
55066
|
+
});
|
|
55067
|
+
}
|
|
55068
|
+
case "imagesc":
|
|
55069
|
+
return addTraces(state, { imagescTrace: action.trace });
|
|
55070
|
+
case "pcolor": {
|
|
55071
|
+
const axes = getAxes(ensureFig(state));
|
|
55072
|
+
return addTraces(state, {
|
|
55073
|
+
pcolorTraces: axes.holdOn ? [...axes.pcolorTraces, action.trace] : [action.trace]
|
|
55074
|
+
});
|
|
55075
|
+
}
|
|
55076
|
+
case "contour": {
|
|
55077
|
+
const axes = getAxes(ensureFig(state));
|
|
55078
|
+
return addTraces(state, {
|
|
55079
|
+
contourTraces: axes.holdOn ? [...axes.contourTraces, action.trace] : [action.trace]
|
|
55080
|
+
});
|
|
55081
|
+
}
|
|
55082
|
+
case "mesh": {
|
|
55083
|
+
const axes = getAxes(ensureFig(state));
|
|
55084
|
+
return addTraces(state, {
|
|
55085
|
+
surfTraces: axes.holdOn ? [...axes.surfTraces, action.trace] : [action.trace]
|
|
55086
|
+
});
|
|
55087
|
+
}
|
|
55088
|
+
case "bar": {
|
|
55089
|
+
const axes = getAxes(ensureFig(state));
|
|
55090
|
+
return addTraces(state, {
|
|
55091
|
+
barTraces: axes.holdOn ? [...axes.barTraces, ...action.traces] : [...action.traces]
|
|
55092
|
+
});
|
|
55093
|
+
}
|
|
55094
|
+
case "barh": {
|
|
55095
|
+
const axes = getAxes(ensureFig(state));
|
|
55096
|
+
return addTraces(state, {
|
|
55097
|
+
barhTraces: axes.holdOn ? [...axes.barhTraces, ...action.traces] : [...action.traces]
|
|
55098
|
+
});
|
|
55099
|
+
}
|
|
55100
|
+
case "bar3": {
|
|
55101
|
+
const axes = getAxes(ensureFig(state));
|
|
55102
|
+
return addTraces(state, {
|
|
55103
|
+
bar3Traces: axes.holdOn ? [...axes.bar3Traces, action.trace] : [action.trace]
|
|
55104
|
+
});
|
|
55105
|
+
}
|
|
55106
|
+
case "bar3h": {
|
|
55107
|
+
const axes = getAxes(ensureFig(state));
|
|
55108
|
+
return addTraces(state, {
|
|
55109
|
+
bar3hTraces: axes.holdOn ? [...axes.bar3hTraces, action.trace] : [action.trace]
|
|
55110
|
+
});
|
|
55111
|
+
}
|
|
55112
|
+
case "errorbar": {
|
|
55113
|
+
const axes = getAxes(ensureFig(state));
|
|
55114
|
+
return addTraces(state, {
|
|
55115
|
+
errorBarTraces: axes.holdOn ? [...axes.errorBarTraces, ...action.traces] : [...action.traces]
|
|
55116
|
+
});
|
|
55117
|
+
}
|
|
55118
|
+
case "boxchart": {
|
|
55119
|
+
const axes = getAxes(ensureFig(state));
|
|
55120
|
+
return addTraces(state, {
|
|
55121
|
+
boxTraces: axes.holdOn ? [...axes.boxTraces, ...action.traces] : [...action.traces]
|
|
55122
|
+
});
|
|
55123
|
+
}
|
|
55124
|
+
case "piechart":
|
|
55125
|
+
return addTraces(state, { pieTrace: action.trace });
|
|
55126
|
+
case "heatmap":
|
|
55127
|
+
return addTraces(state, { heatmapTrace: action.trace });
|
|
55128
|
+
case "quiver": {
|
|
55129
|
+
const axes = getAxes(ensureFig(state));
|
|
55130
|
+
return addTraces(state, {
|
|
55131
|
+
quiverTraces: axes.holdOn ? [...axes.quiverTraces, ...action.traces] : [...action.traces]
|
|
55132
|
+
});
|
|
55133
|
+
}
|
|
55134
|
+
case "quiver3": {
|
|
55135
|
+
const axes = getAxes(ensureFig(state));
|
|
55136
|
+
return addTraces(state, {
|
|
55137
|
+
quiver3Traces: axes.holdOn ? [...axes.quiver3Traces, action.trace] : [action.trace]
|
|
55138
|
+
});
|
|
55139
|
+
}
|
|
55140
|
+
case "area": {
|
|
55141
|
+
const axes = getAxes(ensureFig(state));
|
|
55142
|
+
return addTraces(state, {
|
|
55143
|
+
areaTraces: axes.holdOn ? [...axes.areaTraces, ...action.traces] : [...action.traces],
|
|
55144
|
+
areaBaseValue: action.baseValue
|
|
55145
|
+
});
|
|
55146
|
+
}
|
|
55147
|
+
case "close": {
|
|
55148
|
+
const remainingFigs = Object.fromEntries(
|
|
55149
|
+
Object.entries(state.figs).filter(
|
|
55150
|
+
([k]) => Number(k) !== state.currentHandle
|
|
55151
|
+
)
|
|
55152
|
+
);
|
|
55153
|
+
const handles = Object.keys(remainingFigs).map(Number).sort((a, b) => a - b);
|
|
55154
|
+
return {
|
|
55155
|
+
...state,
|
|
55156
|
+
currentHandle: handles.length > 0 ? handles[handles.length - 1] : 1,
|
|
55157
|
+
figs: remainingFigs
|
|
55158
|
+
};
|
|
55159
|
+
}
|
|
55160
|
+
case "close_all":
|
|
55161
|
+
case "clear":
|
|
55162
|
+
return initialFiguresState;
|
|
55163
|
+
case "set_title":
|
|
55164
|
+
return updateAxes(state, { title: action.text });
|
|
55165
|
+
case "set_xlabel":
|
|
55166
|
+
return updateAxes(state, { xlabel: action.text });
|
|
55167
|
+
case "set_ylabel":
|
|
55168
|
+
return updateAxes(state, { ylabel: action.text });
|
|
55169
|
+
case "set_zlabel":
|
|
55170
|
+
return updateAxes(state, { zlabel: action.text });
|
|
55171
|
+
case "set_shading":
|
|
55172
|
+
return updateAxes(state, { shading: action.shading });
|
|
55173
|
+
case "set_legend":
|
|
55174
|
+
return updateAxes(state, { legend: action.labels });
|
|
55175
|
+
case "set_sgtitle": {
|
|
55176
|
+
const fig = ensureFig(state);
|
|
55177
|
+
return {
|
|
55178
|
+
...state,
|
|
55179
|
+
figs: {
|
|
55180
|
+
...state.figs,
|
|
55181
|
+
[state.currentHandle]: { ...fig, sgtitle: action.text }
|
|
55182
|
+
}
|
|
55183
|
+
};
|
|
55184
|
+
}
|
|
55185
|
+
case "set_grid":
|
|
55186
|
+
return updateAxes(state, { gridOn: action.value });
|
|
55187
|
+
case "set_colorbar":
|
|
55188
|
+
return updateAxes(state, {
|
|
55189
|
+
colorbar: action.value !== "off",
|
|
55190
|
+
colorbarLocation: action.location ?? "eastoutside"
|
|
55191
|
+
});
|
|
55192
|
+
case "set_colormap":
|
|
55193
|
+
return updateAxes(state, {
|
|
55194
|
+
colormap: action.name,
|
|
55195
|
+
colormapData: action.data
|
|
55196
|
+
});
|
|
55197
|
+
case "set_view":
|
|
55198
|
+
return updateAxes(state, { view: { az: action.az, el: action.el } });
|
|
55199
|
+
case "set_axis":
|
|
55200
|
+
return updateAxes(state, { axisMode: action.value });
|
|
55201
|
+
case "set_axis_limits": {
|
|
55202
|
+
const axes = getAxes(ensureFig(state));
|
|
55203
|
+
const resolve = (prev, spec) => {
|
|
55204
|
+
if (spec === void 0) return prev;
|
|
55205
|
+
if (spec === "auto") return void 0;
|
|
55206
|
+
return spec;
|
|
55207
|
+
};
|
|
55208
|
+
return updateAxes(state, {
|
|
55209
|
+
xlim: resolve(axes.xlim, action.xlim),
|
|
55210
|
+
ylim: resolve(axes.ylim, action.ylim),
|
|
55211
|
+
zlim: resolve(axes.zlim, action.zlim)
|
|
55212
|
+
});
|
|
55213
|
+
}
|
|
55214
|
+
case "set_axis_ydir":
|
|
55215
|
+
return updateAxes(state, { yDir: action.dir });
|
|
55216
|
+
case "set_axis_visible":
|
|
55217
|
+
return updateAxes(state, { axisVisible: action.value });
|
|
55218
|
+
case "set_axis_scale":
|
|
55219
|
+
return updateAxes(state, { axisScale: action.value });
|
|
55220
|
+
case "set_caxis":
|
|
55221
|
+
return updateAxes(state, { caxis: action.limits });
|
|
55222
|
+
case "clf": {
|
|
55223
|
+
const fig = state.figs[state.currentHandle];
|
|
55224
|
+
if (!fig) return state;
|
|
55225
|
+
return {
|
|
55226
|
+
...state,
|
|
55227
|
+
figs: {
|
|
55228
|
+
...state.figs,
|
|
55229
|
+
[state.currentHandle]: { ...defaultFigure }
|
|
55230
|
+
}
|
|
55231
|
+
};
|
|
55232
|
+
}
|
|
55233
|
+
case "cla": {
|
|
55234
|
+
const fig = ensureFig(state);
|
|
55235
|
+
const prev = getAxes(fig);
|
|
55236
|
+
const cleared = action.reset ? { ...defaultAxes } : {
|
|
55237
|
+
...defaultAxes,
|
|
55238
|
+
title: prev.title,
|
|
55239
|
+
xlabel: prev.xlabel,
|
|
55240
|
+
ylabel: prev.ylabel,
|
|
55241
|
+
zlabel: prev.zlabel,
|
|
55242
|
+
gridOn: prev.gridOn,
|
|
55243
|
+
colorbar: prev.colorbar,
|
|
55244
|
+
colorbarLocation: prev.colorbarLocation,
|
|
55245
|
+
colormap: prev.colormap,
|
|
55246
|
+
colormapData: prev.colormapData,
|
|
55247
|
+
view: prev.view,
|
|
55248
|
+
axisMode: prev.axisMode,
|
|
55249
|
+
axisScale: prev.axisScale,
|
|
55250
|
+
caxis: prev.caxis,
|
|
55251
|
+
xlim: prev.xlim,
|
|
55252
|
+
ylim: prev.ylim,
|
|
55253
|
+
zlim: prev.zlim,
|
|
55254
|
+
yDir: prev.yDir,
|
|
55255
|
+
axisVisible: prev.axisVisible,
|
|
55256
|
+
shading: prev.shading
|
|
55257
|
+
};
|
|
55258
|
+
return {
|
|
55259
|
+
...state,
|
|
55260
|
+
figs: {
|
|
55261
|
+
...state.figs,
|
|
55262
|
+
[state.currentHandle]: setAxes(fig, cleared)
|
|
55263
|
+
}
|
|
55264
|
+
};
|
|
55265
|
+
}
|
|
55266
|
+
case "set_subplot": {
|
|
55267
|
+
const fig = ensureFig(state);
|
|
55268
|
+
const newFig = {
|
|
55269
|
+
...fig,
|
|
55270
|
+
subplotGrid: { rows: action.rows, cols: action.cols },
|
|
55271
|
+
currentAxesIndex: action.index
|
|
55272
|
+
};
|
|
55273
|
+
if (!newFig.axes[action.index]) {
|
|
55274
|
+
newFig.axes = { ...newFig.axes, [action.index]: { ...defaultAxes } };
|
|
55275
|
+
}
|
|
55276
|
+
return {
|
|
55277
|
+
...state,
|
|
55278
|
+
figs: { ...state.figs, [state.currentHandle]: newFig }
|
|
55279
|
+
};
|
|
55280
|
+
}
|
|
55281
|
+
default:
|
|
55282
|
+
return state;
|
|
55283
|
+
}
|
|
55284
|
+
};
|
|
55285
|
+
|
|
55286
|
+
// src/graphics/axisLimits.ts
|
|
55287
|
+
var EMPTY = { min: Infinity, max: -Infinity };
|
|
55288
|
+
function include(e, v) {
|
|
55289
|
+
if (Number.isFinite(v)) {
|
|
55290
|
+
if (v < e.min) e.min = v;
|
|
55291
|
+
if (v > e.max) e.max = v;
|
|
55292
|
+
}
|
|
55293
|
+
}
|
|
55294
|
+
function includeAll(e, vs) {
|
|
55295
|
+
if (!vs) return;
|
|
55296
|
+
for (let i = 0; i < vs.length; i++) include(e, vs[i]);
|
|
55297
|
+
}
|
|
55298
|
+
function axesIs3D(axes) {
|
|
55299
|
+
return (axes.surfTraces?.length ?? 0) > 0 || (axes.plot3Traces?.length ?? 0) > 0 || (axes.bar3Traces?.length ?? 0) > 0 || (axes.bar3hTraces?.length ?? 0) > 0 || (axes.quiver3Traces?.length ?? 0) > 0;
|
|
55300
|
+
}
|
|
55301
|
+
function dataExtents(axes) {
|
|
55302
|
+
const x = { ...EMPTY };
|
|
55303
|
+
const y = { ...EMPTY };
|
|
55304
|
+
const z = { ...EMPTY };
|
|
55305
|
+
for (const t of axes.traces ?? []) {
|
|
55306
|
+
includeAll(x, t.x);
|
|
55307
|
+
includeAll(y, t.y);
|
|
55308
|
+
}
|
|
55309
|
+
for (const t of axes.plot3Traces ?? []) {
|
|
55310
|
+
includeAll(x, t.x);
|
|
55311
|
+
includeAll(y, t.y);
|
|
55312
|
+
includeAll(z, t.z);
|
|
55313
|
+
}
|
|
55314
|
+
for (const t of [...axes.surfTraces ?? []]) {
|
|
55315
|
+
includeAll(x, t.x);
|
|
55316
|
+
includeAll(y, t.y);
|
|
55317
|
+
includeAll(z, t.z);
|
|
55318
|
+
}
|
|
55319
|
+
if (axes.imagescTrace) {
|
|
55320
|
+
include(x, axes.imagescTrace.x[0]);
|
|
55321
|
+
include(x, axes.imagescTrace.x[1]);
|
|
55322
|
+
include(y, axes.imagescTrace.y[0]);
|
|
55323
|
+
include(y, axes.imagescTrace.y[1]);
|
|
55324
|
+
}
|
|
55325
|
+
for (const t of axes.pcolorTraces ?? []) {
|
|
55326
|
+
includeAll(x, t.x);
|
|
55327
|
+
includeAll(y, t.y);
|
|
55328
|
+
}
|
|
55329
|
+
for (const t of axes.contourTraces ?? []) {
|
|
55330
|
+
includeAll(x, t.x);
|
|
55331
|
+
includeAll(y, t.y);
|
|
55332
|
+
}
|
|
55333
|
+
for (const bt of axes.barTraces ?? []) {
|
|
55334
|
+
const hw = bt.width / 2;
|
|
55335
|
+
for (let i = 0; i < bt.x.length; i++) {
|
|
55336
|
+
include(x, bt.x[i] - hw);
|
|
55337
|
+
include(x, bt.x[i] + hw);
|
|
55338
|
+
include(y, bt.y[i]);
|
|
55339
|
+
}
|
|
55340
|
+
include(y, 0);
|
|
55341
|
+
}
|
|
55342
|
+
for (const bt of axes.barhTraces ?? []) {
|
|
55343
|
+
const hh = bt.width / 2;
|
|
55344
|
+
for (let i = 0; i < bt.x.length; i++) {
|
|
55345
|
+
include(y, bt.x[i] - hh);
|
|
55346
|
+
include(y, bt.x[i] + hh);
|
|
55347
|
+
include(x, bt.y[i]);
|
|
55348
|
+
}
|
|
55349
|
+
include(x, 0);
|
|
55350
|
+
}
|
|
55351
|
+
for (const bt of [...axes.bar3Traces ?? [], ...axes.bar3hTraces ?? []]) {
|
|
55352
|
+
includeAll(x, bt.x);
|
|
55353
|
+
includeAll(y, bt.y);
|
|
55354
|
+
includeAll(z, bt.z);
|
|
55355
|
+
include(z, 0);
|
|
55356
|
+
}
|
|
55357
|
+
for (const et of axes.errorBarTraces ?? []) {
|
|
55358
|
+
for (let i = 0; i < et.x.length; i++) {
|
|
55359
|
+
include(x, et.xNeg ? et.x[i] - et.xNeg[i] : et.x[i]);
|
|
55360
|
+
include(x, et.xPos ? et.x[i] + et.xPos[i] : et.x[i]);
|
|
55361
|
+
include(y, et.y[i] - et.yNeg[i]);
|
|
55362
|
+
include(y, et.y[i] + et.yPos[i]);
|
|
55363
|
+
}
|
|
55364
|
+
}
|
|
55365
|
+
for (const bt of axes.boxTraces ?? []) {
|
|
55366
|
+
const hw = bt.width / 2;
|
|
55367
|
+
include(x, bt.x - hw);
|
|
55368
|
+
include(x, bt.x + hw);
|
|
55369
|
+
include(y, bt.whiskerLow);
|
|
55370
|
+
include(y, bt.whiskerHigh);
|
|
55371
|
+
for (const o of bt.outliers) include(y, o);
|
|
55372
|
+
}
|
|
55373
|
+
if (axes.areaTraces && axes.areaTraces.length > 0) {
|
|
55374
|
+
const base = axes.areaBaseValue ?? 0;
|
|
55375
|
+
include(y, base);
|
|
55376
|
+
const n = axes.areaTraces[0].x.length;
|
|
55377
|
+
for (let i = 0; i < n; i++) {
|
|
55378
|
+
let cum = base;
|
|
55379
|
+
for (const t of axes.areaTraces) {
|
|
55380
|
+
if (i < t.x.length) {
|
|
55381
|
+
include(x, t.x[i]);
|
|
55382
|
+
cum += t.y[i] - base;
|
|
55383
|
+
include(y, cum);
|
|
55384
|
+
}
|
|
55385
|
+
}
|
|
55386
|
+
}
|
|
55387
|
+
}
|
|
55388
|
+
for (const qt of axes.quiverTraces ?? []) {
|
|
55389
|
+
for (let i = 0; i < qt.x.length; i++) {
|
|
55390
|
+
include(x, qt.x[i]);
|
|
55391
|
+
include(x, qt.x[i] + qt.u[i]);
|
|
55392
|
+
include(y, qt.y[i]);
|
|
55393
|
+
include(y, qt.y[i] + qt.v[i]);
|
|
55394
|
+
}
|
|
55395
|
+
}
|
|
55396
|
+
for (const qt of axes.quiver3Traces ?? []) {
|
|
55397
|
+
for (let i = 0; i < qt.x.length; i++) {
|
|
55398
|
+
include(x, qt.x[i]);
|
|
55399
|
+
include(x, qt.x[i] + qt.u[i]);
|
|
55400
|
+
include(y, qt.y[i]);
|
|
55401
|
+
include(y, qt.y[i] + qt.v[i]);
|
|
55402
|
+
include(z, qt.z[i]);
|
|
55403
|
+
include(z, qt.z[i] + qt.w[i]);
|
|
55404
|
+
}
|
|
55405
|
+
}
|
|
55406
|
+
return { x, y, z };
|
|
55407
|
+
}
|
|
55408
|
+
function padExtent(e, tight) {
|
|
55409
|
+
if (!Number.isFinite(e.min) || !Number.isFinite(e.max)) return [0, 1];
|
|
55410
|
+
let { min: min2, max: max2 } = e;
|
|
55411
|
+
if (max2 === min2) {
|
|
55412
|
+
min2 -= 1;
|
|
55413
|
+
max2 += 1;
|
|
55414
|
+
return [min2, max2];
|
|
55415
|
+
}
|
|
55416
|
+
if (tight) return [min2, max2];
|
|
55417
|
+
const pad = (max2 - min2) * 0.05;
|
|
55418
|
+
return [min2 - pad, max2 + pad];
|
|
55419
|
+
}
|
|
55420
|
+
function applyExplicit(auto, explicit) {
|
|
55421
|
+
if (!explicit) return auto;
|
|
55422
|
+
return [explicit[0] ?? auto[0], explicit[1] ?? auto[1]];
|
|
55423
|
+
}
|
|
55424
|
+
function computeAxisLimits(axes) {
|
|
55425
|
+
const tight = axes.axisMode?.includes("tight") || axes.axisMode?.includes("image") ? true : false;
|
|
55426
|
+
const ext = dataExtents(axes);
|
|
55427
|
+
const xl = applyExplicit(padExtent(ext.x, tight), axes.xlim);
|
|
55428
|
+
const yl = applyExplicit(padExtent(ext.y, tight), axes.ylim);
|
|
55429
|
+
if (!axesIs3D(axes)) return [xl[0], xl[1], yl[0], yl[1]];
|
|
55430
|
+
const zl = applyExplicit(padExtent(ext.z, tight), axes.zlim);
|
|
55431
|
+
return [xl[0], xl[1], yl[0], yl[1], zl[0], zl[1]];
|
|
55432
|
+
}
|
|
55433
|
+
|
|
54375
55434
|
// src/numbl-core/runtime/runtime.ts
|
|
54376
55435
|
var Runtime = class _Runtime {
|
|
54377
55436
|
constructor(options, initialVariableValues) {
|
|
@@ -54593,6 +55652,18 @@ var Runtime = class _Runtime {
|
|
|
54593
55652
|
}
|
|
54594
55653
|
return RTV.dummyHandle();
|
|
54595
55654
|
};
|
|
55655
|
+
this.builtins["axis"] = (nargout, args) => {
|
|
55656
|
+
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
55657
|
+
const applied = applyAxisCommand(
|
|
55658
|
+
margs,
|
|
55659
|
+
this.plotInstructions,
|
|
55660
|
+
() => this.currentAxisLimits()
|
|
55661
|
+
);
|
|
55662
|
+
if (!applied && nargout >= 1) {
|
|
55663
|
+
return RTV.row(this.currentAxisLimits());
|
|
55664
|
+
}
|
|
55665
|
+
return void 0;
|
|
55666
|
+
};
|
|
54596
55667
|
this.builtins["fplot"] = (_nargout, args) => {
|
|
54597
55668
|
fplotCall(this, this.plotInstructions, args.map(ensureRuntimeValue));
|
|
54598
55669
|
};
|
|
@@ -55496,6 +56567,21 @@ var Runtime = class _Runtime {
|
|
|
55496
56567
|
ishold() {
|
|
55497
56568
|
return RTV.logical(this.holdState);
|
|
55498
56569
|
}
|
|
56570
|
+
/** Current axis limits of the active axes, as MATLAB's `axis` query
|
|
56571
|
+
* returns them: `[xmin xmax ymin ymax]` (2-D) or with `zmin zmax`
|
|
56572
|
+
* appended (3-D). Reduces the accumulated plot instructions into a figure
|
|
56573
|
+
* state and reads the current axes' explicit/data-derived limits. */
|
|
56574
|
+
currentAxisLimits() {
|
|
56575
|
+
let state = initialFiguresState;
|
|
56576
|
+
for (const instr of this.plotInstructions) {
|
|
56577
|
+
state = figuresReducer(state, instr);
|
|
56578
|
+
}
|
|
56579
|
+
const fig = state.figs[state.currentHandle];
|
|
56580
|
+
if (!fig) return [0, 1, 0, 1];
|
|
56581
|
+
const axes = fig.axes[fig.currentAxesIndex];
|
|
56582
|
+
if (!axes) return [0, 1, 0, 1];
|
|
56583
|
+
return computeAxisLimits(axes);
|
|
56584
|
+
}
|
|
55499
56585
|
// ── Drawnow / Pause ─────────────────────────────────────────────────
|
|
55500
56586
|
drawnow() {
|
|
55501
56587
|
return drawnow(this.plotInstructions, this.options);
|
|
@@ -59257,11 +60343,11 @@ function instantiateClass(className, args, nargout) {
|
|
|
59257
60343
|
} catch {
|
|
59258
60344
|
}
|
|
59259
60345
|
}
|
|
59260
|
-
const
|
|
60346
|
+
const isHandle3 = this.isHandleClass(classInfo);
|
|
59261
60347
|
const instance = RTV.classInstance(
|
|
59262
60348
|
className,
|
|
59263
60349
|
propertyNames,
|
|
59264
|
-
|
|
60350
|
+
isHandle3,
|
|
59265
60351
|
defaults
|
|
59266
60352
|
);
|
|
59267
60353
|
if (classInfo.constructorName) {
|
|
@@ -61313,7 +62399,7 @@ function isNumeric2(t) {
|
|
|
61313
62399
|
function isVoid(t) {
|
|
61314
62400
|
return t.kind === "Void";
|
|
61315
62401
|
}
|
|
61316
|
-
function
|
|
62402
|
+
function isHandle2(t) {
|
|
61317
62403
|
return t.kind === "Handle";
|
|
61318
62404
|
}
|
|
61319
62405
|
function isStruct(t) {
|
|
@@ -64780,17 +65866,17 @@ function complex_sort_indices(a, descending) {
|
|
|
64780
65866
|
});
|
|
64781
65867
|
return idx;
|
|
64782
65868
|
}
|
|
64783
|
-
const
|
|
65869
|
+
const mag2 = new Float64Array(n);
|
|
64784
65870
|
const ph = new Float64Array(n);
|
|
64785
65871
|
for (let i = 0; i < n; i++) {
|
|
64786
65872
|
const re = a.data[i];
|
|
64787
65873
|
const xi = im !== void 0 ? im[i] : 0;
|
|
64788
|
-
|
|
65874
|
+
mag2[i] = Math.hypot(re, xi);
|
|
64789
65875
|
ph[i] = Math.atan2(xi, re);
|
|
64790
65876
|
}
|
|
64791
65877
|
idx.sort((p2, q) => {
|
|
64792
|
-
if (
|
|
64793
|
-
if (
|
|
65878
|
+
if (mag2[p2] < mag2[q]) return descending ? 1 : -1;
|
|
65879
|
+
if (mag2[p2] > mag2[q]) return descending ? -1 : 1;
|
|
64794
65880
|
if (ph[p2] < ph[q]) return descending ? 1 : -1;
|
|
64795
65881
|
if (ph[p2] > ph[q]) return descending ? -1 : 1;
|
|
64796
65882
|
return p2 - q;
|
|
@@ -67611,7 +68697,7 @@ var ge = defineCompare("ge", ">=", (a, b) => a >= b);
|
|
|
67611
68697
|
// src/numbl-core/jit/codegen/cHelpers.ts
|
|
67612
68698
|
function cTypeFor(t) {
|
|
67613
68699
|
if (isMultiElement(t)) return "mtoc2_tensor_t";
|
|
67614
|
-
if (
|
|
68700
|
+
if (isHandle2(t)) return handleTypedefName(t);
|
|
67615
68701
|
if (t.kind === "Struct") return structTypedefName(t);
|
|
67616
68702
|
if (t.kind === "Class") return classTypedefName(t);
|
|
67617
68703
|
if (t.kind === "Cell") return cellTypedefName(t);
|
|
@@ -73247,7 +74333,7 @@ function staticAnswer(t) {
|
|
|
73247
74333
|
}
|
|
73248
74334
|
if (isString(t)) return true;
|
|
73249
74335
|
if (isChar(t)) return false;
|
|
73250
|
-
if (isStruct(t) || isClass(t) ||
|
|
74336
|
+
if (isStruct(t) || isClass(t) || isHandle2(t)) return false;
|
|
73251
74337
|
return void 0;
|
|
73252
74338
|
}
|
|
73253
74339
|
function requireKnown(t) {
|
|
@@ -73366,7 +74452,7 @@ var isstruct = {
|
|
|
73366
74452
|
function staticClassNameOf(t) {
|
|
73367
74453
|
if (isClass(t)) return t.className;
|
|
73368
74454
|
if (isStruct(t)) return "struct";
|
|
73369
|
-
if (
|
|
74455
|
+
if (isHandle2(t)) return "function_handle";
|
|
73370
74456
|
if (isChar(t)) return "char";
|
|
73371
74457
|
if (isString(t)) return "string";
|
|
73372
74458
|
if (isCell(t)) return "cell";
|
|
@@ -78446,7 +79532,7 @@ function lowerFuncCall(e) {
|
|
|
78446
79532
|
if (envEntry === void 0 && e.name === "feval") {
|
|
78447
79533
|
return lowerFevalCall.call(this, e);
|
|
78448
79534
|
}
|
|
78449
|
-
if (envEntry !== void 0 &&
|
|
79535
|
+
if (envEntry !== void 0 && isHandle2(envEntry.ty)) {
|
|
78450
79536
|
return dispatchHandleCall.call(this, e.name, envEntry, e.args, e.span);
|
|
78451
79537
|
}
|
|
78452
79538
|
if (envEntry === void 0 && this.workspace.isClass(e.name)) {
|
|
@@ -78893,7 +79979,7 @@ function lowerMultiAssign(s) {
|
|
|
78893
79979
|
s = { ...s, lvalues: expandedLvalues };
|
|
78894
79980
|
if (s.expr.type === "FuncCall") {
|
|
78895
79981
|
const envEntry = this.env.get(callName);
|
|
78896
|
-
if (envEntry !== void 0 &&
|
|
79982
|
+
if (envEntry !== void 0 && isHandle2(envEntry.ty)) {
|
|
78897
79983
|
return dispatchHandleMultiAssign.call(
|
|
78898
79984
|
this,
|
|
78899
79985
|
callName,
|