numbl 0.4.16 → 0.4.18

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
@@ -22398,7 +22398,7 @@ function sprintfFormat(fmt, args) {
22398
22398
  if (fmt[i] === "%" && i + 1 < fmt.length) {
22399
22399
  i++;
22400
22400
  let spec = "%";
22401
- while (i < fmt.length && !"dfigeEsoxXuc%".includes(fmt[i])) {
22401
+ while (i < fmt.length && !"dfigGeEsoxXuc%".includes(fmt[i])) {
22402
22402
  if (fmt[i] === "*") {
22403
22403
  if (argIdx >= flatArgs.length) {
22404
22404
  outOfArgs = true;
@@ -22488,7 +22488,7 @@ function sprintfFormat(fmt, args) {
22488
22488
  const gPrec = precMatch ? parseInt(precMatch[1]) : 6;
22489
22489
  let gStr;
22490
22490
  if (gVal === 0) {
22491
- gStr = "0";
22491
+ gStr = Object.is(gVal, -0) ? "-0" : "0";
22492
22492
  } else {
22493
22493
  const exp2 = Math.floor(Math.log10(Math.abs(gVal)));
22494
22494
  if (exp2 < -4 || exp2 >= gPrec) {
@@ -25147,6 +25147,7 @@ function indexIntoRTValue(base, indices) {
25147
25147
  if (isRuntimeLogical(idx)) return idx === true;
25148
25148
  if (isRuntimeTensor(idx))
25149
25149
  return idx.data.length === 1 && Math.round(idx.data[0]) === 1;
25150
+ if (isColonIndex(idx)) return true;
25150
25151
  return false;
25151
25152
  });
25152
25153
  if (allOnes) return base;
@@ -25158,6 +25159,9 @@ function indexIntoRTValue(base, indices) {
25158
25159
  if (isRuntimeStructArray(base)) {
25159
25160
  if (indices.length === 1) {
25160
25161
  const idx = indices[0];
25162
+ if (isColonIndex(idx)) {
25163
+ return RTV.structArray(base.fieldNames, [...base.elements]);
25164
+ }
25161
25165
  if (isRuntimeNumber(idx)) {
25162
25166
  const i = Math.round(idx) - 1;
25163
25167
  if (i < 0 || i >= base.elements.length)
@@ -30236,6 +30240,9 @@ var ExpressionParser = class extends ParserBase {
30236
30240
  if (this.peekToken() === 50 /* LParen */ && this.inMatrixExpr && this.pos > 0 && !this.tokensAdjacent(this.pos - 1, this.pos)) {
30237
30241
  break;
30238
30242
  }
30243
+ if (this.peekToken() === 54 /* LBrace */ && this.inMatrixExpr && this.pos > 0 && !this.tokensAdjacent(this.pos - 1, this.pos)) {
30244
+ break;
30245
+ }
30239
30246
  if (this.consume(50 /* LParen */)) {
30240
30247
  const start = expr.span.start;
30241
30248
  const args = [];
@@ -39990,6 +39997,46 @@ function uniquetolElements(v, nargout, tol) {
39990
39997
  if (nargout === 2) return [C, ia];
39991
39998
  return [C, ia, icTensor];
39992
39999
  }
40000
+ defineBuiltin({
40001
+ name: "ismembc2",
40002
+ cases: [
40003
+ {
40004
+ match: (argTypes) => {
40005
+ if (argTypes.length !== 2) return null;
40006
+ return [{ kind: "tensor", isComplex: false }];
40007
+ },
40008
+ apply: (args) => {
40009
+ const toFlat = (v) => {
40010
+ if (isRuntimeNumber(v)) return [v];
40011
+ if (isRuntimeLogical(v)) return [v ? 1 : 0];
40012
+ if (isRuntimeTensor(v)) return v.data;
40013
+ throw new RuntimeError("ismembc2: arguments must be numeric");
40014
+ };
40015
+ const a = toFlat(args[0]);
40016
+ const s = toFlat(args[1]);
40017
+ const out = allocFloat64Array(a.length);
40018
+ for (let i = 0; i < a.length; i++) {
40019
+ const x = a[i];
40020
+ let lo = 0;
40021
+ let hi = s.length - 1;
40022
+ let res = 0;
40023
+ while (lo <= hi) {
40024
+ const mid = lo + hi >> 1;
40025
+ if (s[mid] <= x) {
40026
+ if (s[mid] === x) res = mid + 1;
40027
+ lo = mid + 1;
40028
+ } else {
40029
+ hi = mid - 1;
40030
+ }
40031
+ }
40032
+ out[i] = res;
40033
+ }
40034
+ const shape = isRuntimeTensor(args[0]) ? [...args[0].shape] : [1, 1];
40035
+ return RTV.tensor(out, shape);
40036
+ }
40037
+ }
40038
+ ]
40039
+ });
39993
40040
 
39994
40041
  // src/numbl-core/interpreter/builtins/linear-algebra.ts
39995
40042
  function isNumericJitType(t) {
@@ -46168,6 +46215,45 @@ defineBuiltin({
46168
46215
  },
46169
46216
  apply: (args) => {
46170
46217
  const xArr = toFloatArray(args[0]);
46218
+ if (args.length === 4 && isRuntimeChar(args[2]) && isRuntimeChar(args[3]) && args[3].value.toLowerCase() === "pp") {
46219
+ const method2 = args[2].value.toLowerCase();
46220
+ if (method2 !== "linear")
46221
+ throw new RuntimeError(
46222
+ `interp1: 'pp' output is only supported for 'linear' method (got '${method2}')`
46223
+ );
46224
+ const yArr = toFloatArray(args[1]);
46225
+ const n = xArr.length;
46226
+ if (yArr.length !== n)
46227
+ throw new RuntimeError(
46228
+ "interp1: x and y must have the same length"
46229
+ );
46230
+ if (n < 2)
46231
+ throw new RuntimeError(
46232
+ "interp1: at least 2 sample points are required"
46233
+ );
46234
+ for (let i = 0; i + 1 < n; i++) {
46235
+ if (!(xArr[i] < xArr[i + 1]))
46236
+ throw new RuntimeError(
46237
+ "interp1: sample points must be unique and sorted for 'pp' output"
46238
+ );
46239
+ }
46240
+ const L = n - 1;
46241
+ const breaksOut = allocFloat64Array(n);
46242
+ for (let i = 0; i < n; i++) breaksOut[i] = xArr[i];
46243
+ const coefs = allocFloat64Array(L * 2);
46244
+ for (let i = 0; i < L; i++) {
46245
+ coefs[i] = (yArr[i + 1] - yArr[i]) / (xArr[i + 1] - xArr[i]);
46246
+ coefs[L + i] = yArr[i];
46247
+ }
46248
+ const fields = /* @__PURE__ */ new Map();
46249
+ fields.set("form", "pp");
46250
+ fields.set("breaks", RTV.tensor(breaksOut, [1, n]));
46251
+ fields.set("coefs", RTV.tensor(coefs, [L, 2]));
46252
+ fields.set("pieces", L);
46253
+ fields.set("order", 2);
46254
+ fields.set("dim", 1);
46255
+ return RTV.struct(fields);
46256
+ }
46171
46257
  const xqArg = args[2];
46172
46258
  const nn = xArr.length;
46173
46259
  const yVal = args[1];
@@ -46196,6 +46282,7 @@ defineBuiltin({
46196
46282
  throw new RuntimeError("interp1: x and y must have the same length");
46197
46283
  let method = "linear";
46198
46284
  let doExtrap = false;
46285
+ let fillValue = NaN;
46199
46286
  for (let i = 3; i < args.length; i++) {
46200
46287
  const a = args[i];
46201
46288
  if (isRuntimeChar(a)) {
@@ -46206,11 +46293,13 @@ defineBuiltin({
46206
46293
  const s = a.toLowerCase();
46207
46294
  if (s === "extrap") doExtrap = true;
46208
46295
  else method = s;
46296
+ } else if (isRuntimeNumber(a) || isRuntimeTensor(a)) {
46297
+ fillValue = toNumber(a);
46209
46298
  }
46210
46299
  }
46211
46300
  const interpOne = (yArr, xq) => {
46212
46301
  if (xq < xArr[0] || xq > xArr[nn - 1]) {
46213
- if (!doExtrap) return NaN;
46302
+ if (!doExtrap) return fillValue;
46214
46303
  if (method === "linear") {
46215
46304
  if (xq < xArr[0]) {
46216
46305
  const slope = (yArr[1] - yArr[0]) / (xArr[1] - xArr[0]);
@@ -46641,6 +46730,63 @@ function dimArgToVec(v) {
46641
46730
  }
46642
46731
  throw new RuntimeError("mkpp: dim must be a numeric scalar or vector");
46643
46732
  }
46733
+ var ppIntApply = (fname) => (args) => {
46734
+ const pp = args[0];
46735
+ if (!isRuntimeStruct(pp))
46736
+ throw new RuntimeError(`${fname}: argument must be a pp struct`);
46737
+ const breaksRT = pp.fields.get("breaks");
46738
+ const coefsRT = pp.fields.get("coefs");
46739
+ const piecesRT = pp.fields.get("pieces");
46740
+ const orderRT = pp.fields.get("order");
46741
+ const dimRT = pp.fields.get("dim");
46742
+ if (breaksRT === void 0 || coefsRT === void 0 || piecesRT === void 0 || orderRT === void 0)
46743
+ throw new RuntimeError(`${fname}: pp struct missing required fields`);
46744
+ const breaks = toFloatArray(breaksRT);
46745
+ const L = Math.round(toNumber(piecesRT));
46746
+ const k = Math.round(toNumber(orderRT));
46747
+ const dim = dimRT === void 0 ? [1] : dimArgToVec(dimRT);
46748
+ if (dim.reduce((a, b) => a * b, 1) !== 1)
46749
+ throw new RuntimeError(`${fname}: only scalar-valued pp is supported`);
46750
+ if (!isRuntimeTensor(coefsRT))
46751
+ throw new RuntimeError(`${fname}: pp.coefs must be a matrix`);
46752
+ const coefs = coefsRT.data;
46753
+ const out = allocFloat64Array(L * (k + 1));
46754
+ for (let c = 0; c < k; c++) {
46755
+ for (let i = 0; i < L; i++) out[c * L + i] = coefs[c * L + i] / (k - c);
46756
+ }
46757
+ let A = 0;
46758
+ for (let i = 0; i < L; i++) {
46759
+ out[k * L + i] = A;
46760
+ const h = breaks[i + 1] - breaks[i];
46761
+ let v = out[0 * L + i];
46762
+ for (let c = 1; c <= k; c++) v = v * h + out[c * L + i];
46763
+ A = v;
46764
+ }
46765
+ const fields = /* @__PURE__ */ new Map();
46766
+ fields.set("form", "pp");
46767
+ const breaksOut = allocFloat64Array(breaks.length);
46768
+ for (let i = 0; i < breaks.length; i++) breaksOut[i] = breaks[i];
46769
+ fields.set("breaks", RTV.tensor(breaksOut, [1, breaks.length]));
46770
+ fields.set("coefs", RTV.tensor(out, [L, k + 1]));
46771
+ fields.set("pieces", L);
46772
+ fields.set("order", k + 1);
46773
+ fields.set("dim", 1);
46774
+ return RTV.struct(fields);
46775
+ };
46776
+ for (const fname of ["fnint", "ppint"]) {
46777
+ defineBuiltin({
46778
+ name: fname,
46779
+ cases: [
46780
+ {
46781
+ match: (argTypes) => {
46782
+ if (argTypes.length !== 1) return null;
46783
+ return [{ kind: "struct", fields: {} }];
46784
+ },
46785
+ apply: ppIntApply(fname)
46786
+ }
46787
+ ]
46788
+ });
46789
+ }
46644
46790
  defineBuiltin({
46645
46791
  name: "mkpp",
46646
46792
  cases: [
@@ -47382,6 +47528,8 @@ defineBuiltin({
47382
47528
  {
47383
47529
  match: (argTypes) => {
47384
47530
  if (argTypes.length === 0) return [{ kind: "struct", fields: {} }];
47531
+ if (argTypes.length === 1 && argTypes[0].kind === "tensor")
47532
+ return [{ kind: "struct", fields: {} }];
47385
47533
  if (argTypes.length % 2 !== 0) return null;
47386
47534
  for (let i = 0; i < argTypes.length; i += 2) {
47387
47535
  const k = argTypes[i].kind;
@@ -47391,6 +47539,13 @@ defineBuiltin({
47391
47539
  },
47392
47540
  apply: (args) => {
47393
47541
  if (args.length === 0) return RTV.struct(/* @__PURE__ */ new Map());
47542
+ if (args.length === 1 && isRuntimeTensor(args[0])) {
47543
+ if (args[0].data.length !== 0)
47544
+ throw new RuntimeError(
47545
+ "struct: single non-empty numeric argument is not supported"
47546
+ );
47547
+ return RTV.structArray([], []);
47548
+ }
47394
47549
  if (args.length % 2 !== 0)
47395
47550
  throw new RuntimeError("struct: requires field-value pairs");
47396
47551
  const fieldNames = [];
@@ -48183,13 +48338,48 @@ registerIBuiltin({
48183
48338
  resolve: (argTypes) => {
48184
48339
  if (argTypes.length !== 1) return null;
48185
48340
  return {
48186
- outputTypes: [{ kind: "tensor", isComplex: false }],
48341
+ outputTypes: [{ kind: "unknown" }],
48187
48342
  apply: (args) => {
48188
48343
  const C = args[0];
48189
48344
  if (!isRuntimeCell(C))
48190
48345
  throw new RuntimeError("cell2mat: argument must be a cell array");
48191
48346
  const cellRows = C.shape[0];
48192
48347
  const cellCols = C.shape.length >= 2 ? C.shape[1] : 1;
48348
+ if (C.data.length > 0 && C.data.some((v) => isRuntimeChar(v))) {
48349
+ const asCharBlock = (v) => {
48350
+ if (!isRuntimeChar(v))
48351
+ throw new RuntimeError(
48352
+ "cell2mat: cannot mix char and non-char cell contents"
48353
+ );
48354
+ const rows = v.shape ? v.shape[0] : v.value.length === 0 ? 0 : 1;
48355
+ const cols = v.shape ? v.shape[1] : v.value.length;
48356
+ const rowStrings = [];
48357
+ for (let r = 0; r < rows; r++)
48358
+ rowStrings.push(v.value.slice(r * cols, (r + 1) * cols));
48359
+ return { rows, cols, rowStrings };
48360
+ };
48361
+ const outRows = [];
48362
+ for (let ci = 0; ci < cellRows; ci++) {
48363
+ const blockHeight = asCharBlock(C.data[ci]).rows;
48364
+ const lines = new Array(blockHeight).fill("");
48365
+ for (let cj = 0; cj < cellCols; cj++) {
48366
+ const b = asCharBlock(C.data[cj * cellRows + ci]);
48367
+ if (b.rows !== blockHeight)
48368
+ throw new RuntimeError(
48369
+ "cell2mat: inconsistent cell content sizes"
48370
+ );
48371
+ for (let r = 0; r < blockHeight; r++) lines[r] += b.rowStrings[r];
48372
+ }
48373
+ outRows.push(...lines);
48374
+ }
48375
+ const width = outRows.length > 0 ? outRows[0].length : 0;
48376
+ if (outRows.some((r) => r.length !== width))
48377
+ throw new RuntimeError("cell2mat: inconsistent cell content sizes");
48378
+ if (outRows.length <= 1) return RTV.char(outRows[0] ?? "");
48379
+ const rc = RTV.char(outRows.join(""));
48380
+ rc.shape = [outRows.length, width];
48381
+ return rc;
48382
+ }
48193
48383
  const asTensor = (v) => {
48194
48384
  if (isRuntimeNumber(v))
48195
48385
  return {
@@ -52060,14 +52250,20 @@ function dictRemove(d, keysArg) {
52060
52250
  }
52061
52251
  return RTV.dictionary(entries, d.keyType, d.valueType);
52062
52252
  }
52063
- function dictLookup(d, keysArg) {
52253
+ function dictLookup(d, keysArg, fallbackValue) {
52064
52254
  const keys = expandKeys(keysArg);
52065
52255
  const results = [];
52066
52256
  for (const k of keys) {
52067
52257
  const coerced = d.keyType ? coerceKey(k, d.keyType) : k;
52068
52258
  const h = hashKey(coerced);
52069
52259
  const entry = d.entries.get(h);
52070
- if (!entry) throw new RuntimeError("Key not found in dictionary");
52260
+ if (!entry) {
52261
+ if (fallbackValue !== void 0) {
52262
+ results.push(fallbackValue);
52263
+ continue;
52264
+ }
52265
+ throw new RuntimeError("Key not found in dictionary");
52266
+ }
52071
52267
  results.push(entry.value);
52072
52268
  }
52073
52269
  if (results.length === 1) return results[0];
@@ -52302,11 +52498,21 @@ registerIBuiltin({
52302
52498
  registerIBuiltin({
52303
52499
  name: "lookup",
52304
52500
  resolve: (argTypes) => {
52305
- if (argTypes.length !== 2 || argTypes[0].kind !== "dictionary") return null;
52501
+ if (argTypes.length !== 2 && argTypes.length !== 4 || argTypes[0].kind !== "dictionary")
52502
+ return null;
52306
52503
  return {
52307
52504
  outputTypes: [{ kind: "unknown" }],
52308
52505
  apply: (args) => {
52309
52506
  const d = args[0];
52507
+ if (args.length === 4) {
52508
+ const optName = isRuntimeChar(args[2]) ? args[2].value : isRuntimeString(args[2]) ? args[2] : "";
52509
+ if (String(optName).toLowerCase() !== "fallbackvalue") {
52510
+ throw new RuntimeError(
52511
+ `Unrecognized option '${String(optName)}' for lookup`
52512
+ );
52513
+ }
52514
+ return dictLookup(d, args[1], args[3]);
52515
+ }
52310
52516
  return dictLookup(d, args[1]);
52311
52517
  }
52312
52518
  };
@@ -52326,6 +52532,288 @@ registerIBuiltin({
52326
52532
  }
52327
52533
  });
52328
52534
 
52535
+ // src/numbl-core/interpreter/builtins/hash.ts
52536
+ function valueToByteString(v) {
52537
+ if (isRuntimeChar(v)) return v.value;
52538
+ if (isRuntimeString(v)) return String(v);
52539
+ throw new RuntimeError("hash: STR must be a char array or string");
52540
+ }
52541
+ function md5Hex(input) {
52542
+ const bytes = [];
52543
+ for (let i = 0; i < input.length; i++) bytes.push(input.charCodeAt(i) & 255);
52544
+ const origLenBits = bytes.length * 8;
52545
+ bytes.push(128);
52546
+ while (bytes.length % 64 !== 56) bytes.push(0);
52547
+ let len = origLenBits;
52548
+ for (let i = 0; i < 8; i++) {
52549
+ bytes.push(len & 255);
52550
+ len = Math.floor(len / 256);
52551
+ }
52552
+ const S = [
52553
+ 7,
52554
+ 12,
52555
+ 17,
52556
+ 22,
52557
+ 7,
52558
+ 12,
52559
+ 17,
52560
+ 22,
52561
+ 7,
52562
+ 12,
52563
+ 17,
52564
+ 22,
52565
+ 7,
52566
+ 12,
52567
+ 17,
52568
+ 22,
52569
+ 5,
52570
+ 9,
52571
+ 14,
52572
+ 20,
52573
+ 5,
52574
+ 9,
52575
+ 14,
52576
+ 20,
52577
+ 5,
52578
+ 9,
52579
+ 14,
52580
+ 20,
52581
+ 5,
52582
+ 9,
52583
+ 14,
52584
+ 20,
52585
+ 4,
52586
+ 11,
52587
+ 16,
52588
+ 23,
52589
+ 4,
52590
+ 11,
52591
+ 16,
52592
+ 23,
52593
+ 4,
52594
+ 11,
52595
+ 16,
52596
+ 23,
52597
+ 4,
52598
+ 11,
52599
+ 16,
52600
+ 23,
52601
+ 6,
52602
+ 10,
52603
+ 15,
52604
+ 21,
52605
+ 6,
52606
+ 10,
52607
+ 15,
52608
+ 21,
52609
+ 6,
52610
+ 10,
52611
+ 15,
52612
+ 21,
52613
+ 6,
52614
+ 10,
52615
+ 15,
52616
+ 21
52617
+ ];
52618
+ const K = new Array(64);
52619
+ for (let i = 0; i < 64; i++)
52620
+ K[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 4294967296) >>> 0;
52621
+ let a0 = 1732584193;
52622
+ let b0 = 4023233417;
52623
+ let c0 = 2562383102;
52624
+ let d0 = 271733878;
52625
+ const rotl2 = (x, c) => (x << c | x >>> 32 - c) >>> 0;
52626
+ for (let chunk = 0; chunk < bytes.length; chunk += 64) {
52627
+ const M = new Array(16);
52628
+ for (let j = 0; j < 16; j++) {
52629
+ const o = chunk + j * 4;
52630
+ M[j] = (bytes[o] | bytes[o + 1] << 8 | bytes[o + 2] << 16 | bytes[o + 3] << 24) >>> 0;
52631
+ }
52632
+ let A = a0;
52633
+ let B = b0;
52634
+ let C = c0;
52635
+ let D = d0;
52636
+ for (let i = 0; i < 64; i++) {
52637
+ let F;
52638
+ let g;
52639
+ if (i < 16) {
52640
+ F = B & C | ~B & D;
52641
+ g = i;
52642
+ } else if (i < 32) {
52643
+ F = D & B | ~D & C;
52644
+ g = (5 * i + 1) % 16;
52645
+ } else if (i < 48) {
52646
+ F = B ^ C ^ D;
52647
+ g = (3 * i + 5) % 16;
52648
+ } else {
52649
+ F = C ^ (B | ~D);
52650
+ g = 7 * i % 16;
52651
+ }
52652
+ F = F + A + K[i] + M[g] >>> 0;
52653
+ A = D;
52654
+ D = C;
52655
+ C = B;
52656
+ B = B + rotl2(F, S[i]) >>> 0;
52657
+ }
52658
+ a0 = a0 + A >>> 0;
52659
+ b0 = b0 + B >>> 0;
52660
+ c0 = c0 + C >>> 0;
52661
+ d0 = d0 + D >>> 0;
52662
+ }
52663
+ const le2 = (w) => {
52664
+ let s = "";
52665
+ for (let i = 0; i < 4; i++)
52666
+ s += (w >>> i * 8 & 255).toString(16).padStart(2, "0");
52667
+ return s;
52668
+ };
52669
+ return le2(a0) + le2(b0) + le2(c0) + le2(d0);
52670
+ }
52671
+ function sha256Hex(input) {
52672
+ const bytes = [];
52673
+ for (let i = 0; i < input.length; i++) bytes.push(input.charCodeAt(i) & 255);
52674
+ const origLenBits = bytes.length * 8;
52675
+ bytes.push(128);
52676
+ while (bytes.length % 64 !== 56) bytes.push(0);
52677
+ const hi = Math.floor(origLenBits / 4294967296);
52678
+ const lo = origLenBits >>> 0;
52679
+ for (let i = 3; i >= 0; i--) bytes.push(hi >>> i * 8 & 255);
52680
+ for (let i = 3; i >= 0; i--) bytes.push(lo >>> i * 8 & 255);
52681
+ const K = [
52682
+ 1116352408,
52683
+ 1899447441,
52684
+ 3049323471,
52685
+ 3921009573,
52686
+ 961987163,
52687
+ 1508970993,
52688
+ 2453635748,
52689
+ 2870763221,
52690
+ 3624381080,
52691
+ 310598401,
52692
+ 607225278,
52693
+ 1426881987,
52694
+ 1925078388,
52695
+ 2162078206,
52696
+ 2614888103,
52697
+ 3248222580,
52698
+ 3835390401,
52699
+ 4022224774,
52700
+ 264347078,
52701
+ 604807628,
52702
+ 770255983,
52703
+ 1249150122,
52704
+ 1555081692,
52705
+ 1996064986,
52706
+ 2554220882,
52707
+ 2821834349,
52708
+ 2952996808,
52709
+ 3210313671,
52710
+ 3336571891,
52711
+ 3584528711,
52712
+ 113926993,
52713
+ 338241895,
52714
+ 666307205,
52715
+ 773529912,
52716
+ 1294757372,
52717
+ 1396182291,
52718
+ 1695183700,
52719
+ 1986661051,
52720
+ 2177026350,
52721
+ 2456956037,
52722
+ 2730485921,
52723
+ 2820302411,
52724
+ 3259730800,
52725
+ 3345764771,
52726
+ 3516065817,
52727
+ 3600352804,
52728
+ 4094571909,
52729
+ 275423344,
52730
+ 430227734,
52731
+ 506948616,
52732
+ 659060556,
52733
+ 883997877,
52734
+ 958139571,
52735
+ 1322822218,
52736
+ 1537002063,
52737
+ 1747873779,
52738
+ 1955562222,
52739
+ 2024104815,
52740
+ 2227730452,
52741
+ 2361852424,
52742
+ 2428436474,
52743
+ 2756734187,
52744
+ 3204031479,
52745
+ 3329325298
52746
+ ];
52747
+ const H2 = [
52748
+ 1779033703,
52749
+ 3144134277,
52750
+ 1013904242,
52751
+ 2773480762,
52752
+ 1359893119,
52753
+ 2600822924,
52754
+ 528734635,
52755
+ 1541459225
52756
+ ];
52757
+ const rotr = (x, c) => (x >>> c | x << 32 - c) >>> 0;
52758
+ for (let chunk = 0; chunk < bytes.length; chunk += 64) {
52759
+ const W = new Array(64);
52760
+ for (let j = 0; j < 16; j++) {
52761
+ const o = chunk + j * 4;
52762
+ W[j] = (bytes[o] << 24 | bytes[o + 1] << 16 | bytes[o + 2] << 8 | bytes[o + 3]) >>> 0;
52763
+ }
52764
+ for (let j = 16; j < 64; j++) {
52765
+ const s0 = rotr(W[j - 15], 7) ^ rotr(W[j - 15], 18) ^ W[j - 15] >>> 3;
52766
+ const s1 = rotr(W[j - 2], 17) ^ rotr(W[j - 2], 19) ^ W[j - 2] >>> 10;
52767
+ W[j] = W[j - 16] + s0 + W[j - 7] + s1 >>> 0;
52768
+ }
52769
+ let [a, b, c, d, e, f, g, h] = H2;
52770
+ for (let j = 0; j < 64; j++) {
52771
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
52772
+ const ch = e & f ^ ~e & g;
52773
+ const t1 = h + S1 + ch + K[j] + W[j] >>> 0;
52774
+ const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
52775
+ const maj = a & b ^ a & c ^ b & c;
52776
+ const t2 = S0 + maj >>> 0;
52777
+ h = g;
52778
+ g = f;
52779
+ f = e;
52780
+ e = d + t1 >>> 0;
52781
+ d = c;
52782
+ c = b;
52783
+ b = a;
52784
+ a = t1 + t2 >>> 0;
52785
+ }
52786
+ H2[0] = H2[0] + a >>> 0;
52787
+ H2[1] = H2[1] + b >>> 0;
52788
+ H2[2] = H2[2] + c >>> 0;
52789
+ H2[3] = H2[3] + d >>> 0;
52790
+ H2[4] = H2[4] + e >>> 0;
52791
+ H2[5] = H2[5] + f >>> 0;
52792
+ H2[6] = H2[6] + g >>> 0;
52793
+ H2[7] = H2[7] + h >>> 0;
52794
+ }
52795
+ return H2.map((w) => (w >>> 0).toString(16).padStart(8, "0")).join("");
52796
+ }
52797
+ registerIBuiltin({
52798
+ name: "hash",
52799
+ resolve: (argTypes) => {
52800
+ if (argTypes.length !== 2) return null;
52801
+ return {
52802
+ outputTypes: [{ kind: "char" }],
52803
+ apply: (args) => {
52804
+ const algoRaw = valueToByteString(args[0]);
52805
+ const algo = algoRaw.toUpperCase().replace(/-/g, "");
52806
+ const msg = valueToByteString(args[1]);
52807
+ if (algo === "MD5") return RTV.char(md5Hex(msg));
52808
+ if (algo === "SHA256") return RTV.char(sha256Hex(msg));
52809
+ throw new RuntimeError(
52810
+ `hash: unsupported hash function '${algoRaw}' (supported: MD5, SHA256)`
52811
+ );
52812
+ }
52813
+ };
52814
+ }
52815
+ });
52816
+
52329
52817
  // src/numbl-core/interpreter/builtins/help-text.ts
52330
52818
  var H = {
52331
52819
  // ── Math ──────────────────────────────────────────────────────────────
@@ -56384,33 +56872,66 @@ function registerSpecialBuiltins(rt) {
56384
56872
  };
56385
56873
  }
56386
56874
  });
56875
+ const warningStateOff = /* @__PURE__ */ new Set();
56387
56876
  registerSpecial("warning", (nargout, args) => {
56388
56877
  if (args.length === 0) return nargout >= 1 ? RTV.num(0) : void 0;
56389
56878
  const margs = args.map((a) => ensureRuntimeValue(a));
56879
+ const isOff = (id) => warningStateOff.has(id) || warningStateOff.has("all");
56880
+ const stateStruct = (id) => RTV.struct(
56881
+ /* @__PURE__ */ new Map([
56882
+ ["identifier", RTV.char(id)],
56883
+ ["state", RTV.char(isOff(id) ? "off" : "on")]
56884
+ ])
56885
+ );
56886
+ const setState = (mode, id) => {
56887
+ if (mode === "off") warningStateOff.add(id);
56888
+ else {
56889
+ warningStateOff.delete(id);
56890
+ if (id === "all") warningStateOff.clear();
56891
+ }
56892
+ };
56893
+ const restoreFrom = (s) => {
56894
+ if (!isRuntimeStruct(s)) return false;
56895
+ const idField = s.fields.get("identifier");
56896
+ const stField = s.fields.get("state");
56897
+ if (idField === void 0 || stField === void 0) return false;
56898
+ setState(toString(stField), toString(idField));
56899
+ return true;
56900
+ };
56901
+ if (margs.length === 1 && isRuntimeStruct(margs[0])) {
56902
+ if (restoreFrom(margs[0])) return nargout >= 1 ? RTV.num(0) : void 0;
56903
+ }
56904
+ if (margs.length === 1 && isRuntimeStructArray(margs[0])) {
56905
+ for (const el of margs[0].elements) restoreFrom(el);
56906
+ return nargout >= 1 ? RTV.num(0) : void 0;
56907
+ }
56908
+ if (margs.length === 1 && isRuntimeChar(margs[0])) {
56909
+ const mode = toString(margs[0]);
56910
+ if (mode === "on" || mode === "off") {
56911
+ const prev = stateStruct("all");
56912
+ setState(mode, "all");
56913
+ return nargout >= 1 ? prev : void 0;
56914
+ }
56915
+ }
56390
56916
  if (margs.length === 2 && isRuntimeChar(margs[0]) && isRuntimeChar(margs[1])) {
56391
56917
  const mode = toString(margs[0]);
56918
+ const id = toString(margs[1]);
56392
56919
  if (mode === "on" || mode === "off") {
56393
- if (nargout === 0) return void 0;
56394
- return RTV.struct(
56395
- /* @__PURE__ */ new Map([
56396
- ["state", RTV.char("on")],
56397
- ["identifier", margs[1]]
56398
- ])
56399
- );
56920
+ const prev = stateStruct(id);
56921
+ setState(mode, id);
56922
+ return nargout >= 1 ? prev : void 0;
56400
56923
  }
56401
56924
  if (mode === "query") {
56402
- return RTV.struct(
56403
- /* @__PURE__ */ new Map([
56404
- ["state", RTV.char("on")],
56405
- ["identifier", margs[1]]
56406
- ])
56407
- );
56925
+ return stateStruct(id);
56408
56926
  }
56409
56927
  }
56410
56928
  let fmtIdx = 0;
56411
56929
  if (margs.length >= 2 && isRuntimeChar(margs[0]) && toString(margs[0]).includes(":")) {
56412
56930
  fmtIdx = 1;
56413
56931
  }
56932
+ if (isOff(fmtIdx === 1 ? toString(margs[0]) : "all")) {
56933
+ return nargout >= 1 ? RTV.num(0) : void 0;
56934
+ }
56414
56935
  const fmt = toString(margs[fmtIdx]);
56415
56936
  const fmtArgs = [];
56416
56937
  for (let i = fmtIdx + 1; i < margs.length; i++) {
@@ -60554,7 +61075,7 @@ function multiOutputCellAssign(base, indices, results, rt) {
60554
61075
  }
60555
61076
 
60556
61077
  // src/numbl-core/runtime/runtimeMemberAccess.ts
60557
- function getMember(rt, base, name) {
61078
+ function getMember(rt, base, name, nargout = 1) {
60558
61079
  const mv = ensureRuntimeValue(base);
60559
61080
  if (isRuntimeClassInstance(mv)) {
60560
61081
  const accessorKey = `${mv.className}.get.${name}`;
@@ -60573,7 +61094,7 @@ function getMember(rt, base, name) {
60573
61094
  if (field !== void 0) return field;
60574
61095
  const method = rt.cachedResolveClassMethod(mv.className, name);
60575
61096
  if (method) {
60576
- return method(1, base);
61097
+ return method(nargout, base);
60577
61098
  }
60578
61099
  const guardKey = `${mv.className}.subsref`;
60579
61100
  if (!rt.activeAccessors.has(guardKey)) {
@@ -63277,8 +63798,8 @@ var Runtime = class _Runtime {
63277
63798
  return multiOutputCellAssign(base, indices, results, this);
63278
63799
  }
63279
63800
  // ── Member access ───────────────────────────────────────────────────
63280
- getMember(base, name) {
63281
- return getMember(this, base, name);
63801
+ getMember(base, name, nargout = 1) {
63802
+ return getMember(this, base, name, nargout);
63282
63803
  }
63283
63804
  getMemberDynamic(base, nameExpr) {
63284
63805
  return getMemberDynamic(this, base, nameExpr);
@@ -66106,7 +66627,7 @@ function evalMember(expr, nargout) {
66106
66627
  (el) => ensureRuntimeValue(this.rt.getMember(el, expr.name))
66107
66628
  );
66108
66629
  }
66109
- return this.rt.getMember(base, expr.name);
66630
+ return this.rt.getMember(base, expr.name, nargout);
66110
66631
  }
66111
66632
  function tryExtractDottedName(expr) {
66112
66633
  if (expr.type === "Ident") return expr.name;
@@ -66117,7 +66638,14 @@ function tryExtractDottedName(expr) {
66117
66638
  return null;
66118
66639
  }
66119
66640
  function evalIndex(expr) {
66120
- const base = this.evalExpr(expr.base);
66641
+ let base = this.evalExpr(expr.base);
66642
+ if (Array.isArray(base)) {
66643
+ if (base.length === 1) base = base[0];
66644
+ else
66645
+ throw new RuntimeError(
66646
+ `Expression produced ${base.length} values where one was expected`
66647
+ );
66648
+ }
66121
66649
  const indices = this.evalIndicesWithEnd(base, expr.indices);
66122
66650
  let skipSubsref = false;
66123
66651
  if (this.currentClassName) {
@@ -66503,7 +67031,12 @@ function evalLValueBase(base, defaultVal) {
66503
67031
  }
66504
67032
  const indices = this.evalIndicesWithEnd(baseVal, base.indices);
66505
67033
  try {
66506
- return this.rt.indexCell(baseVal, indices);
67034
+ const result = this.rt.indexCell(baseVal, indices);
67035
+ if (Array.isArray(result)) {
67036
+ if (result.length === 1) return result[0];
67037
+ if (result.length === 0) return defaultVal;
67038
+ }
67039
+ return result;
66507
67040
  } catch {
66508
67041
  return defaultVal;
66509
67042
  }
@@ -69202,7 +69735,11 @@ var stdlibFiles = [
69202
69735
  },
69203
69736
  {
69204
69737
  name: "inputParser.m",
69205
- source: "classdef inputParser < handle\n properties\n CaseSensitive = false\n FunctionName = ''\n KeepUnmatched = false\n PartialMatching = true\n StructExpand = true\n Results = struct()\n Unmatched = struct()\n UsingDefaults = {}\n Parameters = {}\n end\n properties\n required_ = {}\n optional_ = {}\n params_ = {}\n end\n methods\n function addRequired(obj, name, validator)\n if nargin < 3\n validator = [];\n end\n entry = struct('name', name, 'default', {[]}, 'validator', {{}});\n if ~isempty(validator)\n entry.validator = validator;\n end\n obj.required_{end+1} = entry;\n obj.Parameters{end+1} = name;\n end\n\n function addOptional(obj, name, default, validator)\n if nargin < 4\n validator = [];\n end\n entry = struct('name', name, 'default', {default}, 'validator', {{}});\n if ~isempty(validator)\n entry.validator = validator;\n end\n obj.optional_{end+1} = entry;\n obj.Parameters{end+1} = name;\n end\n\n function addParameter(obj, name, default, validator)\n if nargin < 4\n validator = [];\n end\n entry = struct('name', name, 'default', {default}, 'validator', {{}});\n if ~isempty(validator)\n entry.validator = validator;\n end\n obj.params_{end+1} = entry;\n obj.Parameters{end+1} = name;\n end\n\n function addParamValue(obj, name, default, validator)\n addParameter(obj, name, default, validator);\n end\n\n function parse(obj, varargin)\n s = struct();\n usingDefaults = {};\n pos = 1;\n nargs = numel(varargin);\n\n % Parse required arguments\n for i = 1:numel(obj.required_)\n entry = obj.required_{i};\n if pos > nargs\n error('Not enough input arguments. Missing required argument ''%s''.', entry.name);\n end\n val = varargin{pos};\n pos = pos + 1;\n s.(entry.name) = val;\n end\n\n % Parse optional positional arguments\n % An optional arg is consumed only if it is NOT a string matching a parameter name\n for i = 1:numel(obj.optional_)\n entry = obj.optional_{i};\n if pos <= nargs\n nextVal = varargin{pos};\n isParamName = false;\n if ischar(nextVal) || isstring(nextVal)\n paramName = char(nextVal);\n for k = 1:numel(obj.params_)\n pentry = obj.params_{k};\n if inputParser.namesMatch(paramName, pentry.name, obj.CaseSensitive)\n isParamName = true;\n break;\n end\n end\n end\n if ~isParamName\n s.(entry.name) = nextVal;\n pos = pos + 1;\n else\n s.(entry.name) = entry.default;\n usingDefaults{end+1} = entry.name;\n end\n else\n s.(entry.name) = entry.default;\n usingDefaults{end+1} = entry.name;\n end\n end\n\n % Set defaults for all parameters\n for i = 1:numel(obj.params_)\n entry = obj.params_{i};\n s.(entry.name) = entry.default;\n usingDefaults{end+1} = entry.name;\n end\n\n % Parse name-value pairs from remaining arguments\n unmatched = struct();\n while pos <= nargs\n if pos + 1 > nargs\n error('Expected name-value pair argument.');\n end\n name = varargin{pos};\n val = varargin{pos + 1};\n pos = pos + 2;\n\n if ~ischar(name) && ~isstring(name)\n error('Expected parameter name to be a string.');\n end\n name = char(name);\n\n found = false;\n for i = 1:numel(obj.params_)\n entry = obj.params_{i};\n if inputParser.namesMatch(name, entry.name, obj.CaseSensitive)\n s.(entry.name) = val;\n % Remove from usingDefaults\n newDefaults = {};\n for j = 1:numel(usingDefaults)\n if ~strcmp(usingDefaults{j}, entry.name)\n newDefaults{end+1} = usingDefaults{j};\n end\n end\n usingDefaults = newDefaults;\n found = true;\n break;\n end\n end\n if ~found\n if obj.KeepUnmatched\n unmatched.(name) = val;\n else\n error('''%s'' is not a recognized parameter.', name);\n end\n end\n end\n\n obj.Results = s;\n obj.UsingDefaults = usingDefaults;\n obj.Unmatched = unmatched;\n end\n end\n\n methods (Static)\n function tf = namesMatch(input, expected, caseSensitive)\n if caseSensitive\n tf = strcmp(input, expected);\n else\n tf = strcmpi(input, expected);\n end\n end\n end\nend\n"
69738
+ source: "classdef inputParser < handle\n properties\n CaseSensitive = false\n FunctionName = ''\n KeepUnmatched = false\n PartialMatching = true\n StructExpand = true\n Results = struct()\n Unmatched = struct()\n UsingDefaults = {}\n Parameters = {}\n end\n properties\n required_ = {}\n optional_ = {}\n params_ = {}\n end\n methods\n function addRequired(obj, name, validator)\n if nargin < 3\n validator = [];\n end\n entry = struct('name', name, 'default', {[]}, 'validator', {{}});\n if ~isempty(validator)\n entry.validator = validator;\n end\n obj.required_{end+1} = entry;\n obj.Parameters{end+1} = name;\n end\n\n function addOptional(obj, name, default, validator)\n if nargin < 4\n validator = [];\n end\n entry = struct('name', name, 'default', {default}, 'validator', {{}});\n if ~isempty(validator)\n entry.validator = validator;\n end\n obj.optional_{end+1} = entry;\n obj.Parameters{end+1} = name;\n end\n\n function addParameter(obj, name, default, validator)\n if nargin < 4\n validator = [];\n end\n entry = struct('name', name, 'default', {default}, 'validator', {{}});\n if ~isempty(validator)\n entry.validator = validator;\n end\n obj.params_{end+1} = entry;\n obj.Parameters{end+1} = name;\n end\n\n function addParamValue(obj, name, default, validator)\n if nargin < 4\n addParameter(obj, name, default);\n else\n addParameter(obj, name, default, validator);\n end\n end\n\n function parse(obj, varargin)\n s = struct();\n usingDefaults = {};\n pos = 1;\n nargs = numel(varargin);\n\n % Parse required arguments\n for i = 1:numel(obj.required_)\n entry = obj.required_{i};\n if pos > nargs\n error('Not enough input arguments. Missing required argument ''%s''.', entry.name);\n end\n val = varargin{pos};\n pos = pos + 1;\n s.(entry.name) = val;\n end\n\n % Parse optional positional arguments\n % An optional arg is consumed only if it is NOT a string matching a\n % parameter or optional name (MATLAB also accepts optionals as\n % name-value pairs, so their names terminate positional parsing)\n for i = 1:numel(obj.optional_)\n entry = obj.optional_{i};\n if pos <= nargs\n nextVal = varargin{pos};\n isParamName = false;\n if ischar(nextVal) || isstring(nextVal)\n paramName = char(nextVal);\n for k = 1:numel(obj.params_)\n pentry = obj.params_{k};\n if inputParser.namesMatch(paramName, pentry.name, obj.CaseSensitive)\n isParamName = true;\n break;\n end\n end\n if ~isParamName\n for k = 1:numel(obj.optional_)\n oentry = obj.optional_{k};\n if inputParser.namesMatch(paramName, oentry.name, obj.CaseSensitive)\n isParamName = true;\n break;\n end\n end\n end\n end\n if ~isParamName\n s.(entry.name) = nextVal;\n pos = pos + 1;\n else\n s.(entry.name) = entry.default;\n usingDefaults{end+1} = entry.name;\n end\n else\n s.(entry.name) = entry.default;\n usingDefaults{end+1} = entry.name;\n end\n end\n\n % Set defaults for all parameters\n for i = 1:numel(obj.params_)\n entry = obj.params_{i};\n s.(entry.name) = entry.default;\n usingDefaults{end+1} = entry.name;\n end\n\n % Parse name-value pairs from remaining arguments\n unmatched = struct();\n while pos <= nargs\n if pos + 1 > nargs\n error('Expected name-value pair argument.');\n end\n name = varargin{pos};\n val = varargin{pos + 1};\n pos = pos + 2;\n\n if ~ischar(name) && ~isstring(name)\n error('Expected parameter name to be a string.');\n end\n name = char(name);\n\n found = false;\n % Optionals may also be passed by name (undocumented MATLAB\n % behavior relied on by real-world code)\n candidates = [obj.params_, obj.optional_];\n for i = 1:numel(candidates)\n entry = candidates{i};\n if inputParser.namesMatch(name, entry.name, obj.CaseSensitive)\n s.(entry.name) = val;\n % Remove from usingDefaults\n newDefaults = {};\n for j = 1:numel(usingDefaults)\n if ~strcmp(usingDefaults{j}, entry.name)\n newDefaults{end+1} = usingDefaults{j};\n end\n end\n usingDefaults = newDefaults;\n found = true;\n break;\n end\n end\n if ~found\n if obj.KeepUnmatched\n unmatched.(name) = val;\n else\n error('''%s'' is not a recognized parameter.', name);\n end\n end\n end\n\n obj.Results = s;\n obj.UsingDefaults = usingDefaults;\n obj.Unmatched = unmatched;\n end\n end\n\n methods (Static)\n function tf = namesMatch(input, expected, caseSensitive)\n if caseSensitive\n tf = strcmp(input, expected);\n else\n tf = strcmpi(input, expected);\n end\n end\n end\nend\n"
69739
+ },
69740
+ {
69741
+ name: "normalize.m",
69742
+ source: "function Y = normalize(X, method, p)\n % normalize(X) z-score along the first non-singleton dimension\n % normalize(X, 'zscore') same as above\n % normalize(X, 'norm') divide by the 2-norm along that dimension\n % normalize(X, 'norm', p) divide by the p-norm (p = Inf -> max abs)\n if nargin < 2\n method = 'zscore';\n end\n if size(X, 1) == 1\n dim = 2;\n else\n dim = 1;\n end\n switch lower(method)\n case 'zscore'\n mu = mean(X, dim);\n sigma = std(X, 0, dim);\n Y = (X - mu) ./ sigma;\n case 'norm'\n if nargin < 3\n p = 2;\n end\n if isinf(p)\n n = max(abs(X), [], dim);\n else\n n = sum(abs(X) .^ p, dim) .^ (1 / p);\n end\n Y = X ./ n;\n otherwise\n error('normalize: unsupported method ''%s''', method);\n end\nend\n"
69206
69743
  },
69207
69744
  {
69208
69745
  name: "parse.m",
@@ -69393,6 +69930,7 @@ var shimFiles = [
69393
69930
  end
69394
69931
 
69395
69932
  function result = keys(obj)
69933
+ % MATLAB's containers.Map returns keys in sorted order
69396
69934
  if obj.Count == 0
69397
69935
  result = {};
69398
69936
  return;
@@ -69408,6 +69946,8 @@ var shimFiles = [
69408
69946
  for i = 1:numel(k)
69409
69947
  result{i} = char(k{i});
69410
69948
  end
69949
+ % MATLAB returns a sorted 1xN row cell
69950
+ result = reshape(sort(result), 1, []);
69411
69951
  else
69412
69952
  % Numeric keys: parse back from string
69413
69953
  if iscell(k)
@@ -69418,17 +69958,27 @@ var shimFiles = [
69418
69958
  else
69419
69959
  result = {str2double(k)};
69420
69960
  end
69961
+ result = reshape(num2cell(sort(cell2mat(result))), 1, []);
69421
69962
  end
69422
69963
  end
69423
69964
 
69424
69965
  function result = values(obj)
69966
+ % Ordered to correspond with keys() (i.e. key-sorted)
69425
69967
  if obj.Count == 0
69426
69968
  result = {};
69427
69969
  return;
69428
69970
  end
69429
- v = values(obj.data_);
69971
+ sortedKeys = keys(obj);
69972
+ v = cell(1, obj.Count);
69973
+ for i = 1:obj.Count
69974
+ v{i} = obj.data_(makeKey(sortedKeys{i}, obj.KeyType));
69975
+ end
69430
69976
  if strcmp(obj.ValueType, 'any')
69431
- result = v;
69977
+ % Values are stored cell-wrapped (see subsasgn); unwrap each
69978
+ result = cell(1, obj.Count);
69979
+ for i = 1:obj.Count
69980
+ result{i} = v{i}{1};
69981
+ end
69432
69982
  else
69433
69983
  if iscell(v)
69434
69984
  result = v;