@thi.ng/tensors
Version:
0D/1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage
690 lines • 30.8 kB
TypeScript
import type { Type as $Type, ICopy, IEqualsDelta, IEquiv, ILength, IRelease, Maybe, NumericArray } from "@thi.ng/api";
import type { Tensor0, Tensor1, Tensor2, Tensor3, Tensor4 } from "./tensor.js";
export interface TensorData<T = number> extends Iterable<T>, ILength {
[id: number]: T;
fill(x: T, start?: number, end?: number): TensorData<T>;
}
export type Type = $Type | "num" | "str";
export type NumType = $Type | "num";
export type Shape0 = [];
export type Shape1 = [number];
export type Shape2 = [number, number];
export type Shape3 = [number, number, number];
export type Shape4 = [number, number, number, number];
export type Shape = Shape0 | Shape1 | Shape2 | Shape3 | Shape4;
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>;
export type Nested<T> = T[] | T[][] | T[][][] | T[][][][];
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>;
export interface TypeMap {
u8: number;
u8c: number;
i8: number;
u16: number;
i16: number;
u32: number;
i32: number;
f32: number;
f64: number;
num: number;
str: string;
}
export interface TensorOpts<T, S extends Shape> {
/**
* Tensor data. Unless {@link TensorOpts.copy} is false, by default will be
* copied to memory obtained from configured storage.
*/
data?: TensorData<T>;
/**
* Optionally configured storage provider. By default uses the
* datatype-specific implementation from global {@link STORAGE} registry.
*/
storage?: ITensorStorage<T>;
/**
* Optionally configured stride tuple. By default the strides will be
* obtained from the tensor shape and will be in row-major order.
*/
stride?: S;
/**
* Optional start index of the data values (only inteded to be used if
* {@link TensorOpts.data} is given).
*/
offset?: number;
/**
* Only used if {@link TensorOpts.data} is given. If true (default), the
* data will be copied to memory obtained from configured storage.
*/
copy?: boolean;
}
export interface TensorFromArrayOpts<T extends Type, V> {
type: T;
storage?: ITensorStorage<V>;
}
/**
* Source data type for tensor conversion via {@link asTensor}.
*/
export interface TensorLike<T extends Type, S extends Shape> {
/** Data type */
type: T;
/** Tensor data/values (MUST match `type`) */
data: TensorData<TypeMap[T]>;
/** Tensor shape */
shape: S;
/** Stride/layout information of data */
stride: S;
/** Start index (default: 0) */
offset?: number;
}
export interface ITensor<T = number> extends ICopy<ITensor<T>>, IEquiv, IEqualsDelta<ITensor<T>>, IRelease {
readonly type: Type;
readonly storage: ITensorStorage<T>;
readonly data: TensorData<T>;
readonly shape: number[];
readonly stride: number[];
readonly offset: number;
readonly length: number;
readonly dim: number;
readonly order: number[];
orderedShape: number[];
orderedStride: number[];
[Symbol.iterator](): IterableIterator<T>;
/**
* Internal use only. Creates a shallow view used for broadcasting
* operators. See {@link broadcast} for details.
*
* @param shape
* @param stride
*
* @internal
*/
broadcast<S extends Shape>(shape: S, stride: S): ShapeTensor<S, T>;
/**
* Returns a new tensor of same shape, but all values zeroed. Unless
* `storage` is given, the new data will be allocated using this tensor's
* storage provider.
*
* @param storage
*/
empty(storage?: ITensorStorage<T>): this;
/**
* Computes linear array index from given grid position. Reverse-op of
* {@link ITensor.position}.
*
* @remarks
* The given `pos` is assumed to be integral and valid. No bounds checking
* performed.
*
* @param pos
*/
index(pos: NumericArray): number;
/**
* Computes nD grid position for given linear array index. Reverse-op of
* {@link ITensor.index}.
*
* @remarks
* The given `index` is assumed to be valid. No bounds checking performed.
*
* **CAUTION:** Currently only supports tensors with positive strides,
* otherwise will yield incorrect results! Tensors with negative strides
* (aka flipped axes in reverse order) need to be first packed via
* {@link ITensor.pack}.
*
* @param index
*/
position(index: number): number[];
/**
* Returns value at given grid position. No bounds checking.
*
* @param pos
*/
get(pos: NumericArray): T;
/**
* Sets value at given grid position. No bounds checking.
*
* @param pos
* @param value
*/
set(pos: NumericArray, value: T): this;
/**
* Returns a new tensor of the bottom-right region starting from given
* `pos`. View transform only, no data will be copied.
*
* @remarks
* Also see {@link Itensor.hi}, {@link ITensor.crop}.
*
* @example
* ```ts tangle:../export/itensor-lo.ts
* import { print, range } from "@thi.ng/tensors";
*
* const a = range(16).reshape([4, 4]);
* print(a);
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000
* // 12.0000 13.0000 14.0000 15.0000
*
* const b = a.lo([2, 1]);
* print(b);
* // 9.0000 10.0000 11.0000
* // 13.0000 14.0000 15.0000
* ```
*
* @param pos
*/
lo(pos: NumericArray): this;
/**
* Returns a new tensor of the top-left region until given `pos` (excluded).
* View transform only, no data will be copied.
*
* @remarks
* Also see {@link Itensor.lo}, {@link ITensor.crop}.
*
* @example
* ```ts tangle:../export/itensor-hi.ts
* import { print, range } from "@thi.ng/tensors";
*
* const a = range(16).reshape([4, 4]);
* print(a);
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000
* // 12.0000 13.0000 14.0000 15.0000
*
* const b = a.hi([2, 3]);
* print(b);
* // 0 1.0000 2.0000
* // 4.0000 5.0000 6.0000
* ```
*
* @param pos
*/
hi(pos: NumericArray): this;
/**
* Returns a new tensor of the extracted region defined by `pos` and `size`.
* This op is a combination of {@link ITensor.lo} and {@link ITensor.hi}.
* View transform only, no data will be copied.
*
* @example
* ```ts tangle:../export/itensor-crop.ts
* import { print, range } from "@thi.ng/tensors";
*
* const a = range(16).reshape([4, 4]);
* print(a);
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000
* // 12.0000 13.0000 14.0000 15.0000
*
* const b = a.crop([1, 1], [2, 2]);
* print(b);
* // 5.0000 6.0000
* // 9.0000 10.0000
* ```
*
* @param pos
* @param size
*/
crop(pos: NumericArray, size: NumericArray): this;
/**
* Returns a new tensor with step sizes adjusted for selected axes (Using
* zero for an axis will keep its current step size). View transform only,
* no data will be copied.
*
* @example
* ```ts tangle:../export/itensor-step.ts
* import { print, range } from "@thi.ng/tensors";
*
* const a = range(16).reshape([4, 4]);
* print(a);
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000
* // 12.0000 13.0000 14.0000 15.0000
*
* // only select every 2nd row
* const b = a.step([2, 1]);
* print(b);
* // 0 1.0000 2.0000 3.0000
* // 8.0000 9.0000 10.0000 11.0000
*
* // keep rows as is (zero), only select every 2nd column
* print(b.step([0, 2]));
* // 0 2.0000
* // 8.0000 10.0000
* ```
*
* @param select
*/
step(select: NumericArray): this;
/**
* Returns a new tensor with only the `select`ed axes. A -1 will select all
* value in that axis. View transform only, no data will be copied.
*
* @example
* ```ts tangle:../export/itensor-pick.ts
* import { print, range } from "@thi.ng/tensors";
*
* // 3D 4x4x4 tensor with values in [0,64) range
* const a = range(64).reshape([4, 4, 4]);
*
* // pick entire slice #2
* print(a.pick([2]));
* // 32.0000 33.0000 34.0000 35.0000
* // 36.0000 37.0000 38.0000 39.0000
* // 40.0000 41.0000 42.0000 43.0000
* // 44.0000 45.0000 46.0000 47.0000
*
* // pick slice #2, row #2 (1D tensor)
* print(a.pick([2, 2]));
* // 40.0000 41.0000 42.0000 43.0000
*
* // pick slice #2, column #2 (1D tensor)
* print(a.pick([2, -1, 2]));
* // 34.0000 38.0000 42.0000 46.0000
* ```
*
* @param select
*/
pick(select: NumericArray): ITensor<T>;
/**
* Creates a "packed" copy of this tensor with dense striding and the new
* data array only holding the values actually referenced by this tensor.
* Unless `storage` is given, the new data will be allocated using this
* tensor's storage provider.
*
* @remarks
* Since most other `ITensor` ops are zero-copy, view-only transforms, often
* resulting in "sparse" views which are only addressing a subset of the
* values stored, using `.pack()` is useful to extract data into a dense
* tensor/buffer.
*
* @example
* ```ts tangle:../export/itensor-pack.ts
* import { range } from "@thi.ng/tensors";
*
* const a = range(16).reshape([4, 4]);
* console.log("a data", a.data);
* // a data [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]
*
* // only select every 2nd row & column
* const b = a.step([2, 2]);
* console.log("b values", [...b]);
* // b values [ 0, 2, 8, 10 ]
* console.log("b data", b.data);
* // b data [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]
*
* // create packed version of `b`
* const c = b.pack();
* console.log("c data", c.data);
* // c data [ 0, 2, 8, 10 ]
* ```
*
* @param storage
*/
pack(storage?: ITensorStorage<T>): this;
/**
* Returns a new tensor with same data but given new shape (and optionally
* new strides). The total number of elements of the new shape MUST match
* that of the current shape (otherwise an error will be thrown).
*
* @remarks
* Also see {@link ITensor.crop} and {@link ITensor.resize}
*
* @example
* ```ts tangle:../export/itensor-reshape.ts
* import { print, range } from "@thi.ng/tensors";
*
* // 1D tensor
* const a = range(16);
*
* // reshape as 2D tensor
* print(a.reshape([4, 4]));
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000
* // 12.0000 13.0000 14.0000 15.0000
*
* // reshape as 3D tensor
* print(a.reshape([2, 2, 4]));
* // --- 0: ---
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // --- 1: ---
* // 8.0000 9.0000 10.0000 11.0000
* // 12.0000 13.0000 14.0000 15.0000
* ```
*
* @param newShape
* @param newStride
*/
reshape<S extends Shape>(newShape: S, newStride?: S): ShapeTensor<S, T>;
/**
* Returns a copy of the tensor resized to `newShape`. If the new shape is
* larger than the current shape, the extra data values will be initialized
* to `fill` (default: zero). Values will be copied in current iteration
* order (same logic as numpy). Unless `storage` is given, the new data will
* be allocated using this tensor's storage provider.
*
* @remarks
* Also see {@link ITensor.crop}, {@link ITensor.reshape}.
*
* @example
* ```ts tangle:../export/itensor-resize.ts
* import { print, range } from "@thi.ng/tensors";
*
* // 2D 4x4 tensor with values in [0,16) range
* const a = range(16).reshape([4, 4]);
*
* print(a.resize([4, 8]));
* // 0 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000
* // 0 0 0 0 0 0 0 0
* // 0 0 0 0 0 0 0 0
* ```
*
* @param newShape
* @param fill
* @param storage
*/
resize<S extends Shape>(newShape: S, fill?: T, storage?: ITensorStorage<T>): ShapeTensor<S, T>;
/**
* Returns a new tensor with the given new axis `order`. View transform
* only, no data will be copied.
*
* @example
* ```ts tangle:../export/itensor-transpose.ts
* import { print, range } from "@thi.ng/tensors";
*
* const a = range(12).reshape([3, 4]);
* print(a);
* // 0 1.0000 2.0000 3.0000
* // 4.0000 5.0000 6.0000 7.0000
* // 8.0000 9.0000 10.0000 11.0000
*
* // swap row & column order
* const b = a.transpose([1, 0]);
* print(b);
* // 0 4.0000 8.0000
* // 1.0000 5.0000 9.0000
* // 2.0000 6.0000 10.0000
* // 3.0000 7.0000 11.0000
* ```
*
* @param order
*/
transpose(order: NumericArray): this;
toJSON(): any;
}
export interface TensorCtor<T = number> {
new (type: Type, storage: ITensorStorage<T>, data: TensorData<T>, shape: number[], stride: number[], offset?: number): ITensor<T>;
}
export interface ITensorStorage<T> {
/**
* Attempts to allocate/create an array for given number of items. Throws an
* error if unsuccessful.
*
* @param size
*/
alloc(size: number): TensorData<T>;
/**
* Attempts to allocate/create an array for given iterable. Throws an
* error if unsuccessful.
*
* @param iter
*/
from(iter: Iterable<T>): TensorData<T>;
/**
* Attempts to release the array/memory used by given buffer. Returns true
* if successful.
*
* @param buf
*/
release(buf: TensorData<T>): boolean;
}
export type StorageRegistry = Record<Type, ITensorStorage<any>>;
export interface TensorOpT<T = number> {
(out: Tensor0<T> | null, a: Tensor0<T>): Tensor0<T>;
(out: Tensor1<T> | null, a: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor4<T>): Tensor4<T>;
}
export interface TensorOpTT<T = number> {
(out: Tensor0<T> | null, a: Tensor0<T>, b: Tensor0<T>): Tensor0<T>;
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>): Tensor4<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor0<T>): Tensor1<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>): Tensor4<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>): Tensor4<T>;
}
export interface TensorOpTTT<T = number> {
(out: Tensor0<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor0<T>;
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor1<T>;
(out: Tensor1<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor0<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor1<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor1<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor1<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor2<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor2<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor3<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor3<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor0<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor1<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor2<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor3<T>, c: Tensor4<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor0<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor1<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor2<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor3<T>): Tensor4<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, b: Tensor4<T>, c: Tensor4<T>): Tensor4<T>;
}
export interface TensorOpN<A = number, B = A> {
(out: Tensor0<B>, n: A): Tensor0<B>;
(out: Tensor1<B>, n: A): Tensor1<B>;
(out: Tensor2<B>, n: A): Tensor2<B>;
(out: Tensor3<B>, n: A): Tensor3<B>;
(out: Tensor4<B>, n: A): Tensor4<B>;
}
export interface TensorOpTN<T = number> {
(out: Tensor0<T> | null, a: Tensor0<T>, n: T): Tensor0<T>;
(out: Tensor1<T> | null, a: Tensor1<T>, n: T): Tensor1<T>;
(out: Tensor2<T> | null, a: Tensor2<T>, n: T): Tensor2<T>;
(out: Tensor3<T> | null, a: Tensor3<T>, n: T): Tensor3<T>;
(out: Tensor4<T> | null, a: Tensor4<T>, n: T): Tensor4<T>;
}
export interface TensorOpTNN<T = number> {
(out: Tensor0<T>, a: Tensor0<T>, n: T, m: T): Tensor0<T>;
(out: Tensor1<T>, a: Tensor1<T>, n: T, m: T): Tensor1<T>;
(out: Tensor2<T>, a: Tensor2<T>, n: T, m: T): Tensor2<T>;
(out: Tensor3<T>, a: Tensor3<T>, n: T, m: T): Tensor3<T>;
(out: Tensor4<T>, a: Tensor4<T>, n: T, m: T): Tensor4<T>;
}
export type TensorOpRT<A, B, TA extends ITensor<A> = ITensor<A>> = (a: TA) => B;
export type TensorOpRTT<A, B, TA extends ITensor<A> = ITensor<A>> = (a: TA, b: TA) => B;
export interface MultiTensorOp<TOP> {
/**
* Adds / overwrites implementation for given tensor dimension.
*
* @param dim -
* @param op -
*/
add(dim: number, op: TOP): TOP;
/**
* Adds / overwrites default implementation (SHOULD support arbitrary tensor
* dimensions).
*
* @param op -
*/
default(op: TOP): TOP;
/**
* Returns implementation for given tensor dimension or default
* implementation.
*
* @param dim -
*/
impl(dim?: number): Maybe<TOP>;
}
export type MultiTensorOpImpl<T> = T & MultiTensorOp<T>;
/**
* Convolution kernel spec for use with {@link applyKernel}.
*
* @remarks
* Provided implementations:
*
* - {@link MAX2_MOORE}
* - {@link MAX2_VON_NEUMANN}
* - {@link MAXIMA2_MOORE}
* - {@link MAXIMA2_VON_NEUMANN}
*/
export interface KernelSpec<T = any> {
/**
* Kernel shape/size
*/
shape: Exclude<Shape, Shape0>;
/**
* Windowed intialization. Returns initial accumulator for each new kernel
* window.
*/
init: () => T;
/**
* Windowed reduction function. Receives current accumulator, domain value
* and kernel-local coordinates. Returns updated accumulator.
*
* @param acc
* @param value
* @param coords
*/
reduce: (acc: T, value: number, ...coords: number[]) => T;
/**
* Windowed reducer result function. Produces final result from current
* accumulator.
*
* @param acc
*/
complete: (acc: T) => number;
}
//# sourceMappingURL=api.d.ts.map