Recently, Ben Newhouse released a TypeScript-based implementation of GPT called potatogpt. Although the performance may be slow, it contains a very interesting approach to type-checking tensor arithmetic. This approach eliminates the need to run your code to verify whether operations are allowed or to keep track of the sizes of tensors in your head.
The implementation is quite complex, employing several advanced TypeScript techniques. In order to make it more accessible and easier to understand, I’ve attempted to simplify and explain the implementation with clarifying comments below.
Finally, I show how this approach allows us to easily create type-safe versions of functions like zip and matmul.
Exact dimensions
In order that Tensors can have exact dimensions we need to support only numeric literals (e.g. 16, 768, etc) for sizes known at compile time, and “branded types” for sizes only known at runtime. We must disallow non-literal number types or unions of numbers (e.g. 16 | 768) as if these get introduced into an application, data produced using these would also lack exact dimensions.
// We check whether `T` is a numeric literal by checking that `number`
// does not extend from `T` but that `T` does extend from `number`.
type type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteral<T>T> = number extends function (type parameter) T in type IsNumericLiteral<T>T ? false : function (type parameter) T in type IsNumericLiteral<T>T extends number ? true : false;
// In order to support runtime-determined sizes we use a "branded type"
// to give these dimensions labels that they can be type-checked with
// and a function `Var` to generate values with this type.
export type type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in type Var<Label extends string>Label extends string> = number & { label: Label extends stringlabel: function (type parameter) Label in type Var<Label extends string>Label };
export const const Var: <Label extends string>(size: number, label: Label) => Var<Label>Var = <function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label extends string>(size: numbersize: number, label: Label extends stringlabel: function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label) => {
return size: numbersize as type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label>;
};
type type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsVar<T>T> = function (type parameter) T in type IsVar<T>T extends type Var<Label extends string> = number & {
label: Label;
}
Var<string> ? true : false;
// For type-checking of tensors to work they must only ever be
// created using numeric literals (e.g. `5`) or `Var<string>`
// and never from types like `number` or `1 | 2 | 3`.
type type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T extends number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>> = type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<
// We disallow `T` to be a union of types.
type Not<A> = A extends true ? false : trueNot<type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>>,
type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<
// We allow `T` to be a numeric literal but not a number.
type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>,
// We allow `T` to be a `Var`.
type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>
>
>;
// Utilities
type type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<function (type parameter) A in type And<A, B>A, function (type parameter) B in type And<A, B>B> = function (type parameter) A in type And<A, B>A extends true ? (function (type parameter) B in type And<A, B>B extends true ? true : false) : false;
type type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<function (type parameter) A in type Or<A, B>A, function (type parameter) B in type Or<A, B>B> = function (type parameter) A in type Or<A, B>A extends true ? true : function (type parameter) B in type Or<A, B>B extends true ? true : false;
type type Not<A> = A extends true ? false : trueNot<function (type parameter) A in type Not<A>A> = function (type parameter) A in type Not<A>A extends true ? false : true;
// `IsUnion` is based on the principle that a union like `A | B` does not
// extend an intersection like `A & B`. The conditional type uses a
// "tuple trick" technique that avoids distributing the type `T` over
// `UnionToIntersection` by wrapping the type into a one-element tuple.
// This means that if `T` is `'A' | 'B'` the expression is evaluated
// as `['A' | 'B'] extends [UnionToIntersection<'A' | 'B'>]` instead of
// `'A' | 'B' extends UnionToIntersection<'A'> | UnionToIntersection<'B'>`.
type type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsUnion<T>T> = [function (type parameter) T in type IsUnion<T>T] extends [type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) T in type IsUnion<T>T>] ? false : true;
// `UnionToIntersection` takes a union type and uses a "distributive
// conditional type" to map over each element of the union and create a
// series of function types with each element as their argument. It then
// infers the first argument of each of these functions to create a new
// type that is the intersection of all the types in the original union.
type type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) Union in type UnionToIntersection<Union>Union> = (
function (type parameter) Union in type UnionToIntersection<Union>Union extends unknown ? (distributedUnion: UniondistributedUnion: function (type parameter) Union in type UnionToIntersection<Union>Union) => void : never
) extends (mergedIntersection: IntersectionmergedIntersection: infer function (type parameter) IntersectionIntersection) => void
? function (type parameter) IntersectionIntersection
: never;
If you need to, you can read further on the more advanced TypeScript techniques here:
Tensor
We can then implement a type-safe Tensor with a unique constraint: the dimensions must be specified using numeric literals or “branded types”. This approach pushes the limits of TypeScript’s standard type-checking capabilities and requires a non-idiomatic usage of conditional types to represent these errors. Note that, we diverged from Ben’s original implementation by enforcing this dimensional constraint at the argument-level instead of doing so at the return-level with a conditional return type that produces an invalid tensor. The downside of this is that you must use as const on the shape argument to prevent TypeScript from widening the literal types to number.
type type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteral<T>T> = number extends function (type parameter) T in type IsNumericLiteral<T>T ? false : function (type parameter) T in type IsNumericLiteral<T>T extends number ? true : false;
export type type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in type Var<Label extends string>Label extends string> = number & { label: Label extends stringlabel: function (type parameter) Label in type Var<Label extends string>Label };
export const const Var: <Label extends string>(size: number, label: Label) => Var<Label>Var = <function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label extends string>(size: numbersize: number, label: Label extends stringlabel: function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label) => {
return size: numbersize as type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label>;
};
type type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsVar<T>T> = function (type parameter) T in type IsVar<T>T extends type Var<Label extends string> = number & {
label: Label;
}
Var<string> ? true : false;
type type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T extends number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>> = type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<
// We disallow `T` to be a union of types.
type Not<A> = A extends true ? false : trueNot<type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>>,
type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<
// We allow `T` to be a numeric literal but not a number.
type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>,
// We allow `T` to be a `Var`.
type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>
>
>;
type type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<function (type parameter) A in type And<A, B>A, function (type parameter) B in type And<A, B>B> = function (type parameter) A in type And<A, B>A extends true ? (function (type parameter) B in type And<A, B>B extends true ? true : false) : false;
type type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<function (type parameter) A in type Or<A, B>A, function (type parameter) B in type Or<A, B>B> = function (type parameter) A in type Or<A, B>A extends true ? true : function (type parameter) B in type Or<A, B>B extends true ? true : false;
type type Not<A> = A extends true ? false : trueNot<function (type parameter) A in type Not<A>A> = function (type parameter) A in type Not<A>A extends true ? false : true;
type type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsUnion<T>T> = [function (type parameter) T in type IsUnion<T>T] extends [type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) T in type IsUnion<T>T>] ? false : true;
type type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) Union in type UnionToIntersection<Union>Union> = (
function (type parameter) Union in type UnionToIntersection<Union>Union extends unknown ? (distributedUnion: UniondistributedUnion: function (type parameter) Union in type UnionToIntersection<Union>Union) => void : never
) extends (mergedIntersection: IntersectionmergedIntersection: infer function (type parameter) IntersectionIntersection) => void
? function (type parameter) IntersectionIntersection
: never;
/// ---cut---
export type type Dimension = number | Var<string>Dimension = number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>;
export type type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape extends readonly type Dimension = number | Var<string>Dimension[]> = {
data: Float32Array<ArrayBufferLike>data: interface Float32Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
of bytes could not be allocated an exception is raised.Float32Array;
shape: Shape extends readonly Dimension[]shape: function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape;
};
export function function tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>tensor<const function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape extends readonly type Dimension = number | Var<string>Dimension[]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape>,
init: number[] | undefinedinit?: number[],
): type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape> {
return {
data: Float32Array<ArrayBufferLike>data: init: number[] | undefinedinit
? new var Float32Array: Float32ArrayConstructor
new (elements: Iterable<number>) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array(init: number[]init)
: new var Float32Array: Float32ArrayConstructor
new (length: number) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array((shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape).ReadonlyArray<Dimension>.reduce(callbackfn: (previousValue: Dimension, currentValue: Dimension, currentIndex: number, array: readonly Dimension[]) => Dimension, initialValue: Dimension): Dimension (+2 overloads)Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((a: Dimensiona, b: Dimensionb) => a: Dimensiona * b: Dimensionb, 1)),
shape: const Shape extends readonly Dimension[]shape: shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape,
};
}
// `ArrayEveryElementIsNumericLiteralOrVar` is similar to JavaScript's
// `Array#every` in that it checks that a particular condition is true of
// every element in an array and returns `true` if this is the case. In
// TypeScript we have to hardcode our condition (`IsNumericLiteralOrVar`)
// as we do not yet have higher-kinded generic types that can take in
// other generic types and apply these.
//
// In the code below we create a "mapped object type" from an array type
// and then apply the condition to each value in the mapped object type.
// We then use a conditional type to check whether the type outputted
// extends from a type in which the value at every key is `true`.
type type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<unknown>
? { [function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T[function (type parameter) KK]> } extends {
[function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: true;
}
? true
: false
: false;
type type InvalidArgument<T> = readonly [never, T]InvalidArgument<function (type parameter) T in type InvalidArgument<T>T> = readonly [never, function (type parameter) T in type InvalidArgument<T>T];
type type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
true extends type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T>
? function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T
: interface ReadonlyArray<T>ReadonlyArray<
type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">
>;
// Tests
const const fourDimensionalTensorWithStaticSizes: Tensor<readonly [10, 100, 1000, 10000]>fourDimensionalTensorWithStaticSizes = function tensor<readonly [10, 100, 1000, 10000]>(shape: readonly [10, 100, 1000, 10000], init?: number[]): Tensor<readonly [10, 100, 1000, 10000]>tensor([10, 100, 1000, 10000] as type const = readonly [10, 100, 1000, 10000]const);
const const threeDimensionalTensorWithRuntimeSize: Tensor<readonly [5, Var<"dim">, 10]>threeDimensionalTensorWithRuntimeSize = function tensor<readonly [5, Var<"dim">, 10]>(shape: readonly [5, Var<"dim">, 10], init?: number[]): Tensor<readonly [5, Var<"dim">, 10]>tensor([5, const Var: <"dim">(size: number, label: "dim") => Var<"dim">Var(3, "dim"), 10] as type const = readonly [5, Var<"dim">, 10]const);
const const invalidTensor1: Tensor<readonly [10, 100, 1000, 10000]>invalidTensor1 = function tensor<readonly [10, 100, 1000, 10000]>(shape: readonly [10, 100, 1000, 10000], init?: number[]): Tensor<readonly [10, 100, 1000, 10000]>tensor([10, 100, 1000, 10000]);
const const invalidTensor2: Tensor<readonly [number, 100, 1000, 10000]>invalidTensor2 = function tensor<readonly [number, 100, 1000, 10000]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [number, 100, 1000, 10000]>tensor([10 as number, 100, 1000, 10000] as type const = readonly [number, 100, 1000, 10000]const);const const invalidTensor3: Tensor<readonly [5, 3 | 6 | 9, 10]>invalidTensor3 = function tensor<readonly [5, 3 | 6 | 9, 10]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [5, 3 | 6 | 9, 10]>tensor([5, 3 as 3 | 6 | 9, 10] as type const = readonly [5, 3 | 6 | 9, 10]const);
If you need to, you can read further on the more advanced TypeScript techniques here:
Matrix
type type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteral<T>T> = number extends function (type parameter) T in type IsNumericLiteral<T>T ? false : function (type parameter) T in type IsNumericLiteral<T>T extends number ? true : false;
export type type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in type Var<Label extends string>Label extends string> = number & { label: Label extends stringlabel: function (type parameter) Label in type Var<Label extends string>Label };
export const const Var: <Label extends string>(size: number, label: Label) => Var<Label>Var = <function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label extends string>(size: numbersize: number, label: Label extends stringlabel: function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label) => {
return size: numbersize as type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label>;
};
type type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsVar<T>T> = function (type parameter) T in type IsVar<T>T extends type Var<Label extends string> = number & {
label: Label;
}
Var<string> ? true : false;
type type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T extends number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>> = type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<
// We disallow `T` to be a union of types.
type Not<A> = A extends true ? false : trueNot<type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>>,
type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<
// We allow `T` to be a numeric literal but not a number.
type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>,
// We allow `T` to be a `Var`.
type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>
>
>;
type type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<function (type parameter) A in type And<A, B>A, function (type parameter) B in type And<A, B>B> = function (type parameter) A in type And<A, B>A extends true ? (function (type parameter) B in type And<A, B>B extends true ? true : false) : false;
type type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<function (type parameter) A in type Or<A, B>A, function (type parameter) B in type Or<A, B>B> = function (type parameter) A in type Or<A, B>A extends true ? true : function (type parameter) B in type Or<A, B>B extends true ? true : false;
type type Not<A> = A extends true ? false : trueNot<function (type parameter) A in type Not<A>A> = function (type parameter) A in type Not<A>A extends true ? false : true;
type type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsUnion<T>T> = [function (type parameter) T in type IsUnion<T>T] extends [type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) T in type IsUnion<T>T>] ? false : true;
type type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) Union in type UnionToIntersection<Union>Union> = (
function (type parameter) Union in type UnionToIntersection<Union>Union extends unknown ? (distributedUnion: UniondistributedUnion: function (type parameter) Union in type UnionToIntersection<Union>Union) => void : never
) extends (mergedIntersection: IntersectionmergedIntersection: infer function (type parameter) IntersectionIntersection) => void
? function (type parameter) IntersectionIntersection
: never;
export type type Dimension = number | Var<string>Dimension = number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>;
export type type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape extends readonly type Dimension = number | Var<string>Dimension[]> = {
data: Float32Array<ArrayBufferLike>data: interface Float32Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
of bytes could not be allocated an exception is raised.Float32Array;
shape: Shape extends readonly Dimension[]shape: function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape;
};
export function function tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>tensor<const function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape extends readonly type Dimension = number | Var<string>Dimension[]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape>,
init: number[] | undefinedinit?: number[],
): type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape> {
return {
data: Float32Array<ArrayBufferLike>data: init: number[] | undefinedinit
? new var Float32Array: Float32ArrayConstructor
new (elements: Iterable<number>) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array(init: number[]init)
: new var Float32Array: Float32ArrayConstructor
new (length: number) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array((shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape).ReadonlyArray<Dimension>.reduce(callbackfn: (previousValue: Dimension, currentValue: Dimension, currentIndex: number, array: readonly Dimension[]) => Dimension, initialValue: Dimension): Dimension (+2 overloads)Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((a: Dimensiona, b: Dimensionb) => a: Dimensiona * b: Dimensionb, 1)),
shape: const Shape extends readonly Dimension[]shape: shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape,
};
}
type type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<unknown>
? { [function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T[function (type parameter) KK]> } extends {
[function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: true;
}
? true
: false
: false;
type type InvalidArgument<T> = readonly [never, T]InvalidArgument<function (type parameter) T in type InvalidArgument<T>T> = readonly [never, function (type parameter) T in type InvalidArgument<T>T];
type type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
true extends type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T>
? function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T
: interface ReadonlyArray<T>ReadonlyArray<
type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">
>;
/// ---cut---
function function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(maybeDimensionArray: anymaybeDimensionArray: any): maybeDimensionArray: anymaybeDimensionArray is readonly type Dimension = number | Var<string>Dimension[] {
return (
var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybeDimensionArray: anymaybeDimensionArray) && maybeDimensionArray: any[]maybeDimensionArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((d: anyd) => typeof d: anyd === "number")
);
}
function function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(maybe2DArray: anymaybe2DArray: any): maybe2DArray: anymaybe2DArray is number[][] {
return var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybe2DArray: anymaybe2DArray) && maybe2DArray: any[]maybe2DArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((row: anyrow) => var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(row: anyrow));
}
function function flat<T>(arr: T[][]): T[]flat<function (type parameter) T in flat<T>(arr: T[][]): T[]T>(arr: T[][]arr: function (type parameter) T in flat<T>(arr: T[][]): T[]T[][]): function (type parameter) T in flat<T>(arr: T[][]): T[]T[] {
let let result: T[]result: function (type parameter) T in flat<T>(arr: T[][]): T[]T[] = [];
for (let let i: numberi = 0; let i: numberi < arr: T[][]arr.Array<T[]>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.length; let i: numberi++) {
let result: T[]result.Array<T>.push(...items: T[]): numberAppends new elements to the end of an array, and returns the new length of the array.push.CallableFunction.apply<T[], T[], number>(this: (this: T[], ...args: T[]) => number, thisArg: T[], args: T[]): number (+1 overload)Calls the function with the specified object as the this value and the elements of specified array as the arguments.apply(let result: T[]result, arr: T[][]arr[let i: numberi]);
}
return let result: T[]result;
}
export type type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows extends type Dimension = number | Var<string>Dimension, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<
readonly [function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns]
>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray extends interface ReadonlyArray<T>ReadonlyArray<interface ReadonlyArray<T>ReadonlyArray<number>>>(
init: const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>init: function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray,
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray["length"], function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray[0]["length"]>;
export function function matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]> {
let let resolvedShape: readonly [any, any]resolvedShape: readonly [any, any];
if (function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(shape: readonly [Dimension, Dimension] | readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = shape: readonly [Dimension, Dimension]shape;
} else if (function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = [shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape.length: numberGets the length of the array. This is a number one higher than the highest element defined in an array.
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length, shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape[0].Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = function flat<number>(arr: number[][]): number[]flat(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape);
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid shape type for matrix.");
}
return function tensor<readonly [any, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [any, any]>tensor(let resolvedShape: readonly [any, any]resolvedShape, init: number[] | undefinedinit);
}
// Tests
const const matrixWithStaticSizes: Matrix<25, 50>matrixWithStaticSizes = function matrix<readonly [25, 50]>(shape: readonly [25, 50], init?: number[]): Matrix<25, 50> (+1 overload)matrix([25, 50] as type const = readonly [25, 50]const);
const const matrixWithRuntimeSize: Matrix<10, Var<"configuredDimensionName">>matrixWithRuntimeSize = function matrix<readonly [10, Var<"configuredDimensionName">]>(shape: readonly [10, Var<"configuredDimensionName">], init?: number[]): Matrix<10, Var<"configuredDimensionName">> (+1 overload)matrix([10, const Var: <"configuredDimensionName">(size: number, label: "configuredDimensionName") => Var<"configuredDimensionName">Var(100, "configuredDimensionName")] as type const = readonly [10, Var<"configuredDimensionName">]const);
const const matrixWithSizeFromData: Matrix<3, 3>matrixWithSizeFromData = function matrix<readonly [readonly [1, 2, 3], readonly [4, 5, 6], readonly [7, 8, 9]]>(init: readonly [readonly [1, 2, 3], readonly [4, 5, 6], readonly [7, 8, 9]]): Matrix<3, 3> (+1 overload)matrix([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]);
const const invalidMatrix1: Matrix<25, 50>invalidMatrix1 = function matrix<readonly [25, 50]>(shape: readonly [25, 50], init?: number[]): Matrix<25, 50> (+1 overload)matrix([25, 50]);
const const invalidMatrix2: Matrix<number, number>invalidMatrix2 = matrix([25 as number, 50] as type const = readonly [number, 50]const);const const invalidMatrix3: Matrix<number, number>invalidMatrix3 = matrix([10, 100 as 100 | 115] as type const = readonly [10, 100 | 115]const);
Vector
type type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteral<T>T> = number extends function (type parameter) T in type IsNumericLiteral<T>T ? false : function (type parameter) T in type IsNumericLiteral<T>T extends number ? true : false;
export type type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in type Var<Label extends string>Label extends string> = number & { label: Label extends stringlabel: function (type parameter) Label in type Var<Label extends string>Label };
export const const Var: <Label extends string>(size: number, label: Label) => Var<Label>Var = <function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label extends string>(size: numbersize: number, label: Label extends stringlabel: function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label) => {
return size: numbersize as type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label>;
};
type type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsVar<T>T> = function (type parameter) T in type IsVar<T>T extends type Var<Label extends string> = number & {
label: Label;
}
Var<string> ? true : false;
type type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T extends number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>> = type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<
// We disallow `T` to be a union of types.
type Not<A> = A extends true ? false : trueNot<type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>>,
type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<
// We allow `T` to be a numeric literal but not a number.
type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>,
// We allow `T` to be a `Var`.
type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>
>
>;
type type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<function (type parameter) A in type And<A, B>A, function (type parameter) B in type And<A, B>B> = function (type parameter) A in type And<A, B>A extends true ? (function (type parameter) B in type And<A, B>B extends true ? true : false) : false;
type type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<function (type parameter) A in type Or<A, B>A, function (type parameter) B in type Or<A, B>B> = function (type parameter) A in type Or<A, B>A extends true ? true : function (type parameter) B in type Or<A, B>B extends true ? true : false;
type type Not<A> = A extends true ? false : trueNot<function (type parameter) A in type Not<A>A> = function (type parameter) A in type Not<A>A extends true ? false : true;
type type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsUnion<T>T> = [function (type parameter) T in type IsUnion<T>T] extends [type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) T in type IsUnion<T>T>] ? false : true;
type type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) Union in type UnionToIntersection<Union>Union> = (
function (type parameter) Union in type UnionToIntersection<Union>Union extends unknown ? (distributedUnion: UniondistributedUnion: function (type parameter) Union in type UnionToIntersection<Union>Union) => void : never
) extends (mergedIntersection: IntersectionmergedIntersection: infer function (type parameter) IntersectionIntersection) => void
? function (type parameter) IntersectionIntersection
: never;
export type type Dimension = number | Var<string>Dimension = number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>;
export type type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape extends readonly type Dimension = number | Var<string>Dimension[]> = {
data: Float32Array<ArrayBufferLike>data: interface Float32Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
of bytes could not be allocated an exception is raised.Float32Array;
shape: Shape extends readonly Dimension[]shape: function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape;
};
export function function tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>tensor<const function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape extends readonly type Dimension = number | Var<string>Dimension[]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape>,
init: number[] | undefinedinit?: number[],
): type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape> {
return {
data: Float32Array<ArrayBufferLike>data: init: number[] | undefinedinit
? new var Float32Array: Float32ArrayConstructor
new (elements: Iterable<number>) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array(init: number[]init)
: new var Float32Array: Float32ArrayConstructor
new (length: number) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array((shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape).ReadonlyArray<Dimension>.reduce(callbackfn: (previousValue: Dimension, currentValue: Dimension, currentIndex: number, array: readonly Dimension[]) => Dimension, initialValue: Dimension): Dimension (+2 overloads)Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((a: Dimensiona, b: Dimensionb) => a: Dimensiona * b: Dimensionb, 1)),
shape: const Shape extends readonly Dimension[]shape: shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape,
};
}
type type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<unknown>
? { [function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T[function (type parameter) KK]> } extends {
[function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: true;
}
? true
: false
: false;
type type InvalidArgument<T> = readonly [never, T]InvalidArgument<function (type parameter) T in type InvalidArgument<T>T> = readonly [never, function (type parameter) T in type InvalidArgument<T>T];
type type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
true extends type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T>
? function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T
: interface ReadonlyArray<T>ReadonlyArray<
type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">
>;
function function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(maybeDimensionArray: anymaybeDimensionArray: any): maybeDimensionArray: anymaybeDimensionArray is readonly type Dimension = number | Var<string>Dimension[] {
return (
var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybeDimensionArray: anymaybeDimensionArray) && maybeDimensionArray: any[]maybeDimensionArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((d: anyd) => typeof d: anyd === "number")
);
}
function function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(maybe2DArray: anymaybe2DArray: any): maybe2DArray: anymaybe2DArray is number[][] {
return var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybe2DArray: anymaybe2DArray) && maybe2DArray: any[]maybe2DArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((row: anyrow) => var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(row: anyrow));
}
function function flat<T>(arr: T[][]): T[]flat<function (type parameter) T in flat<T>(arr: T[][]): T[]T>(arr: T[][]arr: function (type parameter) T in flat<T>(arr: T[][]): T[]T[][]): function (type parameter) T in flat<T>(arr: T[][]): T[]T[] {
let let result: T[]result: function (type parameter) T in flat<T>(arr: T[][]): T[]T[] = [];
for (let let i: numberi = 0; let i: numberi < arr: T[][]arr.Array<T[]>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.length; let i: numberi++) {
let result: T[]result.Array<T>.push(...items: T[]): numberAppends new elements to the end of an array, and returns the new length of the array.push.CallableFunction.apply<T[], T[], number>(this: (this: T[], ...args: T[]) => number, thisArg: T[], args: T[]): number (+1 overload)Calls the function with the specified object as the this value and the elements of specified array as the arguments.apply(let result: T[]result, arr: T[][]arr[let i: numberi]);
}
return let result: T[]result;
}
export type type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows extends type Dimension = number | Var<string>Dimension, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<
readonly [function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns]
>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray extends interface ReadonlyArray<T>ReadonlyArray<interface ReadonlyArray<T>ReadonlyArray<number>>>(
init: const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>init: function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray,
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray["length"], function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray[0]["length"]>;
export function function matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]> {
let let resolvedShape: readonly [any, any]resolvedShape: readonly [any, any];
if (function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(shape: readonly [Dimension, Dimension] | readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = shape: readonly [Dimension, Dimension]shape;
} else if (function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = [shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape.length: numberGets the length of the array. This is a number one higher than the highest element defined in an array.
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length, shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape[0].Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = function flat<number>(arr: number[][]): number[]flat(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape);
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid shape type for matrix.");
}
return function tensor<readonly [any, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [any, any]>tensor(let resolvedShape: readonly [any, any]resolvedShape, init: number[] | undefinedinit);
}
/// ---cut---
type type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T extends type Dimension = number | Var<string>Dimension> =
true extends type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T>
? function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T
: type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `size` argument must only contain number literals or branded types.">;
export type type RowVector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
RowVector<function (type parameter) Size in type RowVector<Size extends Dimension>Size extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<readonly [1, function (type parameter) Size in type RowVector<Size extends Dimension>Size]>;
export type type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in type Vector<Size extends Dimension>Size extends type Dimension = number | Var<string>Dimension> = type RowVector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
RowVector<function (type parameter) Size in type Vector<Size extends Dimension>Size>;
export function function vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]> (+1 overload)vector<const function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray extends readonly type Dimension = number | Var<string>Dimension[]>(
init: const OneDArray extends readonly Dimension[]init: function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray,
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray["length"]>;
export function function vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size> (+1 overload)vector<const function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size extends type Dimension = number | Var<string>Dimension>(
size: AssertSizeIsNumericLiteralOrVar<Size>size: type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>,
init: number[] | undefinedinit?: number[],
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>;
export function function vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]> (+1 overload)vector<const function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size extends type Dimension = number | Var<string>Dimension>(
size: AssertSizeIsNumericLiteralOrVar<Size>size: type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>,
init: number[] | undefinedinit?: number[],
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size> {
let let shape: readonly [1, any]shape: readonly [1, any];
if (typeof size: AssertSizeIsNumericLiteralOrVar<Size>size === "number") {
let shape: readonly [1, any]shape = [1, size: Dimensionsize];
} else if (var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(size: InvalidArgument<"The `size` argument must only contain number literals or branded types.">size)) {
let shape: readonly [1, any]shape = [1, size: InvalidArgument<"The `size` argument must only contain number literals or branded types."> & any[]size.Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = size: InvalidArgument<"The `size` argument must only contain number literals or branded types."> & any[]size;
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid size type for vector.");
}
return function tensor<readonly [1, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [1, any]>tensor(let shape: readonly [1, any]shape, init: number[] | undefinedinit);
}
// Tests
const const vectorWithStaticSize: Vector<2>vectorWithStaticSize = function vector<2>(size: 2, init?: number[]): Vector<2> (+1 overload)vector(2);
const const vectorWithRuntimeSize: Vector<Var<"configuredDimensionName">>vectorWithRuntimeSize = function vector<Var<"configuredDimensionName">>(size: Var<"configuredDimensionName">, init?: number[]): Vector<Var<"configuredDimensionName">> (+1 overload)vector(const Var: <"configuredDimensionName">(size: number, label: "configuredDimensionName") => Var<"configuredDimensionName">Var(4, "configuredDimensionName"));
const const vectorWithSizeFromData: Vector<3>vectorWithSizeFromData = function vector<readonly [1, 2, 3]>(init: readonly [1, 2, 3]): Vector<3> (+1 overload)vector([1, 2, 3]);
const const invalidVector1: Vector<number>invalidVector1 = function vector<readonly Dimension[]>(init: readonly Dimension[]): Vector<number> (+1 overload)vector(2 as number);const const invalidVector2: Vector<number>invalidVector2 = function vector<readonly Dimension[]>(init: readonly Dimension[]): Vector<number> (+1 overload)vector(100 as 100 | 115);
zip
Once we have a Vector and Matrix type defined, we can use these to write a type-safe zip function that combines two Vectors of the same length into a Matrix of [VectorLength, 2], like so:
type type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteral<T>T> = number extends function (type parameter) T in type IsNumericLiteral<T>T ? false : function (type parameter) T in type IsNumericLiteral<T>T extends number ? true : false;
export type type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in type Var<Label extends string>Label extends string> = number & { label: Label extends stringlabel: function (type parameter) Label in type Var<Label extends string>Label };
export const const Var: <Label extends string>(size: number, label: Label) => Var<Label>Var = <function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label extends string>(size: numbersize: number, label: Label extends stringlabel: function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label) => {
return size: numbersize as type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label>;
};
type type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsVar<T>T> = function (type parameter) T in type IsVar<T>T extends type Var<Label extends string> = number & {
label: Label;
}
Var<string> ? true : false;
type type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T extends number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>> = type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<
// We disallow `T` to be a union of types.
type Not<A> = A extends true ? false : trueNot<type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>>,
type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<
// We allow `T` to be a numeric literal but not a number.
type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>,
// We allow `T` to be a `Var`.
type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>
>
>;
type type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<function (type parameter) A in type And<A, B>A, function (type parameter) B in type And<A, B>B> = function (type parameter) A in type And<A, B>A extends true ? (function (type parameter) B in type And<A, B>B extends true ? true : false) : false;
type type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<function (type parameter) A in type Or<A, B>A, function (type parameter) B in type Or<A, B>B> = function (type parameter) A in type Or<A, B>A extends true ? true : function (type parameter) B in type Or<A, B>B extends true ? true : false;
type type Not<A> = A extends true ? false : trueNot<function (type parameter) A in type Not<A>A> = function (type parameter) A in type Not<A>A extends true ? false : true;
type type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsUnion<T>T> = [function (type parameter) T in type IsUnion<T>T] extends [type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) T in type IsUnion<T>T>] ? false : true;
type type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) Union in type UnionToIntersection<Union>Union> = (
function (type parameter) Union in type UnionToIntersection<Union>Union extends unknown ? (distributedUnion: UniondistributedUnion: function (type parameter) Union in type UnionToIntersection<Union>Union) => void : never
) extends (mergedIntersection: IntersectionmergedIntersection: infer function (type parameter) IntersectionIntersection) => void
? function (type parameter) IntersectionIntersection
: never;
export type type Dimension = number | Var<string>Dimension = number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>;
export type type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape extends readonly type Dimension = number | Var<string>Dimension[]> = {
data: Float32Array<ArrayBufferLike>data: interface Float32Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
of bytes could not be allocated an exception is raised.Float32Array;
shape: Shape extends readonly Dimension[]shape: function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape;
};
export function function tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>tensor<const function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape extends readonly type Dimension = number | Var<string>Dimension[]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape>,
init: number[] | undefinedinit?: number[],
): type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape> {
return {
data: Float32Array<ArrayBufferLike>data: init: number[] | undefinedinit
? new var Float32Array: Float32ArrayConstructor
new (elements: Iterable<number>) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array(init: number[]init)
: new var Float32Array: Float32ArrayConstructor
new (length: number) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array((shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape).ReadonlyArray<Dimension>.reduce(callbackfn: (previousValue: Dimension, currentValue: Dimension, currentIndex: number, array: readonly Dimension[]) => Dimension, initialValue: Dimension): Dimension (+2 overloads)Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((a: Dimensiona, b: Dimensionb) => a: Dimensiona * b: Dimensionb, 1)),
shape: const Shape extends readonly Dimension[]shape: shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape,
};
}
type type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<unknown>
? { [function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T[function (type parameter) KK]> } extends {
[function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: true;
}
? true
: false
: false;
type type InvalidArgument<T> = readonly [never, T]InvalidArgument<function (type parameter) T in type InvalidArgument<T>T> = readonly [never, function (type parameter) T in type InvalidArgument<T>T];
type type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
true extends type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T>
? function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T
: interface ReadonlyArray<T>ReadonlyArray<
type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">
>;
function function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(maybeDimensionArray: anymaybeDimensionArray: any): maybeDimensionArray: anymaybeDimensionArray is readonly type Dimension = number | Var<string>Dimension[] {
return (
var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybeDimensionArray: anymaybeDimensionArray) && maybeDimensionArray: any[]maybeDimensionArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((d: anyd) => typeof d: anyd === "number")
);
}
function function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(maybe2DArray: anymaybe2DArray: any): maybe2DArray: anymaybe2DArray is number[][] {
return var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybe2DArray: anymaybe2DArray) && maybe2DArray: any[]maybe2DArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((row: anyrow) => var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(row: anyrow));
}
function function flat<T>(arr: T[][]): T[]flat<function (type parameter) T in flat<T>(arr: T[][]): T[]T>(arr: T[][]arr: function (type parameter) T in flat<T>(arr: T[][]): T[]T[][]): function (type parameter) T in flat<T>(arr: T[][]): T[]T[] {
let let result: T[]result: function (type parameter) T in flat<T>(arr: T[][]): T[]T[] = [];
for (let let i: numberi = 0; let i: numberi < arr: T[][]arr.Array<T[]>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.length; let i: numberi++) {
let result: T[]result.Array<T>.push(...items: T[]): numberAppends new elements to the end of an array, and returns the new length of the array.push.CallableFunction.apply<T[], T[], number>(this: (this: T[], ...args: T[]) => number, thisArg: T[], args: T[]): number (+1 overload)Calls the function with the specified object as the this value and the elements of specified array as the arguments.apply(let result: T[]result, arr: T[][]arr[let i: numberi]);
}
return let result: T[]result;
}
export type type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows extends type Dimension = number | Var<string>Dimension, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<
readonly [function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns]
>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray extends interface ReadonlyArray<T>ReadonlyArray<interface ReadonlyArray<T>ReadonlyArray<number>>>(
init: const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>init: function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray,
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray["length"], function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray[0]["length"]>;
export function function matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]> {
let let resolvedShape: readonly [any, any]resolvedShape: readonly [any, any];
if (function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(shape: readonly [Dimension, Dimension] | readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = shape: readonly [Dimension, Dimension]shape;
} else if (function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = [shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape.length: numberGets the length of the array. This is a number one higher than the highest element defined in an array.
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length, shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape[0].Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = function flat<number>(arr: number[][]): number[]flat(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape);
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid shape type for matrix.");
}
return function tensor<readonly [any, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [any, any]>tensor(let resolvedShape: readonly [any, any]resolvedShape, init: number[] | undefinedinit);
}
type type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T extends type Dimension = number | Var<string>Dimension> =
true extends type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T>
? function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T
: type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `size` argument must only contain number literals or branded types.">;
export type type RowVector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
RowVector<function (type parameter) Size in type RowVector<Size extends Dimension>Size extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<readonly [1, function (type parameter) Size in type RowVector<Size extends Dimension>Size]>;
export type type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in type Vector<Size extends Dimension>Size extends type Dimension = number | Var<string>Dimension> = type RowVector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
RowVector<function (type parameter) Size in type Vector<Size extends Dimension>Size>;
export function function vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]> (+1 overload)vector<const function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray extends readonly type Dimension = number | Var<string>Dimension[]>(
init: const OneDArray extends readonly Dimension[]init: function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray,
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray["length"]>;
export function function vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size> (+1 overload)vector<const function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size extends type Dimension = number | Var<string>Dimension>(
size: AssertSizeIsNumericLiteralOrVar<Size>size: type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>,
init: number[] | undefinedinit?: number[],
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>;
export function function vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]> (+1 overload)vector<const function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size extends type Dimension = number | Var<string>Dimension>(
size: AssertSizeIsNumericLiteralOrVar<Size>size: type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>,
init: number[] | undefinedinit?: number[],
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size> {
let let shape: readonly [1, any]shape: readonly [1, any];
if (typeof size: AssertSizeIsNumericLiteralOrVar<Size>size === "number") {
let shape: readonly [1, any]shape = [1, size: Dimensionsize];
} else if (var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(size: InvalidArgument<"The `size` argument must only contain number literals or branded types.">size)) {
let shape: readonly [1, any]shape = [1, size: InvalidArgument<"The `size` argument must only contain number literals or branded types."> & any[]size.Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = size: InvalidArgument<"The `size` argument must only contain number literals or branded types."> & any[]size;
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid size type for vector.");
}
return function tensor<readonly [1, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [1, any]>tensor(let shape: readonly [1, any]shape, init: number[] | undefinedinit);
}
/// ---cut---
/**
* The `zip` function combines two vectors of the same length into a matrix
* where each row contains a pair of corresponding elements from the input
* vectors. The output matrix's data is stored in a `Float32Array` with an
* interleaved arrangement of elements (row-major storage order) for efficient
* access.
*
* Example:
* Input vectors: [a1, a2, a3] and [b1, b2, b3]
* Output matrix:
* | a1 b1 |
* | a2 b2 |
* | a3 b3 |
*
* Memory layout in Float32Array: [a1, b1, a2, b2, a3, b3]
*/
function function zip<SameVector extends Vector<Dimension>>(a: SameVector, b: SameVector): Matrix<SameVector["shape"][1], 2>The `zip` function combines two vectors of the same length into a matrix
where each row contains a pair of corresponding elements from the input
vectors. The output matrix's data is stored in a `Float32Array` with an
interleaved arrangement of elements (row-major storage order) for efficient
access.
Example:
Input vectors: [a1, a2, a3] and [b1, b2, b3]
Output matrix:
| a1 b1 |
| a2 b2 |
| a3 b3 |
Memory layout in Float32Array: [a1, b1, a2, b2, a3, b3]zip<function (type parameter) SameVector in zip<SameVector extends Vector<Dimension>>(a: SameVector, b: SameVector): Matrix<SameVector["shape"][1], 2>SameVector extends type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<type Dimension = number | Var<string>Dimension>>(
a: SameVector extends Vector<Dimension>a: function (type parameter) SameVector in zip<SameVector extends Vector<Dimension>>(a: SameVector, b: SameVector): Matrix<SameVector["shape"][1], 2>SameVector,
b: SameVector extends Vector<Dimension>b: function (type parameter) SameVector in zip<SameVector extends Vector<Dimension>>(a: SameVector, b: SameVector): Matrix<SameVector["shape"][1], 2>SameVector,
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) SameVector in zip<SameVector extends Vector<Dimension>>(a: SameVector, b: SameVector): Matrix<SameVector["shape"][1], 2>SameVector["shape"][1], 2> {
if (a: SameVector extends Vector<Dimension>a.shape: readonly [1, Dimension]shape[1] !== b: SameVector extends Vector<Dimension>b.shape: readonly [1, Dimension]shape[1]) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(
`zip cannot operate on different length vectors; ${a: SameVector extends Vector<Dimension>a.shape: readonly [1, Dimension]shape[1]} !== ${b: SameVector extends Vector<Dimension>b.shape: readonly [1, Dimension]shape[1]}`,
);
}
const const length: Dimensionlength = a: SameVector extends Vector<Dimension>a.shape: readonly [1, Dimension]shape[1];
const const resultData: number[]resultData: number[] = [];
for (let let i: numberi = 0; let i: numberi < const length: Dimensionlength; let i: numberi++) {
const resultData: number[]resultData.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.push(a: SameVector extends Vector<Dimension>a.data: Float32Array<ArrayBufferLike>data[let i: numberi], b: SameVector extends Vector<Dimension>b.data: Float32Array<ArrayBufferLike>data[let i: numberi]);
}
return function matrix<readonly [any, 2]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Matrix<any, 2> (+1 overload)matrix([const length: Dimensionlength as any, 2] as type const = readonly [any, 2]const, const resultData: number[]resultData);
}
// Tests
const const threeElementVector1: Vector<3>threeElementVector1 = function vector<readonly [1, 2, 3]>(init: readonly [1, 2, 3]): Vector<3> (+1 overload)vector([1, 2, 3]);
const const threeElementVector2: Vector<3>threeElementVector2 = function vector<readonly [4, 5, 6]>(init: readonly [4, 5, 6]): Vector<3> (+1 overload)vector([4, 5, 6]);
const const fourElementVector1: Vector<4>fourElementVector1 = function vector<readonly [7, 8, 9, 10]>(init: readonly [7, 8, 9, 10]): Vector<4> (+1 overload)vector([7, 8, 9, 10]);
const const zipped: Matrix<3, 2>zipped = function zip<Vector<3>>(a: Vector<3>, b: Vector<3>): Matrix<3, 2>The `zip` function combines two vectors of the same length into a matrix
where each row contains a pair of corresponding elements from the input
vectors. The output matrix's data is stored in a `Float32Array` with an
interleaved arrangement of elements (row-major storage order) for efficient
access.
Example:
Input vectors: [a1, a2, a3] and [b1, b2, b3]
Output matrix:
| a1 b1 |
| a2 b2 |
| a3 b3 |
Memory layout in Float32Array: [a1, b1, a2, b2, a3, b3]zip(const threeElementVector1: Vector<3>threeElementVector1, const threeElementVector2: Vector<3>threeElementVector2);
const const zippedError: Matrix<3, 2>zippedError = function zip<Vector<3>>(a: Vector<3>, b: Vector<3>): Matrix<3, 2>The `zip` function combines two vectors of the same length into a matrix
where each row contains a pair of corresponding elements from the input
vectors. The output matrix's data is stored in a `Float32Array` with an
interleaved arrangement of elements (row-major storage order) for efficient
access.
Example:
Input vectors: [a1, a2, a3] and [b1, b2, b3]
Output matrix:
| a1 b1 |
| a2 b2 |
| a3 b3 |
Memory layout in Float32Array: [a1, b1, a2, b2, a3, b3]zip(const threeElementVector1: Vector<3>threeElementVector1, fourElementVector1);
const const threeElementVector3: Vector<Var<"three">>threeElementVector3 = function vector<Var<"three">>(size: Var<"three">, init?: number[]): Vector<Var<"three">> (+1 overload)vector(const Var: <"three">(size: number, label: "three") => Var<"three">Var(3, "three"), [1, 2, 3]);
const const threeElementVector4: Vector<Var<"three">>threeElementVector4 = function vector<Var<"three">>(size: Var<"three">, init?: number[]): Vector<Var<"three">> (+1 overload)vector(const Var: <"three">(size: number, label: "three") => Var<"three">Var(3, "three"), [5, 10, 15]);
const const fourElementVector2: Vector<Var<"four">>fourElementVector2 = function vector<Var<"four">>(size: Var<"four">, init?: number[]): Vector<Var<"four">> (+1 overload)vector(const Var: <"four">(size: number, label: "four") => Var<"four">Var(4, "four"), [10, 11, 12, 13]);
const const zipped2: Matrix<Var<"three">, 2>zipped2 = function zip<Vector<Var<"three">>>(a: Vector<Var<"three">>, b: Vector<Var<"three">>): Matrix<Var<"three">, 2>The `zip` function combines two vectors of the same length into a matrix
where each row contains a pair of corresponding elements from the input
vectors. The output matrix's data is stored in a `Float32Array` with an
interleaved arrangement of elements (row-major storage order) for efficient
access.
Example:
Input vectors: [a1, a2, a3] and [b1, b2, b3]
Output matrix:
| a1 b1 |
| a2 b2 |
| a3 b3 |
Memory layout in Float32Array: [a1, b1, a2, b2, a3, b3]zip(const threeElementVector3: Vector<Var<"three">>threeElementVector3, const threeElementVector4: Vector<Var<"three">>threeElementVector4);
const const zippedError2: Matrix<Var<"three">, 2>zippedError2 = function zip<Vector<Var<"three">>>(a: Vector<Var<"three">>, b: Vector<Var<"three">>): Matrix<Var<"three">, 2>The `zip` function combines two vectors of the same length into a matrix
where each row contains a pair of corresponding elements from the input
vectors. The output matrix's data is stored in a `Float32Array` with an
interleaved arrangement of elements (row-major storage order) for efficient
access.
Example:
Input vectors: [a1, a2, a3] and [b1, b2, b3]
Output matrix:
| a1 b1 |
| a2 b2 |
| a3 b3 |
Memory layout in Float32Array: [a1, b1, a2, b2, a3, b3]zip(const threeElementVector3: Vector<Var<"three">>threeElementVector3, fourElementVector2);
matmul
Finally, functions like matmul that expect two operands with different but compatible shapes, can be implemented using the same techniques:
type type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteral<T>T> = number extends function (type parameter) T in type IsNumericLiteral<T>T ? false : function (type parameter) T in type IsNumericLiteral<T>T extends number ? true : false;
export type type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in type Var<Label extends string>Label extends string> = number & { label: Label extends stringlabel: function (type parameter) Label in type Var<Label extends string>Label };
export const const Var: <Label extends string>(size: number, label: Label) => Var<Label>Var = <function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label extends string>(size: numbersize: number, label: Label extends stringlabel: function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label) => {
return size: numbersize as type Var<Label extends string> = number & {
label: Label;
}
Var<function (type parameter) Label in <Label extends string>(size: number, label: Label): Var<Label>Label>;
};
type type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsVar<T>T> = function (type parameter) T in type IsVar<T>T extends type Var<Label extends string> = number & {
label: Label;
}
Var<string> ? true : false;
type type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T extends number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>> = type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<
// We disallow `T` to be a union of types.
type Not<A> = A extends true ? false : trueNot<type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>>,
type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<
// We allow `T` to be a numeric literal but not a number.
type IsNumericLiteral<T> = number extends T ? false : T extends number ? true : falseIsNumericLiteral<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>,
// We allow `T` to be a `Var`.
type IsVar<T> = T extends Var<string> ? true : falseIsVar<function (type parameter) T in type IsNumericLiteralOrVar<T extends number | Var<string>>T>
>
>;
type type And<A, B> = A extends true ? B extends true ? true : false : falseAnd<function (type parameter) A in type And<A, B>A, function (type parameter) B in type And<A, B>B> = function (type parameter) A in type And<A, B>A extends true ? (function (type parameter) B in type And<A, B>B extends true ? true : false) : false;
type type Or<A, B> = A extends true ? true : B extends true ? true : falseOr<function (type parameter) A in type Or<A, B>A, function (type parameter) B in type Or<A, B>B> = function (type parameter) A in type Or<A, B>A extends true ? true : function (type parameter) B in type Or<A, B>B extends true ? true : false;
type type Not<A> = A extends true ? false : trueNot<function (type parameter) A in type Not<A>A> = function (type parameter) A in type Not<A>A extends true ? false : true;
type type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : trueIsUnion<function (type parameter) T in type IsUnion<T>T> = [function (type parameter) T in type IsUnion<T>T] extends [type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) T in type IsUnion<T>T>] ? false : true;
type type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : neverUnionToIntersection<function (type parameter) Union in type UnionToIntersection<Union>Union> = (
function (type parameter) Union in type UnionToIntersection<Union>Union extends unknown ? (distributedUnion: UniondistributedUnion: function (type parameter) Union in type UnionToIntersection<Union>Union) => void : never
) extends (mergedIntersection: IntersectionmergedIntersection: infer function (type parameter) IntersectionIntersection) => void
? function (type parameter) IntersectionIntersection
: never;
export type type Dimension = number | Var<string>Dimension = number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>;
export type type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape extends readonly type Dimension = number | Var<string>Dimension[]> = {
data: Float32Array<ArrayBufferLike>data: interface Float32Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
of bytes could not be allocated an exception is raised.Float32Array;
shape: Shape extends readonly Dimension[]shape: function (type parameter) Shape in type Tensor<Shape extends readonly Dimension[]>Shape;
};
export function function tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>tensor<const function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape extends readonly type Dimension = number | Var<string>Dimension[]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape>,
init: number[] | undefinedinit?: number[],
): type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape> {
return {
data: Float32Array<ArrayBufferLike>data: init: number[] | undefinedinit
? new var Float32Array: Float32ArrayConstructor
new (elements: Iterable<number>) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array(init: number[]init)
: new var Float32Array: Float32ArrayConstructor
new (length: number) => Float32Array<ArrayBuffer> (+6 overloads)
Float32Array((shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape).ReadonlyArray<Dimension>.reduce(callbackfn: (previousValue: Dimension, currentValue: Dimension, currentIndex: number, array: readonly Dimension[]) => Dimension, initialValue: Dimension): Dimension (+2 overloads)Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.reduce((a: Dimensiona, b: Dimensionb) => a: Dimensiona * b: Dimensionb, 1)),
shape: const Shape extends readonly Dimension[]shape: shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape as function (type parameter) Shape in tensor<const Shape extends readonly Dimension[]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Tensor<Shape>Shape,
};
}
type type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<unknown>
? { [function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T[function (type parameter) KK]> } extends {
[function (type parameter) KK in keyof function (type parameter) T in type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T]: true;
}
? true
: false
: false;
type type InvalidArgument<T> = readonly [never, T]InvalidArgument<function (type parameter) T in type InvalidArgument<T>T> = readonly [never, function (type parameter) T in type InvalidArgument<T>T];
type type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T extends interface ReadonlyArray<T>ReadonlyArray<number | type Var<Label extends string> = number & {
label: Label;
}
Var<string>>> =
true extends type ArrayEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = T extends readonly unknown[] ? { [K in keyof T]: And<Not<IsUnion<T[K]>>, Or<IsNumericLiteral<T[K]>, IsVar<T[K]>>>; } extends { [K in keyof T]: true; } ? true : false : falseArrayEveryElementIsNumericLiteralOrVar<function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T>
? function (type parameter) T in type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>>T
: interface ReadonlyArray<T>ReadonlyArray<
type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">
>;
function function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(maybeDimensionArray: anymaybeDimensionArray: any): maybeDimensionArray: anymaybeDimensionArray is readonly type Dimension = number | Var<string>Dimension[] {
return (
var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybeDimensionArray: anymaybeDimensionArray) && maybeDimensionArray: any[]maybeDimensionArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((d: anyd) => typeof d: anyd === "number")
);
}
function function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(maybe2DArray: anymaybe2DArray: any): maybe2DArray: anymaybe2DArray is number[][] {
return var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(maybe2DArray: anymaybe2DArray) && maybe2DArray: any[]maybe2DArray.Array<any>.some(predicate: (value: any, index: number, array: any[]) => unknown, thisArg?: any): booleanDetermines whether the specified callback function returns true for any element of an array.some((row: anyrow) => var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(row: anyrow));
}
function function flat<T>(arr: T[][]): T[]flat<function (type parameter) T in flat<T>(arr: T[][]): T[]T>(arr: T[][]arr: function (type parameter) T in flat<T>(arr: T[][]): T[]T[][]): function (type parameter) T in flat<T>(arr: T[][]): T[]T[] {
let let result: T[]result: function (type parameter) T in flat<T>(arr: T[][]): T[]T[] = [];
for (let let i: numberi = 0; let i: numberi < arr: T[][]arr.Array<T[]>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.length; let i: numberi++) {
let result: T[]result.Array<T>.push(...items: T[]): numberAppends new elements to the end of an array, and returns the new length of the array.push.CallableFunction.apply<T[], T[], number>(this: (this: T[], ...args: T[]) => number, thisArg: T[], args: T[]): number (+1 overload)Calls the function with the specified object as the this value and the elements of specified array as the arguments.apply(let result: T[]result, arr: T[][]arr[let i: numberi]);
}
return let result: T[]result;
}
export type type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows extends type Dimension = number | Var<string>Dimension, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<
readonly [function (type parameter) Rows in type Matrix<Rows extends Dimension, Columns extends Dimension>Rows, function (type parameter) Columns in type Matrix<Rows extends Dimension, Columns extends Dimension>Columns]
>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray extends interface ReadonlyArray<T>ReadonlyArray<interface ReadonlyArray<T>ReadonlyArray<number>>>(
init: const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>init: function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray,
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray["length"], function (type parameter) TwoDArray in matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]>TwoDArray[0]["length"]>;
export function function matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]>;
export function function matrix<const TwoDArray extends ReadonlyArray<ReadonlyArray<number>>>(init: TwoDArray): Matrix<TwoDArray["length"], TwoDArray[0]["length"]> (+1 overload)matrix<const function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape extends readonly [type Dimension = number | Var<string>Dimension, type Dimension = number | Var<string>Dimension]>(
shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>shape: type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape>,
init: number[] | undefinedinit?: number[],
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[0], function (type parameter) Shape in matrix<const Shape extends readonly [Dimension, Dimension]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<Shape>, init?: number[]): Matrix<Shape[0], Shape[1]>Shape[1]> {
let let resolvedShape: readonly [any, any]resolvedShape: readonly [any, any];
if (function isDimensionArray(maybeDimensionArray: any): maybeDimensionArray is readonly Dimension[]isDimensionArray(shape: readonly [Dimension, Dimension] | readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = shape: readonly [Dimension, Dimension]shape;
} else if (function is2DArray(maybe2DArray: any): maybe2DArray is number[][]is2DArray(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]shape)) {
let resolvedShape: readonly [any, any]resolvedShape = [shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape.length: numberGets the length of the array. This is a number one higher than the highest element defined in an array.
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length, shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape[0].Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = function flat<number>(arr: number[][]): number[]flat(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[] & number[][]shape);
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid shape type for matrix.");
}
return function tensor<readonly [any, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [any, any]>tensor(let resolvedShape: readonly [any, any]resolvedShape, init: number[] | undefinedinit);
}
type type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T extends type Dimension = number | Var<string>Dimension> =
true extends type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T>
? function (type parameter) T in type AssertSizeIsNumericLiteralOrVar<T extends Dimension>T
: type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The `size` argument must only contain number literals or branded types.">;
export type type RowVector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
RowVector<function (type parameter) Size in type RowVector<Size extends Dimension>Size extends type Dimension = number | Var<string>Dimension> = type Tensor<Shape extends readonly Dimension[]> = {
data: Float32Array;
shape: Shape;
}
Tensor<readonly [1, function (type parameter) Size in type RowVector<Size extends Dimension>Size]>;
export type type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in type Vector<Size extends Dimension>Size extends type Dimension = number | Var<string>Dimension> = type RowVector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
RowVector<function (type parameter) Size in type Vector<Size extends Dimension>Size>;
export function function vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]> (+1 overload)vector<const function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray extends readonly type Dimension = number | Var<string>Dimension[]>(
init: const OneDArray extends readonly Dimension[]init: function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray,
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) OneDArray in vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]>OneDArray["length"]>;
export function function vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size> (+1 overload)vector<const function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size extends type Dimension = number | Var<string>Dimension>(
size: AssertSizeIsNumericLiteralOrVar<Size>size: type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>,
init: number[] | undefinedinit?: number[],
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>;
export function function vector<const OneDArray extends readonly Dimension[]>(init: OneDArray): Vector<OneDArray["length"]> (+1 overload)vector<const function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size extends type Dimension = number | Var<string>Dimension>(
size: AssertSizeIsNumericLiteralOrVar<Size>size: type AssertSizeIsNumericLiteralOrVar<T extends Dimension> = true extends And<Not<IsUnion<T>>, Or<IsNumericLiteral<T>, IsVar<T>>> ? T : InvalidArgument<"The `size` argument must only contain number literals or branded types.">AssertSizeIsNumericLiteralOrVar<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size>,
init: number[] | undefinedinit?: number[],
): type Vector<Size extends Dimension> = {
data: Float32Array;
shape: readonly [1, Size];
}
Vector<function (type parameter) Size in vector<const Size extends Dimension>(size: AssertSizeIsNumericLiteralOrVar<Size>, init?: number[]): Vector<Size>Size> {
let let shape: readonly [1, any]shape: readonly [1, any];
if (typeof size: AssertSizeIsNumericLiteralOrVar<Size>size === "number") {
let shape: readonly [1, any]shape = [1, size: Dimensionsize];
} else if (var Array: ArrayConstructorArray.ArrayConstructor.isArray(arg: any): arg is any[]isArray(size: InvalidArgument<"The `size` argument must only contain number literals or branded types.">size)) {
let shape: readonly [1, any]shape = [1, size: InvalidArgument<"The `size` argument must only contain number literals or branded types."> & any[]size.Array<T>.length: 2Gets or sets the length of the array. This is a number one higher than the highest index in the array.length];
init: number[] | undefinedinit = size: InvalidArgument<"The `size` argument must only contain number literals or branded types."> & any[]size;
} else {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("Invalid size type for vector.");
}
return function tensor<readonly [1, any]>(shape: readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[], init?: number[]): Tensor<readonly [1, any]>tensor(let shape: readonly [1, any]shape, init: number[] | undefinedinit);
}
/// ---cut---
function function matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>matmul<
function (type parameter) RowsA in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>RowsA extends type Dimension = number | Var<string>Dimension,
function (type parameter) SharedDimension in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>SharedDimension extends type Dimension = number | Var<string>Dimension,
function (type parameter) ColumnsB in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>ColumnsB extends type Dimension = number | Var<string>Dimension,
>(
a: Matrix<RowsA, SharedDimension>a: type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) RowsA in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>RowsA, function (type parameter) SharedDimension in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>SharedDimension>,
b: And<Not<IsUnion<SharedDimension>>, Or<IsNumericLiteral<SharedDimension>, IsVar<SharedDimension>>> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">b: type IsNumericLiteralOrVar<T extends number | Var<string>> = Not<IsUnion<T>> extends true ? Or<IsNumericLiteral<T>, IsVar<T>> extends true ? true : false : falseIsNumericLiteralOrVar<function (type parameter) SharedDimension in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>SharedDimension> extends true
? type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) SharedDimension in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>SharedDimension, function (type parameter) ColumnsB in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>ColumnsB>
: type InvalidArgument<T> = readonly [never, T]InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">,
): type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) RowsA in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>RowsA, function (type parameter) ColumnsB in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>ColumnsB> {
const const aMatrix: Matrix<RowsA, SharedDimension>aMatrix = a: Matrix<RowsA, SharedDimension>a;
const const bMatrix: Matrix<SharedDimension, ColumnsB>bMatrix = b: Matrix<SharedDimension, ColumnsB> | InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">b as type Matrix<Rows extends Dimension, Columns extends Dimension> = {
data: Float32Array;
shape: readonly [Rows, Columns];
}
Matrix<function (type parameter) SharedDimension in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>SharedDimension, function (type parameter) ColumnsB in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>ColumnsB>;
const [const aRows: RowsA extends DimensionaRows, const aCols: SharedDimension extends DimensionaCols] = const aMatrix: Matrix<RowsA, SharedDimension>aMatrix.shape: readonly [RowsA, SharedDimension]shape;
const [const bRows: SharedDimension extends DimensionbRows, const bCols: ColumnsB extends DimensionbCols] = const bMatrix: Matrix<SharedDimension, ColumnsB>bMatrix.shape: readonly [SharedDimension, ColumnsB]shape;
if (const aCols: SharedDimension extends DimensionaCols !== const bRows: SharedDimension extends DimensionbRows) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(
"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.",
);
}
const const shape: AssertShapeEveryElementIsNumericLiteralOrVar<[RowsA, ColumnsB]>shape = [const aRows: RowsA extends DimensionaRows, const bCols: ColumnsB extends DimensionbCols] as type AssertShapeEveryElementIsNumericLiteralOrVar<T extends ReadonlyArray<number | Var<string>>> = true extends ArrayEveryElementIsNumericLiteralOrVar<T> ? T : readonly InvalidArgument<"The `shape` argument must be marked `as const` and only contain number literals or branded types.">[]AssertShapeEveryElementIsNumericLiteralOrVar<[function (type parameter) RowsA in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>RowsA, function (type parameter) ColumnsB in matmul<RowsA extends Dimension, SharedDimension extends Dimension, ColumnsB extends Dimension>(a: Matrix<RowsA, SharedDimension>, b: IsNumericLiteralOrVar<SharedDimension> extends true ? Matrix<SharedDimension, ColumnsB> : InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<RowsA, ColumnsB>ColumnsB]>;
const const data: number[]data = var Array: ArrayConstructor
<number>(arrayLength: number) => number[] (+2 overloads)
Array<number>(const aRows: RowsA extends DimensionaRows * const bCols: ColumnsB extends DimensionbCols).Array<number>.fill(value: number, start?: number, end?: number): number[]Changes all array elements from `start` to `end` index to a static `value` and returns the modified arrayfill(0);
for (let let rowIndex: numberrowIndex = 0; let rowIndex: numberrowIndex < const aRows: RowsA extends DimensionaRows; let rowIndex: numberrowIndex++) {
for (let let columnIndex: numbercolumnIndex = 0; let columnIndex: numbercolumnIndex < const bCols: ColumnsB extends DimensionbCols; let columnIndex: numbercolumnIndex++) {
let let dotProduct: numberdotProduct = 0;
for (let let sharedDimensionIndex: numbersharedDimensionIndex = 0; let sharedDimensionIndex: numbersharedDimensionIndex < const aCols: SharedDimension extends DimensionaCols; let sharedDimensionIndex: numbersharedDimensionIndex++) {
const const rowCellFromA: numberrowCellFromA = const aMatrix: Matrix<RowsA, SharedDimension>aMatrix.data: Float32Array<ArrayBufferLike>data[let rowIndex: numberrowIndex * const aCols: SharedDimension extends DimensionaCols + let sharedDimensionIndex: numbersharedDimensionIndex];
const const columnCellFromB: numbercolumnCellFromB = const bMatrix: Matrix<SharedDimension, ColumnsB>bMatrix.data: Float32Array<ArrayBufferLike>data[let sharedDimensionIndex: numbersharedDimensionIndex * const bCols: ColumnsB extends DimensionbCols + let columnIndex: numbercolumnIndex];
let dotProduct: numberdotProduct += const rowCellFromA: numberrowCellFromA * const columnCellFromB: numbercolumnCellFromB;
}
const data: number[]data[let rowIndex: numberrowIndex * const bCols: ColumnsB extends DimensionbCols + let columnIndex: numbercolumnIndex] = let dotProduct: numberdotProduct;
}
}
return function matrix<[RowsA, ColumnsB]>(shape: AssertShapeEveryElementIsNumericLiteralOrVar<[RowsA, ColumnsB]>, init?: number[]): Matrix<RowsA, ColumnsB> (+1 overload)matrix(const shape: AssertShapeEveryElementIsNumericLiteralOrVar<[RowsA, ColumnsB]>shape, const data: number[]data);
}
// Tests
const const a: Matrix<2, 3>a = function matrix<readonly [2, 3]>(shape: readonly [2, 3], init?: number[]): Matrix<2, 3> (+1 overload)matrix([2, 3] as type const = readonly [2, 3]const);
const const b: Matrix<3, 2>b = function matrix<readonly [3, 2]>(shape: readonly [3, 2], init?: number[]): Matrix<3, 2> (+1 overload)matrix([3, 2] as type const = readonly [3, 2]const);
const const c: Matrix<7, 7>c = function matrix<readonly [7, 7]>(shape: readonly [7, 7], init?: number[]): Matrix<7, 7> (+1 overload)matrix([7, 7] as type const = readonly [7, 7]const);
const const validMatmul: Matrix<2, 2>validMatmul = function matmul<2, 3, 2>(a: Matrix<2, 3>, b: Matrix<3, 2>): Matrix<2, 2>matmul(const a: Matrix<2, 3>a, const b: Matrix<3, 2>b);
const const invalidMatmul: Matrix<2, 7>invalidMatmul = function matmul<2, 3 | 7, 7>(a: Matrix<2, 3 | 7>, b: InvalidArgument<"The rows dimension of the `b` matrix must match the columns dimension of the `a` matrix.">): Matrix<2, 7>matmul(const a: Matrix<2, 3>a, c);