catniff 0.8.19 → 0.8.21

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;
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,55 @@ 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 unfold");
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
+ const out = new Tensor(this.value, {
785
+ shape: newShape,
786
+ strides: newStrides,
787
+ offset: this.offset,
788
+ dtype: this.dtype,
789
+ device: this.device
790
+ });
791
+ if (this.requiresGrad) {
792
+ out.requiresGrad = true;
793
+ out.children.push(this);
794
+ out.gradFn = () => {
795
+ const outGrad = out.grad;
796
+ const grad = Tensor.zerosLike(this);
797
+ for (let i = 0; i < out.numel; i++) {
798
+ const coords = Tensor.indexToCoords(i, newStrides);
799
+ const windowIdx = coords[dim];
800
+ const withinWindow = coords[coords.length - 1];
801
+ coords[dim] = windowIdx * step + withinWindow;
802
+ coords.pop();
803
+ const sourceIdx = Tensor.coordsToIndex(coords, this.strides);
804
+ grad.value[sourceIdx] += outGrad.value[i];
805
+ }
806
+ Tensor.addGrad(this, grad);
807
+ };
808
+ }
809
+ return out;
810
+ }
758
811
  // Tensor concatentation
759
812
  cat(other, dim = 0) {
760
813
  other = this.handleOther(other);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catniff",
3
- "version": "0.8.19",
3
+ "version": "0.8.21",
4
4
  "description": "Torch-like deep learning framework for Javascript",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {