catniff 0.8.18 → 0.8.20

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/core.d.ts CHANGED
@@ -66,6 +66,7 @@ export declare class Tensor {
66
66
  slice(ranges: number[][]): Tensor;
67
67
  chunk(chunks: number, dim?: number): Tensor[];
68
68
  expand(newShape: number[]): Tensor;
69
+ unfold(dim: number, size: number, step: number): Tensor;
69
70
  cat(other: Tensor | TensorValue, dim?: number): Tensor;
70
71
  stack(others: (Tensor | TensorValue)[], dim?: number): Tensor;
71
72
  squeeze(dims?: number[] | number): Tensor;
@@ -89,6 +90,12 @@ export declare class Tensor {
89
90
  outIndex: number;
90
91
  }) => number;
91
92
  }): Tensor;
93
+ static reduceArg(tensor: Tensor, dim: number, keepDim: boolean, config: {
94
+ identity: number;
95
+ isBetter: (accumulator: number, value: number) => boolean;
96
+ }): Tensor;
97
+ argmax(dim: number, keepDim?: boolean): Tensor;
98
+ argmin(dim: number, keepDim?: boolean): Tensor;
92
99
  sum(dims?: number[] | number, keepDims?: boolean): Tensor;
93
100
  prod(dims?: number[] | number, keepDims?: boolean): Tensor;
94
101
  mean(dims?: number[] | number, keepDims?: boolean): Tensor;
package/dist/core.js CHANGED
@@ -551,6 +551,9 @@ class Tensor {
551
551
  if (this.shape.length === 0)
552
552
  return this;
553
553
  indices = Tensor.normalizeDims(indices, this.shape[0]);
554
+ if (indices.some(i => i < 0 || i >= this.shape[0])) {
555
+ throw new Error(`Index out of bounds for dimension 0 with size ${this.shape[0]}`);
556
+ }
554
557
  // Init necessary stuff for indexing
555
558
  const reducedShape = this.shape.slice(1);
556
559
  const reducedStrides = this.strides.slice(1);
@@ -618,8 +621,9 @@ class Tensor {
618
621
  // Tensor slicing
619
622
  slice(ranges) {
620
623
  // Handle scalars
621
- if (this.shape.length === 0)
622
- return this;
624
+ if (this.shape.length === 0) {
625
+ throw new Error("slice() cannot be applied to a 0-dim tensor");
626
+ }
623
627
  const newShape = [];
624
628
  const newStrides = [];
625
629
  let newOffset = this.offset;
@@ -755,6 +759,36 @@ class Tensor {
755
759
  }
756
760
  return out;
757
761
  }
762
+ // Tensor unfold
763
+ unfold(dim, size, step) {
764
+ // Handle negative indexing
765
+ if (dim < 0) {
766
+ dim += this.shape.length;
767
+ }
768
+ // If dimension out of bound, throw error
769
+ if (dim >= this.shape.length || dim < 0) {
770
+ throw new Error("Dimension does not exist to apply softmax");
771
+ }
772
+ // Verify size and step
773
+ if (size <= 0 || step <= 0)
774
+ throw new Error("size and step must be greater than 0");
775
+ const dimSize = this.shape[dim];
776
+ // Verify size against dimension size
777
+ if (size > dimSize)
778
+ throw new Error("size can not be greater than dimension size");
779
+ const outSize = Math.floor((dimSize - size) / step) + 1;
780
+ const newShape = [...this.shape, size];
781
+ const newStrides = [...this.strides, this.strides[dim]];
782
+ newShape[dim] = outSize;
783
+ newStrides[dim] = this.strides[dim] * step;
784
+ return new Tensor(this.value, {
785
+ shape: newShape,
786
+ strides: newStrides,
787
+ offset: this.offset,
788
+ dtype: this.dtype,
789
+ device: this.device
790
+ });
791
+ }
758
792
  // Tensor concatentation
759
793
  cat(other, dim = 0) {
760
794
  other = this.handleOther(other);
@@ -1155,6 +1189,67 @@ class Tensor {
1155
1189
  }
1156
1190
  return keepDims ? out : out.squeeze(dims);
1157
1191
  }
1192
+ // Generic arg reduction operation handler
1193
+ static reduceArg(tensor, dim, keepDim, config) {
1194
+ if (tensor.shape.length === 0)
1195
+ return tensor;
1196
+ // Handle negative indexing
1197
+ if (dim < 0) {
1198
+ dim += tensor.shape.length;
1199
+ }
1200
+ // If dimension out of bound, throw error
1201
+ if (dim >= tensor.shape.length || dim < 0) {
1202
+ throw new Error("Dimension does not exist to apply arg reduction");
1203
+ }
1204
+ const dimSize = tensor.shape[dim];
1205
+ const outputShape = tensor.shape.map((d, i) => dim === i ? 1 : d);
1206
+ const outputStrides = Tensor.getStrides(outputShape);
1207
+ const outputSize = tensor.numel / dimSize;
1208
+ const bestValues = new dtype_1.TypedArray[tensor.dtype](outputSize).fill(config.identity);
1209
+ const bestIndices = new Int32Array(outputSize).fill(0);
1210
+ const linearStrides = Tensor.getStrides(tensor.shape);
1211
+ // Forward pass
1212
+ for (let flatIndex = 0; flatIndex < tensor.numel; flatIndex++) {
1213
+ // Convert linear index to coordinates using contiguous strides
1214
+ const coords = Tensor.indexToCoords(flatIndex, linearStrides);
1215
+ // Coordinate in current dim
1216
+ const dimCoord = coords[dim];
1217
+ // Convert coordinates to actual strided index
1218
+ const realFlatIndex = Tensor.coordsToIndex(coords, tensor.strides) + tensor.offset;
1219
+ // Convert coords to reduced index
1220
+ coords[dim] = 0;
1221
+ const outFlatIndex = Tensor.coordsToIndex(coords, outputStrides);
1222
+ // Check if current value is better to swap
1223
+ const val = tensor.value[realFlatIndex];
1224
+ if (config.isBetter(val, bestValues[outFlatIndex])) {
1225
+ bestValues[outFlatIndex] = val;
1226
+ bestIndices[outFlatIndex] = dimCoord;
1227
+ }
1228
+ }
1229
+ const out = new Tensor(bestIndices, {
1230
+ shape: outputShape,
1231
+ strides: outputStrides,
1232
+ offset: 0,
1233
+ numel: outputSize,
1234
+ device: tensor.device,
1235
+ dtype: "int32"
1236
+ });
1237
+ return keepDim ? out : out.squeeze(dim);
1238
+ }
1239
+ // Tensor argmax
1240
+ argmax(dim, keepDim = false) {
1241
+ return Tensor.reduceArg(this, dim, keepDim, {
1242
+ identity: -Infinity,
1243
+ isBetter: (a, b) => a > b
1244
+ });
1245
+ }
1246
+ // Tensor argmin
1247
+ argmin(dim, keepDim = false) {
1248
+ return Tensor.reduceArg(this, dim, keepDim, {
1249
+ identity: Infinity,
1250
+ isBetter: (a, b) => a < b
1251
+ });
1252
+ }
1158
1253
  // Simplified reduction operations
1159
1254
  sum(dims, keepDims = false) {
1160
1255
  return Tensor.reduce(this, dims, keepDims, {
@@ -2552,11 +2647,15 @@ class Tensor {
2552
2647
  // Returns the nicely Pytorch-like formatted string form
2553
2648
  toString() {
2554
2649
  const val = this.val();
2555
- // Format a single number (integers get trailing dot)
2650
+ // Format a single number
2556
2651
  const formatNum = (n) => {
2557
- if (Number.isInteger(n) && Math.abs(n) < 1e8) {
2652
+ // For ints with int dtype
2653
+ if (this.dtype.includes("int"))
2654
+ return n.toFixed(0);
2655
+ // For ints with float dtype
2656
+ if (Number.isInteger(n) && Math.abs(n) < 1e8)
2558
2657
  return n.toFixed(0) + ".";
2559
- }
2658
+ // For floats
2560
2659
  return n.toString();
2561
2660
  };
2562
2661
  // Handle scalar
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catniff",
3
- "version": "0.8.18",
3
+ "version": "0.8.20",
4
4
  "description": "Torch-like deep learning framework for Javascript",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {