catniff 0.6.2 → 0.6.4

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
@@ -182,6 +182,8 @@ export declare class Tensor {
182
182
  mv(other: TensorValue | Tensor): Tensor;
183
183
  matmul(other: TensorValue | Tensor): Tensor;
184
184
  dropout(rate: number): Tensor;
185
+ triu(diagonal?: number): Tensor;
186
+ tril(diagonal?: number): Tensor;
185
187
  static full(shape: readonly number[], num: number, options?: TensorOptions): Tensor;
186
188
  static fullLike(tensor: Tensor, num: number, options?: TensorOptions): Tensor;
187
189
  static ones(shape?: readonly number[], options?: TensorOptions): Tensor;
@@ -194,8 +196,12 @@ export declare class Tensor {
194
196
  static randnLike(tensor: Tensor, options?: TensorOptions): Tensor;
195
197
  static randint(shape: readonly number[], low: number, high: number, options?: TensorOptions): Tensor;
196
198
  static randintLike(tensor: Tensor, low: number, high: number, options?: TensorOptions): Tensor;
199
+ static randperm(n: number, options?: TensorOptions): Tensor;
197
200
  static normal(shape: number[], mean: number, stdDev: number, options?: TensorOptions): Tensor;
198
201
  static uniform(shape: number[], low: number, high: number, options?: TensorOptions): Tensor;
202
+ static arange(start: number, stop?: number, step?: number, options?: TensorOptions): Tensor;
203
+ static linspace(start: number, stop: number, steps: number, options?: TensorOptions): Tensor;
204
+ static eye(n: number, m?: number, options?: TensorOptions): Tensor;
199
205
  backward(options?: {
200
206
  zeroGrad?: boolean;
201
207
  }): void;
package/dist/core.js CHANGED
@@ -1417,6 +1417,54 @@ class Tensor {
1417
1417
  const mask = uniform.lt(keepRate);
1418
1418
  return this.mul(mask).div(keepRate);
1419
1419
  }
1420
+ // Get the upper triangular part with respect to main diagonal
1421
+ triu(diagonal = 0) {
1422
+ if (this.shape.length < 2) {
1423
+ throw new Error("triu requires at least 2 dimensions");
1424
+ }
1425
+ const maskShape = this.shape.slice(-2);
1426
+ const maskStrides = Tensor.getStrides(maskShape);
1427
+ const maskSize = Tensor.shapeToSize(maskShape);
1428
+ const maskValue = new Array(maskSize).fill(1);
1429
+ const [rows, cols] = maskShape;
1430
+ for (let i = 0; i < rows; i++) {
1431
+ const maxJ = Math.min(cols, i + diagonal);
1432
+ for (let j = 0; j < maxJ; j++) {
1433
+ maskValue[i * maskStrides[0] + j * maskStrides[1]] = 0;
1434
+ }
1435
+ }
1436
+ const mask = new Tensor(maskValue, {
1437
+ shape: maskShape,
1438
+ strides: maskStrides,
1439
+ numel: maskSize,
1440
+ device: this.device
1441
+ });
1442
+ return this.mul(mask);
1443
+ }
1444
+ // Get the lower triangular part with respect to main diagonal
1445
+ tril(diagonal = 0) {
1446
+ if (this.shape.length < 2) {
1447
+ throw new Error("triu requires at least 2 dimensions");
1448
+ }
1449
+ const maskShape = this.shape.slice(-2);
1450
+ const maskStrides = Tensor.getStrides(maskShape);
1451
+ const maskSize = Tensor.shapeToSize(maskShape);
1452
+ const maskValue = new Array(maskSize).fill(0);
1453
+ const [rows, cols] = maskShape;
1454
+ for (let i = 0; i < rows; i++) {
1455
+ const maxJ = Math.min(cols, i + diagonal + 1);
1456
+ for (let j = 0; j < maxJ; j++) {
1457
+ maskValue[i * maskStrides[0] + j * maskStrides[1]] = 1;
1458
+ }
1459
+ }
1460
+ const mask = new Tensor(maskValue, {
1461
+ shape: maskShape,
1462
+ strides: maskStrides,
1463
+ numel: maskSize,
1464
+ device: this.device
1465
+ });
1466
+ return this.mul(mask);
1467
+ }
1420
1468
  // Utility to create a new tensor filled with a number
1421
1469
  static full(shape, num, options = {}) {
1422
1470
  if (shape.length === 0)
@@ -1552,6 +1600,15 @@ class Tensor {
1552
1600
  ...options
1553
1601
  });
1554
1602
  }
1603
+ // Utility to create a new tensor filled with integers from 0 to n, randomly shuffled
1604
+ static randperm(n, options = {}) {
1605
+ const outputValue = new Array(n);
1606
+ for (let i = 0; i < n; i++) {
1607
+ outputValue[i] = i;
1608
+ }
1609
+ (0, utils_1.fyShuffle)(outputValue);
1610
+ return new Tensor(outputValue, { shape: [n], numel: n, ...options });
1611
+ }
1555
1612
  // Utility to create a new tensor filled with a random number with normal distribution of custom mean and stddev
1556
1613
  static normal(shape, mean, stdDev, options = {}) {
1557
1614
  if (shape.length === 0)
@@ -1574,6 +1631,47 @@ class Tensor {
1574
1631
  }
1575
1632
  return new Tensor(outputValue, { shape, numel: outputSize, ...options });
1576
1633
  }
1634
+ // Utility to create an 1D tensor from a range incrementing with "step"
1635
+ static arange(start, stop, step = 1, options = {}) {
1636
+ if (typeof stop === "undefined") {
1637
+ stop = start;
1638
+ start = 0;
1639
+ }
1640
+ const outputSize = Math.ceil((stop - start) / step);
1641
+ const outputShape = [outputSize];
1642
+ const outputValue = new Array(outputSize);
1643
+ for (let index = 0; index < outputValue.length; index++) {
1644
+ outputValue[index] = start + step * index;
1645
+ }
1646
+ return new Tensor(outputValue, { shape: outputShape, numel: outputSize, ...options });
1647
+ }
1648
+ // Utility to create an 1D tensor from a range evenly spaced out with a given amount of steps
1649
+ static linspace(start, stop, steps, options = {}) {
1650
+ if (steps <= 0)
1651
+ throw new Error("Steps must be positive");
1652
+ if (steps === 1) {
1653
+ return new Tensor([start], { shape: [1], numel: 1, ...options });
1654
+ }
1655
+ const step = (stop - start) / (steps - 1);
1656
+ const outputValue = new Array(steps);
1657
+ for (let index = 0; index < steps; index++) {
1658
+ outputValue[index] = start + step * index;
1659
+ }
1660
+ // Ensure we hit the endpoint exactly (avoids floating point errors)
1661
+ outputValue[steps - 1] = stop;
1662
+ return new Tensor(outputValue, { shape: [steps], numel: steps, ...options });
1663
+ }
1664
+ // Utility to create a 2D tensor with its main diagonal filled with 1s and others with 0s
1665
+ static eye(n, m = n, options = {}) {
1666
+ const outputSize = n * m;
1667
+ const outputShape = [n, m];
1668
+ const outputStrides = Tensor.getStrides(outputShape);
1669
+ const outputValue = new Array(outputSize).fill(0);
1670
+ for (let i = 0; i < Math.min(n, m); i++) {
1671
+ outputValue[i * outputStrides[0] + i * outputStrides[1]] = 1;
1672
+ }
1673
+ return new Tensor(outputValue, { shape: outputShape, strides: outputStrides, numel: outputSize, ...options });
1674
+ }
1577
1675
  // Reverse-mode autodiff call
1578
1676
  backward(options = {}) {
1579
1677
  // Init
package/dist/utils.d.ts CHANGED
@@ -4,3 +4,4 @@ export declare function erfinv(x: number): number;
4
4
  export declare function randUniform(low?: number, high?: number): number;
5
5
  export declare function randNormal(mean?: number, stdDev?: number): number;
6
6
  export declare function randInt(low: number, high: number): number;
7
+ export declare function fyShuffle(array: any[]): void;
package/dist/utils.js CHANGED
@@ -6,6 +6,7 @@ exports.erfinv = erfinv;
6
6
  exports.randUniform = randUniform;
7
7
  exports.randNormal = randNormal;
8
8
  exports.randInt = randInt;
9
+ exports.fyShuffle = fyShuffle;
9
10
  // Error function using Abramowitz and Stegun approximation
10
11
  function erf(x) {
11
12
  const a1 = 0.254829592;
@@ -36,15 +37,26 @@ function erfinv(x) {
36
37
  const sign = x >= 0 ? 1 : -1;
37
38
  return sign * Math.sqrt(-part1 + Math.sqrt(part1 * part1 - part2));
38
39
  }
40
+ // Generate a random number with uniform distribution
39
41
  function randUniform(low = 0, high = 1) {
40
42
  return Math.random() * (high - low) + low;
41
43
  }
44
+ // Generate a random number with normal distribution
42
45
  function randNormal(mean = 0, stdDev = 1) {
43
46
  const u = 1 - Math.random();
44
47
  const v = 1 - Math.random();
45
48
  const z = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
46
49
  return z * stdDev + mean;
47
50
  }
51
+ // Generate a random integer
48
52
  function randInt(low, high) {
49
53
  return Math.floor(Math.random() * (high - low) + low);
50
54
  }
55
+ // Randomly shuffle an array with fisher-yates algorithm
56
+ function fyShuffle(array) {
57
+ for (let i = array.length - 1; i > 0; i--) {
58
+ const j = Math.floor(Math.random() * (i + 1));
59
+ [array[i], array[j]] = [array[j], array[i]];
60
+ }
61
+ }
62
+ ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catniff",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "A small Torch-like deep learning framework for Javascript",
5
5
  "main": "index.js",
6
6
  "scripts": {