@thi.ng/tensors 0.3.1 → 0.4.0

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2025-05-10T08:50:06Z
3
+ - **Last updated**: 2025-05-12T07:03:24Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -11,6 +11,13 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
11
11
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
12
12
  and/or version bumps of transitive dependencies.
13
13
 
14
+ ## [0.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.4.0) (2025-05-12)
15
+
16
+ #### 🚀 Features
17
+
18
+ - add release() handling for tensors ([da06312](https://github.com/thi-ng/umbrella/commit/da06312))
19
+ - add data type support for range() options ([90d02bc](https://github.com/thi-ng/umbrella/commit/90d02bc))
20
+
14
21
  ## [0.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.3.0) (2025-05-08)
15
22
 
16
23
  #### 🚀 Features
package/README.md CHANGED
@@ -44,54 +44,55 @@ listed below are also based on this approach. The function signatures and naming
44
44
  conventions are closely aligned to the ones used by the
45
45
  [thi.ng/vectors](https://thi.ng/vectors) package.
46
46
 
47
- - [abs](https://docs.thi.ng/umbrella/tensors/variables/abs.html): componentwise `Math.abs`
48
- - [add](https://docs.thi.ng/umbrella/tensors/variables/add.html): tensor-tensor addition
49
- - [addN](https://docs.thi.ng/umbrella/tensors/variables/addN.html): tensor-scalar addition
50
- - [argMax](https://docs.thi.ng/umbrella/tensors/variables/argMax.html): maximum component index/value
51
- - [argMin](https://docs.thi.ng/umbrella/tensors/variables/argMin.html): minimum component index/value
52
- - [clamp](https://docs.thi.ng/umbrella/tensors/variables/clamp.html): tensor-tensor interval clamping
53
- - [clampN](https://docs.thi.ng/umbrella/tensors/variables/clampN.html): tensor-scalar interval clamping
54
- - [cos](https://docs.thi.ng/umbrella/tensors/variables/cos.html): componentwise `Math.cos`
55
- - [diagonal](https://docs.thi.ng/umbrella/tensors/variables/diagonal.html): diagonal extraction
56
- - [div](https://docs.thi.ng/umbrella/tensors/variables/div.html): tensor-tensor division
57
- - [divN](https://docs.thi.ng/umbrella/tensors/variables/divN.html): tensor-scalar division
58
- - [dot](https://docs.thi.ng/umbrella/tensors/variables/dot.html): dot product
59
- - [exp](https://docs.thi.ng/umbrella/tensors/variables/exp.html): componentwise `Math.exp`
60
- - [exp2](https://docs.thi.ng/umbrella/tensors/variables/exp2.html): componentwise `2^x`
61
- - [log](https://docs.thi.ng/umbrella/tensors/variables/log.html): componentwise `Math.log`
62
- - [log2](https://docs.thi.ng/umbrella/tensors/variables/log2.html): componentwise `Math.log2`
63
- - [mag](https://docs.thi.ng/umbrella/tensors/variables/mag.html): tensor magnitude
64
- - [magSq](https://docs.thi.ng/umbrella/tensors/variables/magSq.html): tensor squared magnitude
65
- - [max](https://docs.thi.ng/umbrella/tensors/variables/max.html): tensor-tensor maximum
66
- - [maxN](https://docs.thi.ng/umbrella/tensors/variables/maxN.html): tensor-scalar maximum
67
- - [min](https://docs.thi.ng/umbrella/tensors/variables/min.html): tensor-tensor minimum
68
- - [minN](https://docs.thi.ng/umbrella/tensors/variables/minN.html): tensor-scalar maximum
69
- - [mul](https://docs.thi.ng/umbrella/tensors/variables/mul.html): tensor-tensor multiplication
70
- - [mulN](https://docs.thi.ng/umbrella/tensors/variables/mulN.html): tensor-scalar multiplication
71
- - [mulM](https://docs.thi.ng/umbrella/tensors/variables/mulM.html): matrix-matrix product
72
- - [mulV](https://docs.thi.ng/umbrella/tensors/variables/mulV.html): matrix-vector product
73
- - [normalize](https://docs.thi.ng/umbrella/tensors/variables/normalize.html): tensor normalization (w/ optional length)
74
- - [pow](https://docs.thi.ng/umbrella/tensors/variables/pow.html): tensor-tensor `Math.pow`
75
- - [powN](https://docs.thi.ng/umbrella/tensors/variables/powN.html): tensor-scalar `Math.pow`
76
- - [product](https://docs.thi.ng/umbrella/tensors/variables/product.html): component product
77
- - [randDistrib](https://docs.thi.ng/umbrella/tensors/variables/randDistrib.html): fill with random data from distribution fn
47
+ - [abs](https://docs.thi.ng/umbrella/tensors/variables/abs.html): Componentwise `Math.abs`
48
+ - [add](https://docs.thi.ng/umbrella/tensors/variables/add.html): Tensor-tensor addition
49
+ - [addN](https://docs.thi.ng/umbrella/tensors/variables/addN.html): Tensor-scalar addition
50
+ - [argMax](https://docs.thi.ng/umbrella/tensors/variables/argMax.html): Maximum component index/value
51
+ - [argMin](https://docs.thi.ng/umbrella/tensors/variables/argMin.html): Minimum component index/value
52
+ - [clamp](https://docs.thi.ng/umbrella/tensors/variables/clamp.html): Tensor-tensor interval clamping
53
+ - [clampN](https://docs.thi.ng/umbrella/tensors/variables/clampN.html): Tensor-scalar interval clamping
54
+ - [cos](https://docs.thi.ng/umbrella/tensors/variables/cos.html): Componentwise `Math.cos`
55
+ - [diagonal](https://docs.thi.ng/umbrella/tensors/variables/diagonal.html): Diagonal extraction
56
+ - [div](https://docs.thi.ng/umbrella/tensors/variables/div.html): Tensor-tensor division
57
+ - [divN](https://docs.thi.ng/umbrella/tensors/variables/divN.html): Tensor-scalar division
58
+ - [dot](https://docs.thi.ng/umbrella/tensors/variables/dot.html): Dot product
59
+ - [exp](https://docs.thi.ng/umbrella/tensors/variables/exp.html): Componentwise `Math.exp`
60
+ - [exp2](https://docs.thi.ng/umbrella/tensors/variables/exp2.html): Componentwise `2^x`
61
+ - [log](https://docs.thi.ng/umbrella/tensors/variables/log.html): Componentwise `Math.log`
62
+ - [log2](https://docs.thi.ng/umbrella/tensors/variables/log2.html): Componentwise `Math.log2`
63
+ - [mag](https://docs.thi.ng/umbrella/tensors/variables/mag.html): Tensor magnitude
64
+ - [magSq](https://docs.thi.ng/umbrella/tensors/variables/magSq.html): Tensor squared magnitude
65
+ - [max](https://docs.thi.ng/umbrella/tensors/variables/max.html): Tensor-tensor maximum
66
+ - [maxN](https://docs.thi.ng/umbrella/tensors/variables/maxN.html): Tensor-scalar maximum
67
+ - [min](https://docs.thi.ng/umbrella/tensors/variables/min.html): Tensor-tensor minimum
68
+ - [minN](https://docs.thi.ng/umbrella/tensors/variables/minN.html): Tensor-scalar maximum
69
+ - [mul](https://docs.thi.ng/umbrella/tensors/variables/mul.html): Tensor-tensor multiplication
70
+ - [mulN](https://docs.thi.ng/umbrella/tensors/variables/mulN.html): Tensor-scalar multiplication
71
+ - [mulM](https://docs.thi.ng/umbrella/tensors/variables/mulM.html): Matrix-matrix product
72
+ - [mulV](https://docs.thi.ng/umbrella/tensors/variables/mulV.html): Matrix-vector product
73
+ - [normalize](https://docs.thi.ng/umbrella/tensors/variables/normalize.html): Tensor normalization (w/ optional length)
74
+ - [pow](https://docs.thi.ng/umbrella/tensors/variables/pow.html): Tensor-tensor `Math.pow`
75
+ - [powN](https://docs.thi.ng/umbrella/tensors/variables/powN.html): Tensor-scalar `Math.pow`
76
+ - [product](https://docs.thi.ng/umbrella/tensors/variables/product.html): Component product
77
+ - [randDistrib](https://docs.thi.ng/umbrella/tensors/variables/randDistrib.html): Fill with random data from distribution fn
78
+ - [range](https://docs.thi.ng/umbrella/tensors/variables/range.html): Create 1D tensor of monotonically increasing/decreasing values
78
79
  - [relu](https://docs.thi.ng/umbrella/tensors/variables/relu.html): ReLU activation
79
- - [reluN](https://docs.thi.ng/umbrella/tensors/variables/reluN.html): leaky ReLU activation
80
- - [select](https://docs.thi.ng/umbrella/tensors/variables/select.html): generalization of argMin/Max
81
- - [set](https://docs.thi.ng/umbrella/tensors/variables/set.html): tensor setter
82
- - [setN](https://docs.thi.ng/umbrella/tensors/variables/setN.html): tensor setter w/ uniform scalar
80
+ - [reluN](https://docs.thi.ng/umbrella/tensors/variables/reluN.html): Leaky ReLU activation
81
+ - [select](https://docs.thi.ng/umbrella/tensors/variables/select.html): Generalization of argMin/Max
82
+ - [set](https://docs.thi.ng/umbrella/tensors/variables/set.html): Tensor setter
83
+ - [setN](https://docs.thi.ng/umbrella/tensors/variables/setN.html): Tensor setter w/ uniform scalar
83
84
  - [sigmoid](https://docs.thi.ng/umbrella/tensors/variables/sigmoid.html): Sigmoid activation
84
- - [sin](https://docs.thi.ng/umbrella/tensors/variables/sin.html): componentwise `Math.sin`
85
+ - [sin](https://docs.thi.ng/umbrella/tensors/variables/sin.html): Componentwise `Math.sin`
85
86
  - [softMax](https://docs.thi.ng/umbrella/tensors/variables/softMax.html): Soft Max activation
86
- - [sqrt](https://docs.thi.ng/umbrella/tensors/variables/sqrt.html): componentwise `Math.sqrt`
87
+ - [sqrt](https://docs.thi.ng/umbrella/tensors/variables/sqrt.html): Componentwise `Math.sqrt`
87
88
  - [step](https://docs.thi.ng/umbrella/tensors/variables/step.html): Threshold function (as as GLSL `step()`)
88
- - [sub](https://docs.thi.ng/umbrella/tensors/variables/sub.html): tensor-tensor subtraction
89
- - [subN](https://docs.thi.ng/umbrella/tensors/variables/subN.html): tensor-scalar subtraction
90
- - [sum](https://docs.thi.ng/umbrella/tensors/variables/sum.html): component sum
91
- - [svd](https://docs.thi.ng/umbrella/tensors/variables/sum.html): singular value decomposition
92
- - [tan](https://docs.thi.ng/umbrella/tensors/variables/tan.html): componentwise `Math.tan`
93
- - [tanh](https://docs.thi.ng/umbrella/tensors/variables/tanh.html): componentwise `Math.tanh`
94
- - [trace](https://docs.thi.ng/umbrella/tensors/variables/trace.html): matrix trace (diagonal component sum)
89
+ - [sub](https://docs.thi.ng/umbrella/tensors/variables/sub.html): Tensor-tensor subtraction
90
+ - [subN](https://docs.thi.ng/umbrella/tensors/variables/subN.html): Tensor-scalar subtraction
91
+ - [sum](https://docs.thi.ng/umbrella/tensors/variables/sum.html): Component sum
92
+ - [svd](https://docs.thi.ng/umbrella/tensors/variables/sum.html): Singular value decomposition
93
+ - [tan](https://docs.thi.ng/umbrella/tensors/variables/tan.html): Componentwise `Math.tan`
94
+ - [tanh](https://docs.thi.ng/umbrella/tensors/variables/tanh.html): Componentwise `Math.tanh`
95
+ - [trace](https://docs.thi.ng/umbrella/tensors/variables/trace.html): Matrix trace (diagonal component sum)
95
96
 
96
97
  ### Broadcasting support
97
98
 
@@ -180,7 +181,7 @@ For Node.js REPL:
180
181
  const ten = await import("@thi.ng/tensors");
181
182
  ```
182
183
 
183
- Package sizes (brotli'd, pre-treeshake): ESM: 8.06 KB
184
+ Package sizes (brotli'd, pre-treeshake): ESM: 8.08 KB
184
185
 
185
186
  ## Dependencies
186
187
 
@@ -206,10 +207,9 @@ TODO
206
207
 
207
208
  ```ts tangle:export/readme-1.ts
208
209
  import * as t from "@thi.ng/tensors";
209
- import { range } from "@thi.ng/transducers";
210
210
 
211
211
  // create 4x4x4 3D tensor and fill with values
212
- const a = t.tensor("f32", [4, 4, 4], { data: [...range(64)] });
212
+ const a = t.range(64).reshape([4, 4, 4]);
213
213
 
214
214
  t.print(a);
215
215
  // --- 0: ---
@@ -247,7 +247,7 @@ t.print(a.pick([3, -1, 2]));
247
247
 
248
248
  // use `.pack()` to apply view to standalone densely packed tensor (own data)
249
249
  console.log(a.pick([3, 2]).pack().data);
250
- // Float32Array(4) [ 56, 57, 58, 59 ]
250
+ // [ 56, 57, 58, 59 ]
251
251
 
252
252
  // only select every second value along each axis
253
253
  t.print(a.step([2, 2, 2]));
package/api.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import type { Type as $Type, ICopy, IEqualsDelta, IEquiv, ILength, Maybe, NumericArray } from "@thi.ng/api";
1
+ import type { Type as $Type, ICopy, IEqualsDelta, IEquiv, ILength, IRelease, Maybe, NumericArray } from "@thi.ng/api";
2
2
  import type { Tensor1, Tensor2, Tensor3, Tensor4 } from "./tensor.js";
3
3
  export interface TensorData<T = number> extends Iterable<T>, ILength {
4
4
  [id: number]: T;
5
5
  fill(x: T, start?: number, end?: number): TensorData<T>;
6
6
  }
7
7
  export type Type = $Type | "num" | "str";
8
- export type NumType = Type | "num";
8
+ export type NumType = $Type | "num";
9
9
  export type Shape1 = [number];
10
10
  export type Shape2 = [number, number];
11
11
  export type Shape3 = [number, number, number];
@@ -58,7 +58,7 @@ export interface TensorFromArrayOpts<T extends Type, V> {
58
58
  type: T;
59
59
  storage?: ITensorStorage<V>;
60
60
  }
61
- export interface ITensor<T = number> extends ICopy<ITensor<T>>, IEquiv, IEqualsDelta<ITensor<T>> {
61
+ export interface ITensor<T = number> extends ICopy<ITensor<T>>, IEquiv, IEqualsDelta<ITensor<T>>, IRelease {
62
62
  readonly type: Type;
63
63
  readonly storage: ITensorStorage<T>;
64
64
  readonly data: TensorData<T>;
@@ -118,8 +118,26 @@ export interface TensorCtor<T = number> {
118
118
  new (type: Type, storage: ITensorStorage<T>, data: TensorData<T>, shape: number[], stride: number[], offset?: number): ITensor<T>;
119
119
  }
120
120
  export interface ITensorStorage<T> {
121
+ /**
122
+ * Attempts to allocate/create an array for given number of items. Throws an
123
+ * error if unsuccessful.
124
+ *
125
+ * @param size
126
+ */
121
127
  alloc(size: number): TensorData<T>;
128
+ /**
129
+ * Attempts to allocate/create an array for given iterable. Throws an
130
+ * error if unsuccessful.
131
+ *
132
+ * @param iter
133
+ */
122
134
  from(iter: Iterable<T>): TensorData<T>;
135
+ /**
136
+ * Attempts to release the array/memory used by given buffer. Returns true
137
+ * if successful.
138
+ *
139
+ * @param buf
140
+ */
123
141
  release(buf: TensorData<T>): boolean;
124
142
  }
125
143
  export type StorageRegistry = Record<Type, ITensorStorage<any>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/tensors",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -301,5 +301,5 @@
301
301
  "status": "alpha",
302
302
  "year": 2018
303
303
  },
304
- "gitHead": "e47e081cc7ef3a5adf0b6a92366eab1072c51fec\n"
304
+ "gitHead": "5ec76378887e4f55ad519e235e08a5dd0c53be51\n"
305
305
  }
package/range.d.ts CHANGED
@@ -1,12 +1,20 @@
1
- import type { TensorOpts } from "./api.js";
1
+ import type { NumType, TensorOpts } from "./api.js";
2
2
  import { Tensor1 } from "./tensor.js";
3
+ export interface RangeOpts<T extends NumType> extends Pick<TensorOpts<T, [number]>, "storage"> {
4
+ /**
5
+ * Tensor data type.
6
+ *
7
+ * @defaultValue "num"
8
+ */
9
+ type: T;
10
+ }
3
11
  /**
4
12
  * Creates a 1D tensor of monotonically increasing values in the interval `[0,max)`.
5
13
  *
6
14
  * @param max
7
15
  * @param opts
8
16
  */
9
- export declare function range(max: number, opts?: Pick<TensorOpts<number, any>, "storage">): Tensor1;
17
+ export declare function range<T extends NumType>(max: number, opts?: RangeOpts<T>): Tensor1;
10
18
  /**
11
19
  * Creates a 1D tensor of monotonically increasing values in the interval
12
20
  * `[min,max)`, using optional `step` and `opts`. If `from <= to`, the default
@@ -16,5 +24,5 @@ export declare function range(max: number, opts?: Pick<TensorOpts<number, any>,
16
24
  * @param to
17
25
  * @param opts
18
26
  */
19
- export declare function range(from: number, to: number, step?: number, opts?: Pick<TensorOpts<number, any>, "storage">): Tensor1;
27
+ export declare function range<T extends NumType>(from: number, to: number, step?: number, opts?: RangeOpts<T>): Tensor1;
20
28
  //# sourceMappingURL=range.d.ts.map
package/range.js CHANGED
@@ -3,12 +3,13 @@ import { isPlainObject } from "@thi.ng/checks";
3
3
  import { tensor, Tensor1 } from "./tensor.js";
4
4
  function range(...args) {
5
5
  const opts = isPlainObject(peek(args)) ? args.pop() : void 0;
6
+ const type = opts?.type ?? "num";
6
7
  let [from, to, step] = args;
7
8
  if (to === void 0) {
8
9
  to = from;
9
10
  from = 0;
10
11
  }
11
- step = step === void 0 ? from < to ? 1 : -1 : step;
12
+ step = step ?? (from < to ? 1 : -1);
12
13
  const data = [];
13
14
  if (step > 0) {
14
15
  while (from < to) {
@@ -21,7 +22,7 @@ function range(...args) {
21
22
  from += step;
22
23
  }
23
24
  }
24
- return tensor("num", [data.length], { ...opts, data });
25
+ return tensor(type, [data.length], { ...opts, copy: type !== "num", data });
25
26
  }
26
27
  export {
27
28
  range
package/storage.js CHANGED
@@ -1,21 +1,20 @@
1
- import {} from "@thi.ng/api";
2
1
  import { always } from "@thi.ng/api/fn";
3
2
  import { typedArray, TYPEDARRAY_CTORS } from "@thi.ng/api/typedarray";
4
- const impl = (type) => ({
3
+ const __impl = (type) => ({
5
4
  alloc: (size) => typedArray(type, size),
6
5
  from: (iter) => TYPEDARRAY_CTORS[type].from(iter),
7
6
  release: always
8
7
  });
9
8
  const STORAGE = {
10
- u8: impl("u8"),
11
- u8c: impl("u8c"),
12
- i8: impl("i8"),
13
- u16: impl("u16"),
14
- i16: impl("i16"),
15
- u32: impl("u32"),
16
- i32: impl("i32"),
17
- f32: impl("f32"),
18
- f64: impl("f64"),
9
+ u8: __impl("u8"),
10
+ u8c: __impl("u8c"),
11
+ i8: __impl("i8"),
12
+ u16: __impl("u16"),
13
+ i16: __impl("i16"),
14
+ u32: __impl("u32"),
15
+ i32: __impl("i32"),
16
+ f32: __impl("f32"),
17
+ f64: __impl("f64"),
19
18
  num: {
20
19
  alloc: (size) => new Array(size).fill(0),
21
20
  from: (iter) => [...iter],
package/tensor.d.ts CHANGED
@@ -17,6 +17,10 @@ export declare abstract class ATensor<T = number> implements ITensor<T> {
17
17
  broadcast<S extends Shape>(shape: S, stride: S): ShapeTensor<S, T>;
18
18
  copy(): typeof this;
19
19
  empty(storage?: ITensorStorage<T>): typeof this;
20
+ /**
21
+ * Calls {@link ITensorStorage.release} with this tensor's data.
22
+ */
23
+ release(): boolean;
20
24
  equiv(o: any): boolean;
21
25
  eqDelta(o: ITensor<T>, eps?: number): boolean;
22
26
  abstract index(pos: NumericArray): number;
package/tensor.js CHANGED
@@ -58,6 +58,12 @@ class ATensor {
58
58
  shapeToStride(this.shape)
59
59
  );
60
60
  }
61
+ /**
62
+ * Calls {@link ITensorStorage.release} with this tensor's data.
63
+ */
64
+ release() {
65
+ return this.storage.release(this.data);
66
+ }
61
67
  equiv(o) {
62
68
  return this === o || o instanceof ATensor && equiv(this.shape, o.shape) && equivArrayLike([...this], [...o]);
63
69
  }