numbl 0.1.2 → 0.1.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-lib/lib.js CHANGED
@@ -18259,6 +18259,28 @@ function binaryNumberOnly(argTypes) {
18259
18259
  return null;
18260
18260
  return [{ kind: "number" }];
18261
18261
  }
18262
+ var nativeUnaryOpCode = /* @__PURE__ */ new Map([
18263
+ [Math.exp, 0],
18264
+ [Math.log, 1],
18265
+ [Math.log2, 2],
18266
+ [Math.log10, 3],
18267
+ [Math.sqrt, 4],
18268
+ [Math.abs, 5],
18269
+ [Math.floor, 6],
18270
+ [Math.ceil, 7],
18271
+ [Math.round, 8],
18272
+ [Math.trunc, 9],
18273
+ [Math.sin, 10],
18274
+ [Math.cos, 11],
18275
+ [Math.tan, 12],
18276
+ [Math.asin, 13],
18277
+ [Math.acos, 14],
18278
+ [Math.atan, 15],
18279
+ [Math.sinh, 16],
18280
+ [Math.cosh, 17],
18281
+ [Math.tanh, 18],
18282
+ [Math.sign, 19]
18283
+ ]);
18262
18284
  function applyUnaryElemwise(v, realFn, complexFn, name) {
18263
18285
  if (isRuntimeSparseMatrix(v))
18264
18286
  return applyUnaryElemwise(sparseToDense(v), realFn, complexFn, name);
@@ -18271,6 +18293,14 @@ function applyUnaryElemwise(v, realFn, complexFn, name) {
18271
18293
  if (isRuntimeTensor(v)) {
18272
18294
  const n = v.data.length;
18273
18295
  if (!v.imag) {
18296
+ const opCode = nativeUnaryOpCode.get(realFn);
18297
+ if (opCode !== void 0) {
18298
+ const bridge = getLapackBridge();
18299
+ if (bridge?.unaryElemwise && v.data instanceof Float64Array) {
18300
+ const result = bridge.unaryElemwise(v.data, opCode);
18301
+ return RTV.tensorRaw(result, v.shape.slice());
18302
+ }
18303
+ }
18274
18304
  const out = new FloatXArray(n);
18275
18305
  for (let i = 0; i < n; i++) out[i] = realFn(v.data[i]);
18276
18306
  return makeTensor(out, void 0, v.shape.slice());
@@ -18934,6 +18964,18 @@ function tryNativeElemwiseReal(at, bt, opCode) {
18934
18964
  );
18935
18965
  return RTV.tensorRaw(result, at.shape);
18936
18966
  }
18967
+ function tryNativeElemwiseScalar(scalar, tensor, opCode, scalarOnLeft) {
18968
+ if (tensor.imag) return null;
18969
+ const bridge = getLapackBridge();
18970
+ if (!bridge?.elemwiseScalar) return null;
18971
+ const result = bridge.elemwiseScalar(
18972
+ scalar,
18973
+ tensor.data,
18974
+ opCode,
18975
+ scalarOnLeft
18976
+ );
18977
+ return RTV.tensorRaw(result, tensor.shape);
18978
+ }
18937
18979
  function tensorElemwiseComplex(at, bt, opCode, jsOp) {
18938
18980
  const bridge = getLapackBridge();
18939
18981
  if (bridge?.elemwiseComplex) {
@@ -19004,6 +19046,13 @@ function mAdd(a, b) {
19004
19046
  im: aIm + bIm
19005
19047
  }));
19006
19048
  }
19049
+ if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
19050
+ const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_ADD, true);
19051
+ if (nr) return nr;
19052
+ } else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
19053
+ const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_ADD, false);
19054
+ if (nr) return nr;
19055
+ }
19007
19056
  return binaryOp(a, b, (x, y) => x + y);
19008
19057
  }
19009
19058
  function mSub(a, b) {
@@ -19036,6 +19085,13 @@ function mSub(a, b) {
19036
19085
  im: aIm - bIm
19037
19086
  }));
19038
19087
  }
19088
+ if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
19089
+ const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_SUB, true);
19090
+ if (nr) return nr;
19091
+ } else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
19092
+ const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_SUB, false);
19093
+ if (nr) return nr;
19094
+ }
19039
19095
  return binaryOp(a, b, (x, y) => x - y);
19040
19096
  }
19041
19097
  function mMul(a, b) {
@@ -19052,6 +19108,13 @@ function mMul(a, b) {
19052
19108
  im: aRe * bIm + aIm * bRe
19053
19109
  }));
19054
19110
  }
19111
+ if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
19112
+ const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_MUL, true);
19113
+ if (nr) return nr;
19114
+ } else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
19115
+ const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_MUL, false);
19116
+ if (nr) return nr;
19117
+ }
19055
19118
  return binaryOp(a, b, (x, y) => x * y);
19056
19119
  }
19057
19120
  function mElemMul(a, b) {
@@ -19084,6 +19147,13 @@ function mElemMul(a, b) {
19084
19147
  im: aRe * bIm + aIm * bRe
19085
19148
  }));
19086
19149
  }
19150
+ if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
19151
+ const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_MUL, true);
19152
+ if (nr) return nr;
19153
+ } else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
19154
+ const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_MUL, false);
19155
+ if (nr) return nr;
19156
+ }
19087
19157
  return binaryOp(a, b, (x, y) => x * y);
19088
19158
  }
19089
19159
  function mDiv(a, b) {
@@ -19122,6 +19192,13 @@ function mElemDiv(a, b) {
19122
19192
  if (isComplexOrMixed(a, b)) {
19123
19193
  return complexBinaryOp(a, b, complexDivide);
19124
19194
  }
19195
+ if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
19196
+ const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_DIV, true);
19197
+ if (nr) return nr;
19198
+ } else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
19199
+ const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_DIV, false);
19200
+ if (nr) return nr;
19201
+ }
19125
19202
  return binaryOp(a, b, (x, y) => x / y);
19126
19203
  }
19127
19204
  function mLeftDiv(a, b) {
@@ -31361,7 +31438,7 @@ defineBuiltin({
31361
31438
  cases: [
31362
31439
  {
31363
31440
  match: (argTypes, nargout) => {
31364
- if (nargout !== 1 || argTypes.length < 1 || argTypes.length > 2)
31441
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
31365
31442
  return null;
31366
31443
  if (!isNumericJitType(argTypes[0])) return null;
31367
31444
  return [NUM];
@@ -31478,7 +31555,7 @@ defineBuiltin({
31478
31555
  cases: [
31479
31556
  {
31480
31557
  match: (argTypes, nargout) => {
31481
- if (nargout !== 1 || argTypes.length < 1 || argTypes.length > 3)
31558
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 3)
31482
31559
  return null;
31483
31560
  if (!isNumericJitType(argTypes[0])) return null;
31484
31561
  const a = argTypes[0];
@@ -31557,7 +31634,7 @@ defineBuiltin({
31557
31634
  cases: [
31558
31635
  {
31559
31636
  match: (argTypes, nargout) => {
31560
- if (nargout !== 1 || argTypes.length !== 2) return null;
31637
+ if (nargout > 1 || argTypes.length !== 2) return null;
31561
31638
  if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
31562
31639
  return null;
31563
31640
  const hasTensor = argTypes.some((t) => t.kind === "tensor");
@@ -31641,7 +31718,7 @@ defineBuiltin({
31641
31718
  cases: [
31642
31719
  {
31643
31720
  match: (argTypes, nargout) => {
31644
- if (argTypes.length !== 1 || nargout !== 1) return null;
31721
+ if (argTypes.length !== 1 || nargout > 1) return null;
31645
31722
  if (!isNumericJitType(argTypes[0])) return null;
31646
31723
  const hasComplex = argTypes[0].kind === "complex_or_number" || argTypes[0].kind === "tensor" && argTypes[0].isComplex;
31647
31724
  return [hasComplex ? COMPLEX_OR_NUM : NUM];
@@ -31753,7 +31830,7 @@ defineBuiltin({
31753
31830
  cases: [
31754
31831
  {
31755
31832
  match: (argTypes, nargout) => {
31756
- if (argTypes.length !== 1 || nargout !== 1) return null;
31833
+ if (argTypes.length !== 1 || nargout > 1) return null;
31757
31834
  if (!isNumericJitType(argTypes[0])) return null;
31758
31835
  return [NUM];
31759
31836
  },
@@ -31778,7 +31855,7 @@ defineBuiltin({
31778
31855
  cases: [
31779
31856
  {
31780
31857
  match: (argTypes, nargout) => {
31781
- if (nargout !== 1) return null;
31858
+ if (nargout > 1) return null;
31782
31859
  if (argTypes.length !== 2 && argTypes.length !== 3) return null;
31783
31860
  if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
31784
31861
  return null;
@@ -31844,7 +31921,7 @@ defineBuiltin({
31844
31921
  cases: [
31845
31922
  {
31846
31923
  match: (argTypes, nargout) => {
31847
- if (argTypes.length !== 1 || nargout !== 1) return null;
31924
+ if (argTypes.length !== 1 || nargout > 1) return null;
31848
31925
  if (!isNumericJitType(argTypes[0])) return null;
31849
31926
  const a = argTypes[0];
31850
31927
  if (a.kind === "number" || a.kind === "boolean") return [NUM];
@@ -31957,11 +32034,11 @@ function invComplexJS(dataRe, dataIm, n) {
31957
32034
  registerIBuiltin({
31958
32035
  name: "svd",
31959
32036
  resolve: (argTypes, nargout) => {
31960
- if (nargout < 1 || nargout > 3 || argTypes.length < 1 || argTypes.length > 2)
32037
+ if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 2)
31961
32038
  return null;
31962
32039
  if (!isNumericJitType(argTypes[0])) return null;
31963
32040
  const c = tensorType();
31964
- if (nargout === 1)
32041
+ if (nargout <= 1)
31965
32042
  return { outputTypes: [c], apply: (args, n) => svdApply(args, n) };
31966
32043
  return { outputTypes: [c, c, c], apply: (args, n) => svdApply(args, n) };
31967
32044
  }
@@ -31972,7 +32049,7 @@ function svdApply(args, nargout) {
31972
32049
  const A = args[0];
31973
32050
  if (isRuntimeNumber(A)) {
31974
32051
  const val = Math.abs(A);
31975
- if (nargout === 1) return RTV.tensor(new FloatXArray([val]), [1, 1]);
32052
+ if (nargout <= 1) return RTV.tensor(new FloatXArray([val]), [1, 1]);
31976
32053
  return [
31977
32054
  RTV.tensor(new FloatXArray([A >= 0 ? 1 : -1]), [1, 1]),
31978
32055
  RTV.tensor(new FloatXArray([val]), [1, 1]),
@@ -31999,7 +32076,7 @@ function svdApply(args, nargout) {
31999
32076
  nargout === 3
32000
32077
  );
32001
32078
  if (!result) throw new RuntimeError("svd: complex SVD failed");
32002
- if (nargout === 1) return RTV.tensor(new FloatXArray(result.S), [k, 1]);
32079
+ if (nargout <= 1) return RTV.tensor(new FloatXArray(result.S), [k, 1]);
32003
32080
  const uCols = econ ? k : m;
32004
32081
  const vCols = econ ? k : n;
32005
32082
  return [
@@ -32020,7 +32097,7 @@ function svdApply(args, nargout) {
32020
32097
  if (bridge?.svd) {
32021
32098
  const result = bridge.svd(toF64(A.data), m, n, econ, nargout === 3);
32022
32099
  if (result) {
32023
- if (nargout === 1) return RTV.tensor(new FloatXArray(result.S), [k, 1]);
32100
+ if (nargout <= 1) return RTV.tensor(new FloatXArray(result.S), [k, 1]);
32024
32101
  const uCols = econ ? k : m;
32025
32102
  const vCols = econ ? k : n;
32026
32103
  return [
@@ -32090,12 +32167,12 @@ function powerIterationEigenvalues(A_data, n, numEigenvalues) {
32090
32167
  registerIBuiltin({
32091
32168
  name: "qr",
32092
32169
  resolve: (argTypes, nargout) => {
32093
- if (nargout < 1 || nargout > 3 || argTypes.length < 1 || argTypes.length > 2)
32170
+ if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 2)
32094
32171
  return null;
32095
32172
  if (!isNumericJitType(argTypes[0])) return null;
32096
32173
  const isComplex2 = argTypes[0].kind === "tensor" && argTypes[0].isComplex;
32097
32174
  const t = tensorType(isComplex2 || void 0);
32098
- if (nargout === 1)
32175
+ if (nargout <= 1)
32099
32176
  return { outputTypes: [t], apply: (args, n) => qrApply(args, n) };
32100
32177
  if (nargout === 3)
32101
32178
  return {
@@ -32112,7 +32189,7 @@ function qrApply(args, nargout) {
32112
32189
  if (isRuntimeNumber(A)) {
32113
32190
  const val = A;
32114
32191
  const s = val >= 0 ? 1 : -1;
32115
- if (nargout === 1) return RTV.tensor(new FloatXArray([s * val]), [1, 1]);
32192
+ if (nargout <= 1) return RTV.tensor(new FloatXArray([s * val]), [1, 1]);
32116
32193
  if (nargout === 3)
32117
32194
  return [
32118
32195
  RTV.tensor(new FloatXArray([s]), [1, 1]),
@@ -32145,7 +32222,7 @@ function qrApply(args, nargout) {
32145
32222
  nargout === 2
32146
32223
  );
32147
32224
  if (!result) throw new RuntimeError("qr: complex QR failed");
32148
- if (nargout === 1) {
32225
+ if (nargout <= 1) {
32149
32226
  const rRows = econ ? k : m;
32150
32227
  return RTV.tensor(
32151
32228
  new FloatXArray(result.RRe),
@@ -32171,7 +32248,7 @@ function qrApply(args, nargout) {
32171
32248
  if (bridge?.qr) {
32172
32249
  const result = bridge.qr(toF64(A.data), m, n, econ, nargout === 2);
32173
32250
  if (result) {
32174
- if (nargout === 1)
32251
+ if (nargout <= 1)
32175
32252
  return RTV.tensor(new FloatXArray(result.R), [econ ? k : m, n]);
32176
32253
  const qCols = econ ? k : m;
32177
32254
  return [
@@ -32214,7 +32291,7 @@ function qrApply(args, nargout) {
32214
32291
  R_data[colMajorIndex(j + i, c, m)] -= scale * v[i];
32215
32292
  }
32216
32293
  }
32217
- if (nargout === 1) {
32294
+ if (nargout <= 1) {
32218
32295
  if (econ) {
32219
32296
  const R_econ = new FloatXArray(k * n);
32220
32297
  for (let r = 0; r < k; r++)
@@ -32430,11 +32507,11 @@ function qrPivotApply(A, m, n, k, econ) {
32430
32507
  registerIBuiltin({
32431
32508
  name: "lu",
32432
32509
  resolve: (argTypes, nargout) => {
32433
- if (nargout < 1 || nargout > 3) return null;
32510
+ if (nargout < 0 || nargout > 3) return null;
32434
32511
  if (argTypes.length < 1 || argTypes.length > 2) return null;
32435
32512
  if (!isNumericJitType(argTypes[0])) return null;
32436
32513
  const t = tensorType();
32437
- if (nargout === 1)
32514
+ if (nargout <= 1)
32438
32515
  return { outputTypes: [t], apply: (args, n) => luApply(args, n) };
32439
32516
  if (nargout === 2)
32440
32517
  return { outputTypes: [t, t], apply: (args, n) => luApply(args, n) };
@@ -32453,7 +32530,7 @@ function luApply(args, nargout) {
32453
32530
  if (nargout <= 2) {
32454
32531
  const L2 = RTV.tensor(new FloatXArray([1]), [1, 1]);
32455
32532
  const U2 = RTV.tensor(new FloatXArray([val]), [1, 1]);
32456
- if (nargout === 1) return L2;
32533
+ if (nargout <= 1) return L2;
32457
32534
  return [L2, U2];
32458
32535
  }
32459
32536
  const L = RTV.tensor(new FloatXArray([1]), [1, 1]);
@@ -32491,7 +32568,7 @@ function luApply(args, nargout) {
32491
32568
  if (U_im && LU_im) U_im[i + j * k] = LU_im[i + j * m];
32492
32569
  }
32493
32570
  }
32494
- if (nargout === 1)
32571
+ if (nargout <= 1)
32495
32572
  return RTV.tensor(
32496
32573
  new FloatXArray(LU_re),
32497
32574
  [m, n],
@@ -32567,11 +32644,11 @@ function ipivToPermVector(ipiv, m) {
32567
32644
  registerIBuiltin({
32568
32645
  name: "eig",
32569
32646
  resolve: (argTypes, nargout) => {
32570
- if (nargout < 1 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
32647
+ if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
32571
32648
  return null;
32572
32649
  if (!isNumericJitType(argTypes[0])) return null;
32573
32650
  const c = tensorType(true);
32574
- if (nargout === 1)
32651
+ if (nargout <= 1)
32575
32652
  return { outputTypes: [c], apply: (args, n) => eigApply(args, n) };
32576
32653
  if (nargout === 2)
32577
32654
  return { outputTypes: [c, c], apply: (args, n) => eigApply(args, n) };
@@ -32585,7 +32662,7 @@ function eigApply(args, nargout) {
32585
32662
  const { balance, outputForm } = parseEigOptionsRuntime(args);
32586
32663
  if (isRuntimeNumber(A)) {
32587
32664
  const val = A;
32588
- if (nargout === 1) return RTV.num(val);
32665
+ if (nargout <= 1) return RTV.num(val);
32589
32666
  const V = RTV.tensor(new FloatXArray([1]), [1, 1]);
32590
32667
  if (nargout === 2) {
32591
32668
  if (outputForm === "vector") return [V, RTV.num(val)];
@@ -32614,7 +32691,7 @@ function eigApply(args, nargout) {
32614
32691
  );
32615
32692
  if (!result2) throw new RuntimeError("eig: complex eig failed");
32616
32693
  const { wRe, wIm, VLRe, VLIm, VRRe, VRIm } = result2;
32617
- if (nargout === 1) return maybeComplexTensor(wRe, [n, 1], wIm);
32694
+ if (nargout <= 1) return maybeComplexTensor(wRe, [n, 1], wIm);
32618
32695
  const Vout2 = computeVR && VRRe && VRIm ? maybeComplexTensor(VRRe, [n, n], VRIm) : RTV.tensor(new FloatXArray(n * n), [n, n]);
32619
32696
  const Dout2 = outputForm === "vector" ? maybeComplexTensor(wRe, [n, 1], wIm) : buildDiagMatrix(wRe, wIm, n);
32620
32697
  if (nargout === 2) return [Vout2, Dout2];
@@ -32627,7 +32704,7 @@ function eigApply(args, nargout) {
32627
32704
  if (!result) throw new RuntimeError("eig: LAPACK eig failed");
32628
32705
  const { wr, wi, VL, VR } = result;
32629
32706
  const hasComplex = wi.some((v) => v !== 0);
32630
- if (nargout === 1) return maybeComplexTensor(wr, [n, 1], wi);
32707
+ if (nargout <= 1) return maybeComplexTensor(wr, [n, 1], wi);
32631
32708
  const Vout = computeVR && VR ? buildEigenvectorMatrix(VR, wi, n, hasComplex) : RTV.tensor(new FloatXArray(n * n), [n, n]);
32632
32709
  const Dout = outputForm === "vector" ? maybeComplexTensor(wr, [n, 1], wi) : buildDiagMatrix(wr, wi, n);
32633
32710
  if (nargout === 2) return [Vout, Dout];
@@ -32651,11 +32728,11 @@ function parseEigOptionsRuntime(args) {
32651
32728
  registerIBuiltin({
32652
32729
  name: "chol",
32653
32730
  resolve: (argTypes, nargout) => {
32654
- if (nargout < 1 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
32731
+ if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
32655
32732
  return null;
32656
32733
  if (!isNumericJitType(argTypes[0])) return null;
32657
32734
  const t = tensorType();
32658
- if (nargout === 1)
32735
+ if (nargout <= 1)
32659
32736
  return { outputTypes: [t], apply: (args, n) => cholApply(args, n) };
32660
32737
  if (nargout === 2)
32661
32738
  return { outputTypes: [t, NUM], apply: (args, n) => cholApply(args, n) };
@@ -32816,7 +32893,7 @@ defineBuiltin({
32816
32893
  cases: [
32817
32894
  {
32818
32895
  match: (argTypes, nargout) => {
32819
- if (argTypes.length !== 2 || nargout !== 1) return null;
32896
+ if (argTypes.length !== 2 || nargout > 1) return null;
32820
32897
  if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
32821
32898
  return null;
32822
32899
  return [tensorType()];
@@ -32859,7 +32936,7 @@ defineBuiltin({
32859
32936
  cases: [
32860
32937
  {
32861
32938
  match: (argTypes, nargout) => {
32862
- if (nargout !== 1 || argTypes.length < 1 || argTypes.length > 2)
32939
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
32863
32940
  return null;
32864
32941
  if (!isNumericJitType(argTypes[0])) return null;
32865
32942
  return [NUM];
@@ -32920,7 +32997,7 @@ defineBuiltin({
32920
32997
  cases: [
32921
32998
  {
32922
32999
  match: (argTypes, nargout) => {
32923
- if (nargout !== 1 || argTypes.length < 1 || argTypes.length > 2)
33000
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
32924
33001
  return null;
32925
33002
  if (!isNumericJitType(argTypes[0])) return null;
32926
33003
  return [NUM];
@@ -32968,7 +33045,7 @@ defineBuiltin({
32968
33045
  cases: [
32969
33046
  {
32970
33047
  match: (argTypes, nargout) => {
32971
- if (nargout !== 1 || argTypes.length < 1 || argTypes.length > 2)
33048
+ if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
32972
33049
  return null;
32973
33050
  if (!isNumericJitType(argTypes[0])) return null;
32974
33051
  const a = argTypes[0];
@@ -33065,7 +33142,7 @@ defineBuiltin({
33065
33142
  cases: [
33066
33143
  {
33067
33144
  match: (argTypes, nargout) => {
33068
- if (nargout !== 1 || argTypes.length !== 2) return null;
33145
+ if (nargout > 1 || argTypes.length !== 2) return null;
33069
33146
  if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
33070
33147
  return null;
33071
33148
  return [tensorType()];
@@ -33101,7 +33178,7 @@ defineBuiltin({
33101
33178
  cases: [
33102
33179
  {
33103
33180
  match: (argTypes, nargout) => {
33104
- if (nargout !== 1 || argTypes.length === 0) return null;
33181
+ if (nargout > 1 || argTypes.length === 0) return null;
33105
33182
  if (!argTypes.every(isNumericJitType)) return null;
33106
33183
  return [tensorType()];
33107
33184
  },
@@ -33144,7 +33221,7 @@ defineBuiltin({
33144
33221
  cases: [
33145
33222
  {
33146
33223
  match: (argTypes, nargout) => {
33147
- if (nargout !== 1) return null;
33224
+ if (nargout > 1) return null;
33148
33225
  if (argTypes.length !== 2 && argTypes.length !== 4) return null;
33149
33226
  const xIdx = 0, yIdx = argTypes.length === 4 ? 2 : 1;
33150
33227
  if (!isNumericJitType(argTypes[xIdx]) || !isNumericJitType(argTypes[yIdx]))
@@ -33273,7 +33350,7 @@ defineBuiltin({
33273
33350
  cases: [
33274
33351
  {
33275
33352
  match: (argTypes, nargout) => {
33276
- if (nargout !== 1 || argTypes.length !== 1) return null;
33353
+ if (nargout > 1 || argTypes.length !== 1) return null;
33277
33354
  if (argTypes[0].kind !== "tensor") return null;
33278
33355
  return [tensorType(argTypes[0].isComplex)];
33279
33356
  },
@@ -37135,9 +37212,11 @@ registerIBuiltin({
37135
37212
  // src/numbl-core/helpers/prng.ts
37136
37213
  var _rngState = null;
37137
37214
  var _rngSeed = 0;
37215
+ var _bmSpare = null;
37138
37216
  function setRngShuffle() {
37139
37217
  _rngState = null;
37140
37218
  _rngSeed = 0;
37219
+ _bmSpare = null;
37141
37220
  }
37142
37221
  function setRngSeed(seed) {
37143
37222
  _rngSeed = seed;
@@ -37153,6 +37232,7 @@ function splitmix32(seed) {
37153
37232
  };
37154
37233
  }
37155
37234
  function seedRng(seed) {
37235
+ _bmSpare = null;
37156
37236
  const sm = splitmix32(seed);
37157
37237
  _rngState = new Uint32Array([sm(), sm(), sm(), sm()]);
37158
37238
  if (_rngState[0] === 0 && _rngState[1] === 0 && _rngState[2] === 0 && _rngState[3] === 0) {
@@ -37179,10 +37259,60 @@ function rngRandom() {
37179
37259
  return (xoshiro128ss() >>> 0) / 4294967296;
37180
37260
  }
37181
37261
  function boxMullerRandom() {
37182
- let u = 0, v = 0;
37183
- while (u === 0) u = rngRandom();
37184
- while (v === 0) v = rngRandom();
37185
- return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
37262
+ if (_bmSpare !== null) {
37263
+ const s2 = _bmSpare;
37264
+ _bmSpare = null;
37265
+ return s2;
37266
+ }
37267
+ let u, v, s;
37268
+ do {
37269
+ u = 2 * rngRandom() - 1;
37270
+ v = 2 * rngRandom() - 1;
37271
+ s = u * u + v * v;
37272
+ } while (s >= 1 || s === 0);
37273
+ const mul = Math.sqrt(-2 * Math.log(s) / s);
37274
+ _bmSpare = v * mul;
37275
+ return u * mul;
37276
+ }
37277
+ function fillRandn(data) {
37278
+ if (_rngState !== null) {
37279
+ const bridge = getLapackBridge();
37280
+ if (bridge?.fillRandn) {
37281
+ const r = bridge.fillRandn(
37282
+ _rngState,
37283
+ data.length,
37284
+ _bmSpare ?? 0,
37285
+ _bmSpare !== null
37286
+ );
37287
+ _bmSpare = r.hasSpare ? r.spare : null;
37288
+ if (data instanceof Float64Array) {
37289
+ data.set(r.data);
37290
+ } else {
37291
+ for (let i2 = 0; i2 < data.length; i2++) data[i2] = r.data[i2];
37292
+ }
37293
+ return;
37294
+ }
37295
+ }
37296
+ const n = data.length;
37297
+ let i = 0;
37298
+ if (_bmSpare !== null && i < n) {
37299
+ data[i++] = _bmSpare;
37300
+ _bmSpare = null;
37301
+ }
37302
+ for (; i + 1 < n; i += 2) {
37303
+ let u, v, s;
37304
+ do {
37305
+ u = 2 * rngRandom() - 1;
37306
+ v = 2 * rngRandom() - 1;
37307
+ s = u * u + v * v;
37308
+ } while (s >= 1 || s === 0);
37309
+ const mul = Math.sqrt(-2 * Math.log(s) / s);
37310
+ data[i] = u * mul;
37311
+ data[i + 1] = v * mul;
37312
+ }
37313
+ if (i < n) {
37314
+ data[i] = boxMullerRandom();
37315
+ }
37186
37316
  }
37187
37317
  function getRngStateStruct() {
37188
37318
  const stateArray = _rngState ? RTV.tensor(new FloatXArray(Array.from(_rngState).map((v) => v)), [4, 1]) : RTV.tensor(new FloatXArray(0), [0, 1]);
@@ -37250,7 +37380,7 @@ registerIBuiltin({
37250
37380
  };
37251
37381
  }
37252
37382
  });
37253
- function registerRandBuiltin(name, gen) {
37383
+ function registerRandBuiltin(name, gen, bulkFill) {
37254
37384
  defineBuiltin({
37255
37385
  name,
37256
37386
  cases: [
@@ -37289,7 +37419,11 @@ function registerRandBuiltin(name, gen) {
37289
37419
  if (shape.length === 1) shape.push(shape[0]);
37290
37420
  const n = numel(shape);
37291
37421
  const data = new FloatXArray(n);
37292
- for (let i = 0; i < n; i++) data[i] = gen();
37422
+ if (bulkFill) {
37423
+ bulkFill(data);
37424
+ } else {
37425
+ for (let i = 0; i < n; i++) data[i] = gen();
37426
+ }
37293
37427
  return RTV.tensor(data, shape);
37294
37428
  }
37295
37429
  }
@@ -37297,7 +37431,7 @@ function registerRandBuiltin(name, gen) {
37297
37431
  });
37298
37432
  }
37299
37433
  registerRandBuiltin("rand", rngRandom);
37300
- registerRandBuiltin("randn", boxMullerRandom);
37434
+ registerRandBuiltin("randn", boxMullerRandom, fillRandn);
37301
37435
  defineBuiltin({
37302
37436
  name: "randi",
37303
37437
  cases: [
@@ -37744,6 +37878,9 @@ registerIBuiltin({
37744
37878
 
37745
37879
  // src/numbl-core/interpreter/builtins/time-system.ts
37746
37880
  var ticTime = 0;
37881
+ function getTicTime() {
37882
+ return ticTime;
37883
+ }
37747
37884
  defineBuiltin({
37748
37885
  name: "tic",
37749
37886
  cases: [
@@ -37756,15 +37893,6 @@ defineBuiltin({
37756
37893
  }
37757
37894
  ]
37758
37895
  });
37759
- defineBuiltin({
37760
- name: "toc",
37761
- cases: [
37762
- {
37763
- match: (argTypes) => argTypes.length === 0 ? [{ kind: "number" }] : null,
37764
- apply: () => RTV.num((performance.now() - ticTime) / 1e3)
37765
- }
37766
- ]
37767
- });
37768
37896
  defineBuiltin({
37769
37897
  name: "clock",
37770
37898
  cases: [
@@ -38753,6 +38881,44 @@ registerIBuiltin({
38753
38881
  }
38754
38882
  })
38755
38883
  });
38884
+ var WEBOPTIONS_DEFAULTS = {
38885
+ CharacterEncoding: RTV.char("auto"),
38886
+ UserAgent: RTV.char("numbl"),
38887
+ Timeout: 5,
38888
+ Username: RTV.char(""),
38889
+ Password: RTV.char(""),
38890
+ KeyName: RTV.char(""),
38891
+ KeyValue: RTV.char(""),
38892
+ ContentType: RTV.char("auto"),
38893
+ MediaType: RTV.char("auto"),
38894
+ RequestMethod: RTV.char("auto"),
38895
+ ArrayFormat: RTV.char("csv"),
38896
+ CertificateFilename: RTV.char("default")
38897
+ };
38898
+ registerIBuiltin({
38899
+ name: "weboptions",
38900
+ resolve: () => ({
38901
+ outputTypes: [{ kind: "struct" }],
38902
+ apply: (args) => {
38903
+ const fields = /* @__PURE__ */ new Map();
38904
+ for (const [k, v] of Object.entries(WEBOPTIONS_DEFAULTS)) {
38905
+ fields.set(k, v);
38906
+ }
38907
+ if (args.length % 2 !== 0)
38908
+ throw new RuntimeError("weboptions: expected name-value pairs");
38909
+ for (let i = 0; i < args.length; i += 2) {
38910
+ const key = args[i];
38911
+ if (!isRuntimeChar(key) && !isRuntimeString(key))
38912
+ throw new RuntimeError("weboptions: option name must be a string");
38913
+ const name = isRuntimeChar(key) ? key.value : key;
38914
+ if (!(name in WEBOPTIONS_DEFAULTS))
38915
+ throw new RuntimeError(`weboptions: unknown option '${name}'`);
38916
+ fields.set(name, args[i + 1]);
38917
+ }
38918
+ return RTV.struct(Object.fromEntries(fields));
38919
+ }
38920
+ })
38921
+ });
38756
38922
  registerIBuiltin({
38757
38923
  name: "odeget",
38758
38924
  resolve: () => ({
@@ -43838,7 +44004,8 @@ var SPECIAL_BUILTIN_NAMES = [
43838
44004
  "cd",
43839
44005
  "ode45",
43840
44006
  "ode23",
43841
- "deval"
44007
+ "deval",
44008
+ "toc"
43842
44009
  ];
43843
44010
 
43844
44011
  // src/numbl-core/runtime/specialBuiltins.ts
@@ -43889,6 +44056,14 @@ function registerSpecialBuiltins(rt) {
43889
44056
  }
43890
44057
  return 0;
43891
44058
  });
44059
+ registerSpecial("toc", (nargout) => {
44060
+ const elapsed = (performance.now() - getTicTime()) / 1e3;
44061
+ if (nargout === 0) {
44062
+ rt.output(`Elapsed time is ${elapsed.toFixed(6)} seconds.
44063
+ `);
44064
+ }
44065
+ return RTV.num(elapsed);
44066
+ });
43892
44067
  registerSpecial("warning", (_nargout, args) => {
43893
44068
  if (args.length === 0) return RTV.num(0);
43894
44069
  const margs = args.map((a) => ensureRuntimeValue(a));
@@ -44527,6 +44702,40 @@ function registerSpecialBuiltins(rt) {
44527
44702
  RTV.char("")
44528
44703
  ];
44529
44704
  });
44705
+ function extractWebOptions(arg) {
44706
+ if (!isRuntimeStruct(arg)) return void 0;
44707
+ const s = arg;
44708
+ if (!s.fields.has("Timeout")) return void 0;
44709
+ const opts = {};
44710
+ const t = s.fields.get("Timeout");
44711
+ if (t !== void 0) opts.timeout = toNumber(t);
44712
+ const rm = s.fields.get("RequestMethod");
44713
+ if (rm !== void 0) {
44714
+ const v = toString(rm);
44715
+ if (v !== "auto") opts.requestMethod = v;
44716
+ }
44717
+ const un = s.fields.get("Username");
44718
+ if (un !== void 0) {
44719
+ const v = toString(un);
44720
+ if (v) opts.username = v;
44721
+ }
44722
+ const pw = s.fields.get("Password");
44723
+ if (pw !== void 0) {
44724
+ const v = toString(pw);
44725
+ if (v) opts.password = v;
44726
+ }
44727
+ const kn = s.fields.get("KeyName");
44728
+ if (kn !== void 0) {
44729
+ const v = toString(kn);
44730
+ if (v) opts.keyName = v;
44731
+ }
44732
+ const kv = s.fields.get("KeyValue");
44733
+ if (kv !== void 0) {
44734
+ const v = toString(kv);
44735
+ if (v) opts.keyValue = v;
44736
+ }
44737
+ return opts;
44738
+ }
44530
44739
  registerSpecial("websave", (_nargout, args) => {
44531
44740
  const io = requireFileIO();
44532
44741
  const margs = args.map((a) => ensureRuntimeValue(a));
@@ -44536,8 +44745,14 @@ function registerSpecialBuiltins(rt) {
44536
44745
  throw new RuntimeError("websave is not available in this environment");
44537
44746
  const filename = toString(margs[0]);
44538
44747
  let url = toString(margs[1]);
44748
+ let webOpts;
44749
+ let queryEnd = margs.length;
44750
+ if (margs.length > 2) {
44751
+ webOpts = extractWebOptions(margs[margs.length - 1]);
44752
+ if (webOpts) queryEnd = margs.length - 1;
44753
+ }
44539
44754
  const queryParts = [];
44540
- for (let i = 2; i + 1 < margs.length; i += 2) {
44755
+ for (let i = 2; i + 1 < queryEnd; i += 2) {
44541
44756
  const name = encodeURIComponent(toString(margs[i]));
44542
44757
  const value = encodeURIComponent(toString(margs[i + 1]));
44543
44758
  queryParts.push(`${name}=${value}`);
@@ -44546,7 +44761,7 @@ function registerSpecialBuiltins(rt) {
44546
44761
  const sep = url.includes("?") ? "&" : "?";
44547
44762
  url += sep + queryParts.join("&");
44548
44763
  }
44549
- io.websave(url, filename);
44764
+ io.websave(url, filename, webOpts);
44550
44765
  return RTV.char(filename);
44551
44766
  });
44552
44767
  registerSpecial("webread", (_nargout, args) => {
@@ -44557,8 +44772,14 @@ function registerSpecialBuiltins(rt) {
44557
44772
  if (!io.webread)
44558
44773
  throw new RuntimeError("webread is not available in this environment");
44559
44774
  let url = toString(margs[0]);
44775
+ let webOpts;
44776
+ let queryEnd = margs.length;
44777
+ if (margs.length > 1) {
44778
+ webOpts = extractWebOptions(margs[margs.length - 1]);
44779
+ if (webOpts) queryEnd = margs.length - 1;
44780
+ }
44560
44781
  const queryParts = [];
44561
- for (let i = 1; i + 1 < margs.length; i += 2) {
44782
+ for (let i = 1; i + 1 < queryEnd; i += 2) {
44562
44783
  const name = encodeURIComponent(toString(margs[i]));
44563
44784
  const value = encodeURIComponent(toString(margs[i + 1]));
44564
44785
  queryParts.push(`${name}=${value}`);
@@ -44567,7 +44788,7 @@ function registerSpecialBuiltins(rt) {
44567
44788
  const sep = url.includes("?") ? "&" : "?";
44568
44789
  url += sep + queryParts.join("&");
44569
44790
  }
44570
- const text = io.webread(url);
44791
+ const text = io.webread(url, webOpts);
44571
44792
  try {
44572
44793
  const parsed = JSON.parse(text);
44573
44794
  return convertJsonValue(parsed);
@@ -49175,9 +49396,7 @@ function lowerStmt(ctx, stmt) {
49175
49396
  result = lowerAssign(ctx, stmt);
49176
49397
  break;
49177
49398
  case "ExprStmt":
49178
- if (!stmt.suppressed) return null;
49179
- result = lowerExprStmt(ctx, stmt);
49180
- break;
49399
+ return null;
49181
49400
  case "If":
49182
49401
  result = lowerIf(ctx, stmt);
49183
49402
  break;
@@ -49252,11 +49471,6 @@ function lowerMultiAssign(ctx, stmt) {
49252
49471
  }
49253
49472
  ];
49254
49473
  }
49255
- function lowerExprStmt(ctx, stmt) {
49256
- const expr = lowerExpr(ctx, stmt.expr);
49257
- if (!expr) return null;
49258
- return [{ tag: "ExprStmt", expr }];
49259
- }
49260
49474
  function lowerIf(ctx, stmt) {
49261
49475
  const cond = lowerExpr(ctx, stmt.cond);
49262
49476
  if (!cond) return null;
@@ -50325,10 +50539,11 @@ function execStmt(stmt) {
50325
50539
  }
50326
50540
  switch (stmt.type) {
50327
50541
  case "ExprStmt": {
50328
- const val = this.evalExpr(stmt.expr);
50542
+ const val = this.evalExprNargout(stmt.expr, 0);
50329
50543
  const singleVal = Array.isArray(val) ? val[0] : val;
50330
50544
  const rv = ensureRuntimeValue(singleVal);
50331
50545
  this.ans = rv;
50546
+ this.env.set("ans", rv);
50332
50547
  if (!stmt.suppressed && !this.isOutputExpr(stmt.expr)) {
50333
50548
  this.rt.displayResult(rv);
50334
50549
  }
@@ -50378,10 +50593,12 @@ function execStmt(stmt) {
50378
50593
  const rv = this.rt.share(i < values.length ? values[i] : void 0);
50379
50594
  this.assignLValue(lv, rv);
50380
50595
  }
50381
- if (!stmt.suppressed && values.length > 0) {
50382
- const firstLv = stmt.lvalues[0];
50383
- if (firstLv.type === "Var") {
50384
- this.rt.displayAssign(firstLv.name, ensureRuntimeValue(values[0]));
50596
+ if (!stmt.suppressed) {
50597
+ for (let i = 0; i < stmt.lvalues.length; i++) {
50598
+ const lv = stmt.lvalues[i];
50599
+ if (lv.type === "Var" && i < values.length) {
50600
+ this.rt.displayAssign(lv.name, ensureRuntimeValue(values[i]));
50601
+ }
50385
50602
  }
50386
50603
  }
50387
50604
  return null;
@@ -50738,6 +50955,18 @@ function evalArgs(argExprs) {
50738
50955
  }
50739
50956
  return args;
50740
50957
  }
50958
+ var binopProfileName = {
50959
+ ["Add" /* Add */]: "plus",
50960
+ ["Sub" /* Sub */]: "minus",
50961
+ ["Mul" /* Mul */]: "mtimes",
50962
+ ["ElemMul" /* ElemMul */]: "times",
50963
+ ["Div" /* Div */]: "mrdivide",
50964
+ ["ElemDiv" /* ElemDiv */]: "rdivide",
50965
+ ["LeftDiv" /* LeftDiv */]: "mldivide",
50966
+ ["ElemLeftDiv" /* ElemLeftDiv */]: "ldivide",
50967
+ ["Pow" /* Pow */]: "mpower",
50968
+ ["ElemPow" /* ElemPow */]: "power"
50969
+ };
50741
50970
  function evalBinary(expr) {
50742
50971
  if (expr.op === "AndAnd" /* AndAnd */) {
50743
50972
  const left2 = this.evalExpr(expr.left);
@@ -50763,6 +50992,13 @@ function evalBinary(expr) {
50763
50992
  if (!isNaN(r)) return r;
50764
50993
  return mPow(ensureRuntimeValue(left), ensureRuntimeValue(right));
50765
50994
  }
50995
+ if (this.rt.profilingEnabled && (typeof left !== "number" || typeof right !== "number")) {
50996
+ const opName = binopProfileName[expr.op] ?? expr.op;
50997
+ this.rt.profileEnter("builtin:interp:" + opName);
50998
+ const result = binop(expr.op, left, right);
50999
+ this.rt.profileLeave();
51000
+ return result;
51001
+ }
50766
51002
  return binop(expr.op, left, right);
50767
51003
  }
50768
51004
  function evalUnary(expr) {
@@ -51161,7 +51397,6 @@ function switchMatch2(switchVal, caseVal) {
51161
51397
  return switchMatch(switchVal, caseVal);
51162
51398
  }
51163
51399
  function isOutputExpr(expr) {
51164
- if (expr.type !== "FuncCall") return false;
51165
51400
  const outputFunctions = [
51166
51401
  "disp",
51167
51402
  "display",
@@ -51169,9 +51404,12 @@ function isOutputExpr(expr) {
51169
51404
  "warning",
51170
51405
  "assert",
51171
51406
  "tic",
51407
+ "toc",
51172
51408
  "help"
51173
51409
  ];
51174
- return outputFunctions.includes(expr.name);
51410
+ if (expr.type === "FuncCall") return outputFunctions.includes(expr.name);
51411
+ if (expr.type === "Ident") return outputFunctions.includes(expr.name);
51412
+ return false;
51175
51413
  }
51176
51414
 
51177
51415
  // src/numbl-core/interpreter/interpreterFunctions.ts
@@ -51839,8 +52077,9 @@ function callUserFunction(fn, args, nargout, narginOverride) {
51839
52077
  }
51840
52078
  const hasVarargout = fn.outputs.length > 0 && fn.outputs[fn.outputs.length - 1] === "varargout";
51841
52079
  const regularOutputs = hasVarargout ? fn.outputs.slice(0, -1) : fn.outputs;
52080
+ const collectCount = nargout === 0 && regularOutputs.length > 0 ? 1 : Math.min(regularOutputs.length, nargout);
51842
52081
  const outputs = [];
51843
- for (let i = 0; i < Math.min(regularOutputs.length, nargout); i++) {
52082
+ for (let i = 0; i < collectCount; i++) {
51844
52083
  const val = this.env.get(regularOutputs[i]);
51845
52084
  if (val === void 0 && nargout >= i + 1) {
51846
52085
  throw new RuntimeError(
@@ -53410,10 +53649,17 @@ function executeCode(source, options = {}, workspaceFiles, mainFileName = "scrip
53410
53649
  if (options.log) {
53411
53650
  options.log("AST parsed, starting interpretation");
53412
53651
  }
53652
+ const isRepl = mainFileName === "repl";
53413
53653
  const localFunctions = [];
53414
53654
  const localClasses = [];
53415
53655
  for (const stmt of ast.body) {
53416
53656
  if (stmt.type === "Function") {
53657
+ if (isRepl) {
53658
+ throw new RuntimeError(
53659
+ "Function definitions are not supported in the REPL. Save the function to a .m file instead.",
53660
+ stmt.span
53661
+ );
53662
+ }
53417
53663
  localFunctions.push(stmt);
53418
53664
  } else if (stmt.type === "ClassDef") {
53419
53665
  localClasses.push(stmt);
@@ -53639,7 +53885,7 @@ ${jsCode}`
53639
53885
  output: rt.outputLines,
53640
53886
  generatedJS: jitSections.length > 0 ? `// Interpreter mode \u2014 JIT compiled sections:
53641
53887
 
53642
- ${jitSections.join("\n\n")}` : "// interpreted mode \u2014 no JS generated",
53888
+ ${jitSections.join("\n\n")}` : "// No JS generated",
53643
53889
  plotInstructions: rt.plotInstructions,
53644
53890
  returnValue: interpreter.ans ?? RTV.num(0),
53645
53891
  variableValues: interpreter.getVariableValues(),
@@ -53665,7 +53911,7 @@ ${jitSections.join("\n\n")}` : "// interpreted mode \u2014 no JS generated",
53665
53911
  } catch (e) {
53666
53912
  const generatedJS = jitSections.length > 0 ? `// Interpreter mode \u2014 JIT compiled sections:
53667
53913
 
53668
- ${jitSections.join("\n\n")}` : "// interpreted mode \u2014 no JS generated";
53914
+ ${jitSections.join("\n\n")}` : "// No JS generated";
53669
53915
  if (e instanceof RuntimeError) {
53670
53916
  if (e.line === null && rt.$file && rt.$line > 0) {
53671
53917
  e.file = rt.$file;