numbl 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist-cli/cli.js +547 -1230
  2. package/package.json +1 -1
package/dist-cli/cli.js CHANGED
@@ -158,7 +158,7 @@ async function fetchPackageIndex(backend, indexUrl = DEFAULT_INDEX_URL) {
158
158
  return backend.fetchJson(indexUrl);
159
159
  }
160
160
  function findPackageEntry(index2, packageName, arch) {
161
- for (const candidate of ["numbl_" + arch, "numbl_wasm", "all"]) {
161
+ for (const candidate of ["numbl_" + arch, "numbl_wasm", "any"]) {
162
162
  const entry = index2.packages.find(
163
163
  (p) => p.name === packageName && p.architecture === candidate
164
164
  );
@@ -168,7 +168,7 @@ function findPackageEntry(index2, packageName, arch) {
168
168
  }
169
169
  function listAvailablePackages(index2, arch) {
170
170
  return index2.packages.filter(
171
- (p) => p.architecture === arch || p.architecture === "wasm" || p.architecture === "all"
171
+ (p) => p.architecture === "numbl_" + arch || p.architecture === "numbl_wasm" || p.architecture === "any"
172
172
  );
173
173
  }
174
174
 
@@ -17432,14 +17432,24 @@ function parseEconArg(argType) {
17432
17432
  if (isString(argType) === true || isChar(argType) === true) return "unknown";
17433
17433
  return null;
17434
17434
  }
17435
+ function toF64(data) {
17436
+ return data instanceof Float64Array ? data : new Float64Array(data);
17437
+ }
17438
+ function parseStringArgLower(arg) {
17439
+ if (typeof arg === "string") {
17440
+ return arg.replace(/^['"]|['"]$/g, "").toLowerCase();
17441
+ }
17442
+ if (arg && typeof arg === "object" && "value" in arg) {
17443
+ return String(arg.value).replace(/^['"]|['"]$/g, "").toLowerCase();
17444
+ }
17445
+ return String(arg).toLowerCase();
17446
+ }
17435
17447
 
17436
17448
  // src/numbl-core/builtins/linear-algebra/linsolve.ts
17437
17449
  function linsolveLapack(A, m, n, B, nrhs) {
17438
17450
  const bridge = getEffectiveBridge("linsolve", "linsolve");
17439
17451
  if (!bridge?.linsolve) return null;
17440
- const f64A = A instanceof Float64Array ? A : new Float64Array(A);
17441
- const f64B = B instanceof Float64Array ? B : new Float64Array(B);
17442
- return bridge.linsolve(f64A, m, n, f64B, nrhs);
17452
+ return bridge.linsolve(toF64(A), m, n, toF64(B), nrhs);
17443
17453
  }
17444
17454
  function linsolveComplexLapack(ARe, AIm, m, n, BRe, BIm, nrhs) {
17445
17455
  const bridge = getEffectiveBridge("linsolveComplex", "linsolveComplex");
@@ -17447,11 +17457,15 @@ function linsolveComplexLapack(ARe, AIm, m, n, BRe, BIm, nrhs) {
17447
17457
  throw new RuntimeError(
17448
17458
  "linsolveComplex: no bridge available (should not happen)"
17449
17459
  );
17450
- const f64ARe = ARe instanceof Float64Array ? ARe : new Float64Array(ARe);
17451
- const f64AIm = AIm instanceof Float64Array ? AIm : new Float64Array(AIm);
17452
- const f64BRe = BRe instanceof Float64Array ? BRe : new Float64Array(BRe);
17453
- const f64BIm = BIm instanceof Float64Array ? BIm : new Float64Array(BIm);
17454
- return bridge.linsolveComplex(f64ARe, f64AIm, m, n, f64BRe, f64BIm, nrhs);
17460
+ return bridge.linsolveComplex(
17461
+ toF64(ARe),
17462
+ toF64(AIm),
17463
+ m,
17464
+ n,
17465
+ toF64(BRe),
17466
+ toF64(BIm),
17467
+ nrhs
17468
+ );
17455
17469
  }
17456
17470
  function registerLinsolve() {
17457
17471
  register("linsolve", [
@@ -24523,82 +24537,43 @@ function registerMathFunctions() {
24523
24537
  }),
24524
24538
  1
24525
24539
  );
24526
- register(
24527
- "isnan",
24528
- builtinSingle((args) => {
24529
- if (args.length !== 1)
24530
- throw new RuntimeError("isnan requires 1 argument");
24531
- const v = args[0];
24532
- if (isRuntimeNumber(v)) return RTV.logical(Number.isNaN(v));
24533
- if (isRuntimeLogical(v)) return RTV.logical(false);
24534
- if (isRuntimeComplexNumber(v))
24535
- return RTV.logical(Number.isNaN(v.re) || Number.isNaN(v.im));
24536
- if (isRuntimeTensor(v)) {
24537
- const result = new FloatXArray(v.data.length);
24538
- for (let i = 0; i < v.data.length; i++) {
24539
- const reNaN = Number.isNaN(v.data[i]);
24540
- const imNaN = v.imag ? Number.isNaN(v.imag[i]) : false;
24541
- result[i] = reNaN || imNaN ? 1 : 0;
24542
- }
24543
- const t = RTV.tensor(result, v.shape);
24544
- t._isLogical = true;
24545
- return t;
24546
- }
24547
- throw new RuntimeError("Expected numeric argument");
24548
- }),
24549
- 1
24550
- );
24551
- register(
24552
- "isinf",
24553
- builtinSingle((args) => {
24554
- if (args.length !== 1)
24555
- throw new RuntimeError("isinf requires 1 argument");
24556
- const v = args[0];
24557
- const isInf = (x) => !Number.isFinite(x) && !Number.isNaN(x);
24558
- if (isRuntimeNumber(v)) return RTV.logical(isInf(v));
24559
- if (isRuntimeLogical(v)) return RTV.logical(false);
24560
- if (isRuntimeComplexNumber(v))
24561
- return RTV.logical(isInf(v.re) || isInf(v.im));
24562
- if (isRuntimeTensor(v)) {
24563
- const result = new FloatXArray(v.data.length);
24564
- for (let i = 0; i < v.data.length; i++) {
24565
- const reInf = isInf(v.data[i]);
24566
- const imInf = v.imag ? isInf(v.imag[i]) : false;
24567
- result[i] = reInf || imInf ? 1 : 0;
24540
+ function numericPredicate(name, scalarTest, logicalDefault, combineReIm) {
24541
+ register(
24542
+ name,
24543
+ builtinSingle((args) => {
24544
+ if (args.length !== 1)
24545
+ throw new RuntimeError(`${name} requires 1 argument`);
24546
+ const v = args[0];
24547
+ if (isRuntimeNumber(v)) return RTV.logical(scalarTest(v));
24548
+ if (isRuntimeLogical(v)) return RTV.logical(logicalDefault);
24549
+ if (isRuntimeComplexNumber(v)) {
24550
+ const re = scalarTest(v.re), im = scalarTest(v.im);
24551
+ return RTV.logical(combineReIm === "or" ? re || im : re && im);
24568
24552
  }
24569
- const t = RTV.tensor(result, v.shape);
24570
- t._isLogical = true;
24571
- return t;
24572
- }
24573
- throw new RuntimeError("Expected numeric argument");
24574
- }),
24575
- 1
24576
- );
24577
- register(
24578
- "isfinite",
24579
- builtinSingle((args) => {
24580
- if (args.length !== 1)
24581
- throw new RuntimeError("isfinite requires 1 argument");
24582
- const v = args[0];
24583
- if (isRuntimeNumber(v)) return RTV.logical(Number.isFinite(v));
24584
- if (isRuntimeLogical(v)) return RTV.logical(true);
24585
- if (isRuntimeComplexNumber(v))
24586
- return RTV.logical(Number.isFinite(v.re) && Number.isFinite(v.im));
24587
- if (isRuntimeTensor(v)) {
24588
- const result = new FloatXArray(v.data.length);
24589
- for (let i = 0; i < v.data.length; i++) {
24590
- const reFin = Number.isFinite(v.data[i]);
24591
- const imFin = v.imag ? Number.isFinite(v.imag[i]) : true;
24592
- result[i] = reFin && imFin ? 1 : 0;
24553
+ if (isRuntimeTensor(v)) {
24554
+ const result = new FloatXArray(v.data.length);
24555
+ for (let i = 0; i < v.data.length; i++) {
24556
+ const re = scalarTest(v.data[i]);
24557
+ const im = v.imag ? scalarTest(v.imag[i]) : logicalDefault;
24558
+ result[i] = (combineReIm === "or" ? re || im : re && im) ? 1 : 0;
24559
+ }
24560
+ const t = RTV.tensor(result, v.shape);
24561
+ t._isLogical = true;
24562
+ return t;
24593
24563
  }
24594
- const t = RTV.tensor(result, v.shape);
24595
- t._isLogical = true;
24596
- return t;
24597
- }
24598
- throw new RuntimeError("Expected numeric argument");
24599
- }),
24600
- 1
24564
+ throw new RuntimeError("Expected numeric argument");
24565
+ }),
24566
+ 1
24567
+ );
24568
+ }
24569
+ numericPredicate("isnan", Number.isNaN, false, "or");
24570
+ numericPredicate(
24571
+ "isinf",
24572
+ (x) => !Number.isFinite(x) && !Number.isNaN(x),
24573
+ false,
24574
+ "or"
24601
24575
  );
24576
+ numericPredicate("isfinite", Number.isFinite, true, "and");
24602
24577
  register(
24603
24578
  "real",
24604
24579
  builtinSingle((args) => {
@@ -24915,54 +24890,26 @@ function registerMathFunctions() {
24915
24890
  }),
24916
24891
  1
24917
24892
  );
24918
- register(
24919
- "besselj",
24920
- builtinSingle((args) => {
24921
- if (args.length < 2 || args.length > 3)
24922
- throw new RuntimeError("besselj requires 2 or 3 arguments");
24923
- const scale = args.length === 3 ? toNumber(args[2]) : 0;
24924
- return applyBesselBinary(args[0], args[1], (nu, z) => {
24925
- const val = besselj(nu, z);
24926
- return scale === 1 ? val * Math.exp(-Math.abs(z)) : val;
24927
- });
24928
- })
24929
- );
24930
- register(
24931
- "bessely",
24932
- builtinSingle((args) => {
24933
- if (args.length < 2 || args.length > 3)
24934
- throw new RuntimeError("bessely requires 2 or 3 arguments");
24935
- const scale = args.length === 3 ? toNumber(args[2]) : 0;
24936
- return applyBesselBinary(args[0], args[1], (nu, z) => {
24937
- const val = bessely(nu, z);
24938
- return scale === 1 ? val * Math.exp(-Math.abs(z)) : val;
24939
- });
24940
- })
24941
- );
24942
- register(
24943
- "besseli",
24944
- builtinSingle((args) => {
24945
- if (args.length < 2 || args.length > 3)
24946
- throw new RuntimeError("besseli requires 2 or 3 arguments");
24947
- const scale = args.length === 3 ? toNumber(args[2]) : 0;
24948
- return applyBesselBinary(args[0], args[1], (nu, z) => {
24949
- const val = besseli(nu, z);
24950
- return scale === 1 ? val * Math.exp(-Math.abs(z)) : val;
24951
- });
24952
- })
24953
- );
24954
- register(
24955
- "besselk",
24956
- builtinSingle((args) => {
24957
- if (args.length < 2 || args.length > 3)
24958
- throw new RuntimeError("besselk requires 2 or 3 arguments");
24959
- const scale = args.length === 3 ? toNumber(args[2]) : 0;
24960
- return applyBesselBinary(args[0], args[1], (nu, z) => {
24961
- const val = besselk(nu, z);
24962
- return scale === 1 ? val * Math.exp(z) : val;
24963
- });
24964
- })
24965
- );
24893
+ const besselDefs = [
24894
+ ["besselj", besselj, (z) => Math.exp(-Math.abs(z))],
24895
+ ["bessely", bessely, (z) => Math.exp(-Math.abs(z))],
24896
+ ["besseli", besseli, (z) => Math.exp(-Math.abs(z))],
24897
+ ["besselk", besselk, (z) => Math.exp(z)]
24898
+ ];
24899
+ for (const [name, fn, scaleFn] of besselDefs) {
24900
+ register(
24901
+ name,
24902
+ builtinSingle((args) => {
24903
+ if (args.length < 2 || args.length > 3)
24904
+ throw new RuntimeError(`${name} requires 2 or 3 arguments`);
24905
+ const scale = args.length === 3 ? toNumber(args[2]) : 0;
24906
+ return applyBesselBinary(args[0], args[1], (nu, z) => {
24907
+ const val = fn(nu, z);
24908
+ return scale === 1 ? val * scaleFn(z) : val;
24909
+ });
24910
+ })
24911
+ );
24912
+ }
24966
24913
  const airyFns = [airyAi, airyAiPrime, airyBi, airyBiPrime];
24967
24914
  const airyComplexKeys = ["ai", "aip", "bi", "bip"];
24968
24915
  function applyAiryElementwise(xArg, n, scaled) {
@@ -25378,33 +25325,36 @@ function registerPrngFunctions() {
25378
25325
  return RTV.num(0);
25379
25326
  })
25380
25327
  );
25381
- register("rand", [
25382
- // Legacy: rand('seed', s) — prefer rng(s) instead
25383
- {
25384
- check: (argTypes) => argTypes.length === 2 && (argTypes[0].kind === "Char" || argTypes[0].kind === "String") && (argTypes[1].kind === "Number" || argTypes[1].kind === "Unknown") ? { outputTypes: [{ kind: "Number" }] } : null,
25385
- apply: (args) => {
25386
- const s = args[0];
25387
- if (!isRuntimeString(s) && !isRuntimeChar(s) || rstr(s) !== "seed")
25388
- throw new RuntimeError(
25389
- "rand: only 'seed' string option is supported"
25390
- );
25391
- seedRng(Math.round(toNumber(args[1])));
25392
- return RTV.num(0);
25393
- }
25394
- },
25395
- {
25396
- check: realArrayConstructorCheck,
25397
- apply: (args) => {
25398
- if (args.length === 0) return RTV.num(rngRandom());
25399
- const shape = parseShapeArgs(args);
25400
- if (shape.length === 1) shape.push(shape[0]);
25401
- const n = numel(shape);
25402
- const data = new FloatXArray(n);
25403
- for (let i = 0; i < n; i++) data[i] = rngRandom();
25404
- return RTV.tensor(data, shape);
25328
+ function registerRandFn(name, gen) {
25329
+ register(name, [
25330
+ {
25331
+ check: (argTypes) => argTypes.length === 2 && (argTypes[0].kind === "Char" || argTypes[0].kind === "String") && (argTypes[1].kind === "Number" || argTypes[1].kind === "Unknown") ? { outputTypes: [{ kind: "Number" }] } : null,
25332
+ apply: (args) => {
25333
+ const s = args[0];
25334
+ if (!isRuntimeString(s) && !isRuntimeChar(s) || rstr(s) !== "seed")
25335
+ throw new RuntimeError(
25336
+ `${name}: only 'seed' string option is supported`
25337
+ );
25338
+ seedRng(Math.round(toNumber(args[1])));
25339
+ return RTV.num(0);
25340
+ }
25341
+ },
25342
+ {
25343
+ check: realArrayConstructorCheck,
25344
+ apply: (args) => {
25345
+ if (args.length === 0) return RTV.num(gen());
25346
+ const shape = parseShapeArgs(args);
25347
+ if (shape.length === 1) shape.push(shape[0]);
25348
+ const n = numel(shape);
25349
+ const data = new FloatXArray(n);
25350
+ for (let i = 0; i < n; i++) data[i] = gen();
25351
+ return RTV.tensor(data, shape);
25352
+ }
25405
25353
  }
25406
- }
25407
- ]);
25354
+ ]);
25355
+ }
25356
+ registerRandFn("rand", rngRandom);
25357
+ registerRandFn("randn", boxMullerRandom);
25408
25358
  register(
25409
25359
  "randi",
25410
25360
  builtinSingle((args) => {
@@ -25457,33 +25407,6 @@ function registerPrngFunctions() {
25457
25407
  return RTV.tensor(perm.slice(0, k), [1, k]);
25458
25408
  })
25459
25409
  );
25460
- register("randn", [
25461
- // Legacy: randn('seed', s) — prefer rng(s) instead
25462
- {
25463
- check: (argTypes) => argTypes.length === 2 && (argTypes[0].kind === "Char" || argTypes[0].kind === "String") && (argTypes[1].kind === "Number" || argTypes[1].kind === "Unknown") ? { outputTypes: [{ kind: "Number" }] } : null,
25464
- apply: (args) => {
25465
- const s = args[0];
25466
- if (!isRuntimeString(s) && !isRuntimeChar(s) || rstr(s) !== "seed")
25467
- throw new RuntimeError(
25468
- "randn: only 'seed' string option is supported"
25469
- );
25470
- seedRng(Math.round(toNumber(args[1])));
25471
- return RTV.num(0);
25472
- }
25473
- },
25474
- {
25475
- check: realArrayConstructorCheck,
25476
- apply: (args) => {
25477
- if (args.length === 0) return RTV.num(boxMullerRandom());
25478
- const shape = parseShapeArgs(args);
25479
- if (shape.length === 1) shape.push(shape[0]);
25480
- const n = numel(shape);
25481
- const data = new FloatXArray(n);
25482
- for (let i = 0; i < n; i++) data[i] = boxMullerRandom();
25483
- return RTV.tensor(data, shape);
25484
- }
25485
- }
25486
- ]);
25487
25410
  }
25488
25411
 
25489
25412
  // src/numbl-core/builtins/array.ts
@@ -25556,7 +25479,7 @@ function registerArrayFunctions() {
25556
25479
  "linspace",
25557
25480
  builtinSingle((args) => {
25558
25481
  if (args.length < 2 || args.length > 3)
25559
- throw new Error("linspace requires 2 or 3 arguments");
25482
+ throw new RuntimeError("linspace requires 2 or 3 arguments");
25560
25483
  const start = toNumber(args[0]);
25561
25484
  const end = toNumber(args[1]);
25562
25485
  const n = args.length === 3 ? Math.round(toNumber(args[2])) : 100;
@@ -25576,7 +25499,7 @@ function registerArrayFunctions() {
25576
25499
  return makeRangeTensor(toNumber(args[0]), 1, toNumber(args[1]));
25577
25500
  if (args.length === 3)
25578
25501
  return makeRangeTensor(toNumber(args[0]), toNumber(args[1]), toNumber(args[2]));
25579
- throw new Error("colon requires 2 or 3 arguments");
25502
+ throw new RuntimeError("colon requires 2 or 3 arguments");
25580
25503
  })
25581
25504
  );
25582
25505
  register(
@@ -27209,6 +27132,69 @@ function registerIntrospectionFunctions() {
27209
27132
  }
27210
27133
 
27211
27134
  // src/numbl-core/builtins/reduction.ts
27135
+ function nextSubscripts(subs, shape, skipDim) {
27136
+ for (let d = 0; d < subs.length; d++) {
27137
+ if (skipDim !== void 0 && d === skipDim) continue;
27138
+ subs[d]++;
27139
+ if (subs[d] < shape[d]) return true;
27140
+ subs[d] = 0;
27141
+ }
27142
+ return false;
27143
+ }
27144
+ function squeezeTrailing(shape) {
27145
+ while (shape.length > 2 && shape[shape.length - 1] === 1) {
27146
+ shape.pop();
27147
+ }
27148
+ }
27149
+ function scanLogical(data, imag, mode) {
27150
+ const defaultResult = mode === "all";
27151
+ for (let i = 0; i < data.length; i++) {
27152
+ const isNonZero = data[i] !== 0 || imag !== void 0 && imag[i] !== 0;
27153
+ if (isNonZero !== defaultResult) return !defaultResult;
27154
+ }
27155
+ return defaultResult;
27156
+ }
27157
+ function logicalAlongDim(v, dim, mode) {
27158
+ const shape = v.shape;
27159
+ const dimIdx = dim - 1;
27160
+ if (dimIdx >= shape.length) {
27161
+ const result2 = new FloatXArray(v.data.length);
27162
+ for (let i = 0; i < v.data.length; i++)
27163
+ result2[i] = v.data[i] !== 0 || v.imag && v.imag[i] !== 0 ? 1 : 0;
27164
+ const t2 = RTV.tensor(result2, [...shape]);
27165
+ t2._isLogical = true;
27166
+ return t2;
27167
+ }
27168
+ const reduceDimSize = shape[dimIdx];
27169
+ const resultShape = [...shape];
27170
+ resultShape[dimIdx] = 1;
27171
+ const totalElems = resultShape.reduce((a, b) => a * b, 1);
27172
+ const result = new FloatXArray(totalElems);
27173
+ const outSubs = new Array(shape.length).fill(0);
27174
+ for (let i = 0; i < totalElems; i++) {
27175
+ let val = mode === "all";
27176
+ for (let k = 0; k < reduceDimSize; k++) {
27177
+ const srcSubs = [...outSubs];
27178
+ srcSubs[dimIdx] = k;
27179
+ const srcIdx = sub2ind(shape, srcSubs);
27180
+ const isNonZero = v.data[srcIdx] !== 0 || v.imag !== void 0 && v.imag[srcIdx] !== 0;
27181
+ if (mode === "any" && isNonZero) {
27182
+ val = true;
27183
+ break;
27184
+ }
27185
+ if (mode === "all" && !isNonZero) {
27186
+ val = false;
27187
+ break;
27188
+ }
27189
+ }
27190
+ result[i] = val ? 1 : 0;
27191
+ nextSubscripts(outSubs, resultShape, dimIdx);
27192
+ }
27193
+ squeezeTrailing(resultShape);
27194
+ const t = RTV.tensor(result, resultShape);
27195
+ t._isLogical = true;
27196
+ return t;
27197
+ }
27212
27198
  function dimReduce(v, dim, reduceFn, initialValue, finalizeFn) {
27213
27199
  if (!isRuntimeTensor(v))
27214
27200
  throw new RuntimeError("dimReduce: argument must be a tensor");
@@ -27241,16 +27227,9 @@ function dimReduce(v, dim, reduceFn, initialValue, finalizeFn) {
27241
27227
  result[i] = finalizeFn ? finalizeFn(acc, reduceDimSize) : acc;
27242
27228
  if (resultImag)
27243
27229
  resultImag[i] = finalizeFn ? finalizeFn(accIm, reduceDimSize) : accIm;
27244
- for (let d = 0; d < outSubs.length; d++) {
27245
- if (d === dimIdx) continue;
27246
- outSubs[d]++;
27247
- if (outSubs[d] < resultShape[d]) break;
27248
- outSubs[d] = 0;
27249
- }
27250
- }
27251
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1) {
27252
- resultShape.pop();
27230
+ nextSubscripts(outSubs, resultShape, dimIdx);
27253
27231
  }
27232
+ squeezeTrailing(resultShape);
27254
27233
  const imOut = resultImag && resultImag.some((x) => x !== 0) ? resultImag : void 0;
27255
27234
  return RTV.tensor(result, resultShape, imOut);
27256
27235
  }
@@ -27294,15 +27273,9 @@ function complexProd(v, dim) {
27294
27273
  }
27295
27274
  resultRe[i] = accRe;
27296
27275
  resultIm[i] = accIm;
27297
- for (let d = 0; d < outSubs.length; d++) {
27298
- if (d === dimIdx) continue;
27299
- outSubs[d]++;
27300
- if (outSubs[d] < resultShape[d]) break;
27301
- outSubs[d] = 0;
27302
- }
27276
+ nextSubscripts(outSubs, resultShape, dimIdx);
27303
27277
  }
27304
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1)
27305
- resultShape.pop();
27278
+ squeezeTrailing(resultShape);
27306
27279
  const imOut = resultIm.some((x) => x !== 0) ? resultIm : void 0;
27307
27280
  return RTV.tensor(resultRe, resultShape, imOut);
27308
27281
  }
@@ -27366,92 +27339,6 @@ function preserveTypeCheck(argTypes, nargout) {
27366
27339
  if (nargout === 2) return { outputTypes: [outType, outType] };
27367
27340
  return null;
27368
27341
  }
27369
- function anyAlongDim(v, dim) {
27370
- const shape = v.shape;
27371
- const dimIdx = dim - 1;
27372
- if (dimIdx >= shape.length) {
27373
- const result2 = new FloatXArray(v.data.length);
27374
- for (let i = 0; i < v.data.length; i++)
27375
- result2[i] = v.data[i] !== 0 || v.imag && v.imag[i] !== 0 ? 1 : 0;
27376
- const t2 = RTV.tensor(result2, [...shape]);
27377
- t2._isLogical = true;
27378
- return t2;
27379
- }
27380
- const reduceDimSize = shape[dimIdx];
27381
- const resultShape = [...shape];
27382
- resultShape[dimIdx] = 1;
27383
- const totalElems = resultShape.reduce((a, b) => a * b, 1);
27384
- const result = new FloatXArray(totalElems);
27385
- const outSubs = new Array(shape.length).fill(0);
27386
- for (let i = 0; i < totalElems; i++) {
27387
- let found = false;
27388
- for (let k = 0; k < reduceDimSize; k++) {
27389
- const srcSubs = [...outSubs];
27390
- srcSubs[dimIdx] = k;
27391
- const srcIdx = sub2ind(shape, srcSubs);
27392
- if (v.data[srcIdx] !== 0 || v.imag && v.imag[srcIdx] !== 0) {
27393
- found = true;
27394
- break;
27395
- }
27396
- }
27397
- result[i] = found ? 1 : 0;
27398
- for (let d = 0; d < outSubs.length; d++) {
27399
- if (d === dimIdx) continue;
27400
- outSubs[d]++;
27401
- if (outSubs[d] < resultShape[d]) break;
27402
- outSubs[d] = 0;
27403
- }
27404
- }
27405
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1) {
27406
- resultShape.pop();
27407
- }
27408
- const t = RTV.tensor(result, resultShape);
27409
- t._isLogical = true;
27410
- return t;
27411
- }
27412
- function allAlongDim(v, dim) {
27413
- const shape = v.shape;
27414
- const dimIdx = dim - 1;
27415
- if (dimIdx >= shape.length) {
27416
- const result2 = new FloatXArray(v.data.length);
27417
- for (let i = 0; i < v.data.length; i++)
27418
- result2[i] = v.data[i] !== 0 || v.imag && v.imag[i] !== 0 ? 1 : 0;
27419
- const t2 = RTV.tensor(result2, [...shape]);
27420
- t2._isLogical = true;
27421
- return t2;
27422
- }
27423
- const reduceDimSize = shape[dimIdx];
27424
- const resultShape = [...shape];
27425
- resultShape[dimIdx] = 1;
27426
- const totalElems = resultShape.reduce((a, b) => a * b, 1);
27427
- const result = new FloatXArray(totalElems);
27428
- const outSubs = new Array(shape.length).fill(0);
27429
- for (let i = 0; i < totalElems; i++) {
27430
- let allNonZero = true;
27431
- for (let k = 0; k < reduceDimSize; k++) {
27432
- const srcSubs = [...outSubs];
27433
- srcSubs[dimIdx] = k;
27434
- const srcIdx = sub2ind(shape, srcSubs);
27435
- if (v.data[srcIdx] === 0 && (!v.imag || v.imag[srcIdx] === 0)) {
27436
- allNonZero = false;
27437
- break;
27438
- }
27439
- }
27440
- result[i] = allNonZero ? 1 : 0;
27441
- for (let d = 0; d < outSubs.length; d++) {
27442
- if (d === dimIdx) continue;
27443
- outSubs[d]++;
27444
- if (outSubs[d] < resultShape[d]) break;
27445
- outSubs[d] = 0;
27446
- }
27447
- }
27448
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1) {
27449
- resultShape.pop();
27450
- }
27451
- const t = RTV.tensor(result, resultShape);
27452
- t._isLogical = true;
27453
- return t;
27454
- }
27455
27342
  function registerReductionFunctions() {
27456
27343
  const defaultDimOrScalar = (v, reduceFn, initial, finalizeFn) => {
27457
27344
  const shape = v.shape;
@@ -27516,15 +27403,9 @@ function registerReductionFunctions() {
27516
27403
  slice[k] = v.data[sub2ind(shape, srcSubs)];
27517
27404
  }
27518
27405
  result[i] = sliceFn(slice);
27519
- for (let d = 0; d < outSubs.length; d++) {
27520
- if (d === dimIdx) continue;
27521
- outSubs[d]++;
27522
- if (outSubs[d] < resultShape[d]) break;
27523
- outSubs[d] = 0;
27524
- }
27406
+ nextSubscripts(outSubs, resultShape, dimIdx);
27525
27407
  }
27526
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1)
27527
- resultShape.pop();
27408
+ squeezeTrailing(resultShape);
27528
27409
  return RTV.tensor(result, resultShape);
27529
27410
  };
27530
27411
  const makeSliceReduction = (name, sliceFn) => ({
@@ -27788,16 +27669,9 @@ function registerReductionFunctions() {
27788
27669
  resultRe[i] = mRe;
27789
27670
  resultIm[i] = mIm;
27790
27671
  if (indices2) indices2[i] = mIdx + 1;
27791
- for (let d = 0; d < outSubsC.length; d++) {
27792
- if (d === dimIdx) continue;
27793
- outSubsC[d]++;
27794
- if (outSubsC[d] < resultShape[d]) break;
27795
- outSubsC[d] = 0;
27796
- }
27797
- }
27798
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1) {
27799
- resultShape.pop();
27672
+ nextSubscripts(outSubsC, resultShape, dimIdx);
27800
27673
  }
27674
+ squeezeTrailing(resultShape);
27801
27675
  const hasImag = resultIm.some((x) => x !== 0);
27802
27676
  const outTensorC = RTV.tensor(
27803
27677
  resultRe,
@@ -27829,16 +27703,9 @@ function registerReductionFunctions() {
27829
27703
  if (!foundNonNaN) m = NaN;
27830
27704
  result[i] = m;
27831
27705
  if (indices) indices[i] = mIdx + 1;
27832
- for (let d = 0; d < outSubs.length; d++) {
27833
- if (d === dimIdx) continue;
27834
- outSubs[d]++;
27835
- if (outSubs[d] < resultShape[d]) break;
27836
- outSubs[d] = 0;
27837
- }
27838
- }
27839
- while (resultShape.length > 2 && resultShape[resultShape.length - 1] === 1) {
27840
- resultShape.pop();
27706
+ nextSubscripts(outSubs, resultShape, dimIdx);
27841
27707
  }
27708
+ squeezeTrailing(resultShape);
27842
27709
  const outTensor3 = RTV.tensor(result, resultShape);
27843
27710
  if (v._isLogical) outTensor3._isLogical = true;
27844
27711
  if (nargout > 1) return [outTensor3, RTV.tensor(indices, resultShape)];
@@ -27914,168 +27781,82 @@ function registerReductionFunctions() {
27914
27781
  apply: stdVarApply("var", (v) => v)
27915
27782
  }
27916
27783
  ]);
27917
- register("any", [
27918
- {
27919
- check: (argTypes, nargout) => {
27920
- if (nargout !== 1) return null;
27921
- if (argTypes.length === 1) {
27784
+ const makeAnyAll = (name, mode) => {
27785
+ const anyAllCheck = (argTypes, nargout) => {
27786
+ if (nargout !== 1) return null;
27787
+ if (argTypes.length === 1) {
27788
+ return { outputTypes: [{ kind: "Boolean" }] };
27789
+ }
27790
+ if (argTypes.length === 2) {
27791
+ const arg2 = argTypes[1];
27792
+ if (arg2.kind === "Char" || arg2.kind === "String") {
27922
27793
  return { outputTypes: [{ kind: "Boolean" }] };
27923
27794
  }
27924
- if (argTypes.length === 2) {
27925
- const arg2 = argTypes[1];
27926
- if (arg2.kind === "Char" || arg2.kind === "String") {
27927
- return { outputTypes: [{ kind: "Boolean" }] };
27928
- }
27929
- return {
27930
- outputTypes: [
27931
- { kind: "Tensor", ndim: 2, shape: "unknown" }
27932
- ]
27933
- };
27934
- }
27935
- return null;
27936
- },
27937
- apply: (args) => {
27938
- if (args.length < 1)
27939
- throw new RuntimeError("any requires at least 1 argument");
27940
- const v = args[0];
27941
- if (args.length === 1) {
27942
- if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
27943
- if (isRuntimeLogical(v)) return RTV.logical(v);
27944
- if (isRuntimeComplexNumber(v))
27945
- return RTV.logical(v.re !== 0 || v.im !== 0);
27946
- if (isRuntimeTensor(v)) {
27947
- if (v.data.length === 0) return RTV.logical(false);
27948
- const shape = v.shape;
27949
- if (shape[0] === 1) {
27950
- for (let i = 0; i < v.data.length; i++) {
27951
- if (v.data[i] !== 0) return RTV.logical(true);
27952
- if (v.imag && v.imag[i] !== 0) return RTV.logical(true);
27953
- }
27954
- return RTV.logical(false);
27955
- }
27956
- return anyAlongDim(v, 1);
27957
- }
27958
- throw new RuntimeError("any: argument must be numeric or logical");
27959
- }
27960
- const arg2 = args[1];
27961
- if ((isRuntimeString(arg2) || isRuntimeChar(arg2)) && rstr(arg2).toLowerCase() === "all") {
27962
- if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
27963
- if (isRuntimeLogical(v)) return RTV.logical(v);
27964
- if (isRuntimeComplexNumber(v))
27965
- return RTV.logical(v.re !== 0 || v.im !== 0);
27966
- if (isRuntimeTensor(v)) {
27967
- for (let i = 0; i < v.data.length; i++) {
27968
- if (v.data[i] !== 0) return RTV.logical(true);
27969
- if (v.imag && v.imag[i] !== 0) return RTV.logical(true);
27970
- }
27971
- return RTV.logical(false);
27972
- }
27973
- throw new RuntimeError("any: argument must be numeric or logical");
27974
- }
27975
- if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
27976
- if (isRuntimeLogical(v)) return RTV.logical(v);
27977
- if (isRuntimeComplexNumber(v))
27978
- return RTV.logical(v.re !== 0 || v.im !== 0);
27979
- if (isRuntimeTensor(v)) {
27980
- if (isRuntimeNumber(arg2)) {
27981
- return anyAlongDim(v, Math.round(arg2));
27982
- }
27983
- if (isRuntimeTensor(arg2)) {
27984
- const dims = Array.from(arg2.data).map((d) => Math.round(d));
27985
- let result = v;
27986
- for (const dim of dims) {
27987
- if (isRuntimeTensor(result)) {
27988
- result = anyAlongDim(result, dim);
27989
- }
27990
- }
27991
- return result;
27992
- }
27993
- }
27994
- throw new RuntimeError("any: invalid arguments");
27795
+ return {
27796
+ outputTypes: [{ kind: "Tensor" }]
27797
+ };
27995
27798
  }
27996
- }
27997
- ]);
27998
- register("all", [
27999
- {
28000
- check: (argTypes, nargout) => {
28001
- if (nargout !== 1) return null;
28002
- if (argTypes.length === 1) {
28003
- return { outputTypes: [{ kind: "Boolean" }] };
28004
- }
28005
- if (argTypes.length === 2) {
28006
- const arg2 = argTypes[1];
28007
- if (arg2.kind === "Char" || arg2.kind === "String") {
28008
- return { outputTypes: [{ kind: "Boolean" }] };
28009
- }
28010
- return {
28011
- outputTypes: [
28012
- { kind: "Tensor", ndim: 2, shape: "unknown" }
28013
- ]
28014
- };
28015
- }
28016
- return null;
28017
- },
27799
+ return null;
27800
+ };
27801
+ const scalarLogical = (v) => {
27802
+ if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
27803
+ if (isRuntimeLogical(v)) return RTV.logical(v);
27804
+ if (isRuntimeComplexNumber(v))
27805
+ return RTV.logical(v.re !== 0 || v.im !== 0);
27806
+ return null;
27807
+ };
27808
+ return {
27809
+ check: anyAllCheck,
28018
27810
  apply: (args) => {
28019
27811
  if (args.length < 1)
28020
- throw new RuntimeError("all requires at least 1 argument");
27812
+ throw new RuntimeError(`${name} requires at least 1 argument`);
28021
27813
  const v = args[0];
28022
27814
  if (args.length === 1) {
28023
- if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
28024
- if (isRuntimeLogical(v)) return RTV.logical(v);
28025
- if (isRuntimeComplexNumber(v))
28026
- return RTV.logical(v.re !== 0 || v.im !== 0);
27815
+ const scalar2 = scalarLogical(v);
27816
+ if (scalar2 !== null) return scalar2;
28027
27817
  if (isRuntimeTensor(v)) {
28028
- if (v.data.length === 0) return RTV.logical(true);
28029
- const shape = v.shape;
28030
- if (shape[0] === 1) {
28031
- for (let i = 0; i < v.data.length; i++) {
28032
- if (v.data[i] === 0 && (!v.imag || v.imag[i] === 0))
28033
- return RTV.logical(false);
28034
- }
28035
- return RTV.logical(v.data.length > 0);
28036
- }
28037
- return allAlongDim(v, 1);
27818
+ if (v.data.length === 0) return RTV.logical(mode === "all");
27819
+ if (v.shape[0] === 1)
27820
+ return RTV.logical(scanLogical(v.data, v.imag, mode));
27821
+ return logicalAlongDim(v, 1, mode);
28038
27822
  }
28039
- throw new RuntimeError("all: argument must be numeric or logical");
27823
+ throw new RuntimeError(
27824
+ `${name}: argument must be numeric or logical`
27825
+ );
28040
27826
  }
28041
27827
  const arg2 = args[1];
28042
27828
  if ((isRuntimeString(arg2) || isRuntimeChar(arg2)) && rstr(arg2).toLowerCase() === "all") {
28043
- if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
28044
- if (isRuntimeLogical(v)) return RTV.logical(v);
28045
- if (isRuntimeComplexNumber(v))
28046
- return RTV.logical(v.re !== 0 || v.im !== 0);
28047
- if (isRuntimeTensor(v)) {
28048
- for (let i = 0; i < v.data.length; i++) {
28049
- if (v.data[i] === 0 && (!v.imag || v.imag[i] === 0))
28050
- return RTV.logical(false);
28051
- }
28052
- return RTV.logical(v.data.length > 0);
28053
- }
28054
- throw new RuntimeError("all: argument must be numeric or logical");
27829
+ const scalar2 = scalarLogical(v);
27830
+ if (scalar2 !== null) return scalar2;
27831
+ if (isRuntimeTensor(v))
27832
+ return RTV.logical(scanLogical(v.data, v.imag, mode));
27833
+ throw new RuntimeError(
27834
+ `${name}: argument must be numeric or logical`
27835
+ );
28055
27836
  }
28056
- if (isRuntimeNumber(v)) return RTV.logical(v !== 0);
28057
- if (isRuntimeLogical(v)) return RTV.logical(v);
28058
- if (isRuntimeComplexNumber(v))
28059
- return RTV.logical(v.re !== 0 || v.im !== 0);
27837
+ const scalar = scalarLogical(v);
27838
+ if (scalar !== null) return scalar;
28060
27839
  if (isRuntimeTensor(v)) {
28061
27840
  if (isRuntimeNumber(arg2)) {
28062
- return allAlongDim(v, Math.round(arg2));
27841
+ return logicalAlongDim(v, Math.round(arg2), mode);
28063
27842
  }
28064
27843
  if (isRuntimeTensor(arg2)) {
28065
27844
  const dims = Array.from(arg2.data).map((d) => Math.round(d));
28066
27845
  let result = v;
28067
27846
  for (const dim of dims) {
28068
27847
  if (isRuntimeTensor(result)) {
28069
- result = allAlongDim(result, dim);
27848
+ result = logicalAlongDim(result, dim, mode);
28070
27849
  }
28071
27850
  }
28072
27851
  return result;
28073
27852
  }
28074
27853
  }
28075
- throw new RuntimeError("all: invalid arguments");
27854
+ throw new RuntimeError(`${name}: invalid arguments`);
28076
27855
  }
28077
- }
28078
- ]);
27856
+ };
27857
+ };
27858
+ register("any", [makeAnyAll("any", "any")]);
27859
+ register("all", [makeAnyAll("all", "all")]);
28079
27860
  register(
28080
27861
  "xor",
28081
27862
  builtinSingle(
@@ -28326,11 +28107,7 @@ function registerReductionFunctions() {
28326
28107
  resultIm[fiberFlatIdx[r]] = im[fiberFlatIdx[order[r]]];
28327
28108
  if (resultIdx) resultIdx[fiberFlatIdx[r]] = order[r] + 1;
28328
28109
  }
28329
- for (let d = 0; d < fiberSubs.length; d++) {
28330
- fiberSubs[d]++;
28331
- if (fiberSubs[d] < fiberShape[d]) break;
28332
- fiberSubs[d] = 0;
28333
- }
28110
+ nextSubscripts(fiberSubs, fiberShape);
28334
28111
  }
28335
28112
  }
28336
28113
  const imOut = resultIm && resultIm.some((x) => x !== 0) ? resultIm : void 0;
@@ -28709,11 +28486,7 @@ function registerReductionFunctions() {
28709
28486
  if (resultImag) resultImag[idx] = accIm;
28710
28487
  }
28711
28488
  }
28712
- for (let d = 0; d < fiberSubs.length; d++) {
28713
- fiberSubs[d]++;
28714
- if (fiberSubs[d] < fiberShape[d]) break;
28715
- fiberSubs[d] = 0;
28716
- }
28489
+ nextSubscripts(fiberSubs, fiberShape);
28717
28490
  }
28718
28491
  }
28719
28492
  const imOut = resultImag && resultImag.some((x) => x !== 0) ? resultImag : void 0;
@@ -30676,15 +30449,12 @@ function registerDot() {
30676
30449
  function qrLapack(data, m, n, econ, wantQ) {
30677
30450
  const bridge = getEffectiveBridge("qr", "qr");
30678
30451
  if (!bridge?.qr) return null;
30679
- const f64 = data instanceof Float64Array ? data : new Float64Array(data);
30680
- return bridge.qr(f64, m, n, econ, wantQ);
30452
+ return bridge.qr(toF64(data), m, n, econ, wantQ);
30681
30453
  }
30682
30454
  function qrLapackComplex(dataRe, dataIm, m, n, econ, wantQ) {
30683
30455
  const bridge = getEffectiveBridge("qr", "qrComplex");
30684
30456
  if (!bridge?.qrComplex) return null;
30685
- const re = dataRe instanceof Float64Array ? dataRe : new Float64Array(dataRe);
30686
- const im = dataIm instanceof Float64Array ? dataIm : new Float64Array(dataIm);
30687
- return bridge.qrComplex(re, im, m, n, econ, wantQ);
30457
+ return bridge.qrComplex(toF64(dataRe), toF64(dataIm), m, n, econ, wantQ);
30688
30458
  }
30689
30459
  function registerQr() {
30690
30460
  register("qr", [
@@ -30902,15 +30672,12 @@ function registerQr() {
30902
30672
  // src/numbl-core/builtins/linear-algebra/inv.ts
30903
30673
  function invLapack(data, n) {
30904
30674
  const bridge = getEffectiveBridge("inv");
30905
- const f64 = data instanceof Float64Array ? data : new Float64Array(data);
30906
- return bridge.inv(f64, n);
30675
+ return bridge.inv(toF64(data), n);
30907
30676
  }
30908
30677
  function invLapackComplex(dataRe, dataIm, n) {
30909
30678
  const bridge = getLapackBridge();
30910
30679
  if (!bridge || !bridge.invComplex) return null;
30911
- const f64Re = dataRe instanceof Float64Array ? dataRe : new Float64Array(dataRe);
30912
- const f64Im = dataIm instanceof Float64Array ? dataIm : new Float64Array(dataIm);
30913
- return bridge.invComplex(f64Re, f64Im, n);
30680
+ return bridge.invComplex(toF64(dataRe), toF64(dataIm), n);
30914
30681
  }
30915
30682
  function invComplexJS(dataRe, dataIm, n) {
30916
30683
  const augRe = new Float64Array(n * 2 * n);
@@ -31140,14 +30907,11 @@ function registerDet() {
31140
30907
  const [m, n] = tensorSize2D(A);
31141
30908
  if (m !== n) throw new RuntimeError("det: matrix must be square");
31142
30909
  if (A.imag) {
31143
- const dataRe = A.data instanceof Float64Array ? A.data : new Float64Array(A.data);
31144
- const dataIm = A.imag instanceof Float64Array ? A.imag : new Float64Array(A.imag);
31145
- const [detRe, detIm] = detComplexJS(dataRe, dataIm, n);
30910
+ const [detRe, detIm] = detComplexJS(toF64(A.data), toF64(A.imag), n);
31146
30911
  if (Math.abs(detIm) < 1e-15) return RTV.num(detRe);
31147
30912
  return RTV.complex(detRe, detIm);
31148
30913
  }
31149
- const data = A.data instanceof Float64Array ? A.data : new Float64Array(A.data);
31150
- return RTV.num(detJS(data, n));
30914
+ return RTV.num(detJS(toF64(A.data), n));
31151
30915
  }
31152
30916
  }
31153
30917
  ]);
@@ -31235,15 +30999,12 @@ function registerDet() {
31235
30999
  function svdLapack(data, m, n, econ, computeUV) {
31236
31000
  const bridge = getEffectiveBridge("svd", "svd");
31237
31001
  if (!bridge || !bridge.svd) return null;
31238
- const f64 = data instanceof Float64Array ? data : new Float64Array(data);
31239
- return bridge.svd(f64, m, n, econ, computeUV);
31002
+ return bridge.svd(toF64(data), m, n, econ, computeUV);
31240
31003
  }
31241
31004
  function svdLapackComplex(dataRe, dataIm, m, n, econ, computeUV) {
31242
31005
  const bridge = getLapackBridge();
31243
31006
  if (!bridge || !bridge.svdComplex) return null;
31244
- const f64Re = dataRe instanceof Float64Array ? dataRe : new Float64Array(dataRe);
31245
- const f64Im = dataIm instanceof Float64Array ? dataIm : new Float64Array(dataIm);
31246
- return bridge.svdComplex(f64Re, f64Im, m, n, econ, computeUV);
31007
+ return bridge.svdComplex(toF64(dataRe), toF64(dataIm), m, n, econ, computeUV);
31247
31008
  }
31248
31009
  function registerSvd() {
31249
31010
  register("svd", [
@@ -31858,14 +31619,8 @@ function parseEigOptionsRuntime(args) {
31858
31619
  let outputForm = "matrix";
31859
31620
  for (let i = 1; i < args.length; i++) {
31860
31621
  const arg = args[i];
31861
- if (isRuntimeString(arg)) {
31862
- const val = arg.replace(/^['"]|['"]$/g, "").toLowerCase();
31863
- if (val === "nobalance") balance = false;
31864
- else if (val === "balance") balance = true;
31865
- else if (val === "vector") outputForm = "vector";
31866
- else if (val === "matrix") outputForm = "matrix";
31867
- } else if (isRuntimeChar(arg)) {
31868
- const val = arg.value.replace(/^['"]|['"]$/g, "").toLowerCase();
31622
+ if (isRuntimeString(arg) || isRuntimeChar(arg)) {
31623
+ const val = parseStringArgLower(arg);
31869
31624
  if (val === "nobalance") balance = false;
31870
31625
  else if (val === "balance") balance = true;
31871
31626
  else if (val === "vector") outputForm = "vector";
@@ -31965,11 +31720,9 @@ function registerEig() {
31965
31720
  const computeVL = nargout >= 3;
31966
31721
  const computeVR = nargout >= 2;
31967
31722
  if (A.imag) {
31968
- const f64Re = A.data instanceof Float64Array ? A.data : new Float64Array(A.data);
31969
- const f64Im = A.imag instanceof Float64Array ? A.imag : new Float64Array(A.imag);
31970
31723
  const result2 = eigLapackComplex(
31971
- f64Re,
31972
- f64Im,
31724
+ toF64(A.data),
31725
+ toF64(A.imag),
31973
31726
  n,
31974
31727
  computeVL,
31975
31728
  computeVR
@@ -32056,8 +31809,13 @@ function registerEig() {
32056
31809
  }
32057
31810
  return [Vout2, Dout2, Wout2];
32058
31811
  }
32059
- const f64 = A.data instanceof Float64Array ? A.data : new Float64Array(A.data);
32060
- const result = eigLapack(f64, n, computeVL, computeVR, balance);
31812
+ const result = eigLapack(
31813
+ toF64(A.data),
31814
+ n,
31815
+ computeVL,
31816
+ computeVR,
31817
+ balance
31818
+ );
32061
31819
  if (!result) {
32062
31820
  throw new RuntimeError("eig: LAPACK bridge not available");
32063
31821
  }
@@ -32450,15 +32208,12 @@ function registerPagetranspose() {
32450
32208
  function luLapack(data, m, n) {
32451
32209
  const bridge = getEffectiveBridge("lu", "lu");
32452
32210
  if (!bridge?.lu) return null;
32453
- const f64 = data instanceof Float64Array ? data : new Float64Array(data);
32454
- return bridge.lu(f64, m, n);
32211
+ return bridge.lu(toF64(data), m, n);
32455
32212
  }
32456
32213
  function luLapackComplex(dataRe, dataIm, m, n) {
32457
32214
  const bridge = getEffectiveBridge("lu", "luComplex");
32458
32215
  if (!bridge?.luComplex) return null;
32459
- const re = dataRe instanceof Float64Array ? dataRe : new Float64Array(dataRe);
32460
- const im = dataIm instanceof Float64Array ? dataIm : new Float64Array(dataIm);
32461
- return bridge.luComplex(re, im, m, n);
32216
+ return bridge.luComplex(toF64(dataRe), toF64(dataIm), m, n);
32462
32217
  }
32463
32218
  function ipivToPermVector(ipiv, m) {
32464
32219
  const perm = new Int32Array(m);
@@ -32475,15 +32230,9 @@ function ipivToPermVector(ipiv, m) {
32475
32230
  }
32476
32231
  function parseOutputForm(arg) {
32477
32232
  if (arg === void 0) return "matrix";
32478
- let s;
32479
- if (isRuntimeString(arg)) {
32480
- s = arg.replace(/^['"]|['"]$/g, "").toLowerCase();
32481
- } else if (typeof arg === "object" && arg !== null && arg.kind === "char") {
32482
- s = arg.value.toLowerCase();
32483
- }
32233
+ const s = parseStringArgLower(arg);
32484
32234
  if (s === "vector") return "vector";
32485
32235
  if (s === "matrix") return "matrix";
32486
- if (s !== void 0) return null;
32487
32236
  return null;
32488
32237
  }
32489
32238
  function registerLu() {
@@ -32691,24 +32440,16 @@ function registerBlkdiag() {
32691
32440
  function cholLapack(data, n, upper) {
32692
32441
  const bridge = getEffectiveBridge("chol", "chol");
32693
32442
  if (!bridge?.chol) return null;
32694
- const f64 = data instanceof Float64Array ? data : new Float64Array(data);
32695
- return bridge.chol(f64, n, upper);
32443
+ return bridge.chol(toF64(data), n, upper);
32696
32444
  }
32697
32445
  function cholLapackComplex(dataRe, dataIm, n, upper) {
32698
32446
  const bridge = getEffectiveBridge("chol", "cholComplex");
32699
32447
  if (!bridge?.cholComplex) return null;
32700
- const re = dataRe instanceof Float64Array ? dataRe : new Float64Array(dataRe);
32701
- const im = dataIm instanceof Float64Array ? dataIm : new Float64Array(dataIm);
32702
- return bridge.cholComplex(re, im, n, upper);
32448
+ return bridge.cholComplex(toF64(dataRe), toF64(dataIm), n, upper);
32703
32449
  }
32704
32450
  function parseTriangleArg(arg) {
32705
32451
  if (arg === void 0) return "upper";
32706
- let s;
32707
- if (isRuntimeString(arg)) {
32708
- s = arg.replace(/^['"]|['"]$/g, "").toLowerCase();
32709
- } else if (typeof arg === "object" && arg !== null && arg.kind === "char") {
32710
- s = arg.value.toLowerCase();
32711
- }
32452
+ const s = parseStringArgLower(arg);
32712
32453
  if (s === "upper") return "upper";
32713
32454
  if (s === "lower") return "lower";
32714
32455
  return null;
@@ -32856,8 +32597,7 @@ function registerPinv() {
32856
32597
  if (!bridge || !bridge.svd) {
32857
32598
  return pinvFallback(A.data, m, n);
32858
32599
  }
32859
- const f64 = A.data instanceof Float64Array ? A.data : new Float64Array(A.data);
32860
- const svdResult = bridge.svd(f64, m, n, true, true);
32600
+ const svdResult = bridge.svd(toF64(A.data), m, n, true, true);
32861
32601
  if (!svdResult || !svdResult.U || !svdResult.V)
32862
32602
  throw new RuntimeError("pinv: SVD computation failed");
32863
32603
  const { U, S, V } = svdResult;
@@ -33038,9 +32778,6 @@ function qzComplexLapack(dataARe, dataAIm, dataBRe, dataBIm, n, computeEigvecs)
33038
32778
  computeEigvecs
33039
32779
  );
33040
32780
  }
33041
- function toF64(data) {
33042
- return data instanceof Float64Array ? data : new Float64Array(data);
33043
- }
33044
32781
  function zeroF64(n) {
33045
32782
  return new Float64Array(n);
33046
32783
  }
@@ -33815,48 +33552,32 @@ function registerMiscFunctions() {
33815
33552
  { outputType: { kind: "Number" } }
33816
33553
  )
33817
33554
  );
33818
- register(
33819
- "true",
33820
- builtinSingle((args) => {
33821
- if (args.length === 0) return RTV.logical(true);
33822
- const shape = parseShapeArgs(args);
33823
- const rows = shape[0];
33824
- const cols = shape[1] ?? rows;
33825
- const t = RTV.tensor(new FloatXArray(rows * cols).fill(1), [rows, cols]);
33826
- t._isLogical = true;
33827
- return t;
33828
- })
33829
- );
33830
- register(
33831
- "false",
33832
- builtinSingle((args) => {
33833
- if (args.length === 0) return RTV.logical(false);
33834
- const shape = parseShapeArgs(args);
33835
- const rows = shape[0];
33836
- const cols = shape[1] ?? rows;
33837
- const t = RTV.tensor(new FloatXArray(rows * cols), [rows, cols]);
33838
- t._isLogical = true;
33839
- return t;
33840
- })
33841
- );
33842
- register(
33843
- "clear",
33844
- builtinSingle(() => {
33845
- return RTV.num(0);
33846
- })
33847
- );
33848
- register(
33849
- "clc",
33850
- builtinSingle(() => {
33851
- return RTV.num(0);
33852
- })
33853
- );
33854
- register(
33855
- "clf",
33856
- builtinSingle(() => {
33857
- return RTV.num(0);
33858
- })
33859
- );
33555
+ for (const [name, scalarVal, fillVal] of [
33556
+ ["true", true, 1],
33557
+ ["false", false, 0]
33558
+ ]) {
33559
+ register(
33560
+ name,
33561
+ builtinSingle((args) => {
33562
+ if (args.length === 0) return RTV.logical(scalarVal);
33563
+ const shape = parseShapeArgs(args);
33564
+ const rows = shape[0];
33565
+ const cols = shape[1] ?? rows;
33566
+ const t = RTV.tensor(
33567
+ fillVal ? new FloatXArray(rows * cols).fill(1) : new FloatXArray(rows * cols),
33568
+ [rows, cols]
33569
+ );
33570
+ t._isLogical = true;
33571
+ return t;
33572
+ })
33573
+ );
33574
+ }
33575
+ for (const name of ["clear", "clc", "clf"]) {
33576
+ register(
33577
+ name,
33578
+ builtinSingle(() => RTV.num(0))
33579
+ );
33580
+ }
33860
33581
  register(
33861
33582
  "exist",
33862
33583
  builtinSingle((args) => {
@@ -33906,12 +33627,14 @@ function registerMiscFunctions() {
33906
33627
  return result.returnValue;
33907
33628
  })
33908
33629
  );
33909
- register(
33910
- "feval",
33911
- builtinSingle(() => {
33912
- throw new RuntimeError("feval: should be handled by runtime");
33913
- })
33914
- );
33630
+ for (const name of ["feval", "arrayfun", "cellfun", "structfun", "bsxfun"]) {
33631
+ register(
33632
+ name,
33633
+ builtinSingle(() => {
33634
+ throw new RuntimeError(`${name}: should be handled by runtime`);
33635
+ })
33636
+ );
33637
+ }
33915
33638
  register(
33916
33639
  "deal",
33917
33640
  builtinSingle((args, nargout) => {
@@ -33940,30 +33663,6 @@ function registerMiscFunctions() {
33940
33663
  return RTV.string(v.name);
33941
33664
  })
33942
33665
  );
33943
- register(
33944
- "arrayfun",
33945
- builtinSingle(() => {
33946
- throw new RuntimeError("arrayfun: should be handled by runtime");
33947
- })
33948
- );
33949
- register(
33950
- "cellfun",
33951
- builtinSingle(() => {
33952
- throw new RuntimeError("cellfun: should be handled by runtime");
33953
- })
33954
- );
33955
- register(
33956
- "structfun",
33957
- builtinSingle(() => {
33958
- throw new RuntimeError("structfun: should be handled by runtime");
33959
- })
33960
- );
33961
- register(
33962
- "bsxfun",
33963
- builtinSingle(() => {
33964
- throw new RuntimeError("bsxfun: should be handled by runtime");
33965
- })
33966
- );
33967
33666
  const opMap = [
33968
33667
  ["plus", mAdd],
33969
33668
  ["minus", mSub],
@@ -34010,18 +33709,12 @@ function registerMiscFunctions() {
34010
33709
  return args[0];
34011
33710
  })
34012
33711
  );
34013
- register(
34014
- "narginchk",
34015
- builtinSingle(() => {
34016
- return RTV.num(0);
34017
- })
34018
- );
34019
- register(
34020
- "nargoutchk",
34021
- builtinSingle(() => {
34022
- return RTV.num(0);
34023
- })
34024
- );
33712
+ for (const name of ["narginchk", "nargoutchk"]) {
33713
+ register(
33714
+ name,
33715
+ builtinSingle(() => RTV.num(0))
33716
+ );
33717
+ }
34025
33718
  register(
34026
33719
  "__inferred_type_str",
34027
33720
  builtinSingle(
@@ -34033,335 +33726,119 @@ function registerMiscFunctions() {
34033
33726
  { outputType: { kind: "String" } }
34034
33727
  )
34035
33728
  );
34036
- register(
34037
- "cart2sph",
34038
- builtinSingle((args, nargout) => {
34039
- if (args.length !== 3)
34040
- throw new RuntimeError("cart2sph requires 3 arguments");
34041
- const x = args[0];
34042
- const y = args[1];
34043
- const z = args[2];
34044
- const xIsT = isRuntimeTensor(x);
34045
- const yIsT = isRuntimeTensor(y);
34046
- const zIsT = isRuntimeTensor(z);
34047
- if (xIsT || yIsT || zIsT) {
34048
- const xd = xIsT ? x.data : null;
34049
- const yd = yIsT ? y.data : null;
34050
- const zd = zIsT ? z.data : null;
34051
- const shape = xIsT ? x.shape : yIsT ? y.shape : z.shape;
34052
- const len = xIsT ? xd.length : yIsT ? yd.length : zd.length;
34053
- const azData = new FloatXArray(len);
34054
- const elData = new FloatXArray(len);
34055
- const rData = new FloatXArray(len);
34056
- for (let i = 0; i < len; i++) {
34057
- const xi = xd ? xd[i] : toNumber(x);
34058
- const yi = yd ? yd[i] : toNumber(y);
34059
- const zi = zd ? zd[i] : toNumber(z);
34060
- const hypotxy2 = Math.sqrt(xi * xi + yi * yi);
34061
- azData[i] = Math.atan2(yi, xi);
34062
- elData[i] = Math.atan2(zi, hypotxy2);
34063
- rData[i] = Math.sqrt(xi * xi + yi * yi + zi * zi);
34064
- }
34065
- if (nargout <= 1) return RTV.tensor(azData, shape);
34066
- return [
34067
- RTV.tensor(azData, shape),
34068
- RTV.tensor(elData, shape),
34069
- RTV.tensor(rData, shape)
34070
- ];
34071
- }
34072
- const xv = toNumber(x);
34073
- const yv = toNumber(y);
34074
- const zv = toNumber(z);
34075
- const hypotxy = Math.sqrt(xv * xv + yv * yv);
34076
- const az = Math.atan2(yv, xv);
34077
- const el = Math.atan2(zv, hypotxy);
34078
- const r = Math.sqrt(xv * xv + yv * yv + zv * zv);
34079
- if (nargout <= 1) return RTV.num(az);
34080
- return [RTV.num(az), RTV.num(el), RTV.num(r)];
34081
- }),
34082
- 3
34083
- );
34084
- register(
34085
- "sph2cart",
34086
- builtinSingle((args, nargout) => {
34087
- if (args.length !== 3)
34088
- throw new RuntimeError("sph2cart requires 3 arguments");
34089
- const az = args[0];
34090
- const el = args[1];
34091
- const r = args[2];
34092
- const azIsT = isRuntimeTensor(az);
34093
- const elIsT = isRuntimeTensor(el);
34094
- const rIsT = isRuntimeTensor(r);
34095
- if (azIsT || elIsT || rIsT) {
34096
- const azd = azIsT ? az.data : null;
34097
- const eld = elIsT ? el.data : null;
34098
- const rd = rIsT ? r.data : null;
34099
- const shape = azIsT ? az.shape : elIsT ? el.shape : r.shape;
34100
- const len = azIsT ? azd.length : elIsT ? eld.length : rd.length;
34101
- const xData = new FloatXArray(len);
34102
- const yData = new FloatXArray(len);
34103
- const zData = new FloatXArray(len);
34104
- for (let i = 0; i < len; i++) {
34105
- const a = azd ? azd[i] : toNumber(az);
34106
- const e = eld ? eld[i] : toNumber(el);
34107
- const rv2 = rd ? rd[i] : toNumber(r);
34108
- const rcosel2 = rv2 * Math.cos(e);
34109
- xData[i] = rcosel2 * Math.cos(a);
34110
- yData[i] = rcosel2 * Math.sin(a);
34111
- zData[i] = rv2 * Math.sin(e);
34112
- }
34113
- if (nargout <= 1) return RTV.tensor(xData, shape);
34114
- return [
34115
- RTV.tensor(xData, shape),
34116
- RTV.tensor(yData, shape),
34117
- RTV.tensor(zData, shape)
34118
- ];
34119
- }
34120
- const av = toNumber(az);
34121
- const ev = toNumber(el);
34122
- const rv = toNumber(r);
34123
- const rcosel = rv * Math.cos(ev);
34124
- const xv = rcosel * Math.cos(av);
34125
- const yv = rcosel * Math.sin(av);
34126
- const zv = rv * Math.sin(ev);
34127
- if (nargout <= 1) return RTV.num(xv);
34128
- return [RTV.num(xv), RTV.num(yv), RTV.num(zv)];
34129
- }),
34130
- 3
34131
- );
34132
- register(
34133
- "cart2pol",
34134
- builtinSingle((args, nargout) => {
34135
- if (args.length < 2 || args.length > 3)
34136
- throw new RuntimeError("cart2pol requires 2 or 3 arguments");
34137
- const x = args[0];
34138
- const y = args[1];
34139
- const hasZ = args.length === 3;
34140
- const z = hasZ ? args[2] : void 0;
34141
- const xIsT = isRuntimeTensor(x);
34142
- const yIsT = isRuntimeTensor(y);
34143
- const zIsT = z !== void 0 && isRuntimeTensor(z);
34144
- if (xIsT || yIsT || zIsT) {
34145
- const xd = xIsT ? x.data : null;
34146
- const yd = yIsT ? y.data : null;
34147
- const zd = zIsT ? z.data : null;
34148
- const shape = xIsT ? x.shape : yIsT ? y.shape : z.shape;
34149
- const len = xIsT ? xd.length : yIsT ? yd.length : zd.length;
34150
- const thData = new FloatXArray(len);
34151
- const rhoData = new FloatXArray(len);
34152
- for (let i = 0; i < len; i++) {
34153
- const xi = xd ? xd[i] : toNumber(x);
34154
- const yi = yd ? yd[i] : toNumber(y);
34155
- thData[i] = Math.atan2(yi, xi);
34156
- rhoData[i] = Math.sqrt(xi * xi + yi * yi);
34157
- }
34158
- if (!hasZ) {
34159
- if (nargout <= 1) return RTV.tensor(thData, shape);
34160
- return [RTV.tensor(thData, shape), RTV.tensor(rhoData, shape)];
34161
- }
34162
- const zOutData = new FloatXArray(len);
34163
- for (let i = 0; i < len; i++) {
34164
- zOutData[i] = zd ? zd[i] : toNumber(z);
34165
- }
34166
- if (nargout <= 1) return RTV.tensor(thData, shape);
34167
- if (nargout === 2)
34168
- return [RTV.tensor(thData, shape), RTV.tensor(rhoData, shape)];
34169
- return [
34170
- RTV.tensor(thData, shape),
34171
- RTV.tensor(rhoData, shape),
34172
- RTV.tensor(zOutData, shape)
34173
- ];
34174
- }
34175
- const xv = toNumber(x);
34176
- const yv = toNumber(y);
34177
- const th = Math.atan2(yv, xv);
34178
- const rho = Math.sqrt(xv * xv + yv * yv);
34179
- if (!hasZ) {
34180
- if (nargout <= 1) return RTV.num(th);
34181
- return [RTV.num(th), RTV.num(rho)];
34182
- }
34183
- const zv = toNumber(z);
34184
- if (nargout <= 1) return RTV.num(th);
34185
- if (nargout === 2) return [RTV.num(th), RTV.num(rho)];
34186
- return [RTV.num(th), RTV.num(rho), RTV.num(zv)];
34187
- })
34188
- );
34189
- register(
34190
- "pol2cart",
34191
- builtinSingle((args, nargout) => {
34192
- if (args.length < 2 || args.length > 3)
34193
- throw new RuntimeError("pol2cart requires 2 or 3 arguments");
34194
- const theta = args[0];
34195
- const rho = args[1];
34196
- const hasZ = args.length === 3;
34197
- const z = hasZ ? args[2] : void 0;
34198
- const thIsT = isRuntimeTensor(theta);
34199
- const rhoIsT = isRuntimeTensor(rho);
34200
- const zIsT = z !== void 0 && isRuntimeTensor(z);
34201
- if (thIsT || rhoIsT || zIsT) {
34202
- const thd = thIsT ? theta.data : null;
34203
- const rhod = rhoIsT ? rho.data : null;
34204
- const zd = zIsT ? z.data : null;
34205
- const shape = thIsT ? theta.shape : rhoIsT ? rho.shape : z.shape;
34206
- const len = thIsT ? thd.length : rhoIsT ? rhod.length : zd.length;
34207
- const xData = new FloatXArray(len);
34208
- const yData = new FloatXArray(len);
34209
- for (let i = 0; i < len; i++) {
34210
- const t = thd ? thd[i] : toNumber(theta);
34211
- const rv2 = rhod ? rhod[i] : toNumber(rho);
34212
- xData[i] = rv2 * Math.cos(t);
34213
- yData[i] = rv2 * Math.sin(t);
34214
- }
34215
- if (!hasZ) {
34216
- if (nargout <= 1) return RTV.tensor(xData, shape);
34217
- return [RTV.tensor(xData, shape), RTV.tensor(yData, shape)];
34218
- }
34219
- const zOutData = new FloatXArray(len);
34220
- for (let i = 0; i < len; i++) {
34221
- zOutData[i] = zd ? zd[i] : toNumber(z);
34222
- }
34223
- if (nargout <= 1) return RTV.tensor(xData, shape);
34224
- if (nargout === 2)
34225
- return [RTV.tensor(xData, shape), RTV.tensor(yData, shape)];
34226
- return [
34227
- RTV.tensor(xData, shape),
34228
- RTV.tensor(yData, shape),
34229
- RTV.tensor(zOutData, shape)
34230
- ];
34231
- }
34232
- const tv = toNumber(theta);
34233
- const rv = toNumber(rho);
34234
- const xv = rv * Math.cos(tv);
34235
- const yv = rv * Math.sin(tv);
34236
- if (!hasZ) {
34237
- if (nargout <= 1) return RTV.num(xv);
34238
- return [RTV.num(xv), RTV.num(yv)];
34239
- }
34240
- const zv = toNumber(z);
34241
- if (nargout <= 1) return RTV.num(xv);
34242
- if (nargout === 2) return [RTV.num(xv), RTV.num(yv)];
34243
- return [RTV.num(xv), RTV.num(yv), RTV.num(zv)];
34244
- })
34245
- );
33729
+ function coordTransform(name, nArgs, nOut, fn) {
33730
+ register(
33731
+ name,
33732
+ builtinSingle((args, nargout) => {
33733
+ const minArgs = nArgs === "2or3" ? 2 : nArgs;
33734
+ const maxArgs = nArgs === "2or3" ? 3 : nArgs;
33735
+ if (args.length < minArgs || args.length > maxArgs)
33736
+ throw new RuntimeError(
33737
+ `${name} requires ${nArgs === "2or3" ? "2 or 3" : nArgs} arguments`
33738
+ );
33739
+ const n = args.length;
33740
+ const tensors = args.map((a) => isRuntimeTensor(a) ? a : null);
33741
+ const anyTensor = tensors.some((t) => t !== null);
33742
+ if (anyTensor) {
33743
+ const refT = tensors.find((t) => t !== null);
33744
+ const shape = refT.shape;
33745
+ const len = refT.data.length;
33746
+ const datas = tensors.map((t) => t ? t.data : null);
33747
+ const scalars = args.map((a, i) => datas[i] ? 0 : toNumber(a));
33748
+ const outArrays = Array.from(
33749
+ { length: nOut },
33750
+ () => new FloatXArray(len)
33751
+ );
33752
+ for (let i = 0; i < len; i++) {
33753
+ const vals2 = datas.map((d, j) => d ? d[i] : scalars[j]);
33754
+ const result2 = fn(...vals2);
33755
+ for (let k = 0; k < nOut; k++) outArrays[k][i] = result2[k];
33756
+ }
33757
+ const effOut2 = nArgs === "2or3" && n === 3 ? 3 : nOut;
33758
+ const outTensors = outArrays.map((d) => RTV.tensor(d, shape));
33759
+ if (nArgs === "2or3" && n === 3 && nOut === 2) {
33760
+ const zd = datas[2];
33761
+ const zOut = new FloatXArray(len);
33762
+ for (let i = 0; i < len; i++) zOut[i] = zd ? zd[i] : scalars[2];
33763
+ outTensors.push(RTV.tensor(zOut, shape));
33764
+ }
33765
+ if (nargout <= 1) return outTensors[0];
33766
+ return outTensors.slice(0, Math.min(nargout, effOut2));
33767
+ }
33768
+ const vals = args.map((a) => toNumber(a));
33769
+ const result = fn(...vals);
33770
+ const effOut = nArgs === "2or3" && n === 3 ? 3 : nOut;
33771
+ const outVals = result.map((v) => RTV.num(v));
33772
+ if (nArgs === "2or3" && n === 3 && nOut === 2) {
33773
+ outVals.push(RTV.num(vals[2]));
33774
+ }
33775
+ if (nargout <= 1) return outVals[0];
33776
+ return outVals.slice(0, Math.min(nargout, effOut));
33777
+ }),
33778
+ nOut
33779
+ );
33780
+ }
33781
+ coordTransform("cart2sph", 3, 3, (x, y, z) => {
33782
+ const hypotxy = Math.sqrt(x * x + y * y);
33783
+ return [
33784
+ Math.atan2(y, x),
33785
+ Math.atan2(z, hypotxy),
33786
+ Math.sqrt(x * x + y * y + z * z)
33787
+ ];
33788
+ });
33789
+ coordTransform("sph2cart", 3, 3, (az, el, r) => {
33790
+ const rcosel = r * Math.cos(el);
33791
+ return [rcosel * Math.cos(az), rcosel * Math.sin(az), r * Math.sin(el)];
33792
+ });
33793
+ coordTransform("cart2pol", "2or3", 2, (x, y) => [
33794
+ Math.atan2(y, x),
33795
+ Math.sqrt(x * x + y * y)
33796
+ ]);
33797
+ coordTransform("pol2cart", "2or3", 2, (theta, rho) => [
33798
+ rho * Math.cos(theta),
33799
+ rho * Math.sin(theta)
33800
+ ]);
34246
33801
  }
34247
33802
 
34248
33803
  // src/numbl-core/builtins/graphics.ts
34249
33804
  function registerGraphicsFunctions() {
34250
- register(
33805
+ const placeholderNames = [
34251
33806
  "figure",
34252
- builtinSingle(() => RTV.num(0))
34253
- );
34254
- register(
34255
33807
  "plot",
34256
- builtinSingle(() => RTV.num(0))
34257
- );
34258
- register(
34259
33808
  "plot3",
34260
- builtinSingle(() => RTV.num(0))
34261
- );
34262
- register(
34263
33809
  "surf",
34264
- builtinSingle(() => RTV.num(0))
34265
- );
34266
- register(
34267
33810
  "hold",
34268
- builtinSingle(() => RTV.num(0))
34269
- );
34270
- register(
34271
- "ishold",
34272
- builtinSingle(() => RTV.logical(false), { outputType: IType.Logical })
34273
- );
34274
- register(
34275
33811
  "grid",
34276
- builtinSingle(() => RTV.num(0))
34277
- );
34278
- register(
34279
33812
  "clf",
34280
- builtinSingle(() => RTV.num(0))
34281
- );
34282
- register(
34283
33813
  "close",
34284
- builtinSingle(() => RTV.num(0))
34285
- );
34286
- register(
34287
33814
  "title",
34288
- builtinSingle(() => RTV.num(0))
34289
- );
34290
- register(
34291
33815
  "xlabel",
34292
- builtinSingle(() => RTV.num(0))
34293
- );
34294
- register(
34295
33816
  "ylabel",
34296
- builtinSingle(() => RTV.num(0))
34297
- );
34298
- register(
34299
33817
  "shading",
34300
- builtinSingle(() => RTV.num(0))
34301
- );
34302
- register(
34303
33818
  "subplot",
34304
- builtinSingle(() => RTV.num(0))
34305
- );
34306
- register(
34307
33819
  "legend",
34308
- builtinSingle(() => RTV.num(0))
34309
- );
34310
- register(
34311
33820
  "sgtitle",
34312
- builtinSingle(() => RTV.num(0))
34313
- );
34314
- register(
34315
33821
  "zlabel",
34316
- builtinSingle(() => RTV.num(0))
34317
- );
34318
- register(
34319
33822
  "colorbar",
34320
- builtinSingle(() => RTV.num(0))
34321
- );
34322
- register(
34323
33823
  "colormap",
34324
- builtinSingle(() => RTV.num(0))
34325
- );
34326
- register(
34327
33824
  "axis",
34328
- builtinSingle(() => RTV.num(0))
34329
- );
34330
- register(
34331
33825
  "view",
34332
- builtinSingle(() => RTV.num(0))
34333
- );
34334
- register(
34335
33826
  "imagesc",
34336
- builtinSingle(() => RTV.num(0))
34337
- );
34338
- register(
34339
33827
  "contour",
34340
- builtinSingle(() => RTV.num(0))
34341
- );
34342
- register(
34343
33828
  "contourf",
34344
- builtinSingle(() => RTV.num(0))
34345
- );
34346
- register(
34347
33829
  "mesh",
34348
- builtinSingle(() => RTV.num(0))
34349
- );
34350
- register(
34351
33830
  "waterfall",
34352
- builtinSingle(() => RTV.num(0))
34353
- );
34354
- register(
34355
33831
  "scatter",
34356
- builtinSingle(() => RTV.num(0))
34357
- );
34358
- register(
34359
33832
  "drawnow",
34360
- builtinSingle(() => RTV.num(0))
34361
- );
33833
+ "pause"
33834
+ ];
33835
+ const placeholder = builtinSingle(() => RTV.num(0));
33836
+ for (const name of placeholderNames) {
33837
+ register(name, placeholder);
33838
+ }
34362
33839
  register(
34363
- "pause",
34364
- builtinSingle(() => RTV.num(0))
33840
+ "ishold",
33841
+ builtinSingle(() => RTV.logical(false), { outputType: IType.Logical })
34365
33842
  );
34366
33843
  const colormapNames = [
34367
33844
  "parula",
@@ -34539,6 +34016,9 @@ function registerValidatorFunctions() {
34539
34016
  }
34540
34017
 
34541
34018
  // src/numbl-core/builtins/dummy.ts
34019
+ function registerDummyGroup(names, fn) {
34020
+ for (const name of names) register(name, fn);
34021
+ }
34542
34022
  var dummyHandleFunctions = [
34543
34023
  "groot",
34544
34024
  "gcf",
@@ -34550,14 +34030,6 @@ var dummyHandleFunctions = [
34550
34030
  "axis",
34551
34031
  "odeset"
34552
34032
  ];
34553
- function registerDummyHandleFunctions() {
34554
- const fn = builtinSingle(() => RTV.dummyHandle(), {
34555
- outputType: IType.DummyHandle
34556
- });
34557
- for (const name of dummyHandleFunctions) {
34558
- register(name, fn);
34559
- }
34560
- }
34561
34033
  var returnDummyStringFunctions = [
34562
34034
  "pwd",
34563
34035
  "datestr",
@@ -34565,41 +34037,9 @@ var returnDummyStringFunctions = [
34565
34037
  "lastwarn",
34566
34038
  "mfilename"
34567
34039
  ];
34568
- function registerDummyStringFunctions() {
34569
- const fn = builtinSingle(() => RTV.string(""), {
34570
- outputType: IType.String
34571
- });
34572
- for (const name of returnDummyStringFunctions) {
34573
- register(name, fn);
34574
- }
34575
- }
34576
34040
  var returnEmptyArrayFunctions = ["who", "xlim", "ylim"];
34577
- function registerDummyArrayFunctions() {
34578
- const fn = builtinSingle(() => RTV.tensor([], [0, 0]), {
34579
- outputType: IType.tensor()
34580
- });
34581
- for (const name of returnEmptyArrayFunctions) {
34582
- register(name, fn);
34583
- }
34584
- }
34585
34041
  var returnDummyBooleanFunctions = ["ispc", "ismac", "isunix"];
34586
- function registerDummyBooleanFunctions() {
34587
- const fn = builtinSingle(() => RTV.logical(false), {
34588
- outputType: IType.Logical
34589
- });
34590
- for (const name of returnDummyBooleanFunctions) {
34591
- register(name, fn);
34592
- }
34593
- }
34594
34042
  var returnDummyCellArrayFunctions = ["listfonts"];
34595
- function registerDummyCellArrayFunctions() {
34596
- const fn = builtinSingle(() => RTV.cell([], [0, 0]), {
34597
- outputType: IType.cell(IType.Unknown, "unknown")
34598
- });
34599
- for (const name of returnDummyCellArrayFunctions) {
34600
- register(name, fn);
34601
- }
34602
- }
34603
34043
  function registerPathFunctions() {
34604
34044
  const dummyStr = builtinSingle(() => RTV.string(""), {
34605
34045
  outputType: IType.String
@@ -34647,11 +34087,28 @@ function registerHandleGetSet() {
34647
34087
  );
34648
34088
  }
34649
34089
  var registerDummyFunctions = () => {
34650
- registerDummyHandleFunctions();
34651
- registerDummyStringFunctions();
34652
- registerDummyArrayFunctions();
34653
- registerDummyBooleanFunctions();
34654
- registerDummyCellArrayFunctions();
34090
+ registerDummyGroup(
34091
+ dummyHandleFunctions,
34092
+ builtinSingle(() => RTV.dummyHandle(), { outputType: IType.DummyHandle })
34093
+ );
34094
+ registerDummyGroup(
34095
+ returnDummyStringFunctions,
34096
+ builtinSingle(() => RTV.string(""), { outputType: IType.String })
34097
+ );
34098
+ registerDummyGroup(
34099
+ returnEmptyArrayFunctions,
34100
+ builtinSingle(() => RTV.tensor([], [0, 0]), { outputType: IType.tensor() })
34101
+ );
34102
+ registerDummyGroup(
34103
+ returnDummyBooleanFunctions,
34104
+ builtinSingle(() => RTV.logical(false), { outputType: IType.Logical })
34105
+ );
34106
+ registerDummyGroup(
34107
+ returnDummyCellArrayFunctions,
34108
+ builtinSingle(() => RTV.cell([], [0, 0]), {
34109
+ outputType: IType.cell(IType.Unknown, "unknown")
34110
+ })
34111
+ );
34655
34112
  registerHandleGetSet();
34656
34113
  registerPathFunctions();
34657
34114
  registerFileIOFunctions();
@@ -34789,6 +34246,11 @@ function registerNumericalFunctions() {
34789
34246
  throw new RuntimeError("polyfit: x and y must have the same length");
34790
34247
  if (n < 0) throw new RuntimeError("polyfit: degree must be non-negative");
34791
34248
  const ncols = n + 1;
34249
+ if (ncols > m) {
34250
+ console.warn(
34251
+ "Warning: Polynomial is not unique; degree >= number of data points."
34252
+ );
34253
+ }
34792
34254
  const V = new FloatXArray(m * ncols);
34793
34255
  for (let j = 0; j < ncols; j++) {
34794
34256
  const power = n - j;
@@ -34796,65 +34258,31 @@ function registerNumericalFunctions() {
34796
34258
  V[j * m + i] = Math.pow(xArr[i], power);
34797
34259
  }
34798
34260
  }
34799
- const VTV = new FloatXArray(ncols * ncols);
34261
+ const B = new FloatXArray(m);
34262
+ for (let i = 0; i < m; i++) B[i] = yArr[i];
34263
+ const X = linsolveLapack(V, m, ncols, B, 1);
34264
+ if (!X) throw new RuntimeError("polyfit: LAPACK bridge unavailable");
34265
+ let badlyConditioned = false;
34800
34266
  for (let i = 0; i < ncols; i++) {
34801
- for (let j = 0; j < ncols; j++) {
34802
- let sum = 0;
34803
- for (let k = 0; k < m; k++) {
34804
- sum += V[i * m + k] * V[j * m + k];
34805
- }
34806
- VTV[j * ncols + i] = sum;
34807
- }
34808
- }
34809
- const VTy = new FloatXArray(ncols);
34810
- for (let i = 0; i < ncols; i++) {
34811
- let sum = 0;
34812
- for (let k = 0; k < m; k++) {
34813
- sum += V[i * m + k] * yArr[k];
34267
+ if (!isFinite(X[i])) {
34268
+ badlyConditioned = true;
34269
+ break;
34814
34270
  }
34815
- VTy[i] = sum;
34816
34271
  }
34817
- const aug = new FloatXArray(ncols * (ncols + 1));
34818
- for (let i = 0; i < ncols; i++) {
34819
- for (let j = 0; j < ncols; j++) {
34820
- aug[j * ncols + i] = VTV[j * ncols + i];
34821
- }
34822
- aug[ncols * ncols + i] = VTy[i];
34272
+ if (!badlyConditioned) {
34273
+ let maxX = 0;
34274
+ for (let i = 0; i < ncols; i++) maxX = Math.max(maxX, Math.abs(X[i]));
34275
+ let maxY = 0;
34276
+ for (let i = 0; i < m; i++) maxY = Math.max(maxY, Math.abs(yArr[i]));
34277
+ if (maxY > 0 && maxX / maxY > 1e10) badlyConditioned = true;
34823
34278
  }
34824
- for (let col = 0; col < ncols; col++) {
34825
- let maxVal = Math.abs(aug[col * ncols + col]);
34826
- let maxRow = col;
34827
- for (let row = col + 1; row < ncols; row++) {
34828
- const val = Math.abs(aug[col * ncols + row]);
34829
- if (val > maxVal) {
34830
- maxVal = val;
34831
- maxRow = row;
34832
- }
34833
- }
34834
- if (maxRow !== col) {
34835
- for (let j = 0; j <= ncols; j++) {
34836
- const tmp = aug[j * ncols + col];
34837
- aug[j * ncols + col] = aug[j * ncols + maxRow];
34838
- aug[j * ncols + maxRow] = tmp;
34839
- }
34840
- }
34841
- const pivot = aug[col * ncols + col];
34842
- if (Math.abs(pivot) < 1e-14) continue;
34843
- for (let j = 0; j <= ncols; j++) {
34844
- aug[j * ncols + col] /= pivot;
34845
- }
34846
- for (let row = 0; row < ncols; row++) {
34847
- if (row === col) continue;
34848
- const factor = aug[col * ncols + row];
34849
- for (let j = 0; j <= ncols; j++) {
34850
- aug[j * ncols + row] -= factor * aug[j * ncols + col];
34851
- }
34852
- }
34279
+ if (badlyConditioned) {
34280
+ console.warn(
34281
+ "Warning: Polynomial is badly conditioned. Add points with distinct X values, reduce the degree of the polynomial, or try centering and scaling as described in HELP POLYFIT."
34282
+ );
34853
34283
  }
34854
34284
  const result = new FloatXArray(ncols);
34855
- for (let i = 0; i < ncols; i++) {
34856
- result[i] = aug[ncols * ncols + i];
34857
- }
34285
+ for (let i = 0; i < ncols; i++) result[i] = X[i];
34858
34286
  return RTV.tensor(result, [1, ncols]);
34859
34287
  })
34860
34288
  );
@@ -36328,6 +35756,65 @@ function switchMatch(control, caseVal) {
36328
35756
  }
36329
35757
 
36330
35758
  // src/numbl-core/runtime/runtimeDispatch.ts
35759
+ function dispatchPlotCall(rt, name, args) {
35760
+ switch (name) {
35761
+ case "plot":
35762
+ return rt.plot_call(args.map((a) => ensureRuntimeValue(a)));
35763
+ case "plot3":
35764
+ return rt.plot3_call(args.map((a) => ensureRuntimeValue(a)));
35765
+ case "surf":
35766
+ return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
35767
+ case "scatter":
35768
+ return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
35769
+ case "imagesc":
35770
+ return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
35771
+ case "contour":
35772
+ return rt.contour_call(
35773
+ args.map((a) => ensureRuntimeValue(a)),
35774
+ false
35775
+ );
35776
+ case "contourf":
35777
+ return rt.contour_call(
35778
+ args.map((a) => ensureRuntimeValue(a)),
35779
+ true
35780
+ );
35781
+ case "mesh":
35782
+ case "waterfall":
35783
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
35784
+ default:
35785
+ return void 0;
35786
+ }
35787
+ }
35788
+ function packResults(results, shape) {
35789
+ const allScalar = results.every(
35790
+ (r) => isRuntimeNumber(r) || isRuntimeLogical(r) || isRuntimeTensor(r) && r.data.length === 1
35791
+ );
35792
+ if (allScalar) {
35793
+ const data = new FloatXArray(results.length);
35794
+ const allLogical = results.every((r) => isRuntimeLogical(r));
35795
+ for (let i = 0; i < results.length; i++) {
35796
+ data[i] = toNumber(results[i]);
35797
+ }
35798
+ const result = RTV.tensor(data, [...shape]);
35799
+ if (allLogical) result._isLogical = true;
35800
+ return result;
35801
+ }
35802
+ return RTV.cell(results, [...shape]);
35803
+ }
35804
+ function coerceToTensor(v, fnName, which) {
35805
+ if (isRuntimeNumber(v)) {
35806
+ return RTV.tensor(new FloatXArray([v]), [1, 1]);
35807
+ }
35808
+ if (isRuntimeComplexNumber(v)) {
35809
+ return RTV.tensor(new FloatXArray([v.re]), [1, 1], new FloatXArray([v.im]));
35810
+ }
35811
+ if (isRuntimeTensor(v)) {
35812
+ return v;
35813
+ }
35814
+ throw new RuntimeError(
35815
+ `${fnName}: unsupported type for ${which} input argument: ${kstr(v)}`
35816
+ );
35817
+ }
36331
35818
  function getFuncHandle(name) {
36332
35819
  const handle = RTV.func(name, isBuiltin(name) ? "builtin" : "user");
36333
35820
  const nargin = getBuiltinNargin(name);
@@ -36426,39 +35913,8 @@ function dispatch(rt, name, nargout, args, targetClassName) {
36426
35913
  const callerLine = rt.$line;
36427
35914
  try {
36428
35915
  if (!targetClassName) {
36429
- if (name === "plot") {
36430
- return rt.plot_call(args.map((a) => ensureRuntimeValue(a)));
36431
- }
36432
- if (name === "plot3") {
36433
- return rt.plot3_call(args.map((a) => ensureRuntimeValue(a)));
36434
- }
36435
- if (name === "surf") {
36436
- return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
36437
- }
36438
- if (name === "scatter") {
36439
- return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
36440
- }
36441
- if (name === "imagesc") {
36442
- return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
36443
- }
36444
- if (name === "contour") {
36445
- return rt.contour_call(
36446
- args.map((a) => ensureRuntimeValue(a)),
36447
- false
36448
- );
36449
- }
36450
- if (name === "contourf") {
36451
- return rt.contour_call(
36452
- args.map((a) => ensureRuntimeValue(a)),
36453
- true
36454
- );
36455
- }
36456
- if (name === "mesh") {
36457
- return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36458
- }
36459
- if (name === "waterfall") {
36460
- return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36461
- }
35916
+ const plotResult = dispatchPlotCall(rt, name, args);
35917
+ if (plotResult !== void 0) return plotResult;
36462
35918
  }
36463
35919
  if (rt.compileSpecialized) {
36464
35920
  const argTypes = args.map(
@@ -36497,77 +35953,15 @@ function dispatch(rt, name, nargout, args, targetClassName) {
36497
35953
  }
36498
35954
  }
36499
35955
  function callBuiltin(rt, name, nargout, args) {
36500
- if (name === "plot") {
36501
- return rt.plot_call(args.map((a) => ensureRuntimeValue(a)));
36502
- }
36503
- if (name === "plot3") {
36504
- return rt.plot3_call(args.map((a) => ensureRuntimeValue(a)));
36505
- }
36506
- if (name === "surf") {
36507
- return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
36508
- }
36509
- if (name === "scatter") {
36510
- return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
36511
- }
36512
- if (name === "imagesc") {
36513
- return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
36514
- }
36515
- if (name === "contour") {
36516
- return rt.contour_call(
36517
- args.map((a) => ensureRuntimeValue(a)),
36518
- false
36519
- );
36520
- }
36521
- if (name === "contourf") {
36522
- return rt.contour_call(
36523
- args.map((a) => ensureRuntimeValue(a)),
36524
- true
36525
- );
36526
- }
36527
- if (name === "mesh") {
36528
- return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36529
- }
36530
- if (name === "waterfall") {
36531
- return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36532
- }
35956
+ const plotResult = dispatchPlotCall(rt, name, args);
35957
+ if (plotResult !== void 0) return plotResult;
36533
35958
  const builtin = rt.builtins[name];
36534
35959
  if (builtin) return builtin(nargout, args);
36535
35960
  throw new RuntimeError(`'${name}' is not a builtin function`);
36536
35961
  }
36537
35962
  function callBuiltinSync(rt, name, nargout, args) {
36538
- if (name === "plot") {
36539
- return rt.plot_call(args.map((a) => ensureRuntimeValue(a)));
36540
- }
36541
- if (name === "plot3") {
36542
- return rt.plot3_call(args.map((a) => ensureRuntimeValue(a)));
36543
- }
36544
- if (name === "surf") {
36545
- return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
36546
- }
36547
- if (name === "scatter") {
36548
- return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
36549
- }
36550
- if (name === "imagesc") {
36551
- return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
36552
- }
36553
- if (name === "contour") {
36554
- return rt.contour_call(
36555
- args.map((a) => ensureRuntimeValue(a)),
36556
- false
36557
- );
36558
- }
36559
- if (name === "contourf") {
36560
- return rt.contour_call(
36561
- args.map((a) => ensureRuntimeValue(a)),
36562
- true
36563
- );
36564
- }
36565
- if (name === "mesh") {
36566
- return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36567
- }
36568
- if (name === "waterfall") {
36569
- return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36570
- }
35963
+ const plotResult = dispatchPlotCall(rt, name, args);
35964
+ if (plotResult !== void 0) return plotResult;
36571
35965
  const builtin = rt.builtins[name];
36572
35966
  if (builtin) return builtin(nargout, args);
36573
35967
  throw new RuntimeError(`'${name}' is not a builtin function`);
@@ -36752,28 +36146,12 @@ function arrayfunCellfunImpl(rt, name, nargout, args) {
36752
36146
  }
36753
36147
  }
36754
36148
  if (!uniformOutput) {
36755
- const outputs2 = allResults.map(
36149
+ const outputs = allResults.map(
36756
36150
  (results2) => RTV.cell(results2, [...shape])
36757
36151
  );
36758
- return outputs2;
36152
+ return outputs;
36759
36153
  }
36760
- const outputs = allResults.map((results2) => {
36761
- const allScalar2 = results2.every(
36762
- (r2) => isRuntimeNumber(r2) || isRuntimeLogical(r2) || isRuntimeTensor(r2) && r2.data.length === 1
36763
- );
36764
- if (allScalar2) {
36765
- const data = new FloatXArray(results2.length);
36766
- const allLogical = results2.every((r2) => isRuntimeLogical(r2));
36767
- for (let j = 0; j < results2.length; j++) {
36768
- data[j] = toNumber(results2[j]);
36769
- }
36770
- const result = RTV.tensor(data, [...shape]);
36771
- if (allLogical) result._isLogical = true;
36772
- return result;
36773
- }
36774
- return RTV.cell(results2, [...shape]);
36775
- });
36776
- return outputs;
36154
+ return allResults.map((results2) => packResults(results2, shape));
36777
36155
  }
36778
36156
  const results = [];
36779
36157
  for (let i = 0; i < len; i++) {
@@ -36783,20 +36161,7 @@ function arrayfunCellfunImpl(rt, name, nargout, args) {
36783
36161
  if (!uniformOutput) {
36784
36162
  return RTV.cell(results, [...shape]);
36785
36163
  }
36786
- const allScalar = results.every(
36787
- (r2) => isRuntimeNumber(r2) || isRuntimeLogical(r2) || isRuntimeTensor(r2) && r2.data.length === 1
36788
- );
36789
- if (allScalar) {
36790
- const data = new FloatXArray(results.length);
36791
- const allLogical = results.every((r2) => isRuntimeLogical(r2));
36792
- for (let i = 0; i < results.length; i++) {
36793
- data[i] = toNumber(results[i]);
36794
- }
36795
- const result = RTV.tensor(data, [...shape]);
36796
- if (allLogical) result._isLogical = true;
36797
- return result;
36798
- }
36799
- return RTV.cell(results, [...shape]);
36164
+ return packResults(results, shape);
36800
36165
  }
36801
36166
  const r = callFn(collectArgs(0));
36802
36167
  if (typeof r === "number") return r;
@@ -36906,38 +36271,8 @@ function bsxfunImpl(rt, _nargout, args) {
36906
36271
  }
36907
36272
  const rawA = ensureRuntimeValue(args[1]);
36908
36273
  const rawB = ensureRuntimeValue(args[2]);
36909
- let a;
36910
- let b;
36911
- if (isRuntimeNumber(rawA)) {
36912
- a = RTV.tensor(new FloatXArray([rawA]), [1, 1]);
36913
- } else if (isRuntimeComplexNumber(rawA)) {
36914
- a = RTV.tensor(
36915
- new FloatXArray([rawA.re]),
36916
- [1, 1],
36917
- new FloatXArray([rawA.im])
36918
- );
36919
- } else if (isRuntimeTensor(rawA)) {
36920
- a = rawA;
36921
- } else {
36922
- throw new RuntimeError(
36923
- `bsxfun: unsupported type for first input argument: ${kstr(rawA)}`
36924
- );
36925
- }
36926
- if (isRuntimeNumber(rawB)) {
36927
- b = RTV.tensor(new FloatXArray([rawB]), [1, 1]);
36928
- } else if (isRuntimeComplexNumber(rawB)) {
36929
- b = RTV.tensor(
36930
- new FloatXArray([rawB.re]),
36931
- [1, 1],
36932
- new FloatXArray([rawB.im])
36933
- );
36934
- } else if (isRuntimeTensor(rawB)) {
36935
- b = rawB;
36936
- } else {
36937
- throw new RuntimeError(
36938
- `bsxfun: unsupported type for second input argument: ${kstr(rawB)}`
36939
- );
36940
- }
36274
+ const a = coerceToTensor(rawA, "bsxfun", "first");
36275
+ const b = coerceToTensor(rawB, "bsxfun", "second");
36941
36276
  const outShape = getBroadcastShape(a.shape, b.shape);
36942
36277
  if (!outShape)
36943
36278
  throw new RuntimeError(
@@ -37028,6 +36363,20 @@ function extractSubsIndices(subs) {
37028
36363
  }
37029
36364
  return [subs];
37030
36365
  }
36366
+ function applySubsEntry(rt, entry, target, nargout, fnName) {
36367
+ if (entry.type === ".") {
36368
+ return rt.getMember(target, extractSubsType(entry.subs));
36369
+ }
36370
+ if (entry.type === "()") {
36371
+ return rt.index(target, extractSubsIndices(entry.subs), nargout);
36372
+ }
36373
+ if (entry.type === "{}") {
36374
+ return rt.indexCell(target, extractSubsIndices(entry.subs));
36375
+ }
36376
+ throw new RuntimeError(
36377
+ `${fnName}: unsupported subscript type '${entry.type}'`
36378
+ );
36379
+ }
37031
36380
  function subsrefBuiltin(rt, nargout, args) {
37032
36381
  if (args.length !== 2)
37033
36382
  throw new RuntimeError("subsref requires exactly 2 arguments");
@@ -37055,20 +36404,7 @@ function subsrefBuiltin(rt, nargout, args) {
37055
36404
  }
37056
36405
  let result = obj;
37057
36406
  for (const entry of elements) {
37058
- if (entry.type === ".") {
37059
- const fieldName = extractSubsType(entry.subs);
37060
- result = rt.getMember(result, fieldName);
37061
- } else if (entry.type === "()") {
37062
- const indices = extractSubsIndices(entry.subs);
37063
- result = rt.index(result, indices, nargout);
37064
- } else if (entry.type === "{}") {
37065
- const indices = extractSubsIndices(entry.subs);
37066
- result = rt.indexCell(result, indices);
37067
- } else {
37068
- throw new RuntimeError(
37069
- `subsref: unsupported subscript type '${entry.type}'`
37070
- );
37071
- }
36407
+ result = applySubsEntry(rt, entry, result, nargout, "subsref");
37072
36408
  }
37073
36409
  return result;
37074
36410
  }
@@ -37103,21 +36439,7 @@ function subsasgnBuiltin(rt, _nargout, args) {
37103
36439
  const intermediates = [obj];
37104
36440
  let current = obj;
37105
36441
  for (let i = 0; i < elements.length - 1; i++) {
37106
- const entry = elements[i];
37107
- if (entry.type === ".") {
37108
- const fieldName = extractSubsType(entry.subs);
37109
- current = rt.getMember(current, fieldName);
37110
- } else if (entry.type === "()") {
37111
- const indices = extractSubsIndices(entry.subs);
37112
- current = rt.index(current, indices, 1);
37113
- } else if (entry.type === "{}") {
37114
- const indices = extractSubsIndices(entry.subs);
37115
- current = rt.indexCell(current, indices);
37116
- } else {
37117
- throw new RuntimeError(
37118
- `subsasgn: unsupported subscript type '${entry.type}'`
37119
- );
37120
- }
36442
+ current = applySubsEntry(rt, elements[i], current, 1, "subsasgn");
37121
36443
  intermediates.push(current);
37122
36444
  }
37123
36445
  const last = elements[elements.length - 1];
@@ -42418,42 +41740,37 @@ function genFuncCall(cg, kind) {
42418
41740
  }
42419
41741
  }
42420
41742
  }
42421
- if (kind.name === "figure")
42422
- return `$rt.plot_instr({type: "set_figure_handle", handle: ${args[0] ?? "1"}})`;
42423
- if (kind.name === "hold")
42424
- return `$rt.plot_instr({type: "set_hold", value: ${args[0]}})`;
42425
- if (kind.name === "ishold") return `$rt.ishold()`;
42426
- if (kind.name === "clf") return `$rt.plot_instr({type: "clf"})`;
42427
- if (kind.name === "title")
42428
- return `$rt.plot_instr({type: "set_title", text: ${args[0] ?? '""'}})`;
42429
- if (kind.name === "xlabel")
42430
- return `$rt.plot_instr({type: "set_xlabel", text: ${args[0] ?? '""'}})`;
42431
- if (kind.name === "ylabel")
42432
- return `$rt.plot_instr({type: "set_ylabel", text: ${args[0] ?? '""'}})`;
42433
- if (kind.name === "shading")
42434
- return `$rt.plot_instr({type: "set_shading", shading: ${args[0] ?? '"faceted"'}})`;
42435
- if (kind.name === "close") {
42436
- if (args.length > 0) {
42437
- return `$rt.plot_instr({type: "close_all"})`;
42438
- }
42439
- return `$rt.plot_instr({type: "close"})`;
42440
- }
42441
- if (kind.name === "subplot")
42442
- return `$rt.plot_instr({type: "set_subplot", rows: ${args[0] ?? "1"}, cols: ${args[1] ?? "1"}, index: ${args[2] ?? "1"}})`;
42443
- if (kind.name === "legend") return `$rt.legend_call([${args.join(", ")}])`;
42444
- if (kind.name === "sgtitle")
42445
- return `$rt.plot_instr({type: "set_sgtitle", text: ${args[0] ?? '""'}})`;
42446
- if (kind.name === "grid")
42447
- return `$rt.plot_instr({type: "set_grid", value: ${args[0] ?? "true"}})`;
42448
- if (kind.name === "zlabel")
42449
- return `$rt.plot_instr({type: "set_zlabel", text: ${args[0] ?? '""'}})`;
42450
- if (kind.name === "colorbar")
42451
- return `$rt.plot_instr({type: "set_colorbar", value: ${args[0] ?? '"on"'}})`;
42452
- if (kind.name === "colormap")
42453
- return `$rt.plot_instr({type: "set_colormap", name: ${args[0] ?? '"parula"'}})`;
42454
- if (kind.name === "axis")
42455
- return `$rt.plot_instr({type: "set_axis", value: ${args[0] ?? '"auto"'}})`;
42456
- if (kind.name === "view") return `$rt.view_call([${args.join(", ")}])`;
41743
+ {
41744
+ const plotInstrTable = {
41745
+ figure: ["set_figure_handle", "handle", "1"],
41746
+ hold: ["set_hold", "value", "true"],
41747
+ clf: ["clf", "", ""],
41748
+ title: ["set_title", "text", '""'],
41749
+ xlabel: ["set_xlabel", "text", '""'],
41750
+ ylabel: ["set_ylabel", "text", '""'],
41751
+ zlabel: ["set_zlabel", "text", '""'],
41752
+ shading: ["set_shading", "shading", '"faceted"'],
41753
+ sgtitle: ["set_sgtitle", "text", '""'],
41754
+ grid: ["set_grid", "value", "true"],
41755
+ colorbar: ["set_colorbar", "value", '"on"'],
41756
+ colormap: ["set_colormap", "name", '"parula"'],
41757
+ axis: ["set_axis", "value", '"auto"']
41758
+ };
41759
+ const entry = Object.hasOwn(plotInstrTable, kind.name) ? plotInstrTable[kind.name] : void 0;
41760
+ if (entry) {
41761
+ const [instrType, paramName, defaultVal] = entry;
41762
+ if (!paramName) return `$rt.plot_instr({type: "${instrType}"})`;
41763
+ return `$rt.plot_instr({type: "${instrType}", ${paramName}: ${args[0] ?? defaultVal}})`;
41764
+ }
41765
+ if (kind.name === "ishold") return `$rt.ishold()`;
41766
+ if (kind.name === "close") {
41767
+ return args.length > 0 ? `$rt.plot_instr({type: "close_all"})` : `$rt.plot_instr({type: "close"})`;
41768
+ }
41769
+ if (kind.name === "subplot")
41770
+ return `$rt.plot_instr({type: "set_subplot", rows: ${args[0] ?? "1"}, cols: ${args[1] ?? "1"}, index: ${args[2] ?? "1"}})`;
41771
+ if (kind.name === "legend") return `$rt.legend_call([${args.join(", ")}])`;
41772
+ if (kind.name === "view") return `$rt.view_call([${args.join(", ")}])`;
41773
+ }
42457
41774
  if (cg.nestedFunctionNames.has(kind.name)) {
42458
41775
  return buildSpecializedCall(
42459
41776
  cg,