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 +7 -0
- package/dist/core.js +104 -5
- package/package.json +1 -1
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
|
-
|
|
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
|
|
2650
|
+
// Format a single number
|
|
2556
2651
|
const formatNum = (n) => {
|
|
2557
|
-
|
|
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
|