@thi.ng/tensors 0.8.12 → 0.9.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-08-04T09:13:01Z
3
+ - **Last updated**: 2025-08-16T18:12:02Z
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,15 @@ 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.9.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.9.0) (2025-08-16)
15
+
16
+ #### 🚀 Features
17
+
18
+ - add 0-dim (wrapped scalar) tensor support ([cd22ee6](https://github.com/thi-ng/umbrella/commit/cd22ee6))
19
+ - add `Tensor0`, `Shape0`
20
+ - update HOF tensor op generators
21
+ - add/update tests
22
+
14
23
  ## [0.8.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/tensors@0.8.0) (2025-07-10)
15
24
 
16
25
  #### 🚀 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, at the moment, is
38
- > undergoing heavy refactoring to be stylistically more aligned with other thi.ng
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: 9.75 KB
253
+ Package sizes (brotli'd, pre-treeshake): ESM: 10.06 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
- void 0,
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, void 0, f1, f2, f3, f4);
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, void 0, f1, f2, f3, f4);
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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thi.ng/tensors",
3
- "version": "0.8.12",
4
- "description": "1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage",
3
+ "version": "0.9.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",
@@ -40,14 +40,14 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@thi.ng/api": "^8.12.1",
43
- "@thi.ng/arrays": "^2.13.9",
44
- "@thi.ng/checks": "^3.7.16",
43
+ "@thi.ng/arrays": "^2.13.10",
44
+ "@thi.ng/checks": "^3.7.17",
45
45
  "@thi.ng/equiv": "^2.1.91",
46
46
  "@thi.ng/errors": "^2.5.41",
47
47
  "@thi.ng/math": "^5.11.35",
48
48
  "@thi.ng/random": "^4.1.26",
49
49
  "@thi.ng/strings": "^3.9.21",
50
- "@thi.ng/vectors": "^8.6.4"
50
+ "@thi.ng/vectors": "^8.6.5"
51
51
  },
52
52
  "devDependencies": {
53
53
  "esbuild": "^0.25.8",
@@ -339,5 +339,5 @@
339
339
  "status": "alpha",
340
340
  "year": 2018
341
341
  },
342
- "gitHead": "9a998c33c7a524c95b552b9cbdc2734d28a5dafc\n"
342
+ "gitHead": "b133e905b546bff0d244826684269cdbb2fcfa25\n"
343
343
  }
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
- void 0,
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/tensor.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Maybe, NumericArray } from "@thi.ng/api";
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): any[];
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: any[];
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): Tensor1<T>;
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: Maybe<TensorCtor<any>>[];
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[]) => any[];
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 Tensor1(
265
+ return new Tensor0(
210
266
  this.type,
211
267
  this.storage,
212
268
  this.data,
213
- [1],
214
- [1],
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 this.copy();
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
- void 0,
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[shape.length];
476
- return ctor ? new ctor(type, storage, data, shape, stride, offset) : unsupported(`unsupported dimension: ${shape.length}`);
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
  };