@thi.ng/tensors 0.2.0 → 0.3.1
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 +20 -1
- package/README.md +1 -1
- package/api.d.ts +20 -1
- package/broadcast.d.ts +2 -2
- package/defoprt.d.ts +3 -3
- package/defoprt.js +4 -4
- package/defoprtt.d.ts +6 -5
- package/defoprtt.js +10 -8
- package/dot.js +1 -1
- package/filtered-indices.d.ts +34 -0
- package/filtered-indices.js +17 -0
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/magsq.js +1 -1
- package/normalize.d.ts +1 -1
- package/package.json +11 -2
- package/product.js +4 -2
- package/range.d.ts +20 -0
- package/range.js +28 -0
- package/sum.js +4 -2
- package/swap.d.ts +26 -0
- package/swap.js +15 -0
- package/tensor.d.ts +4 -2
- package/tensor.js +14 -1
- package/defopbtt.d.ts +0 -11
- package/defopbtt.js +0 -153
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2025-05-
|
|
3
|
+
- **Last updated**: 2025-05-10T08:50:06Z
|
|
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,25 @@ 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.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.3.0) (2025-05-08)
|
|
15
|
+
|
|
16
|
+
#### 🚀 Features
|
|
17
|
+
|
|
18
|
+
- add swap(), update defOpRT/TT() fns ([5d2dd2a](https://github.com/thi-ng/umbrella/commit/5d2dd2a))
|
|
19
|
+
- add range() tensor factory ([a8a6365](https://github.com/thi-ng/umbrella/commit/a8a6365))
|
|
20
|
+
- add ITensor.position() & impls ([595764d](https://github.com/thi-ng/umbrella/commit/595764d))
|
|
21
|
+
- add filteredIndices() & presets ([edd8983](https://github.com/thi-ng/umbrella/commit/edd8983))
|
|
22
|
+
- add nonZeroIndices()
|
|
23
|
+
- add negativeIndices(), positiveIndices()
|
|
24
|
+
|
|
25
|
+
#### 🩹 Bug fixes
|
|
26
|
+
|
|
27
|
+
- update ITensor.broadcast() return type ([f7b2e7a](https://github.com/thi-ng/umbrella/commit/f7b2e7a))
|
|
28
|
+
|
|
29
|
+
#### ♻️ Refactoring
|
|
30
|
+
|
|
31
|
+
- update range() impl (w/o dependencies) ([ce89d71](https://github.com/thi-ng/umbrella/commit/ce89d71))
|
|
32
|
+
|
|
14
33
|
## [0.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.2.0) (2025-05-02)
|
|
15
34
|
|
|
16
35
|
#### 🚀 Features
|
package/README.md
CHANGED
package/api.d.ts
CHANGED
|
@@ -80,9 +80,28 @@ export interface ITensor<T = number> extends ICopy<ITensor<T>>, IEquiv, IEqualsD
|
|
|
80
80
|
*
|
|
81
81
|
* @internal
|
|
82
82
|
*/
|
|
83
|
-
broadcast(shape:
|
|
83
|
+
broadcast<S extends Shape>(shape: S, stride: S): ShapeTensor<S, T>;
|
|
84
84
|
empty(storage?: ITensorStorage<T>): this;
|
|
85
|
+
/**
|
|
86
|
+
* Computes linear array index from given grid position. Reverse-op of
|
|
87
|
+
* {@link ITensor.position}.
|
|
88
|
+
*
|
|
89
|
+
* @param pos
|
|
90
|
+
*/
|
|
85
91
|
index(pos: NumericArray): number;
|
|
92
|
+
/**
|
|
93
|
+
* Computes nD grid position for given linear array index. Reverse-op of
|
|
94
|
+
* {@link ITensor.index}.
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* **CAUTION:** Currently only supports tensors with positive strides,
|
|
98
|
+
* otherwise will yield incorrect results! Tensors with negative strides
|
|
99
|
+
* (aka flipped axes in reverse order) need to be first packed via
|
|
100
|
+
* {@link ITensor.pack}.
|
|
101
|
+
*
|
|
102
|
+
* @param index
|
|
103
|
+
*/
|
|
104
|
+
position(index: number): number[];
|
|
86
105
|
get(pos: NumericArray): T;
|
|
87
106
|
set(pos: NumericArray, value: T): this;
|
|
88
107
|
lo(pos: NumericArray): this;
|
package/broadcast.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ import type { ITensor, Shape } from "./api.js";
|
|
|
18
18
|
*/
|
|
19
19
|
export declare const broadcast: <T = number>(a: ITensor<T>, b: ITensor<T>) => {
|
|
20
20
|
shape: Shape;
|
|
21
|
-
a: ITensor<T>;
|
|
22
|
-
b: ITensor<T>;
|
|
21
|
+
a: ITensor<T> | import("./tensor.js").Tensor4<T> | import("./tensor.js").Tensor3<T> | import("./tensor.js").Tensor2<T> | import("./tensor.js").Tensor1<T>;
|
|
22
|
+
b: ITensor<T> | import("./tensor.js").Tensor4<T> | import("./tensor.js").Tensor3<T> | import("./tensor.js").Tensor2<T> | import("./tensor.js").Tensor1<T>;
|
|
23
23
|
};
|
|
24
24
|
//# sourceMappingURL=broadcast.d.ts.map
|
package/defoprt.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Fn0
|
|
2
|
-
import type { TensorOpRT } from "./api.js";
|
|
1
|
+
import type { Fn0 } from "@thi.ng/api";
|
|
2
|
+
import type { TensorData, TensorOpRT } from "./api.js";
|
|
3
3
|
/**
|
|
4
4
|
* Higher order tensor reduction op factory. Takes given reduction `rfn` and
|
|
5
5
|
* `init` function to produce an initial result. Returns a {@link TensorOpRT}
|
|
@@ -8,5 +8,5 @@ import type { TensorOpRT } from "./api.js";
|
|
|
8
8
|
* @param rfn
|
|
9
9
|
* @param init
|
|
10
10
|
*/
|
|
11
|
-
export declare const defOpRT: <A = number, B = A>(rfn:
|
|
11
|
+
export declare const defOpRT: <A = number, B = A>(rfn: (acc: B, data: TensorData<A>, i: number) => B, init: Fn0<B>) => import("./api.js").MultiTensorOpImpl<TensorOpRT<A, B>>;
|
|
12
12
|
//# sourceMappingURL=defoprt.d.ts.map
|
package/defoprt.js
CHANGED
|
@@ -9,7 +9,7 @@ const defOpRT = (rfn, init) => {
|
|
|
9
9
|
} = a;
|
|
10
10
|
let res = init();
|
|
11
11
|
for (let x = 0; x < sx; x++) {
|
|
12
|
-
res = rfn(res, data
|
|
12
|
+
res = rfn(res, data, offset + x * tx);
|
|
13
13
|
}
|
|
14
14
|
return res;
|
|
15
15
|
};
|
|
@@ -25,7 +25,7 @@ const defOpRT = (rfn, init) => {
|
|
|
25
25
|
for (let x = 0; x < sx; x++) {
|
|
26
26
|
ox = offset + x * tx;
|
|
27
27
|
for (let y = 0; y < sy; y++) {
|
|
28
|
-
res = rfn(res, data
|
|
28
|
+
res = rfn(res, data, ox + y * ty);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
return res;
|
|
@@ -44,7 +44,7 @@ const defOpRT = (rfn, init) => {
|
|
|
44
44
|
for (let y = 0; y < sy; y++) {
|
|
45
45
|
oy = ox + y * ty;
|
|
46
46
|
for (let z = 0; z < sz; z++) {
|
|
47
|
-
res = rfn(res, data
|
|
47
|
+
res = rfn(res, data, oy + z * tz);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -66,7 +66,7 @@ const defOpRT = (rfn, init) => {
|
|
|
66
66
|
for (let z = 0; z < sz; z++) {
|
|
67
67
|
oz = oy + z * tz;
|
|
68
68
|
for (let w = 0; w < sw; w++) {
|
|
69
|
-
res = rfn(res, data
|
|
69
|
+
res = rfn(res, data, oz + w * tw);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
}
|
package/defoprtt.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import type { Fn0
|
|
2
|
-
import type { TensorOpRTT } from "./api.js";
|
|
1
|
+
import type { Fn0 } from "@thi.ng/api";
|
|
2
|
+
import type { TensorData, TensorOpRTT } from "./api.js";
|
|
3
3
|
/**
|
|
4
4
|
* Higher order tensor reduction op factory. Takes given reduction `rfn` and
|
|
5
5
|
* `init` function to produce an initial result. Returns a {@link TensorOpRTT}
|
|
6
|
-
* applying the given function componentwise with broadcasting rules
|
|
7
|
-
* {@link broadcast} for details).
|
|
6
|
+
* applying the given function componentwise, by default with broadcasting rules
|
|
7
|
+
* (see {@link broadcast} for details).
|
|
8
8
|
*
|
|
9
9
|
* @param rfn
|
|
10
10
|
* @param init
|
|
11
|
+
* @param useBroadcast
|
|
11
12
|
*/
|
|
12
|
-
export declare const defOpRTT: <A = number, B = A>(rfn:
|
|
13
|
+
export declare const defOpRTT: <A = number, B = A>(rfn: (acc: B, adata: TensorData<A>, bdata: TensorData<A>, ia: number, ib: number) => B, init: Fn0<B>, useBroadcast?: boolean) => TensorOpRTT<A, B>;
|
|
13
14
|
//# sourceMappingURL=defoprtt.d.ts.map
|
package/defoprtt.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { broadcast } from "./broadcast.js";
|
|
2
|
-
const defOpRTT = (rfn, init) => {
|
|
2
|
+
const defOpRTT = (rfn, init, useBroadcast = true) => {
|
|
3
3
|
const f1 = (a, b) => {
|
|
4
4
|
const {
|
|
5
5
|
data: adata,
|
|
@@ -14,7 +14,7 @@ const defOpRTT = (rfn, init) => {
|
|
|
14
14
|
} = b;
|
|
15
15
|
let res = init();
|
|
16
16
|
for (let x = 0; x < sx; x++) {
|
|
17
|
-
res = rfn(res, adata
|
|
17
|
+
res = rfn(res, adata, bdata, oa + x * txa, ob + x * txb);
|
|
18
18
|
}
|
|
19
19
|
return res;
|
|
20
20
|
};
|
|
@@ -36,7 +36,7 @@ const defOpRTT = (rfn, init) => {
|
|
|
36
36
|
oax = oa + x * txa;
|
|
37
37
|
obx = ob + x * txb;
|
|
38
38
|
for (let y = 0; y < sy; y++) {
|
|
39
|
-
res = rfn(res, adata
|
|
39
|
+
res = rfn(res, adata, bdata, oax + y * tya, obx + y * tyb);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
return res;
|
|
@@ -62,7 +62,7 @@ const defOpRTT = (rfn, init) => {
|
|
|
62
62
|
oay = oax + y * tya;
|
|
63
63
|
oby = obx + y * tyb;
|
|
64
64
|
for (let z = 0; z < sz; z++) {
|
|
65
|
-
res = rfn(res, adata
|
|
65
|
+
res = rfn(res, adata, bdata, oay + z * tza, oby + z * tzb);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -94,8 +94,10 @@ const defOpRTT = (rfn, init) => {
|
|
|
94
94
|
for (let w = 0; w < sw; w++) {
|
|
95
95
|
res = rfn(
|
|
96
96
|
res,
|
|
97
|
-
adata
|
|
98
|
-
bdata
|
|
97
|
+
adata,
|
|
98
|
+
bdata,
|
|
99
|
+
oaz + w * twa,
|
|
100
|
+
obz + w * twb
|
|
99
101
|
);
|
|
100
102
|
}
|
|
101
103
|
}
|
|
@@ -104,10 +106,10 @@ const defOpRTT = (rfn, init) => {
|
|
|
104
106
|
return res;
|
|
105
107
|
};
|
|
106
108
|
const impls = [, f1, f2, f3, f4];
|
|
107
|
-
const wrapper = (a, b) => {
|
|
109
|
+
const wrapper = useBroadcast ? (a, b) => {
|
|
108
110
|
const { shape, a: $a, b: $b } = broadcast(a, b);
|
|
109
111
|
return impls[shape.length]($a, $b);
|
|
110
|
-
};
|
|
112
|
+
} : (a, b) => impls[a.dim](a, b);
|
|
111
113
|
return wrapper;
|
|
112
114
|
};
|
|
113
115
|
export {
|
package/dot.js
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Predicate } from "@thi.ng/api";
|
|
2
|
+
/**
|
|
3
|
+
* Higher order function. Takes a predicate function and returns a new function
|
|
4
|
+
* which accepts a tensor and then returns an array of tensor component indices
|
|
5
|
+
* for which the predicate passed.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Also see {@link nonZeroIndices}.
|
|
9
|
+
*
|
|
10
|
+
* @param pred
|
|
11
|
+
*/
|
|
12
|
+
export declare const filteredIndices: <T = number>(pred: Predicate<T>) => import("./api.js").MultiTensorOpImpl<import("./api.js").TensorOpRT<T, number[]>>;
|
|
13
|
+
/**
|
|
14
|
+
* Returns an array of indices where the given tensor has non-zero component
|
|
15
|
+
* values.
|
|
16
|
+
*
|
|
17
|
+
* @param a
|
|
18
|
+
*/
|
|
19
|
+
export declare const nonZeroIndices: import("./api.js").MultiTensorOpImpl<import("./api.js").TensorOpRT<number, number[]>>;
|
|
20
|
+
/**
|
|
21
|
+
* Returns an array of indices where the given tensor has negative component
|
|
22
|
+
* values.
|
|
23
|
+
*
|
|
24
|
+
* @param a
|
|
25
|
+
*/
|
|
26
|
+
export declare const negativeIndices: import("./api.js").MultiTensorOpImpl<import("./api.js").TensorOpRT<number, number[]>>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns an array of indices where the given tensor has positive component
|
|
29
|
+
* values.
|
|
30
|
+
*
|
|
31
|
+
* @param a
|
|
32
|
+
*/
|
|
33
|
+
export declare const positiveIndices: import("./api.js").MultiTensorOpImpl<import("./api.js").TensorOpRT<number, number[]>>;
|
|
34
|
+
//# sourceMappingURL=filtered-indices.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defOpRT } from "./defoprt.js";
|
|
2
|
+
const filteredIndices = (pred) => defOpRT(
|
|
3
|
+
(acc, data, i) => {
|
|
4
|
+
if (pred(data[i])) acc.push(i);
|
|
5
|
+
return acc;
|
|
6
|
+
},
|
|
7
|
+
() => []
|
|
8
|
+
);
|
|
9
|
+
const nonZeroIndices = filteredIndices((x) => x !== 0);
|
|
10
|
+
const negativeIndices = filteredIndices((x) => x < 0);
|
|
11
|
+
const positiveIndices = filteredIndices((x) => x > 0);
|
|
12
|
+
export {
|
|
13
|
+
filteredIndices,
|
|
14
|
+
negativeIndices,
|
|
15
|
+
nonZeroIndices,
|
|
16
|
+
positiveIndices
|
|
17
|
+
};
|
package/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export * from "./dot.js";
|
|
|
21
21
|
export * from "./errors.js";
|
|
22
22
|
export * from "./exp.js";
|
|
23
23
|
export * from "./exp2.js";
|
|
24
|
+
export * from "./filtered-indices.js";
|
|
24
25
|
export * from "./format.js";
|
|
25
26
|
export * from "./identity.js";
|
|
26
27
|
export * from "./log.js";
|
|
@@ -40,6 +41,7 @@ export * from "./pow.js";
|
|
|
40
41
|
export * from "./pown.js";
|
|
41
42
|
export * from "./product.js";
|
|
42
43
|
export * from "./rand-distrib.js";
|
|
44
|
+
export * from "./range.js";
|
|
43
45
|
export * from "./relu.js";
|
|
44
46
|
export * from "./relun.js";
|
|
45
47
|
export * from "./select.js";
|
|
@@ -56,6 +58,7 @@ export * from "./sub.js";
|
|
|
56
58
|
export * from "./subn.js";
|
|
57
59
|
export * from "./sum.js";
|
|
58
60
|
export * from "./svd.js";
|
|
61
|
+
export * from "./swap.js";
|
|
59
62
|
export * from "./tan.js";
|
|
60
63
|
export * from "./tanh.js";
|
|
61
64
|
export * from "./tensor.js";
|
package/index.js
CHANGED
|
@@ -21,6 +21,7 @@ export * from "./dot.js";
|
|
|
21
21
|
export * from "./errors.js";
|
|
22
22
|
export * from "./exp.js";
|
|
23
23
|
export * from "./exp2.js";
|
|
24
|
+
export * from "./filtered-indices.js";
|
|
24
25
|
export * from "./format.js";
|
|
25
26
|
export * from "./identity.js";
|
|
26
27
|
export * from "./log.js";
|
|
@@ -40,6 +41,7 @@ export * from "./pow.js";
|
|
|
40
41
|
export * from "./pown.js";
|
|
41
42
|
export * from "./product.js";
|
|
42
43
|
export * from "./rand-distrib.js";
|
|
44
|
+
export * from "./range.js";
|
|
43
45
|
export * from "./relu.js";
|
|
44
46
|
export * from "./relun.js";
|
|
45
47
|
export * from "./select.js";
|
|
@@ -56,6 +58,7 @@ export * from "./sub.js";
|
|
|
56
58
|
export * from "./subn.js";
|
|
57
59
|
export * from "./sum.js";
|
|
58
60
|
export * from "./svd.js";
|
|
61
|
+
export * from "./swap.js";
|
|
59
62
|
export * from "./tan.js";
|
|
60
63
|
export * from "./tanh.js";
|
|
61
64
|
export * from "./tensor.js";
|
package/magsq.js
CHANGED
package/normalize.d.ts
CHANGED
|
@@ -7,5 +7,5 @@ import type { ITensor } from "./api.js";
|
|
|
7
7
|
* @param a
|
|
8
8
|
* @param n
|
|
9
9
|
*/
|
|
10
|
-
export declare const normalize: (out: ITensor | null, a: ITensor, n?: number) =>
|
|
10
|
+
export declare const normalize: (out: ITensor | null, a: ITensor, n?: number) => import("./tensor.js").Tensor1<any> | ITensor<number>;
|
|
11
11
|
//# sourceMappingURL=normalize.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/tensors",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -170,6 +170,9 @@
|
|
|
170
170
|
"./exp2": {
|
|
171
171
|
"default": "./exp2.js"
|
|
172
172
|
},
|
|
173
|
+
"./filtered-indices": {
|
|
174
|
+
"default": "./filtered-indices.js"
|
|
175
|
+
},
|
|
173
176
|
"./format": {
|
|
174
177
|
"default": "./format.js"
|
|
175
178
|
},
|
|
@@ -227,6 +230,9 @@
|
|
|
227
230
|
"./rand-distrib": {
|
|
228
231
|
"default": "./rand-distrib.js"
|
|
229
232
|
},
|
|
233
|
+
"./range": {
|
|
234
|
+
"default": "./range.js"
|
|
235
|
+
},
|
|
230
236
|
"./relu": {
|
|
231
237
|
"default": "./relu.js"
|
|
232
238
|
},
|
|
@@ -275,6 +281,9 @@
|
|
|
275
281
|
"./svd": {
|
|
276
282
|
"default": "./svd.js"
|
|
277
283
|
},
|
|
284
|
+
"./swap": {
|
|
285
|
+
"default": "./swap.js"
|
|
286
|
+
},
|
|
278
287
|
"./tan": {
|
|
279
288
|
"default": "./tan.js"
|
|
280
289
|
},
|
|
@@ -292,5 +301,5 @@
|
|
|
292
301
|
"status": "alpha",
|
|
293
302
|
"year": 2018
|
|
294
303
|
},
|
|
295
|
-
"gitHead": "
|
|
304
|
+
"gitHead": "e47e081cc7ef3a5adf0b6a92366eab1072c51fec\n"
|
|
296
305
|
}
|
package/product.js
CHANGED
package/range.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TensorOpts } from "./api.js";
|
|
2
|
+
import { Tensor1 } from "./tensor.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a 1D tensor of monotonically increasing values in the interval `[0,max)`.
|
|
5
|
+
*
|
|
6
|
+
* @param max
|
|
7
|
+
* @param opts
|
|
8
|
+
*/
|
|
9
|
+
export declare function range(max: number, opts?: Pick<TensorOpts<number, any>, "storage">): Tensor1;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a 1D tensor of monotonically increasing values in the interval
|
|
12
|
+
* `[min,max)`, using optional `step` and `opts`. If `from <= to`, the default
|
|
13
|
+
* step is 1, otherise -1.
|
|
14
|
+
*
|
|
15
|
+
* @param from
|
|
16
|
+
* @param to
|
|
17
|
+
* @param opts
|
|
18
|
+
*/
|
|
19
|
+
export declare function range(from: number, to: number, step?: number, opts?: Pick<TensorOpts<number, any>, "storage">): Tensor1;
|
|
20
|
+
//# sourceMappingURL=range.d.ts.map
|
package/range.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { peek } from "@thi.ng/arrays/peek";
|
|
2
|
+
import { isPlainObject } from "@thi.ng/checks";
|
|
3
|
+
import { tensor, Tensor1 } from "./tensor.js";
|
|
4
|
+
function range(...args) {
|
|
5
|
+
const opts = isPlainObject(peek(args)) ? args.pop() : void 0;
|
|
6
|
+
let [from, to, step] = args;
|
|
7
|
+
if (to === void 0) {
|
|
8
|
+
to = from;
|
|
9
|
+
from = 0;
|
|
10
|
+
}
|
|
11
|
+
step = step === void 0 ? from < to ? 1 : -1 : step;
|
|
12
|
+
const data = [];
|
|
13
|
+
if (step > 0) {
|
|
14
|
+
while (from < to) {
|
|
15
|
+
data.push(from);
|
|
16
|
+
from += step;
|
|
17
|
+
}
|
|
18
|
+
} else if (step < 0) {
|
|
19
|
+
while (from > to) {
|
|
20
|
+
data.push(from);
|
|
21
|
+
from += step;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return tensor("num", [data.length], { ...opts, data });
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
range
|
|
28
|
+
};
|
package/sum.js
CHANGED
package/swap.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ITensor } from "./api.js";
|
|
2
|
+
/**
|
|
3
|
+
* Swaps all data value of the two given tensors (which must have same shape).
|
|
4
|
+
* Returns `a`.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Combined with {@link ITensor.pick}, this can be used to swap
|
|
8
|
+
* columns/rows/slices of a shared parent tensor.
|
|
9
|
+
*
|
|
10
|
+
* ```ts tangle:../export/swap.ts
|
|
11
|
+
* import { swap, range, print } from "@thi.ng/tensors";
|
|
12
|
+
*
|
|
13
|
+
* const a = range(12).reshape([3,4]);
|
|
14
|
+
* print(a);
|
|
15
|
+
*
|
|
16
|
+
* // swap data from 1st & 3rd column
|
|
17
|
+
* swap(a.pick([-1,0]), a.pick([-1,2]));
|
|
18
|
+
*
|
|
19
|
+
* print(a);
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param a
|
|
23
|
+
* @param b
|
|
24
|
+
*/
|
|
25
|
+
export declare const swap: <A, TA extends ITensor<A>>(a: TA, b: TA) => TA;
|
|
26
|
+
//# sourceMappingURL=swap.d.ts.map
|
package/swap.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defOpRTT } from "./defoprtt.js";
|
|
2
|
+
const $swap = defOpRTT(
|
|
3
|
+
(_, adata, bdata, ia, ib) => {
|
|
4
|
+
const t = adata[ia];
|
|
5
|
+
adata[ia] = bdata[ib];
|
|
6
|
+
bdata[ib] = t;
|
|
7
|
+
},
|
|
8
|
+
() => {
|
|
9
|
+
},
|
|
10
|
+
false
|
|
11
|
+
);
|
|
12
|
+
const swap = (a, b) => $swap(a, b);
|
|
13
|
+
export {
|
|
14
|
+
swap
|
|
15
|
+
};
|
package/tensor.d.ts
CHANGED
|
@@ -14,12 +14,13 @@ export declare abstract class ATensor<T = number> implements ITensor<T> {
|
|
|
14
14
|
get orderedShape(): number[];
|
|
15
15
|
get orderedStride(): number[];
|
|
16
16
|
abstract [Symbol.iterator](): IterableIterator<T>;
|
|
17
|
-
broadcast(shape:
|
|
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
20
|
equiv(o: any): boolean;
|
|
21
21
|
eqDelta(o: ITensor<T>, eps?: number): boolean;
|
|
22
22
|
abstract index(pos: NumericArray): number;
|
|
23
|
+
position(index: number): any[];
|
|
23
24
|
abstract get(pos: NumericArray): T;
|
|
24
25
|
abstract set(pos: NumericArray, v: T): this;
|
|
25
26
|
hi(pos: NumericArray): this;
|
|
@@ -43,6 +44,7 @@ export declare class Tensor1<T = number> extends ATensor<T> {
|
|
|
43
44
|
get order(): number[];
|
|
44
45
|
get length(): number;
|
|
45
46
|
index([x]: NumericArray): number;
|
|
47
|
+
position(index: number): number[];
|
|
46
48
|
get([x]: NumericArray): T;
|
|
47
49
|
set([x]: NumericArray, v: T): this;
|
|
48
50
|
pick([x]: NumericArray): Tensor1<T>;
|
|
@@ -125,6 +127,6 @@ export declare function tensorFromArray<T extends NumType, N extends Nested<numb
|
|
|
125
127
|
export declare function tensorFromArray<N extends Nested<string>>(data: N, opts?: TensorFromArrayOpts<"str", string>): NestedTensor<N, string>;
|
|
126
128
|
export declare const zeroes: <S extends Shape>(shape: S, type?: NumType, storage?: ITensorStorage<number>) => ShapeTensor<S, number>;
|
|
127
129
|
export declare const ones: <S extends Shape>(shape: S, type?: NumType, storage?: ITensorStorage<number>) => ShapeTensor<S, number>;
|
|
128
|
-
export declare const shapeToStride: (shape:
|
|
130
|
+
export declare const shapeToStride: (shape: number[]) => any[];
|
|
129
131
|
export declare const strideOrder: (strides: number[]) => number[];
|
|
130
132
|
//# sourceMappingURL=tensor.d.ts.map
|
package/tensor.js
CHANGED
|
@@ -30,7 +30,7 @@ class ATensor {
|
|
|
30
30
|
return swizzle(this.order)(this.stride);
|
|
31
31
|
}
|
|
32
32
|
broadcast(shape, stride) {
|
|
33
|
-
return new
|
|
33
|
+
return new TENSOR_IMPLS[shape.length](
|
|
34
34
|
this.type,
|
|
35
35
|
this.storage,
|
|
36
36
|
this.data,
|
|
@@ -64,6 +64,16 @@ class ATensor {
|
|
|
64
64
|
eqDelta(o, eps = 1e-6) {
|
|
65
65
|
return this === o || equiv(this.shape, o.shape) && _eqDelta([...this], [...o], this.length, eps);
|
|
66
66
|
}
|
|
67
|
+
position(index) {
|
|
68
|
+
const { order, stride } = this;
|
|
69
|
+
index -= this.offset;
|
|
70
|
+
const idx = order.map((o) => {
|
|
71
|
+
const i = ~~(index / stride[o]);
|
|
72
|
+
index -= i * stride[o];
|
|
73
|
+
return i;
|
|
74
|
+
});
|
|
75
|
+
return swizzle(order)(idx);
|
|
76
|
+
}
|
|
67
77
|
hi(pos) {
|
|
68
78
|
return new this.constructor(
|
|
69
79
|
this.type,
|
|
@@ -167,6 +177,9 @@ class Tensor1 extends ATensor {
|
|
|
167
177
|
index([x]) {
|
|
168
178
|
return this.offset + x * this.stride[0];
|
|
169
179
|
}
|
|
180
|
+
position(index) {
|
|
181
|
+
return [~~((index - this.offset) / this.stride[0])];
|
|
182
|
+
}
|
|
170
183
|
get([x]) {
|
|
171
184
|
return this.data[this.offset + x * this.stride[0]];
|
|
172
185
|
}
|
package/defopbtt.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { FnU2 } from "@thi.ng/api";
|
|
2
|
-
import type { ITensor } from "./api.js";
|
|
3
|
-
/**
|
|
4
|
-
* Higher order tensor op factory. Takes given `fn` and returns a
|
|
5
|
-
* {@link TensorOpTT}s applying the given function component-wise.
|
|
6
|
-
*
|
|
7
|
-
* @param fn
|
|
8
|
-
* @param dispatch
|
|
9
|
-
*/
|
|
10
|
-
export declare const defOpBTT: <T = number>(fn: FnU2<T>) => (out: ITensor<T> | null, a: ITensor<T>, b: ITensor<T>) => ITensor<T>;
|
|
11
|
-
//# sourceMappingURL=defopbtt.d.ts.map
|
package/defopbtt.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { equals } from "@thi.ng/vectors/equals";
|
|
2
|
-
import { broadcast } from "./broadcast.js";
|
|
3
|
-
import { illegalShape } from "./errors.js";
|
|
4
|
-
import { tensor } from "./tensor.js";
|
|
5
|
-
const defOpBTT = (fn) => {
|
|
6
|
-
const f1 = (out, a, b) => {
|
|
7
|
-
!out && (out = a);
|
|
8
|
-
const {
|
|
9
|
-
data: odata,
|
|
10
|
-
offset: oo,
|
|
11
|
-
stride: [txo]
|
|
12
|
-
} = out;
|
|
13
|
-
const {
|
|
14
|
-
data: adata,
|
|
15
|
-
offset: oa,
|
|
16
|
-
shape: [sx],
|
|
17
|
-
stride: [txa]
|
|
18
|
-
} = a;
|
|
19
|
-
const {
|
|
20
|
-
data: bdata,
|
|
21
|
-
offset: ob,
|
|
22
|
-
stride: [txb]
|
|
23
|
-
} = b;
|
|
24
|
-
for (let x = 0; x < sx; x++) {
|
|
25
|
-
odata[oo + x * txo] = fn(adata[oa + x * txa], bdata[ob + x * txb]);
|
|
26
|
-
}
|
|
27
|
-
return out;
|
|
28
|
-
};
|
|
29
|
-
const f2 = (out, a, b) => {
|
|
30
|
-
!out && (out = a);
|
|
31
|
-
const {
|
|
32
|
-
data: odata,
|
|
33
|
-
offset: oo,
|
|
34
|
-
stride: [txo, tyo]
|
|
35
|
-
} = out;
|
|
36
|
-
const {
|
|
37
|
-
data: adata,
|
|
38
|
-
offset: oa,
|
|
39
|
-
shape: [sx, sy],
|
|
40
|
-
stride: [txa, tya]
|
|
41
|
-
} = a;
|
|
42
|
-
const {
|
|
43
|
-
data: bdata,
|
|
44
|
-
offset: ob,
|
|
45
|
-
stride: [txb, tyb]
|
|
46
|
-
} = b;
|
|
47
|
-
let oox, oax, obx;
|
|
48
|
-
for (let x = 0; x < sx; x++) {
|
|
49
|
-
oox = oo + x * txo;
|
|
50
|
-
oax = oa + x * txa;
|
|
51
|
-
obx = ob + x * txb;
|
|
52
|
-
for (let y = 0; y < sy; y++) {
|
|
53
|
-
odata[oox + y * tyo] = fn(
|
|
54
|
-
adata[oax + y * tya],
|
|
55
|
-
bdata[obx + y * tyb]
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return out;
|
|
60
|
-
};
|
|
61
|
-
const f3 = (out, a, b) => {
|
|
62
|
-
!out && (out = a);
|
|
63
|
-
const {
|
|
64
|
-
data: odata,
|
|
65
|
-
offset: oo,
|
|
66
|
-
stride: [txo, tyo, tzo]
|
|
67
|
-
} = out;
|
|
68
|
-
const {
|
|
69
|
-
data: adata,
|
|
70
|
-
offset: oa,
|
|
71
|
-
shape: [sx, sy, sz],
|
|
72
|
-
stride: [txa, tya, tza]
|
|
73
|
-
} = a;
|
|
74
|
-
const {
|
|
75
|
-
data: bdata,
|
|
76
|
-
offset: ob,
|
|
77
|
-
stride: [txb, tyb, tzb]
|
|
78
|
-
} = b;
|
|
79
|
-
let oox, oax, obx, ooy, oay, oby;
|
|
80
|
-
for (let x = 0; x < sx; x++) {
|
|
81
|
-
oox = oo + x * txo;
|
|
82
|
-
oax = oa + x * txa;
|
|
83
|
-
obx = ob + x * txb;
|
|
84
|
-
for (let y = 0; y < sy; y++) {
|
|
85
|
-
ooy = oox + y * tyo;
|
|
86
|
-
oay = oax + y * tya;
|
|
87
|
-
oby = obx + y * tyb;
|
|
88
|
-
for (let z = 0; z < sz; z++) {
|
|
89
|
-
odata[ooy + z * tzo] = fn(
|
|
90
|
-
adata[oay + z * tza],
|
|
91
|
-
bdata[oby + z * tzb]
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return out;
|
|
97
|
-
};
|
|
98
|
-
const f4 = (out, a, b) => {
|
|
99
|
-
!out && (out = a);
|
|
100
|
-
const {
|
|
101
|
-
data: odata,
|
|
102
|
-
offset: oo,
|
|
103
|
-
stride: [txo, tyo, tzo, two]
|
|
104
|
-
} = out;
|
|
105
|
-
const {
|
|
106
|
-
data: adata,
|
|
107
|
-
offset: oa,
|
|
108
|
-
shape: [sx, sy, sz, sw],
|
|
109
|
-
stride: [txa, tya, tza, twa]
|
|
110
|
-
} = a;
|
|
111
|
-
const {
|
|
112
|
-
data: bdata,
|
|
113
|
-
offset: ob,
|
|
114
|
-
stride: [txb, tyb, tzb, twb]
|
|
115
|
-
} = b;
|
|
116
|
-
let oox, oax, obx, ooy, oay, oby, ooz, oaz, obz;
|
|
117
|
-
for (let x = 0; x < sx; x++) {
|
|
118
|
-
oox = oo + x * txo;
|
|
119
|
-
oax = oa + x * txa;
|
|
120
|
-
obx = ob + x * txb;
|
|
121
|
-
for (let y = 0; y < sy; y++) {
|
|
122
|
-
ooy = oox + y * tyo;
|
|
123
|
-
oay = oax + y * tya;
|
|
124
|
-
oby = obx + y * tyb;
|
|
125
|
-
for (let z = 0; z < sz; z++) {
|
|
126
|
-
ooz = ooy + z * tzo;
|
|
127
|
-
oaz = oay + z * tza;
|
|
128
|
-
obz = oby + z * tzb;
|
|
129
|
-
for (let w = 0; w < sw; w++) {
|
|
130
|
-
odata[ooz + w * two] = fn(
|
|
131
|
-
adata[oaz + w * twa],
|
|
132
|
-
bdata[obz + w * twb]
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return out;
|
|
139
|
-
};
|
|
140
|
-
const impls = [, f1, f2, f3, f4];
|
|
141
|
-
return (out, a, b) => {
|
|
142
|
-
const { shape, a: $a, b: $b } = broadcast(a, b);
|
|
143
|
-
if (out) {
|
|
144
|
-
if (!equals(out.shape, shape)) illegalShape(out.shape);
|
|
145
|
-
} else {
|
|
146
|
-
out = tensor(a.type, shape, { storage: a.storage });
|
|
147
|
-
}
|
|
148
|
-
return impls[shape.length](out, $a, $b);
|
|
149
|
-
};
|
|
150
|
-
};
|
|
151
|
-
export {
|
|
152
|
-
defOpBTT
|
|
153
|
-
};
|