@elaraai/east 1.0.65 → 1.0.67

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.
@@ -1363,6 +1363,40 @@ function allocateTypedArray(elementType, length) {
1363
1363
  return new Uint8ClampedArray(length);
1364
1364
  throw new Error(`Unsupported vector element type: ${elementType.type}`);
1365
1365
  }
1366
+ /** Wraps to East's 64-bit Integer semantics */
1367
+ function wrapI64(x) {
1368
+ return BigInt.asIntN(64, x);
1369
+ }
1370
+ /** Throws unless the vector/matrix element type parameter is Float or Integer */
1371
+ function requireNumericElem(builtin, T, loc_id, source_map) {
1372
+ if (T.type !== "Float" && T.type !== "Integer") {
1373
+ throw new EastError(`${builtin} requires Float or Integer elements`, { location: (source_map?.resolve(loc_id) ?? []) });
1374
+ }
1375
+ return T.type;
1376
+ }
1377
+ /** Throws the shared length-mismatch error for elementwise vector operands */
1378
+ function requireSameLength(a, b, loc_id, source_map) {
1379
+ if (a.length !== b.length) {
1380
+ throw new EastError(`Vector length mismatch (${a.length} vs ${b.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
1381
+ }
1382
+ }
1383
+ /** Throws the shared dimension-mismatch error for elementwise matrix operands */
1384
+ function requireSameDims(a, b, loc_id, source_map) {
1385
+ if (a.rows !== b.rows || a.cols !== b.cols) {
1386
+ throw new EastError(`Matrix dimension mismatch (${a.rows}x${a.cols} vs ${b.rows}x${b.cols})`, { location: (source_map?.resolve(loc_id) ?? []) });
1387
+ }
1388
+ }
1389
+ /** Validates the sparse-accumulator invariant: parallel lengths and strictly ascending indices */
1390
+ function requireSparse(ix, v, loc_id, source_map) {
1391
+ if (ix.length !== v.length) {
1392
+ throw new EastError(`Sparse index and value lengths differ (${ix.length} vs ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
1393
+ }
1394
+ for (let i = 1; i < ix.length; i++) {
1395
+ if (ix[i] <= ix[i - 1]) {
1396
+ throw new EastError(`Sparse index vector must be strictly ascending`, { location: (source_map?.resolve(loc_id) ?? []) });
1397
+ }
1398
+ }
1399
+ }
1366
1400
  /** Creates the appropriate TypedArray for a given element type */
1367
1401
  function createTypedArray(elementType, values) {
1368
1402
  if (elementType.type === "Float") {
@@ -3510,6 +3544,483 @@ const builtin_evaluators = {
3510
3544
  }
3511
3545
  return acc;
3512
3546
  },
3547
+ // Vector elementwise arithmetic + reductions. Reductions fold in index
3548
+ // order, left to right — part of the cross-runtime contract, since a
3549
+ // reassociated float sum gives a different last bit.
3550
+ VectorScale: (loc_id, source_map, _platformDef, T) => {
3551
+ const elem = requireNumericElem("VectorScale", T, loc_id, source_map);
3552
+ return (v, alpha) => {
3553
+ if (elem === "Float") {
3554
+ const result = new Float64Array(v.length);
3555
+ for (let i = 0; i < v.length; i++)
3556
+ result[i] = v[i] * alpha;
3557
+ return result;
3558
+ }
3559
+ const result = new BigInt64Array(v.length);
3560
+ for (let i = 0; i < v.length; i++)
3561
+ result[i] = wrapI64(v[i] * alpha);
3562
+ return result;
3563
+ };
3564
+ },
3565
+ VectorSum: (loc_id, source_map, _platformDef, T) => {
3566
+ const elem = requireNumericElem("VectorSum", T, loc_id, source_map);
3567
+ return (v) => {
3568
+ if (elem === "Float") {
3569
+ let acc = 0;
3570
+ for (let i = 0; i < v.length; i++)
3571
+ acc += v[i];
3572
+ return acc;
3573
+ }
3574
+ let acc = 0n;
3575
+ for (let i = 0; i < v.length; i++)
3576
+ acc = wrapI64(acc + v[i]);
3577
+ return acc;
3578
+ };
3579
+ },
3580
+ VectorAddScaled: (loc_id, source_map, _platformDef, T) => {
3581
+ const elem = requireNumericElem("VectorAddScaled", T, loc_id, source_map);
3582
+ return (a, b, alpha) => {
3583
+ requireSameLength(a, b, loc_id, source_map);
3584
+ if (elem === "Float") {
3585
+ const result = new Float64Array(a.length);
3586
+ for (let i = 0; i < a.length; i++)
3587
+ result[i] = a[i] + alpha * b[i];
3588
+ return result;
3589
+ }
3590
+ const result = new BigInt64Array(a.length);
3591
+ for (let i = 0; i < a.length; i++)
3592
+ result[i] = wrapI64(a[i] + wrapI64(alpha * b[i]));
3593
+ return result;
3594
+ };
3595
+ },
3596
+ VectorMul: (loc_id, source_map, _platformDef, T) => {
3597
+ const elem = requireNumericElem("VectorMul", T, loc_id, source_map);
3598
+ return (a, b) => {
3599
+ requireSameLength(a, b, loc_id, source_map);
3600
+ if (elem === "Float") {
3601
+ const result = new Float64Array(a.length);
3602
+ for (let i = 0; i < a.length; i++)
3603
+ result[i] = a[i] * b[i];
3604
+ return result;
3605
+ }
3606
+ const result = new BigInt64Array(a.length);
3607
+ for (let i = 0; i < a.length; i++)
3608
+ result[i] = wrapI64(a[i] * b[i]);
3609
+ return result;
3610
+ };
3611
+ },
3612
+ VectorAddScalar: (loc_id, source_map, _platformDef, T) => {
3613
+ const elem = requireNumericElem("VectorAddScalar", T, loc_id, source_map);
3614
+ return (v, c) => {
3615
+ if (elem === "Float") {
3616
+ const result = new Float64Array(v.length);
3617
+ for (let i = 0; i < v.length; i++)
3618
+ result[i] = v[i] + c;
3619
+ return result;
3620
+ }
3621
+ const result = new BigInt64Array(v.length);
3622
+ for (let i = 0; i < v.length; i++)
3623
+ result[i] = wrapI64(v[i] + c);
3624
+ return result;
3625
+ };
3626
+ },
3627
+ VectorDot: (loc_id, source_map, _platformDef, T) => {
3628
+ const elem = requireNumericElem("VectorDot", T, loc_id, source_map);
3629
+ return (a, b) => {
3630
+ requireSameLength(a, b, loc_id, source_map);
3631
+ if (elem === "Float") {
3632
+ let acc = 0;
3633
+ for (let i = 0; i < a.length; i++)
3634
+ acc += a[i] * b[i];
3635
+ return acc;
3636
+ }
3637
+ let acc = 0n;
3638
+ for (let i = 0; i < a.length; i++)
3639
+ acc = wrapI64(acc + wrapI64(a[i] * b[i]));
3640
+ return acc;
3641
+ };
3642
+ },
3643
+ VectorMax: (loc_id, source_map, _platformDef, T) => {
3644
+ requireNumericElem("VectorMax", T, loc_id, source_map);
3645
+ const less = lessFor(T);
3646
+ return (v) => {
3647
+ if (v.length === 0) {
3648
+ throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3649
+ }
3650
+ let best = v[0];
3651
+ for (let i = 1; i < v.length; i++) {
3652
+ if (less(best, v[i]))
3653
+ best = v[i];
3654
+ }
3655
+ return best;
3656
+ };
3657
+ },
3658
+ VectorMin: (loc_id, source_map, _platformDef, T) => {
3659
+ requireNumericElem("VectorMin", T, loc_id, source_map);
3660
+ const less = lessFor(T);
3661
+ return (v) => {
3662
+ if (v.length === 0) {
3663
+ throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3664
+ }
3665
+ let best = v[0];
3666
+ for (let i = 1; i < v.length; i++) {
3667
+ if (less(v[i], best))
3668
+ best = v[i];
3669
+ }
3670
+ return best;
3671
+ };
3672
+ },
3673
+ VectorArgMax: (loc_id, source_map, _platformDef, T) => {
3674
+ requireNumericElem("VectorArgMax", T, loc_id, source_map);
3675
+ const less = lessFor(T);
3676
+ return (v) => {
3677
+ if (v.length === 0) {
3678
+ throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3679
+ }
3680
+ let bestIdx = 0;
3681
+ for (let i = 1; i < v.length; i++) {
3682
+ if (less(v[bestIdx], v[i]))
3683
+ bestIdx = i;
3684
+ }
3685
+ return BigInt(bestIdx);
3686
+ };
3687
+ },
3688
+ VectorArgMin: (loc_id, source_map, _platformDef, T) => {
3689
+ requireNumericElem("VectorArgMin", T, loc_id, source_map);
3690
+ const less = lessFor(T);
3691
+ return (v) => {
3692
+ if (v.length === 0) {
3693
+ throw new EastError("Cannot reduce empty Vector", { location: (source_map?.resolve(loc_id) ?? []) });
3694
+ }
3695
+ let bestIdx = 0;
3696
+ for (let i = 1; i < v.length; i++) {
3697
+ if (less(v[i], v[bestIdx]))
3698
+ bestIdx = i;
3699
+ }
3700
+ return BigInt(bestIdx);
3701
+ };
3702
+ },
3703
+ VectorMean: (loc_id, source_map, _platformDef, T) => {
3704
+ requireNumericElem("VectorMean", T, loc_id, source_map);
3705
+ return (v) => {
3706
+ let acc = 0;
3707
+ for (let i = 0; i < v.length; i++)
3708
+ acc += Number(v[i]);
3709
+ return acc / v.length;
3710
+ };
3711
+ },
3712
+ VectorCumSum: (loc_id, source_map, _platformDef, T) => {
3713
+ const elem = requireNumericElem("VectorCumSum", T, loc_id, source_map);
3714
+ return (v) => {
3715
+ if (elem === "Float") {
3716
+ const result = new Float64Array(v.length);
3717
+ let acc = 0;
3718
+ for (let i = 0; i < v.length; i++) {
3719
+ acc += v[i];
3720
+ result[i] = acc;
3721
+ }
3722
+ return result;
3723
+ }
3724
+ const result = new BigInt64Array(v.length);
3725
+ let acc = 0n;
3726
+ for (let i = 0; i < v.length; i++) {
3727
+ acc = wrapI64(acc + v[i]);
3728
+ result[i] = acc;
3729
+ }
3730
+ return result;
3731
+ };
3732
+ },
3733
+ VectorAbs: (loc_id, source_map, _platformDef, T) => {
3734
+ const elem = requireNumericElem("VectorAbs", T, loc_id, source_map);
3735
+ return (v) => {
3736
+ if (elem === "Float") {
3737
+ const result = new Float64Array(v.length);
3738
+ for (let i = 0; i < v.length; i++) {
3739
+ const x = v[i];
3740
+ result[i] = x < 0 ? -x : x;
3741
+ }
3742
+ return result;
3743
+ }
3744
+ const result = new BigInt64Array(v.length);
3745
+ for (let i = 0; i < v.length; i++) {
3746
+ const x = v[i];
3747
+ result[i] = wrapI64(x < 0n ? -x : x);
3748
+ }
3749
+ return result;
3750
+ };
3751
+ },
3752
+ VectorClamp: (loc_id, source_map, _platformDef, T) => {
3753
+ const elem = requireNumericElem("VectorClamp", T, loc_id, source_map);
3754
+ const less = lessFor(T);
3755
+ return (v, lo, hi) => {
3756
+ const result = elem === "Float" ? new Float64Array(v.length) : new BigInt64Array(v.length);
3757
+ for (let i = 0; i < v.length; i++) {
3758
+ const x = v[i];
3759
+ result[i] = less(x, lo) ? lo : less(hi, x) ? hi : x;
3760
+ }
3761
+ return result;
3762
+ };
3763
+ },
3764
+ // Vector gather/scatter and sorted search
3765
+ VectorGather: (loc_id, source_map, _platformDef, T) => (v, idx) => {
3766
+ const result = allocateTypedArray(T, idx.length);
3767
+ for (let j = 0; j < idx.length; j++) {
3768
+ const i = Number(idx[j]);
3769
+ if (i < 0 || i >= v.length) {
3770
+ throw new EastError(`Vector index ${idx[j]} out of bounds (length ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3771
+ }
3772
+ result[j] = v[i];
3773
+ }
3774
+ return result;
3775
+ },
3776
+ VectorScatterAdd: (loc_id, source_map, _platformDef, T) => {
3777
+ const elem = requireNumericElem("VectorScatterAdd", T, loc_id, source_map);
3778
+ return (dst, idx, src) => {
3779
+ requireSameLength(idx, src, loc_id, source_map);
3780
+ const result = dst.slice();
3781
+ for (let j = 0; j < idx.length; j++) {
3782
+ const i = Number(idx[j]);
3783
+ if (i < 0 || i >= dst.length) {
3784
+ throw new EastError(`Vector index ${idx[j]} out of bounds (length ${dst.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3785
+ }
3786
+ if (elem === "Float") {
3787
+ result[i] = (result[i]) + src[j];
3788
+ }
3789
+ else {
3790
+ result[i] = wrapI64((result[i]) + src[j]);
3791
+ }
3792
+ }
3793
+ return result;
3794
+ };
3795
+ },
3796
+ VectorSearchSorted: (loc_id, source_map, _platformDef, T) => {
3797
+ const less = lessFor(T);
3798
+ const readElem = T.type === "Boolean"
3799
+ ? (v, i) => v[i] !== 0
3800
+ : (v, i) => v[i];
3801
+ return (haystack, needles) => {
3802
+ const result = new BigInt64Array(needles.length);
3803
+ for (let j = 0; j < needles.length; j++) {
3804
+ const needle = readElem(needles, j);
3805
+ let lo = 0;
3806
+ let hi = haystack.length;
3807
+ while (lo < hi) {
3808
+ const mid = (lo + hi) >>> 1;
3809
+ if (less(readElem(haystack, mid), needle)) {
3810
+ lo = mid + 1;
3811
+ }
3812
+ else {
3813
+ hi = mid;
3814
+ }
3815
+ }
3816
+ result[j] = BigInt(lo);
3817
+ }
3818
+ return result;
3819
+ };
3820
+ },
3821
+ // Vector masks and selection (comparisons use East's total order)
3822
+ VectorEq: (loc_id, source_map, _platformDef, T) => {
3823
+ const equal = equalFor(T);
3824
+ const readElem = T.type === "Boolean"
3825
+ ? (v, i) => v[i] !== 0
3826
+ : (v, i) => v[i];
3827
+ return (a, b) => {
3828
+ requireSameLength(a, b, loc_id, source_map);
3829
+ const result = new Uint8ClampedArray(a.length);
3830
+ for (let i = 0; i < a.length; i++)
3831
+ result[i] = equal(readElem(a, i), readElem(b, i)) ? 1 : 0;
3832
+ return result;
3833
+ };
3834
+ },
3835
+ VectorLt: (loc_id, source_map, _platformDef, T) => {
3836
+ const less = lessFor(T);
3837
+ const readElem = T.type === "Boolean"
3838
+ ? (v, i) => v[i] !== 0
3839
+ : (v, i) => v[i];
3840
+ return (a, b) => {
3841
+ requireSameLength(a, b, loc_id, source_map);
3842
+ const result = new Uint8ClampedArray(a.length);
3843
+ for (let i = 0; i < a.length; i++)
3844
+ result[i] = less(readElem(a, i), readElem(b, i)) ? 1 : 0;
3845
+ return result;
3846
+ };
3847
+ },
3848
+ VectorGt: (loc_id, source_map, _platformDef, T) => {
3849
+ const greater = greaterFor(T);
3850
+ const readElem = T.type === "Boolean"
3851
+ ? (v, i) => v[i] !== 0
3852
+ : (v, i) => v[i];
3853
+ return (a, b) => {
3854
+ requireSameLength(a, b, loc_id, source_map);
3855
+ const result = new Uint8ClampedArray(a.length);
3856
+ for (let i = 0; i < a.length; i++)
3857
+ result[i] = greater(readElem(a, i), readElem(b, i)) ? 1 : 0;
3858
+ return result;
3859
+ };
3860
+ },
3861
+ VectorSelect: (loc_id, source_map, _platformDef, T) => (mask, a, b) => {
3862
+ requireSameLength(mask, a, loc_id, source_map);
3863
+ requireSameLength(a, b, loc_id, source_map);
3864
+ const result = allocateTypedArray(T, mask.length);
3865
+ for (let i = 0; i < mask.length; i++)
3866
+ result[i] = (mask[i] !== 0 ? a[i] : b[i]);
3867
+ return result;
3868
+ },
3869
+ VectorCompress: (loc_id, source_map, _platformDef, T) => (mask, v) => {
3870
+ requireSameLength(mask, v, loc_id, source_map);
3871
+ let count = 0;
3872
+ for (let i = 0; i < mask.length; i++) {
3873
+ if (mask[i] !== 0)
3874
+ count++;
3875
+ }
3876
+ const result = allocateTypedArray(T, count);
3877
+ let j = 0;
3878
+ for (let i = 0; i < mask.length; i++) {
3879
+ if (mask[i] !== 0)
3880
+ result[j++] = v[i];
3881
+ }
3882
+ return result;
3883
+ },
3884
+ VectorCountTrue: (_loc_id, _source_map, _platformDef) => (mask) => {
3885
+ let count = 0n;
3886
+ for (let i = 0; i < mask.length; i++) {
3887
+ if (mask[i] !== 0)
3888
+ count += 1n;
3889
+ }
3890
+ return count;
3891
+ },
3892
+ // Sparse accumulators: parallel (ix, v) with strictly ascending ix.
3893
+ // Entries absent from a side are structurally absent, not explicit zeros:
3894
+ // an A-only entry passes through unscaled, a B-only entry contributes
3895
+ // alpha*vB even when alpha is NaN or infinite.
3896
+ SparseAxpy: (loc_id, source_map, _platformDef, T) => {
3897
+ const elem = requireNumericElem("SparseAxpy", T, loc_id, source_map);
3898
+ return (ixA, vA, ixB, vB, alpha) => {
3899
+ requireSparse(ixA, vA, loc_id, source_map);
3900
+ requireSparse(ixB, vB, loc_id, source_map);
3901
+ let count = 0;
3902
+ let i = 0;
3903
+ let j = 0;
3904
+ while (i < ixA.length && j < ixB.length) {
3905
+ const a = ixA[i];
3906
+ const b = ixB[j];
3907
+ if (a < b)
3908
+ i++;
3909
+ else if (b < a)
3910
+ j++;
3911
+ else {
3912
+ i++;
3913
+ j++;
3914
+ }
3915
+ count++;
3916
+ }
3917
+ count += (ixA.length - i) + (ixB.length - j);
3918
+ const outIx = new BigInt64Array(count);
3919
+ const outV = elem === "Float" ? new Float64Array(count) : new BigInt64Array(count);
3920
+ i = 0;
3921
+ j = 0;
3922
+ let k = 0;
3923
+ while (i < ixA.length && j < ixB.length) {
3924
+ const a = ixA[i];
3925
+ const b = ixB[j];
3926
+ if (a < b) {
3927
+ outIx[k] = a;
3928
+ outV[k] = vA[i];
3929
+ i++;
3930
+ }
3931
+ else if (b < a) {
3932
+ outIx[k] = b;
3933
+ outV[k] = elem === "Float" ? alpha * vB[j] : wrapI64(alpha * vB[j]);
3934
+ j++;
3935
+ }
3936
+ else {
3937
+ outIx[k] = a;
3938
+ outV[k] = elem === "Float"
3939
+ ? vA[i] + alpha * vB[j]
3940
+ : wrapI64(vA[i] + wrapI64(alpha * vB[j]));
3941
+ i++;
3942
+ j++;
3943
+ }
3944
+ k++;
3945
+ }
3946
+ for (; i < ixA.length; i++, k++) {
3947
+ outIx[k] = ixA[i];
3948
+ outV[k] = vA[i];
3949
+ }
3950
+ for (; j < ixB.length; j++, k++) {
3951
+ outIx[k] = ixB[j];
3952
+ outV[k] = elem === "Float" ? alpha * vB[j] : wrapI64(alpha * vB[j]);
3953
+ }
3954
+ return { ix: outIx, v: outV };
3955
+ };
3956
+ },
3957
+ SparseFromPairs: (loc_id, source_map, _platformDef, T) => {
3958
+ const elem = requireNumericElem("SparseFromPairs", T, loc_id, source_map);
3959
+ return (ix, v) => {
3960
+ if (ix.length !== v.length) {
3961
+ throw new EastError(`Sparse index and value lengths differ (${ix.length} vs ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
3962
+ }
3963
+ // Stable: order by (index, original position) so equal indices
3964
+ // accumulate in input order and the float result is deterministic.
3965
+ const order = new Array(ix.length);
3966
+ for (let i = 0; i < ix.length; i++)
3967
+ order[i] = i;
3968
+ order.sort((p, q) => {
3969
+ const a = ix[p];
3970
+ const b = ix[q];
3971
+ if (a < b)
3972
+ return -1;
3973
+ if (a > b)
3974
+ return 1;
3975
+ return p - q;
3976
+ });
3977
+ let count = 0;
3978
+ for (let i = 0; i < order.length; i++) {
3979
+ if (i === 0 || ix[order[i]] !== ix[order[i - 1]])
3980
+ count++;
3981
+ }
3982
+ const outIx = new BigInt64Array(count);
3983
+ const outV = elem === "Float" ? new Float64Array(count) : new BigInt64Array(count);
3984
+ let k = -1;
3985
+ for (let i = 0; i < order.length; i++) {
3986
+ const p = order[i];
3987
+ if (i === 0 || ix[p] !== outIx[k]) {
3988
+ k++;
3989
+ outIx[k] = ix[p];
3990
+ outV[k] = v[p];
3991
+ }
3992
+ else {
3993
+ outV[k] = elem === "Float"
3994
+ ? (outV[k]) + v[p]
3995
+ : wrapI64((outV[k]) + v[p]);
3996
+ }
3997
+ }
3998
+ return { ix: outIx, v: outV };
3999
+ };
4000
+ },
4001
+ SparseFilterGt: (loc_id, source_map, _platformDef, T) => {
4002
+ const elem = requireNumericElem("SparseFilterGt", T, loc_id, source_map);
4003
+ const greater = greaterFor(T);
4004
+ return (ix, v, threshold) => {
4005
+ requireSparse(ix, v, loc_id, source_map);
4006
+ let count = 0;
4007
+ for (let i = 0; i < v.length; i++) {
4008
+ if (greater(v[i], threshold))
4009
+ count++;
4010
+ }
4011
+ const outIx = new BigInt64Array(count);
4012
+ const outV = elem === "Float" ? new Float64Array(count) : new BigInt64Array(count);
4013
+ let k = 0;
4014
+ for (let i = 0; i < v.length; i++) {
4015
+ if (greater(v[i], threshold)) {
4016
+ outIx[k] = ix[i];
4017
+ outV[k] = v[i];
4018
+ k++;
4019
+ }
4020
+ }
4021
+ return { ix: outIx, v: outV };
4022
+ };
4023
+ },
3513
4024
  // Matrix builtins
3514
4025
  MatrixRows: (_loc_id, _source_map, _platformDef, _T) => (m) => BigInt(m.rows),
3515
4026
  MatrixCols: (_loc_id, _source_map, _platformDef, _T) => (m) => BigInt(m.cols),
@@ -3677,6 +4188,137 @@ const builtin_evaluators = {
3677
4188
  data.set(arr[r], r * cols);
3678
4189
  return matrix(data, arr.length, cols);
3679
4190
  },
4191
+ // Matrix elementwise arithmetic + reductions. Sums accumulate in ascending
4192
+ // index order (row-major for whole-matrix walks, ascending row for column
4193
+ // sums, ascending column within each row for row sums and vec-mul) — the
4194
+ // same left-to-right contract as the Vector reductions.
4195
+ MatrixScale: (loc_id, source_map, _platformDef, T) => {
4196
+ const elem = requireNumericElem("MatrixScale", T, loc_id, source_map);
4197
+ return (m, alpha) => {
4198
+ const src = m.data;
4199
+ if (elem === "Float") {
4200
+ const data = new Float64Array(src.length);
4201
+ for (let i = 0; i < src.length; i++)
4202
+ data[i] = src[i] * alpha;
4203
+ return matrix(data, m.rows, m.cols);
4204
+ }
4205
+ const data = new BigInt64Array(src.length);
4206
+ for (let i = 0; i < src.length; i++)
4207
+ data[i] = wrapI64(src[i] * alpha);
4208
+ return matrix(data, m.rows, m.cols);
4209
+ };
4210
+ },
4211
+ MatrixAddScaled: (loc_id, source_map, _platformDef, T) => {
4212
+ const elem = requireNumericElem("MatrixAddScaled", T, loc_id, source_map);
4213
+ return (a, b, alpha) => {
4214
+ requireSameDims(a, b, loc_id, source_map);
4215
+ const ad = a.data;
4216
+ const bd = b.data;
4217
+ if (elem === "Float") {
4218
+ const data = new Float64Array(ad.length);
4219
+ for (let i = 0; i < ad.length; i++)
4220
+ data[i] = ad[i] + alpha * bd[i];
4221
+ return matrix(data, a.rows, a.cols);
4222
+ }
4223
+ const data = new BigInt64Array(ad.length);
4224
+ for (let i = 0; i < ad.length; i++)
4225
+ data[i] = wrapI64(ad[i] + wrapI64(alpha * bd[i]));
4226
+ return matrix(data, a.rows, a.cols);
4227
+ };
4228
+ },
4229
+ MatrixMulElementwise: (loc_id, source_map, _platformDef, T) => {
4230
+ const elem = requireNumericElem("MatrixMulElementwise", T, loc_id, source_map);
4231
+ return (a, b) => {
4232
+ requireSameDims(a, b, loc_id, source_map);
4233
+ const ad = a.data;
4234
+ const bd = b.data;
4235
+ if (elem === "Float") {
4236
+ const data = new Float64Array(ad.length);
4237
+ for (let i = 0; i < ad.length; i++)
4238
+ data[i] = ad[i] * bd[i];
4239
+ return matrix(data, a.rows, a.cols);
4240
+ }
4241
+ const data = new BigInt64Array(ad.length);
4242
+ for (let i = 0; i < ad.length; i++)
4243
+ data[i] = wrapI64(ad[i] * bd[i]);
4244
+ return matrix(data, a.rows, a.cols);
4245
+ };
4246
+ },
4247
+ MatrixRowSums: (loc_id, source_map, _platformDef, T) => {
4248
+ const elem = requireNumericElem("MatrixRowSums", T, loc_id, source_map);
4249
+ return (m) => {
4250
+ const src = m.data;
4251
+ if (elem === "Float") {
4252
+ const result = new Float64Array(m.rows);
4253
+ for (let r = 0; r < m.rows; r++) {
4254
+ let acc = 0;
4255
+ for (let c = 0; c < m.cols; c++)
4256
+ acc += src[r * m.cols + c];
4257
+ result[r] = acc;
4258
+ }
4259
+ return result;
4260
+ }
4261
+ const result = new BigInt64Array(m.rows);
4262
+ for (let r = 0; r < m.rows; r++) {
4263
+ let acc = 0n;
4264
+ for (let c = 0; c < m.cols; c++)
4265
+ acc = wrapI64(acc + src[r * m.cols + c]);
4266
+ result[r] = acc;
4267
+ }
4268
+ return result;
4269
+ };
4270
+ },
4271
+ MatrixColSums: (loc_id, source_map, _platformDef, T) => {
4272
+ const elem = requireNumericElem("MatrixColSums", T, loc_id, source_map);
4273
+ return (m) => {
4274
+ const src = m.data;
4275
+ if (elem === "Float") {
4276
+ const result = new Float64Array(m.cols);
4277
+ for (let c = 0; c < m.cols; c++) {
4278
+ let acc = 0;
4279
+ for (let r = 0; r < m.rows; r++)
4280
+ acc += src[r * m.cols + c];
4281
+ result[c] = acc;
4282
+ }
4283
+ return result;
4284
+ }
4285
+ const result = new BigInt64Array(m.cols);
4286
+ for (let c = 0; c < m.cols; c++) {
4287
+ let acc = 0n;
4288
+ for (let r = 0; r < m.rows; r++)
4289
+ acc = wrapI64(acc + src[r * m.cols + c]);
4290
+ result[c] = acc;
4291
+ }
4292
+ return result;
4293
+ };
4294
+ },
4295
+ MatrixVecMul: (loc_id, source_map, _platformDef, T) => {
4296
+ const elem = requireNumericElem("MatrixVecMul", T, loc_id, source_map);
4297
+ return (m, v) => {
4298
+ if (v.length !== m.cols) {
4299
+ throw new EastError(`MatrixVecMul dimension mismatch (${m.rows}x${m.cols} vs length ${v.length})`, { location: (source_map?.resolve(loc_id) ?? []) });
4300
+ }
4301
+ const src = m.data;
4302
+ if (elem === "Float") {
4303
+ const result = new Float64Array(m.rows);
4304
+ for (let r = 0; r < m.rows; r++) {
4305
+ let acc = 0;
4306
+ for (let c = 0; c < m.cols; c++)
4307
+ acc += src[r * m.cols + c] * v[c];
4308
+ result[r] = acc;
4309
+ }
4310
+ return result;
4311
+ }
4312
+ const result = new BigInt64Array(m.rows);
4313
+ for (let r = 0; r < m.rows; r++) {
4314
+ let acc = 0n;
4315
+ for (let c = 0; c < m.cols; c++)
4316
+ acc = wrapI64(acc + wrapI64(src[r * m.cols + c] * v[c]));
4317
+ result[r] = acc;
4318
+ }
4319
+ return result;
4320
+ };
4321
+ },
3680
4322
  };
3681
4323
  /** @internal */
3682
4324
  export function applyTypeParameters(t, params) {