@thi.ng/tensors 0.8.13 → 0.10.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 +23 -1
- package/README.md +4 -5
- package/api.d.ts +85 -4
- package/broadcast.d.ts +2 -2
- package/defopn.js +5 -8
- package/defoprt.js +2 -1
- package/defoprtt.js +2 -1
- package/defopt.js +6 -1
- package/defoptn.js +6 -1
- package/defoptnn.js +6 -8
- package/defoptt.js +6 -1
- package/defopttt.js +9 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +17 -14
- package/rand-distrib.d.ts +2 -1
- package/rand-distrib.js +6 -1
- package/sample.d.ts +27 -0
- package/sample.js +290 -0
- package/tensor.d.ts +31 -6
- package/tensor.js +88 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2025-
|
|
3
|
+
- **Last updated**: 2025-09-01T16:38:35Z
|
|
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,28 @@ 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.10.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.10.0) (2025-09-01)
|
|
15
|
+
|
|
16
|
+
#### 🚀 Features
|
|
17
|
+
|
|
18
|
+
- add 1D/2D/3D samplers and resampling fns ([2130067](https://github.com/thi-ng/umbrella/commit/2130067))
|
|
19
|
+
- add `defSampler1/2/3/4()` and supporting helpers
|
|
20
|
+
- add sampling kernel presets:
|
|
21
|
+
- `SAMPLE_NEAREST`
|
|
22
|
+
- `SAMPLE_LINEAR`
|
|
23
|
+
- `SAMPLE_CUBIC`
|
|
24
|
+
- `SAMPLE_LANCZOS` (higher order)
|
|
25
|
+
- add `resample1/2/3()` fns
|
|
26
|
+
|
|
27
|
+
## [0.9.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.9.0) (2025-08-16)
|
|
28
|
+
|
|
29
|
+
#### 🚀 Features
|
|
30
|
+
|
|
31
|
+
- add 0-dim (wrapped scalar) tensor support ([cd22ee6](https://github.com/thi-ng/umbrella/commit/cd22ee6))
|
|
32
|
+
- add `Tensor0`, `Shape0`
|
|
33
|
+
- update HOF tensor op generators
|
|
34
|
+
- add/update tests
|
|
35
|
+
|
|
14
36
|
## [0.8.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.8.0) (2025-07-10)
|
|
15
37
|
|
|
16
38
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -31,12 +31,11 @@
|
|
|
31
31
|
|
|
32
32
|
## About
|
|
33
33
|
|
|
34
|
-
1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage.
|
|
34
|
+
0D/1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage.
|
|
35
35
|
|
|
36
36
|
> [!NOTE]
|
|
37
|
-
> This package contains code originally written in 2017/18 and
|
|
38
|
-
>
|
|
39
|
-
> packages — use with caution!
|
|
37
|
+
> This package contains code originally written in 2017/18 and has been
|
|
38
|
+
> refactored to be stylistically more aligned with other thi.ng packages.
|
|
40
39
|
|
|
41
40
|
## Built-in tensor operations
|
|
42
41
|
|
|
@@ -251,7 +250,7 @@ For Node.js REPL:
|
|
|
251
250
|
const ten = await import("@thi.ng/tensors");
|
|
252
251
|
```
|
|
253
252
|
|
|
254
|
-
Package sizes (brotli'd, pre-treeshake): ESM:
|
|
253
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 11.49 KB
|
|
255
254
|
|
|
256
255
|
## Dependencies
|
|
257
256
|
|
package/api.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import type { Type as $Type, ICopy, IEqualsDelta, IEquiv, ILength, IRelease, Maybe, NumericArray } from "@thi.ng/api";
|
|
2
|
-
import type { Tensor1, Tensor2, Tensor3, Tensor4 } from "./tensor.js";
|
|
2
|
+
import type { Tensor0, 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
8
|
export type NumType = $Type | "num";
|
|
9
|
+
export type Shape0 = [];
|
|
9
10
|
export type Shape1 = [number];
|
|
10
11
|
export type Shape2 = [number, number];
|
|
11
12
|
export type Shape3 = [number, number, number];
|
|
12
13
|
export type Shape4 = [number, number, number, number];
|
|
13
|
-
export type Shape = Shape1 | Shape2 | Shape3 | Shape4;
|
|
14
|
-
export type ShapeTensor<S extends Shape, T> = S extends Shape4 ? Tensor4<T> : S extends Shape3 ? Tensor3<T> : S extends Shape2 ? Tensor2<T> : Tensor1<T>;
|
|
14
|
+
export type Shape = Shape0 | Shape1 | Shape2 | Shape3 | Shape4;
|
|
15
|
+
export type ShapeTensor<S extends Shape, T> = S extends Shape4 ? Tensor4<T> : S extends Shape3 ? Tensor3<T> : S extends Shape2 ? Tensor2<T> : S extends Shape1 ? Tensor1<T> : Tensor0<T>;
|
|
15
16
|
export type Nested<T> = T[] | T[][] | T[][][] | T[][][][];
|
|
16
17
|
export type NestedTensor<N extends Nested<T>, T> = N extends T[][][][] ? Tensor4<T> : N extends T[][][] ? Tensor3<T> : N extends T[][] ? Tensor2<T> : Tensor1<T>;
|
|
17
18
|
export interface TypeMap {
|
|
@@ -108,6 +109,10 @@ export interface ITensor<T = number> extends ICopy<ITensor<T>>, IEquiv, IEqualsD
|
|
|
108
109
|
* Computes linear array index from given grid position. Reverse-op of
|
|
109
110
|
* {@link ITensor.position}.
|
|
110
111
|
*
|
|
112
|
+
* @remarks
|
|
113
|
+
* The given `pos` is assumed to be integral and valid. No bounds checking
|
|
114
|
+
* performed.
|
|
115
|
+
*
|
|
111
116
|
* @param pos
|
|
112
117
|
*/
|
|
113
118
|
index(pos: NumericArray): number;
|
|
@@ -116,6 +121,8 @@ export interface ITensor<T = number> extends ICopy<ITensor<T>>, IEquiv, IEqualsD
|
|
|
116
121
|
* {@link ITensor.index}.
|
|
117
122
|
*
|
|
118
123
|
* @remarks
|
|
124
|
+
* The given `index` is assumed to be valid. No bounds checking performed.
|
|
125
|
+
*
|
|
119
126
|
* **CAUTION:** Currently only supports tensors with positive strides,
|
|
120
127
|
* otherwise will yield incorrect results! Tensors with negative strides
|
|
121
128
|
* (aka flipped axes in reverse order) need to be first packed via
|
|
@@ -435,108 +442,182 @@ export interface ITensorStorage<T> {
|
|
|
435
442
|
}
|
|
436
443
|
export type StorageRegistry = Record<Type, ITensorStorage<any>>;
|
|
437
444
|
export interface TensorOpT<T = number> {
|
|
445
|
+
(out: Tensor0<T> | null, a: Tensor0<T>): Tensor0<T>;
|
|
438
446
|
(out: Tensor1<T> | null, a: Tensor1<T>): Tensor1<T>;
|
|
439
447
|
(out: Tensor2<T> | null, a: Tensor2<T>): Tensor2<T>;
|
|
440
448
|
(out: Tensor3<T> | null, a: Tensor3<T>): Tensor3<T>;
|
|
441
449
|
(out: Tensor4<T> | null, a: Tensor4<T>): Tensor4<T>;
|
|
442
450
|
}
|
|
443
451
|
export interface TensorOpTT<T = number> {
|
|
452
|
+
(out: Tensor0<T> | null, a: Tensor0<T>, b: Tensor0<T>): Tensor0<T>;
|
|
453
|
+
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor1<T>): Tensor1<T>;
|
|
454
|
+
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>): Tensor2<T>;
|
|
455
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>): Tensor3<T>;
|
|
456
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>): Tensor4<T>;
|
|
457
|
+
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor0<T>): Tensor1<T>;
|
|
444
458
|
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor1<T>): Tensor1<T>;
|
|
445
459
|
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>): Tensor2<T>;
|
|
446
460
|
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>): Tensor3<T>;
|
|
447
461
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>): Tensor4<T>;
|
|
462
|
+
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>): Tensor2<T>;
|
|
448
463
|
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>): Tensor2<T>;
|
|
449
464
|
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>): Tensor2<T>;
|
|
450
465
|
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>): Tensor3<T>;
|
|
451
466
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>): Tensor4<T>;
|
|
467
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>): Tensor3<T>;
|
|
452
468
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>): Tensor3<T>;
|
|
453
469
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>): Tensor3<T>;
|
|
454
470
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>): Tensor3<T>;
|
|
455
471
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>): Tensor4<T>;
|
|
472
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>): Tensor4<T>;
|
|
456
473
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>): Tensor4<T>;
|
|
457
474
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>): Tensor4<T>;
|
|
458
475
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>): Tensor4<T>;
|
|
459
476
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>): Tensor4<T>;
|
|
460
477
|
}
|
|
461
478
|
export interface TensorOpTTT<T = number> {
|
|
479
|
+
(out: Tensor0<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor0<T>;
|
|
480
|
+
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor1<T>;
|
|
481
|
+
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor2<T>;
|
|
482
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
|
|
483
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
|
|
484
|
+
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor1<T>;
|
|
485
|
+
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor1<T>;
|
|
486
|
+
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor2<T>;
|
|
487
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
|
|
488
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
|
|
489
|
+
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor2<T>;
|
|
490
|
+
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor2<T>;
|
|
491
|
+
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor2<T>;
|
|
492
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
|
|
493
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
|
|
494
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
|
|
495
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
|
|
496
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
|
|
497
|
+
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
|
|
498
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
|
|
499
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
|
|
500
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
|
|
501
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
|
|
502
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
|
|
503
|
+
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
|
|
504
|
+
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor1<T>;
|
|
505
|
+
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor1<T>;
|
|
506
|
+
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor2<T>;
|
|
507
|
+
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
|
|
508
|
+
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
|
|
509
|
+
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor1<T>;
|
|
462
510
|
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor1<T>;
|
|
463
511
|
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor2<T>;
|
|
464
512
|
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
|
|
465
513
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
|
|
514
|
+
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor2<T>;
|
|
466
515
|
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor2<T>;
|
|
467
516
|
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor2<T>;
|
|
468
517
|
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
|
|
469
518
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
|
|
519
|
+
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
|
|
470
520
|
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
|
|
471
521
|
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
|
|
472
522
|
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
|
|
473
523
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
|
|
524
|
+
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
|
|
474
525
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
|
|
475
526
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
|
|
476
527
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
|
|
477
528
|
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
|
|
529
|
+
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor2<T>;
|
|
530
|
+
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor2<T>;
|
|
531
|
+
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor2<T>;
|
|
532
|
+
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
|
|
533
|
+
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
|
|
534
|
+
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor2<T>;
|
|
478
535
|
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor2<T>;
|
|
479
536
|
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor2<T>;
|
|
480
537
|
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
|
|
481
538
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
|
|
539
|
+
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor2<T>;
|
|
482
540
|
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor2<T>;
|
|
483
541
|
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor2<T>;
|
|
484
542
|
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
|
|
485
543
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
|
|
544
|
+
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
|
|
486
545
|
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
|
|
487
546
|
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
|
|
488
547
|
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
|
|
489
548
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
|
|
549
|
+
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
|
|
490
550
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
|
|
491
551
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
|
|
492
552
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
|
|
493
553
|
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
|
|
554
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor3<T>;
|
|
555
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor3<T>;
|
|
556
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor3<T>;
|
|
557
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
|
|
558
|
+
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
|
|
559
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor3<T>;
|
|
494
560
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor3<T>;
|
|
495
561
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor3<T>;
|
|
496
562
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
|
|
497
563
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
|
|
564
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor3<T>;
|
|
498
565
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor3<T>;
|
|
499
566
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor3<T>;
|
|
500
567
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
|
|
501
568
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
|
|
569
|
+
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
|
|
502
570
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
|
|
503
571
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
|
|
504
572
|
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
|
|
505
573
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
|
|
574
|
+
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
|
|
506
575
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
|
|
507
576
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
|
|
508
577
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
|
|
509
578
|
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
|
|
579
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor4<T>;
|
|
580
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor4<T>;
|
|
581
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor4<T>;
|
|
582
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor4<T>;
|
|
583
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
|
|
584
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor4<T>;
|
|
510
585
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor4<T>;
|
|
511
586
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor4<T>;
|
|
512
587
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor4<T>;
|
|
513
588
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
|
|
589
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor4<T>;
|
|
514
590
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor4<T>;
|
|
515
591
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor4<T>;
|
|
516
592
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor4<T>;
|
|
517
593
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
|
|
594
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor4<T>;
|
|
518
595
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor4<T>;
|
|
519
596
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor4<T>;
|
|
520
597
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor4<T>;
|
|
521
598
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
|
|
599
|
+
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
|
|
522
600
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
|
|
523
601
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
|
|
524
602
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
|
|
525
603
|
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
|
|
526
604
|
}
|
|
527
605
|
export interface TensorOpN<A = number, B = A> {
|
|
606
|
+
(out: Tensor0<B>, n: A): Tensor0<B>;
|
|
528
607
|
(out: Tensor1<B>, n: A): Tensor1<B>;
|
|
529
608
|
(out: Tensor2<B>, n: A): Tensor2<B>;
|
|
530
609
|
(out: Tensor3<B>, n: A): Tensor3<B>;
|
|
531
610
|
(out: Tensor4<B>, n: A): Tensor4<B>;
|
|
532
611
|
}
|
|
533
612
|
export interface TensorOpTN<T = number> {
|
|
613
|
+
(out: Tensor0<T> | null, a: Tensor0<T>, n: T): Tensor0<T>;
|
|
534
614
|
(out: Tensor1<T> | null, a: Tensor1<T>, n: T): Tensor1<T>;
|
|
535
615
|
(out: Tensor2<T> | null, a: Tensor2<T>, n: T): Tensor2<T>;
|
|
536
616
|
(out: Tensor3<T> | null, a: Tensor3<T>, n: T): Tensor3<T>;
|
|
537
617
|
(out: Tensor4<T> | null, a: Tensor4<T>, n: T): Tensor4<T>;
|
|
538
618
|
}
|
|
539
619
|
export interface TensorOpTNN<T = number> {
|
|
620
|
+
(out: Tensor0<T>, a: Tensor0<T>, n: T, m: T): Tensor0<T>;
|
|
540
621
|
(out: Tensor1<T>, a: Tensor1<T>, n: T, m: T): Tensor1<T>;
|
|
541
622
|
(out: Tensor2<T>, a: Tensor2<T>, n: T, m: T): Tensor2<T>;
|
|
542
623
|
(out: Tensor3<T>, a: Tensor3<T>, n: T, m: T): Tensor3<T>;
|
|
@@ -583,7 +664,7 @@ export interface KernelSpec<T = any> {
|
|
|
583
664
|
/**
|
|
584
665
|
* Kernel shape/size
|
|
585
666
|
*/
|
|
586
|
-
shape: Shape
|
|
667
|
+
shape: Exclude<Shape, Shape0>;
|
|
587
668
|
/**
|
|
588
669
|
* Windowed intialization. Returns initial accumulator for each new kernel
|
|
589
670
|
* window.
|
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> | 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>;
|
|
21
|
+
a: ITensor<T> | import("./tensor.js").Tensor4<T> | import("./tensor.js").Tensor3<T> | import("./tensor.js").Tensor2<T> | import("./tensor.js").Tensor0<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").Tensor0<T> | import("./tensor.js").Tensor1<T>;
|
|
23
23
|
};
|
|
24
24
|
//# sourceMappingURL=broadcast.d.ts.map
|
package/defopn.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { top } from "./top.js";
|
|
2
2
|
const defOpN = (fn) => {
|
|
3
|
+
const f0 = (out, a) => {
|
|
4
|
+
out.data[out.offset] = fn(a);
|
|
5
|
+
return out;
|
|
6
|
+
};
|
|
3
7
|
const f1 = (out, a) => {
|
|
4
8
|
const {
|
|
5
9
|
data,
|
|
@@ -61,14 +65,7 @@ const defOpN = (fn) => {
|
|
|
61
65
|
}
|
|
62
66
|
return out;
|
|
63
67
|
};
|
|
64
|
-
return top(
|
|
65
|
-
0,
|
|
66
|
-
void 0,
|
|
67
|
-
f1,
|
|
68
|
-
f2,
|
|
69
|
-
f3,
|
|
70
|
-
f4
|
|
71
|
-
);
|
|
68
|
+
return top(0, f0, f1, f2, f3, f4);
|
|
72
69
|
};
|
|
73
70
|
export {
|
|
74
71
|
defOpN
|
package/defoprt.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { identity } from "@thi.ng/api/fn";
|
|
2
2
|
import { top } from "./top.js";
|
|
3
3
|
const defOpRT = (rfn, init, complete = identity) => {
|
|
4
|
+
const f0 = (a) => complete(rfn(init(), a.data, a.offset), a);
|
|
4
5
|
const f1 = (a) => {
|
|
5
6
|
const {
|
|
6
7
|
data,
|
|
@@ -76,7 +77,7 @@ const defOpRT = (rfn, init, complete = identity) => {
|
|
|
76
77
|
};
|
|
77
78
|
return top(
|
|
78
79
|
0,
|
|
79
|
-
|
|
80
|
+
f0,
|
|
80
81
|
f1,
|
|
81
82
|
f2,
|
|
82
83
|
f3,
|
package/defoprtt.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { identity } from "@thi.ng/api/fn";
|
|
2
2
|
import { broadcast } from "./broadcast.js";
|
|
3
3
|
const defOpRTT = (rfn, init, complete = identity, useBroadcast = true) => {
|
|
4
|
+
const f0 = (a, b) => complete(rfn(init(), a.data, b.data, a.offset, b.offset), a, b);
|
|
4
5
|
const f1 = (a, b) => {
|
|
5
6
|
const {
|
|
6
7
|
data: adata,
|
|
@@ -106,7 +107,7 @@ const defOpRTT = (rfn, init, complete = identity, useBroadcast = true) => {
|
|
|
106
107
|
}
|
|
107
108
|
return complete(res, a, b);
|
|
108
109
|
};
|
|
109
|
-
const impls = [, f1, f2, f3, f4];
|
|
110
|
+
const impls = [f0, f1, f2, f3, f4];
|
|
110
111
|
const wrapper = useBroadcast ? (a, b) => {
|
|
111
112
|
const { shape, a: $a, b: $b } = broadcast(a, b);
|
|
112
113
|
return impls[shape.length]($a, $b);
|
package/defopt.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { top } from "./top.js";
|
|
2
2
|
const defOpT = (fn) => {
|
|
3
|
+
const f0 = (out, a) => {
|
|
4
|
+
!out && (out = a);
|
|
5
|
+
out.data[out.offset] = fn(a.data[a.offset]);
|
|
6
|
+
return out;
|
|
7
|
+
};
|
|
3
8
|
const f1 = (out, a) => {
|
|
4
9
|
!out && (out = a);
|
|
5
10
|
const {
|
|
@@ -99,7 +104,7 @@ const defOpT = (fn) => {
|
|
|
99
104
|
}
|
|
100
105
|
return out;
|
|
101
106
|
};
|
|
102
|
-
return top(1,
|
|
107
|
+
return top(1, f0, f1, f2, f3, f4);
|
|
103
108
|
};
|
|
104
109
|
export {
|
|
105
110
|
defOpT
|
package/defoptn.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { top } from "./top.js";
|
|
2
2
|
const defOpTN = (fn) => {
|
|
3
|
+
const f0 = (out, a, n) => {
|
|
4
|
+
!out && (out = a);
|
|
5
|
+
out.data[out.offset] = fn(a.data[a.offset], n);
|
|
6
|
+
return out;
|
|
7
|
+
};
|
|
3
8
|
const f1 = (out, a, n) => {
|
|
4
9
|
!out && (out = a);
|
|
5
10
|
const {
|
|
@@ -99,7 +104,7 @@ const defOpTN = (fn) => {
|
|
|
99
104
|
}
|
|
100
105
|
return out;
|
|
101
106
|
};
|
|
102
|
-
return top(1,
|
|
107
|
+
return top(1, f0, f1, f2, f3, f4);
|
|
103
108
|
};
|
|
104
109
|
export {
|
|
105
110
|
defOpTN
|
package/defoptnn.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { top } from "./top.js";
|
|
2
2
|
const defOpTNN = (fn) => {
|
|
3
|
+
const f0 = (out, a, n, m) => {
|
|
4
|
+
!out && (out = a);
|
|
5
|
+
out.data[out.offset] = fn(a.data[a.offset], n, m);
|
|
6
|
+
return out;
|
|
7
|
+
};
|
|
3
8
|
const f1 = (out, a, n, m) => {
|
|
4
9
|
!out && (out = a);
|
|
5
10
|
const {
|
|
@@ -99,14 +104,7 @@ const defOpTNN = (fn) => {
|
|
|
99
104
|
}
|
|
100
105
|
return out;
|
|
101
106
|
};
|
|
102
|
-
return top(
|
|
103
|
-
1,
|
|
104
|
-
void 0,
|
|
105
|
-
f1,
|
|
106
|
-
f2,
|
|
107
|
-
f3,
|
|
108
|
-
f4
|
|
109
|
-
);
|
|
107
|
+
return top(1, f0, f1, f2, f3, f4);
|
|
110
108
|
};
|
|
111
109
|
export {
|
|
112
110
|
defOpTNN
|
package/defoptt.js
CHANGED
|
@@ -2,6 +2,11 @@ import { broadcast } from "./broadcast.js";
|
|
|
2
2
|
import { ensureShape } from "./errors.js";
|
|
3
3
|
import { tensor } from "./tensor.js";
|
|
4
4
|
const defOpTT = (fn) => {
|
|
5
|
+
const f0 = (out, a, b) => {
|
|
6
|
+
!out && (out = a);
|
|
7
|
+
out.data[out.offset] = fn(a.data[a.offset], b.data[b.offset]);
|
|
8
|
+
return out;
|
|
9
|
+
};
|
|
5
10
|
const f1 = (out, a, b) => {
|
|
6
11
|
!out && (out = a);
|
|
7
12
|
const {
|
|
@@ -136,7 +141,7 @@ const defOpTT = (fn) => {
|
|
|
136
141
|
}
|
|
137
142
|
return out;
|
|
138
143
|
};
|
|
139
|
-
const impls = [, f1, f2, f3, f4];
|
|
144
|
+
const impls = [f0, f1, f2, f3, f4];
|
|
140
145
|
const wrapper = (out, a, b) => {
|
|
141
146
|
const { shape, a: $a, b: $b } = broadcast(a, b);
|
|
142
147
|
if (out) {
|
package/defopttt.js
CHANGED
|
@@ -2,6 +2,14 @@ import { broadcast } from "./broadcast.js";
|
|
|
2
2
|
import { ensureShape } from "./errors.js";
|
|
3
3
|
import { tensor } from "./tensor.js";
|
|
4
4
|
const defOpTTT = (fn) => {
|
|
5
|
+
const f0 = (out, a, b, c) => {
|
|
6
|
+
out.data[out.offset] = fn(
|
|
7
|
+
a.data[a.offset],
|
|
8
|
+
b.data[b.offset],
|
|
9
|
+
c.data[c.offset]
|
|
10
|
+
);
|
|
11
|
+
return out;
|
|
12
|
+
};
|
|
5
13
|
const f1 = (out, a, b, c) => {
|
|
6
14
|
const {
|
|
7
15
|
data: odata,
|
|
@@ -165,7 +173,7 @@ const defOpTTT = (fn) => {
|
|
|
165
173
|
}
|
|
166
174
|
return out;
|
|
167
175
|
};
|
|
168
|
-
const impls = [, f1, f2, f3, f4];
|
|
176
|
+
const impls = [f0, f1, f2, f3, f4];
|
|
169
177
|
const wrapper = (out, a, b, c) => {
|
|
170
178
|
const { a: $a1, b: $b } = broadcast(a, b);
|
|
171
179
|
const { shape, a: $a2, b: $c } = broadcast($a1, c);
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/tensors",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "0D/1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
7
7
|
"typings": "./index.d.ts",
|
|
@@ -39,19 +39,19 @@
|
|
|
39
39
|
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@thi.ng/api": "^8.12.
|
|
43
|
-
"@thi.ng/arrays": "^2.13.
|
|
44
|
-
"@thi.ng/checks": "^3.7.
|
|
45
|
-
"@thi.ng/equiv": "^2.1.
|
|
46
|
-
"@thi.ng/errors": "^2.5.
|
|
47
|
-
"@thi.ng/math": "^5.
|
|
48
|
-
"@thi.ng/random": "^4.1.
|
|
49
|
-
"@thi.ng/strings": "^3.9.
|
|
50
|
-
"@thi.ng/vectors": "^8.6.
|
|
42
|
+
"@thi.ng/api": "^8.12.2",
|
|
43
|
+
"@thi.ng/arrays": "^2.13.11",
|
|
44
|
+
"@thi.ng/checks": "^3.7.18",
|
|
45
|
+
"@thi.ng/equiv": "^2.1.92",
|
|
46
|
+
"@thi.ng/errors": "^2.5.42",
|
|
47
|
+
"@thi.ng/math": "^5.12.0",
|
|
48
|
+
"@thi.ng/random": "^4.1.27",
|
|
49
|
+
"@thi.ng/strings": "^3.9.22",
|
|
50
|
+
"@thi.ng/vectors": "^8.6.6"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"esbuild": "^0.25.
|
|
54
|
-
"typedoc": "^0.28.
|
|
53
|
+
"esbuild": "^0.25.9",
|
|
54
|
+
"typedoc": "^0.28.12",
|
|
55
55
|
"typescript": "^5.9.2"
|
|
56
56
|
},
|
|
57
57
|
"keywords": [
|
|
@@ -268,6 +268,9 @@
|
|
|
268
268
|
"./relun": {
|
|
269
269
|
"default": "./relun.js"
|
|
270
270
|
},
|
|
271
|
+
"./sample": {
|
|
272
|
+
"default": "./sample.js"
|
|
273
|
+
},
|
|
271
274
|
"./select": {
|
|
272
275
|
"default": "./select.js"
|
|
273
276
|
},
|
|
@@ -339,5 +342,5 @@
|
|
|
339
342
|
"status": "alpha",
|
|
340
343
|
"year": 2018
|
|
341
344
|
},
|
|
342
|
-
"gitHead": "
|
|
345
|
+
"gitHead": "e215a3e8de3809736ba0042c93bd8703a5a1a337\n"
|
|
343
346
|
}
|
package/rand-distrib.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Fn0 } from "@thi.ng/api";
|
|
2
2
|
import type { ITensor } from "./api.js";
|
|
3
|
-
import type { Tensor1, Tensor2, Tensor3, Tensor4 } from "./tensor.js";
|
|
3
|
+
import type { Tensor0, Tensor1, Tensor2, Tensor3, Tensor4 } from "./tensor.js";
|
|
4
|
+
export declare const randDistrib0: (a: Tensor0, rnd?: () => number, n?: number) => Tensor0<number>;
|
|
4
5
|
/**
|
|
5
6
|
* Same as {@link randDistrib} for 1D tensors.
|
|
6
7
|
*
|
package/rand-distrib.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { normal as op } from "@thi.ng/random/distributions/normal";
|
|
2
2
|
import { top } from "./top.js";
|
|
3
|
+
const randDistrib0 = (a, rnd = op(), n = 1) => {
|
|
4
|
+
a.data[a.offset] = rnd() * n;
|
|
5
|
+
return a;
|
|
6
|
+
};
|
|
3
7
|
const randDistrib1 = (a, rnd = op(), n = 1) => {
|
|
4
8
|
const {
|
|
5
9
|
data,
|
|
@@ -69,7 +73,7 @@ const randDistrib4 = (a, rnd = op(), n = 1) => {
|
|
|
69
73
|
};
|
|
70
74
|
const randDistrib = top(
|
|
71
75
|
0,
|
|
72
|
-
|
|
76
|
+
randDistrib0,
|
|
73
77
|
randDistrib1,
|
|
74
78
|
randDistrib2,
|
|
75
79
|
randDistrib3,
|
|
@@ -77,6 +81,7 @@ const randDistrib = top(
|
|
|
77
81
|
);
|
|
78
82
|
export {
|
|
79
83
|
randDistrib,
|
|
84
|
+
randDistrib0,
|
|
80
85
|
randDistrib1,
|
|
81
86
|
randDistrib2,
|
|
82
87
|
randDistrib3,
|
package/sample.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Fn2, Fn3, Fn4, Fn5, FnN, FnN2 } from "@thi.ng/api";
|
|
2
|
+
import type { ITensor } from "./api.js";
|
|
3
|
+
import { type Tensor1 } from "./tensor.js";
|
|
4
|
+
type BoundaryFn = FnN2;
|
|
5
|
+
type Sampler1 = Fn2<ITensor, number, number>;
|
|
6
|
+
type Sampler2 = Fn3<ITensor, number, number, number>;
|
|
7
|
+
type Sampler3 = Fn4<ITensor, number, number, number, number>;
|
|
8
|
+
type Sampler4 = Fn5<ITensor, number, number, number, number, number>;
|
|
9
|
+
type BoundaryType = "clamp" | "mirror" | "wrap" | "zero";
|
|
10
|
+
type SamplerType = "nearest" | "linear" | "cubic" | "lanczos";
|
|
11
|
+
interface SamplerKernel {
|
|
12
|
+
radius: number;
|
|
13
|
+
weight: FnN;
|
|
14
|
+
}
|
|
15
|
+
export declare const SAMPLE_NEAREST: SamplerKernel;
|
|
16
|
+
export declare const SAMPLE_LINEAR: SamplerKernel;
|
|
17
|
+
export declare const SAMPLE_CUBIC: SamplerKernel;
|
|
18
|
+
export declare const SAMPLE_LANCZOS: (r?: number) => SamplerKernel;
|
|
19
|
+
export declare const defSampler1: (kernel: SamplerKernel | SamplerType, boundary?: BoundaryFn | BoundaryType) => Sampler1;
|
|
20
|
+
export declare const defSampler2: (kernel: SamplerType | SamplerKernel | [SamplerType | SamplerKernel, SamplerType | SamplerKernel], boundary?: BoundaryType | BoundaryFn | [BoundaryType | BoundaryFn, BoundaryType | BoundaryFn]) => Sampler2;
|
|
21
|
+
export declare const defSampler3: (kernel: SamplerType | SamplerKernel | [SamplerType | SamplerKernel, SamplerType | SamplerKernel, SamplerType | SamplerKernel], boundary?: BoundaryType | BoundaryFn | [BoundaryType | BoundaryFn, BoundaryType | BoundaryFn, BoundaryType | BoundaryFn]) => Sampler3;
|
|
22
|
+
export declare const defSampler4: (kernel: SamplerType | SamplerKernel | [SamplerType | SamplerKernel, SamplerType | SamplerKernel, SamplerType | SamplerKernel, SamplerType | SamplerKernel], boundary?: BoundaryType | BoundaryFn | [BoundaryType | BoundaryFn, BoundaryType | BoundaryFn, BoundaryType | BoundaryFn, BoundaryType | BoundaryFn]) => Sampler4;
|
|
23
|
+
export declare const resample1: (out: Tensor1, a: Tensor1, sampler: Sampler1) => Tensor1<number>;
|
|
24
|
+
export declare const resample2: (out: ITensor, a: ITensor, [samplerX, samplerY]: Sampler1[]) => ITensor<number>;
|
|
25
|
+
export declare const resample3: (out: ITensor, a: ITensor, [samplerX, samplerY, samplerZ]: Sampler1[]) => ITensor<number>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=sample.d.ts.map
|
package/sample.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { isArray } from "@thi.ng/checks/is-array";
|
|
2
|
+
import { isString } from "@thi.ng/checks/is-string";
|
|
3
|
+
import { PI } from "@thi.ng/math/api";
|
|
4
|
+
import { clamp } from "@thi.ng/math/interval";
|
|
5
|
+
import { tensor } from "./tensor.js";
|
|
6
|
+
const { abs, floor, sin } = Math;
|
|
7
|
+
const __boundaryClamp = (i, max) => clamp(i, 0, max - 1);
|
|
8
|
+
const __boundaryWrap = (i, max) => (i % max + max) % max;
|
|
9
|
+
const __boundaryMirror = (i, max) => {
|
|
10
|
+
if (max === 1) return 0;
|
|
11
|
+
const period = 2 * (max - 1);
|
|
12
|
+
i = (i % period + period) % period;
|
|
13
|
+
return i < max ? i : period - i;
|
|
14
|
+
};
|
|
15
|
+
const __boundaryZero = (i, max) => i >= 0 || i < max ? i : -1;
|
|
16
|
+
const BOUNDARY_MODES = {
|
|
17
|
+
clamp: __boundaryClamp,
|
|
18
|
+
wrap: __boundaryWrap,
|
|
19
|
+
mirror: __boundaryMirror,
|
|
20
|
+
zero: __boundaryZero
|
|
21
|
+
};
|
|
22
|
+
const SAMPLE_NEAREST = {
|
|
23
|
+
radius: 1,
|
|
24
|
+
weight: (t) => t >= -0.5 && t < 0.5 ? 1 : 0
|
|
25
|
+
};
|
|
26
|
+
const SAMPLE_LINEAR = {
|
|
27
|
+
radius: 1,
|
|
28
|
+
weight: (t) => {
|
|
29
|
+
t = abs(t);
|
|
30
|
+
return t < 1 ? 1 - t : 0;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const SAMPLE_CUBIC = {
|
|
34
|
+
radius: 2,
|
|
35
|
+
weight: (t) => {
|
|
36
|
+
t = abs(t);
|
|
37
|
+
const a = -0.5;
|
|
38
|
+
return t < 2 ? t <= 1 ? ((a + 2) * t - (a + 3)) * t * t + 1 : ((a * t - 5 * a) * t + 8 * a) * t - 4 * a : 0;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const SAMPLE_LANCZOS = (r = 2) => ({
|
|
42
|
+
radius: r,
|
|
43
|
+
weight: (t) => {
|
|
44
|
+
if (t === 0) return 1;
|
|
45
|
+
if (t > -r && t < r) {
|
|
46
|
+
t *= PI;
|
|
47
|
+
return r * sin(t) * sin(t / r) / (t * t);
|
|
48
|
+
}
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const SAMPLER_TYPES = {
|
|
53
|
+
nearest: SAMPLE_NEAREST,
|
|
54
|
+
linear: SAMPLE_LINEAR,
|
|
55
|
+
cubic: SAMPLE_CUBIC,
|
|
56
|
+
lanczos: SAMPLE_LANCZOS(2)
|
|
57
|
+
};
|
|
58
|
+
const defSampler1 = (kernel, boundary = "clamp") => {
|
|
59
|
+
const index = __resolveBoundary(boundary);
|
|
60
|
+
const { radius, weight } = __resolveKernel(kernel);
|
|
61
|
+
return ({ data, shape: [sx], stride: [tx], offset }, x) => {
|
|
62
|
+
const c = floor(x);
|
|
63
|
+
let sum = 0;
|
|
64
|
+
let wsum = 0;
|
|
65
|
+
for (let k = -radius; k <= radius; k++) {
|
|
66
|
+
const $x = c + k;
|
|
67
|
+
const w = weight(x - $x);
|
|
68
|
+
if (w === 0) continue;
|
|
69
|
+
const i = index($x, sx);
|
|
70
|
+
if (i < 0) {
|
|
71
|
+
wsum += w;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
sum += data[offset + i * tx] * w;
|
|
75
|
+
wsum += w;
|
|
76
|
+
}
|
|
77
|
+
return wsum !== 0 ? sum / wsum : 0;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const defSampler2 = (kernel, boundary = "clamp") => {
|
|
81
|
+
const [indexX, indexY] = (isArray(boundary) ? boundary : [boundary, boundary]).map(__resolveBoundary);
|
|
82
|
+
const [kernelX, kernelY] = isArray(kernel) ? kernel : [kernel, kernel];
|
|
83
|
+
const { radius: rx, weight: weightX } = __resolveKernel(kernelX);
|
|
84
|
+
const { radius: ry, weight: weightY } = __resolveKernel(kernelY);
|
|
85
|
+
const sizeY = 2 * ry + 1;
|
|
86
|
+
const cacheY = new Array(sizeY);
|
|
87
|
+
return ({ data, shape: [sx, sy], stride: [tx, ty], offset }, x, y) => {
|
|
88
|
+
const cx = floor(x);
|
|
89
|
+
const cy = floor(y);
|
|
90
|
+
let sum = 0;
|
|
91
|
+
let wsum = 0;
|
|
92
|
+
for (let i = 0; i < sizeY; i++) {
|
|
93
|
+
cacheY[i] = weightY(y - (cy + i - ry));
|
|
94
|
+
}
|
|
95
|
+
for (let kx = -rx; kx <= rx; kx++) {
|
|
96
|
+
const $x = cx + kx;
|
|
97
|
+
const ix = indexX($x, sx);
|
|
98
|
+
const wx = weightX(x - $x);
|
|
99
|
+
const idx = offset + ix * tx;
|
|
100
|
+
for (let ky = -ry; ky <= ry; ky++) {
|
|
101
|
+
const wy = cacheY[ky + ry];
|
|
102
|
+
const weight = wx * wy;
|
|
103
|
+
if (weight === 0) continue;
|
|
104
|
+
const iy = indexY(cy + ky, sy);
|
|
105
|
+
if (ix < 0 || iy < 0) {
|
|
106
|
+
wsum += weight;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
sum += data[idx + iy * ty] * weight;
|
|
110
|
+
wsum += weight;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return wsum !== 0 ? sum / wsum : 0;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
const defSampler3 = (kernel, boundary = "clamp") => {
|
|
117
|
+
const [indexX, indexY, indexZ] = (isArray(boundary) ? boundary : [boundary, boundary, boundary]).map(__resolveBoundary);
|
|
118
|
+
const [kernelX, kernelY, kernelZ] = (isArray(kernel) ? kernel : [kernel, kernel, kernel]).map(__resolveKernel);
|
|
119
|
+
const { radius: rx, weight: weightX } = kernelX;
|
|
120
|
+
const { radius: ry, weight: weightY } = kernelY;
|
|
121
|
+
const { radius: rz, weight: weightZ } = kernelZ;
|
|
122
|
+
const sizeY = 2 * ry + 1;
|
|
123
|
+
const sizeZ = 2 * rz + 1;
|
|
124
|
+
const cacheY = new Array(sizeY);
|
|
125
|
+
const cacheZ = new Array(sizeZ);
|
|
126
|
+
return ({ data, shape: [sx, sy, sz], stride: [tx, ty, tz], offset }, x, y, z) => {
|
|
127
|
+
const cx = floor(x);
|
|
128
|
+
const cy = floor(y);
|
|
129
|
+
const cz = floor(z);
|
|
130
|
+
let sum = 0;
|
|
131
|
+
let wsum = 0;
|
|
132
|
+
for (let i = 0; i < sizeY; i++) cacheY[i] = weightY(y - (cy + i - ry));
|
|
133
|
+
for (let i = 0; i < sizeZ; i++) cacheZ[i] = weightZ(z - (cz + i - rz));
|
|
134
|
+
for (let kx = -rx; kx <= rx; kx++) {
|
|
135
|
+
const $x = cx + kx;
|
|
136
|
+
const ix = indexX($x, sx);
|
|
137
|
+
const wx = weightX(x - $x);
|
|
138
|
+
const idxX = offset + ix * tx;
|
|
139
|
+
for (let ky = -ry; ky <= ry; ky++) {
|
|
140
|
+
const iy = indexY(cy + ky, sy);
|
|
141
|
+
const wy = cacheY[ky + ry];
|
|
142
|
+
const idxXY = idxX + iy * ty;
|
|
143
|
+
for (let kz = -rz; kz <= rz; kz++) {
|
|
144
|
+
const wz = cacheZ[kz + rz];
|
|
145
|
+
const weight = wx * wy * wz;
|
|
146
|
+
if (weight === 0) continue;
|
|
147
|
+
const iz = indexZ(cz + kz, sz);
|
|
148
|
+
if (ix < 0 || iy < 0 || iz < 0) {
|
|
149
|
+
wsum += weight;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
sum += data[idxXY + iz * tz] * weight;
|
|
153
|
+
wsum += weight;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return wsum !== 0 ? sum / wsum : 0;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
const defSampler4 = (kernel, boundary = "clamp") => {
|
|
161
|
+
const [indexX, indexY, indexZ, indexW] = (isArray(boundary) ? boundary : [boundary, boundary, boundary, boundary]).map(__resolveBoundary);
|
|
162
|
+
const [kernelX, kernelY, kernelZ, kernelW] = (isArray(kernel) ? kernel : [kernel, kernel, kernel, kernel]).map(__resolveKernel);
|
|
163
|
+
const { radius: rx, weight: weightX } = kernelX;
|
|
164
|
+
const { radius: ry, weight: weightY } = kernelY;
|
|
165
|
+
const { radius: rz, weight: weightZ } = kernelZ;
|
|
166
|
+
const { radius: rw, weight: weightW } = kernelW;
|
|
167
|
+
const sizeY = 2 * ry + 1;
|
|
168
|
+
const sizeZ = 2 * rz + 1;
|
|
169
|
+
const sizeW = 2 * rw + 1;
|
|
170
|
+
const cacheY = new Array(sizeY);
|
|
171
|
+
const cacheZ = new Array(sizeZ);
|
|
172
|
+
const cacheW = new Array(sizeW);
|
|
173
|
+
return ({ data, shape: [sx, sy, sz, sw], stride: [tx, ty, tz, tw], offset }, x, y, z, w) => {
|
|
174
|
+
const cx = floor(x);
|
|
175
|
+
const cy = floor(y);
|
|
176
|
+
const cz = floor(z);
|
|
177
|
+
const cw = floor(w);
|
|
178
|
+
let sum = 0;
|
|
179
|
+
let wsum = 0;
|
|
180
|
+
for (let i = 0; i < sizeY; i++) cacheY[i] = weightY(y - (cy + i - ry));
|
|
181
|
+
for (let i = 0; i < sizeZ; i++) cacheZ[i] = weightZ(z - (cz + i - rz));
|
|
182
|
+
for (let i = 0; i < sizeW; i++) cacheW[i] = weightW(w - (cw + i - rw));
|
|
183
|
+
for (let kx = -rx; kx <= rx; kx++) {
|
|
184
|
+
const $x = cx + kx;
|
|
185
|
+
const ix = indexX($x, sx);
|
|
186
|
+
const wx = weightX(x - $x);
|
|
187
|
+
const idxX = offset + ix * tx;
|
|
188
|
+
for (let ky = -ry; ky <= ry; ky++) {
|
|
189
|
+
const iy = indexY(cy + ky, sy);
|
|
190
|
+
const wy = cacheY[ky + ry];
|
|
191
|
+
const idxXY = idxX + iy * ty;
|
|
192
|
+
for (let kz = -rz; kz <= rz; kz++) {
|
|
193
|
+
const wz = cacheZ[kz + rz];
|
|
194
|
+
const iz = indexZ(cz + kz, sz);
|
|
195
|
+
const idxXYZ = idxXY + iz * tz;
|
|
196
|
+
for (let kw = -rw; kw <= rw; kw++) {
|
|
197
|
+
const ww = cacheW[kw + rw];
|
|
198
|
+
const weight = wx * wy * wz * ww;
|
|
199
|
+
if (weight === 0) continue;
|
|
200
|
+
const iw = indexW(cw + kw, sw);
|
|
201
|
+
if (ix < 0 || iy < 0 || iz < 0 || iw < 0) {
|
|
202
|
+
wsum += weight;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
sum += data[idxXYZ + iw * tw] * weight;
|
|
206
|
+
wsum += w;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return wsum !== 0 ? sum / wsum : 0;
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
const __resolveBoundary = (mode) => isString(mode) ? BOUNDARY_MODES[mode] : mode ?? __boundaryClamp;
|
|
215
|
+
const __resolveKernel = (kernel) => isString(kernel) ? SAMPLER_TYPES[kernel] : kernel;
|
|
216
|
+
const resample1 = (out, a, sampler) => {
|
|
217
|
+
const {
|
|
218
|
+
data: odata,
|
|
219
|
+
shape: [sxo],
|
|
220
|
+
stride: [txo],
|
|
221
|
+
offset: oo
|
|
222
|
+
} = out;
|
|
223
|
+
const {
|
|
224
|
+
shape: [sxa]
|
|
225
|
+
} = a;
|
|
226
|
+
const scale = sxa / sxo;
|
|
227
|
+
for (let i = 0; i < sxo; i++) {
|
|
228
|
+
odata[oo + i * txo] = sampler(a, (i + 0.5) * scale - 0.5);
|
|
229
|
+
}
|
|
230
|
+
return out;
|
|
231
|
+
};
|
|
232
|
+
const resample2 = (out, a, [samplerX, samplerY]) => {
|
|
233
|
+
const {
|
|
234
|
+
shape: [_, syo]
|
|
235
|
+
} = out;
|
|
236
|
+
const {
|
|
237
|
+
shape: [sxa]
|
|
238
|
+
} = a;
|
|
239
|
+
const tmp = tensor("num", [sxa, syo]);
|
|
240
|
+
for (let x = 0; x < sxa; x++) {
|
|
241
|
+
resample1(tmp.pick([x, -1]), a.pick([x, -1]), samplerX);
|
|
242
|
+
}
|
|
243
|
+
for (let y = 0; y < syo; y++) {
|
|
244
|
+
resample1(out.pick([-1, y]), tmp.pick([-1, y]), samplerY);
|
|
245
|
+
}
|
|
246
|
+
return out;
|
|
247
|
+
};
|
|
248
|
+
const resample3 = (out, a, [samplerX, samplerY, samplerZ]) => {
|
|
249
|
+
const {
|
|
250
|
+
shape: [_, syo, szo]
|
|
251
|
+
} = out;
|
|
252
|
+
const {
|
|
253
|
+
shape: [sxa, sya]
|
|
254
|
+
} = a;
|
|
255
|
+
const tmpX = tensor("num", [sxa, sya, szo]);
|
|
256
|
+
for (let i = 0; i < sxa; i++) {
|
|
257
|
+
const src = a.pick([i]);
|
|
258
|
+
const dest = tmpX.pick([i]);
|
|
259
|
+
for (let j = 0; j < sya; j++) {
|
|
260
|
+
resample1(dest.pick([j]), src.pick([j]), samplerX);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const tmpY = tensor("num", [sxa, syo, szo]);
|
|
264
|
+
for (let i = 0; i < sxa; i++) {
|
|
265
|
+
const src = tmpX.pick([i]);
|
|
266
|
+
const dest = tmpY.pick([i]);
|
|
267
|
+
for (let j = 0; j < szo; j++) {
|
|
268
|
+
resample1(dest.pick([-1, j]), src.pick([-1, j]), samplerY);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
for (let i = 0; i < syo; i++) {
|
|
272
|
+
for (let j = 0; j < szo; j++) {
|
|
273
|
+
resample1(out.pick([-1, i, j]), tmpY.pick([-1, i, j]), samplerZ);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return out;
|
|
277
|
+
};
|
|
278
|
+
export {
|
|
279
|
+
SAMPLE_CUBIC,
|
|
280
|
+
SAMPLE_LANCZOS,
|
|
281
|
+
SAMPLE_LINEAR,
|
|
282
|
+
SAMPLE_NEAREST,
|
|
283
|
+
defSampler1,
|
|
284
|
+
defSampler2,
|
|
285
|
+
defSampler3,
|
|
286
|
+
defSampler4,
|
|
287
|
+
resample1,
|
|
288
|
+
resample2,
|
|
289
|
+
resample3
|
|
290
|
+
};
|
package/tensor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NumericArray } from "@thi.ng/api";
|
|
2
2
|
import type { ITensor, ITensorStorage, Nested, NestedTensor, NumType, Shape, ShapeTensor, TensorCtor, TensorData, TensorFromArrayOpts, TensorOpts, Type, TypeMap } from "./api.js";
|
|
3
3
|
export declare abstract class ATensor<T = number> implements ITensor<T> {
|
|
4
4
|
type: Type;
|
|
@@ -24,7 +24,7 @@ export declare abstract class ATensor<T = number> implements ITensor<T> {
|
|
|
24
24
|
equiv(o: any): boolean;
|
|
25
25
|
eqDelta(o: ITensor<T>, eps?: number): boolean;
|
|
26
26
|
abstract index(pos: NumericArray): number;
|
|
27
|
-
position(index: number):
|
|
27
|
+
position(index: number): number[];
|
|
28
28
|
abstract get(pos: NumericArray): T;
|
|
29
29
|
abstract set(pos: NumericArray, v: T): this;
|
|
30
30
|
hi(pos: NumericArray): this;
|
|
@@ -40,9 +40,23 @@ export declare abstract class ATensor<T = number> implements ITensor<T> {
|
|
|
40
40
|
toJSON(): {
|
|
41
41
|
buf: T[];
|
|
42
42
|
shape: number[];
|
|
43
|
-
stride:
|
|
43
|
+
stride: number[];
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
export declare class Tensor0<T = number> extends ATensor<T> {
|
|
47
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
48
|
+
get dim(): number;
|
|
49
|
+
get order(): number[];
|
|
50
|
+
get length(): number;
|
|
51
|
+
index(): number;
|
|
52
|
+
position(): number[];
|
|
53
|
+
get(): T;
|
|
54
|
+
set(_: NumericArray, v: T): this;
|
|
55
|
+
pick([x]: NumericArray): Tensor0<T>;
|
|
56
|
+
resize<S extends Shape>(newShape: S, fill?: T, storage?: ITensorStorage<T>): ShapeTensor<S, T>;
|
|
57
|
+
transpose(_: number[]): this;
|
|
58
|
+
toString(): string;
|
|
59
|
+
}
|
|
46
60
|
export declare class Tensor1<T = number> extends ATensor<T> {
|
|
47
61
|
[Symbol.iterator](): IterableIterator<T>;
|
|
48
62
|
get dim(): number;
|
|
@@ -52,7 +66,7 @@ export declare class Tensor1<T = number> extends ATensor<T> {
|
|
|
52
66
|
position(index: number): number[];
|
|
53
67
|
get([x]: NumericArray): T;
|
|
54
68
|
set([x]: NumericArray, v: T): this;
|
|
55
|
-
pick([x]: NumericArray):
|
|
69
|
+
pick([x]: NumericArray): ITensor<T>;
|
|
56
70
|
resize<S extends Shape>(newShape: S, fill?: T, storage?: ITensorStorage<T>): ShapeTensor<S, T>;
|
|
57
71
|
transpose(_: number[]): this;
|
|
58
72
|
toString(): string;
|
|
@@ -91,7 +105,10 @@ export declare class Tensor4<T = number> extends ATensor<T> {
|
|
|
91
105
|
resize<S extends Shape>(newShape: S, fill?: T, storage?: ITensorStorage<T>): ShapeTensor<S, T>;
|
|
92
106
|
toString(): string;
|
|
93
107
|
}
|
|
94
|
-
export declare const TENSOR_IMPLS:
|
|
108
|
+
export declare const TENSOR_IMPLS: TensorCtor<any>[];
|
|
109
|
+
/** Syntax sugar for wrapping a single scalar value */
|
|
110
|
+
export declare function tensor(value: number): Tensor0<number>;
|
|
111
|
+
export declare function tensor(value: string): Tensor0<string>;
|
|
95
112
|
/** Syntax sugar for {@link tensorFromArray}. */
|
|
96
113
|
export declare function tensor<T extends NumType, N extends Nested<number>>(data: N, opts?: TensorFromArrayOpts<T, number>): NestedTensor<N, number>;
|
|
97
114
|
/** Syntax sugar for {@link tensorFromArray}. */
|
|
@@ -108,6 +125,13 @@ export declare function tensor<N extends Nested<string>>(data: N, opts?: TensorF
|
|
|
108
125
|
* @param opts
|
|
109
126
|
*/
|
|
110
127
|
export declare function tensor<T extends Type, S extends Shape>(type: T, shape: S, opts?: TensorOpts<TypeMap[T], S>): ShapeTensor<S, TypeMap[T]>;
|
|
128
|
+
/**
|
|
129
|
+
* Returns a matching tensor impl for given shape. If `shape=[1]` the function
|
|
130
|
+
* returns {@link Tensor0}. Returns undefined if no matching impl is available.
|
|
131
|
+
*
|
|
132
|
+
* @param shape
|
|
133
|
+
*/
|
|
134
|
+
export declare const tensorImpl: (shape: number[]) => TensorCtor<any>;
|
|
111
135
|
/**
|
|
112
136
|
* Creates a new {@link ITensor} instance from given (possibly nested) numeric
|
|
113
137
|
* array, and options.
|
|
@@ -133,6 +157,7 @@ export declare function tensorFromArray<N extends Nested<string>>(data: N, opts?
|
|
|
133
157
|
export declare const zeroes: <S extends Shape>(shape: S, type?: NumType, storage?: ITensorStorage<number>) => ShapeTensor<S, number>;
|
|
134
158
|
export declare const ones: <S extends Shape>(shape: S, type?: NumType, storage?: ITensorStorage<number>) => ShapeTensor<S, number>;
|
|
135
159
|
export declare const constant: <T extends Type, S extends Shape>(shape: S, value: TypeMap[T], type: T, storage?: ITensorStorage<TypeMap[T]>) => ShapeTensor<S, TypeMap[T]>;
|
|
136
|
-
export declare const shapeToStride: (shape: number[]) =>
|
|
160
|
+
export declare const shapeToStride: (shape: number[]) => number[];
|
|
137
161
|
export declare const strideOrder: (strides: number[]) => number[];
|
|
162
|
+
export declare const computeOffset: (shape: number[], stride: number[]) => number;
|
|
138
163
|
//# sourceMappingURL=tensor.d.ts.map
|
package/tensor.js
CHANGED
|
@@ -72,6 +72,7 @@ class ATensor {
|
|
|
72
72
|
}
|
|
73
73
|
position(index) {
|
|
74
74
|
const { order, stride } = this;
|
|
75
|
+
index |= 0;
|
|
75
76
|
index -= this.offset;
|
|
76
77
|
const idx = order.map((o) => {
|
|
77
78
|
const i = ~~(index / stride[o]);
|
|
@@ -172,6 +173,61 @@ class ATensor {
|
|
|
172
173
|
};
|
|
173
174
|
}
|
|
174
175
|
}
|
|
176
|
+
class Tensor0 extends ATensor {
|
|
177
|
+
*[Symbol.iterator]() {
|
|
178
|
+
yield this.data[this.offset];
|
|
179
|
+
}
|
|
180
|
+
get dim() {
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
get order() {
|
|
184
|
+
return [0];
|
|
185
|
+
}
|
|
186
|
+
get length() {
|
|
187
|
+
return 1;
|
|
188
|
+
}
|
|
189
|
+
index() {
|
|
190
|
+
return this.offset;
|
|
191
|
+
}
|
|
192
|
+
position() {
|
|
193
|
+
return [0];
|
|
194
|
+
}
|
|
195
|
+
get() {
|
|
196
|
+
return this.data[this.offset];
|
|
197
|
+
}
|
|
198
|
+
set(_, v) {
|
|
199
|
+
this.data[this.offset] = v;
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
pick([x]) {
|
|
203
|
+
if (x !== 0) outOfBounds(x);
|
|
204
|
+
return new Tensor0(
|
|
205
|
+
this.type,
|
|
206
|
+
this.storage,
|
|
207
|
+
this.data,
|
|
208
|
+
[],
|
|
209
|
+
[],
|
|
210
|
+
this.offset
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
resize(newShape, fill, storage = this.storage) {
|
|
214
|
+
const newLength = product(newShape);
|
|
215
|
+
const newData = storage.alloc(newLength);
|
|
216
|
+
if (fill !== void 0) newData.fill(fill);
|
|
217
|
+
newData[0] = this.get();
|
|
218
|
+
return tensor(this.type, newShape, {
|
|
219
|
+
storage,
|
|
220
|
+
data: newData,
|
|
221
|
+
copy: false
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
transpose(_) {
|
|
225
|
+
return unsupported();
|
|
226
|
+
}
|
|
227
|
+
toString() {
|
|
228
|
+
return format(this.get());
|
|
229
|
+
}
|
|
230
|
+
}
|
|
175
231
|
class Tensor1 extends ATensor {
|
|
176
232
|
*[Symbol.iterator]() {
|
|
177
233
|
let {
|
|
@@ -195,7 +251,7 @@ class Tensor1 extends ATensor {
|
|
|
195
251
|
return this.offset + x * this.stride[0];
|
|
196
252
|
}
|
|
197
253
|
position(index) {
|
|
198
|
-
return [~~((index - this.offset) / this.stride[0])];
|
|
254
|
+
return [~~(((index | 0) - this.offset) / this.stride[0])];
|
|
199
255
|
}
|
|
200
256
|
get([x]) {
|
|
201
257
|
return this.data[this.offset + x * this.stride[0]];
|
|
@@ -206,12 +262,12 @@ class Tensor1 extends ATensor {
|
|
|
206
262
|
}
|
|
207
263
|
pick([x]) {
|
|
208
264
|
if (x < 0 && x >= this.length) outOfBounds(x);
|
|
209
|
-
return new
|
|
265
|
+
return new Tensor0(
|
|
210
266
|
this.type,
|
|
211
267
|
this.storage,
|
|
212
268
|
this.data,
|
|
213
|
-
[
|
|
214
|
-
[
|
|
269
|
+
[],
|
|
270
|
+
[],
|
|
215
271
|
this.offset + x * this.stride[0]
|
|
216
272
|
);
|
|
217
273
|
}
|
|
@@ -235,7 +291,7 @@ class Tensor1 extends ATensor {
|
|
|
235
291
|
});
|
|
236
292
|
}
|
|
237
293
|
transpose(_) {
|
|
238
|
-
return
|
|
294
|
+
return unsupported();
|
|
239
295
|
}
|
|
240
296
|
toString() {
|
|
241
297
|
const res = [];
|
|
@@ -443,7 +499,7 @@ class Tensor4 extends ATensor {
|
|
|
443
499
|
}
|
|
444
500
|
}
|
|
445
501
|
const TENSOR_IMPLS = [
|
|
446
|
-
|
|
502
|
+
Tensor0,
|
|
447
503
|
Tensor1,
|
|
448
504
|
Tensor2,
|
|
449
505
|
Tensor3,
|
|
@@ -451,30 +507,32 @@ const TENSOR_IMPLS = [
|
|
|
451
507
|
];
|
|
452
508
|
function tensor(...args) {
|
|
453
509
|
if (Array.isArray(args[0])) return tensorFromArray(args[0], args[1]);
|
|
510
|
+
if (args.length === 1) return __tensor0(args[0]);
|
|
454
511
|
const type = args[0];
|
|
455
512
|
const shape = args[1];
|
|
513
|
+
const dim = shape.length;
|
|
456
514
|
const opts = args[2];
|
|
457
515
|
const storage = opts?.storage ?? STORAGE[type];
|
|
458
516
|
const stride = opts?.stride ?? shapeToStride(shape);
|
|
517
|
+
const offset = opts?.offset ?? computeOffset(shape, stride);
|
|
459
518
|
let data;
|
|
460
519
|
if (opts?.data) {
|
|
461
520
|
if (opts?.copy === false) data = opts.data;
|
|
462
521
|
else data = storage.from(opts.data);
|
|
463
522
|
} else {
|
|
464
|
-
data = storage.alloc(product(shape));
|
|
465
|
-
}
|
|
466
|
-
let offset = opts?.offset;
|
|
467
|
-
if (offset === void 0) {
|
|
468
|
-
offset = 0;
|
|
469
|
-
for (let i = 0; i < shape.length; i++) {
|
|
470
|
-
if (stride[i] < 0) {
|
|
471
|
-
offset -= (shape[i] - 1) * stride[i];
|
|
472
|
-
}
|
|
473
|
-
}
|
|
523
|
+
data = storage.alloc(dim > 0 ? product(shape) : 1);
|
|
474
524
|
}
|
|
475
|
-
const ctor = TENSOR_IMPLS[
|
|
476
|
-
return ctor ? new ctor(type, storage, data, shape, stride, offset) : unsupported(`unsupported dimension: ${
|
|
525
|
+
const ctor = TENSOR_IMPLS[dim];
|
|
526
|
+
return ctor ? new ctor(type, storage, data, shape, stride, offset) : unsupported(`unsupported dimension: ${dim}`);
|
|
477
527
|
}
|
|
528
|
+
const __tensor0 = (x) => {
|
|
529
|
+
const type = isNumber(x) ? "num" : "str";
|
|
530
|
+
const storage = STORAGE[type];
|
|
531
|
+
const data = storage.alloc(1);
|
|
532
|
+
data[0] = x;
|
|
533
|
+
return new Tensor0(type, storage, data, [], []);
|
|
534
|
+
};
|
|
535
|
+
const tensorImpl = (shape) => shape.length === 1 && shape[0] === 1 ? Tensor0 : TENSOR_IMPLS[shape.length];
|
|
478
536
|
function tensorFromArray(data, opts) {
|
|
479
537
|
const shape = [data.length];
|
|
480
538
|
let $data = data;
|
|
@@ -507,6 +565,15 @@ const shapeToStride = (shape) => {
|
|
|
507
565
|
return stride;
|
|
508
566
|
};
|
|
509
567
|
const strideOrder = (strides) => strides.map((x, i) => [x, i]).sort((a, b) => abs(b[0]) - abs(a[0])).map((x) => x[1]);
|
|
568
|
+
const computeOffset = (shape, stride) => {
|
|
569
|
+
let offset = 0;
|
|
570
|
+
for (let i = 0; i < shape.length; i++) {
|
|
571
|
+
if (stride[i] < 0) {
|
|
572
|
+
offset -= (shape[i] - 1) * stride[i];
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return offset;
|
|
576
|
+
};
|
|
510
577
|
const __lo = (select, { shape, stride, offset }) => {
|
|
511
578
|
const newShape = [];
|
|
512
579
|
for (let i = 0, n = shape.length; i < n; i++) {
|
|
@@ -566,15 +633,18 @@ const __pick = (select, { shape, stride, offset }) => {
|
|
|
566
633
|
export {
|
|
567
634
|
ATensor,
|
|
568
635
|
TENSOR_IMPLS,
|
|
636
|
+
Tensor0,
|
|
569
637
|
Tensor1,
|
|
570
638
|
Tensor2,
|
|
571
639
|
Tensor3,
|
|
572
640
|
Tensor4,
|
|
641
|
+
computeOffset,
|
|
573
642
|
constant,
|
|
574
643
|
ones,
|
|
575
644
|
shapeToStride,
|
|
576
645
|
strideOrder,
|
|
577
646
|
tensor,
|
|
578
647
|
tensorFromArray,
|
|
648
|
+
tensorImpl,
|
|
579
649
|
zeroes
|
|
580
650
|
};
|