vek-engine
Version:
Efficient WebAssembly-based vector math engine for JavaScript/TypeScript
1,054 lines • 149 kB
JavaScript
/**
***********************************************************************
* Copyright 2022-present Jonathan Barronville *
* *
* This Source Code Form is subject to the terms of the Mozilla Public *
* License, v. 2.0. If a copy of the MPL was not distributed with this *
* file, You can obtain one at https://mozilla.org/MPL/2.0/. *
***********************************************************************
*/
import { assertOk } from './utilities.mjs';
import { isEnvDebug } from './utilities.mjs';
import { loadWasmModule } from './utilities.mjs';
var VectorModalityType;
(function (VectorModalityType) {
VectorModalityType[VectorModalityType["NULLIMODAL"] = 0] = "NULLIMODAL";
VectorModalityType[VectorModalityType["UNIMODAL"] = 1] = "UNIMODAL";
VectorModalityType[VectorModalityType["BIMODAL"] = 2] = "BIMODAL";
VectorModalityType[VectorModalityType["MULTIMODAL"] = 3] = "MULTIMODAL";
})(VectorModalityType || (VectorModalityType = {}));
var VectorPrecision;
(function (VectorPrecision) {
VectorPrecision[VectorPrecision["SINGLE"] = 4] = "SINGLE";
VectorPrecision[VectorPrecision["DOUBLE"] = 8] = "DOUBLE";
})(VectorPrecision || (VectorPrecision = {}));
const INT32_MAX_VALUE = 2 ** 31 - 1;
const createClass = async (options) => {
const customInspectMethodKey = Symbol.for('nodejs.util.inspect.custom');
const { memory: wasmMemory, module: wasmModule } = await (async () => {
const memory = (() => {
let memory;
memory = options?.wasm?.memory;
if (!(memory instanceof WebAssembly.Memory)) {
memory = new WebAssembly.Memory({
initial: 1,
maximum: 65536 /* (1024 * 64) */,
shared: true,
});
}
return memory;
})();
const module = await loadWasmModule({
env: { memory },
});
return {
memory,
module,
};
})();
const ___instanceInternalScopes = new WeakMap();
let ___isConstructingClassInstance = false;
let _disableArrayIndexing = null;
const ___getInstanceInternalScope = (instance) => {
const scope = ___instanceInternalScopes.get(instance);
return scope ?? null;
};
const ___getIsArrayIndexingEnabled = (instance) => {
const scope = ___getInstanceInternalScope(instance);
return scope?.isArrayIndexingEnabled ?? null;
};
const ___getIsConstructingClassInstance = () => ___isConstructingClassInstance;
const ___getNativePointer = (instance) => {
const scope = ___getInstanceInternalScope(instance);
return scope?.nativePointer ?? null;
};
const ___makeInstanceInternalScope = (instance, scope) => {
scope = Object.seal(scope);
___instanceInternalScopes.set(instance, scope);
return scope;
};
const ___setIsConstructingClassInstance = (value) => {
___isConstructingClassInstance = value;
};
const _getDisableArrayIndexing = () => _disableArrayIndexing;
const _proxifyInstance = (instance) => {
return new Proxy(instance, {
get: (target, name, receiver) => {
const propertyValue = Reflect.get(target, name, receiver);
if (typeof propertyValue !== 'undefined') {
return propertyValue;
}
if (typeof name === 'symbol') {
return undefined;
}
const index = Number(name);
if (!Number.isInteger(index)) {
return undefined;
}
const dataValue = target.get.call(receiver, index);
return dataValue ?? undefined;
},
set: (target, name, value, receiver) => {
if (Reflect.has(target, name)) {
return Reflect.set(target, name, value, receiver);
}
if (typeof name === 'symbol') {
return false;
}
const index = Number(name);
if (!Number.isInteger(index)) {
return false;
}
if (typeof value !== 'number') {
return false;
}
return target.set.call(receiver, index, value);
},
});
};
const _setDisableArrayIndexing = (value) => {
_disableArrayIndexing = value;
};
const convertElementByteSizeToPrecision = (size) => {
switch (size) {
case 4: {
return VectorPrecision.SINGLE;
}
case 8: {
return VectorPrecision.DOUBLE;
}
default: {
return VectorPrecision.DOUBLE;
}
}
};
const convertPrecisionToElementByteSize = (precision) => {
switch (precision) {
case VectorPrecision.DOUBLE: {
return VectorPrecision.DOUBLE;
}
case VectorPrecision.SINGLE: {
return VectorPrecision.SINGLE;
}
default: {
return VectorPrecision.DOUBLE;
}
}
};
const isNumbersArrayValid = (array) => {
return array.every((value) => {
return isNumberValid(value);
});
};
const isNumberValid = (value) => {
if (typeof value !== 'number') {
return false;
}
if (Number.isNaN(value)) {
return false;
}
return Number.isFinite(value);
};
const v = (...args) => Vector.create(...args);
class Vector {
set ___nativePointer(pointer) {
const scope = ___getInstanceInternalScope(this);
assertOk(scope !== null);
scope.nativePointer = pointer;
}
get dimensions() {
return wasmModule.vectorInstanceGetDimensions(this.nativePointer);
}
set disableArrayIndexing(value) {
_setDisableArrayIndexing(value);
}
get elementByteSize() {
return wasmModule.vectorInstanceGetElementByteSize(this.nativePointer);
}
get is64Bit() {
return wasmModule.vectorInstanceGetIs64Bit(this.nativePointer);
}
get isDebugModeActive() {
return isEnvDebug;
}
get maxIndex() {
return wasmModule.vectorInstanceGetMaxIndex(this.nativePointer);
}
get nativePointer() {
const pointer = ___getNativePointer(this);
assertOk(pointer !== null);
return pointer;
}
get precision() {
return convertElementByteSizeToPrecision(this.elementByteSize);
}
get wasmMemory() {
return wasmMemory;
}
get wasmModule() {
return wasmModule;
}
constructor(...args) {
if (!___getIsConstructingClassInstance()) {
throw new TypeError('Can only create instances of `Vector` via `Vector.create()`');
}
if (args.length < 1) {
throw new TypeError('Could not create an instance of `Vector`');
}
let instanceIsReadyForInitialization = false;
let disableArrayIndexingOptionValue;
let nativePointer;
if (typeof args[0] === 'number' &&
Number.isInteger(args[0]) &&
args[0] > 0 &&
(typeof args[1] === 'undefined' ||
args[1] === VectorPrecision.DOUBLE ||
args[1] === VectorPrecision.SINGLE) &&
(typeof args[2] === 'undefined' ||
(typeof args[2] === 'object' && args[2] !== null))) {
const [dimensions, precision, options] = args;
disableArrayIndexingOptionValue =
typeof options?.disableArrayIndexing === 'boolean'
? options.disableArrayIndexing
: undefined;
const elementByteSize = convertPrecisionToElementByteSize(precision);
if (dimensions * elementByteSize > INT32_MAX_VALUE) {
throw new TypeError('Could not create an instance of `Vector`');
}
nativePointer = wasmModule.vectorCreate(dimensions, elementByteSize);
instanceIsReadyForInitialization = true;
}
else if (Array.isArray(args[0]) &&
isNumbersArrayValid(args[0]) &&
(typeof args[1] === 'undefined' ||
args[1] === VectorPrecision.DOUBLE ||
args[1] === VectorPrecision.SINGLE) &&
(typeof args[2] === 'undefined' ||
(typeof args[2] === 'object' && args[2] !== null))) {
const array = args[0].slice();
const [, precision, options] = args;
const vector = new Vector(array.length, precision, options);
for (let i = 0, j = vector.maxIndex; i <= j; i++) {
const index = i;
const value = array[index];
assertOk(typeof value !== 'undefined');
vector.set(index, value);
}
return vector;
}
else if (args[0] instanceof Uint8Array &&
(typeof args[1] === 'undefined' ||
(typeof args[1] === 'object' && args[1] !== null))) {
const buffer = args[0].slice();
const [, options] = args;
const vector = new Vector(1, VectorPrecision.SINGLE, options);
const nativePointer = wasmModule.vectorStaticFromBuffer(buffer.buffer);
vector.___nativePointer = nativePointer;
return vector;
}
else if (args[0] instanceof Float32Array &&
(typeof args[1] === 'undefined' ||
(typeof args[1] === 'object' && args[1] !== null))) {
const array = args[0].slice();
const [, options] = args;
const vector = new Vector(array.length, VectorPrecision.SINGLE, options);
for (let i = 0, j = vector.maxIndex; i <= j; i++) {
const index = i;
const value = array[index];
assertOk(typeof value !== 'undefined');
vector.set(index, value);
}
return vector;
}
else if (args[0] instanceof Float64Array &&
(typeof args[1] === 'undefined' ||
(typeof args[1] === 'object' && args[1] !== null))) {
const array = args[0].slice();
const [, options] = args;
const vector = new Vector(array.length, VectorPrecision.DOUBLE, options);
for (let i = 0, j = vector.maxIndex; i <= j; i++) {
const index = i;
const value = array[index];
assertOk(typeof value !== 'undefined');
vector.set(index, value);
}
return vector;
}
if (!instanceIsReadyForInitialization) {
throw new TypeError('Could not create an instance of `Vector`');
}
const enableArrayIndexing = (() => {
let disableArrayIndexing = _getDisableArrayIndexing();
if (disableArrayIndexing !== null) {
return !disableArrayIndexing;
}
disableArrayIndexing = disableArrayIndexingOptionValue ?? false;
return !disableArrayIndexing;
})();
assertOk(typeof nativePointer !== 'undefined');
// eslint-disable-next-line @typescript-eslint/no-this-alias
let vector = this;
if (enableArrayIndexing) {
vector = _proxifyInstance(this);
}
void ([
[this, nativePointer],
[vector, nativePointer],
]).forEach((values) => {
const [vector, nativePointer] = values;
___makeInstanceInternalScope(vector, {
isArrayIndexingEnabled: enableArrayIndexing,
nativePointer,
});
});
return vector;
}
*[Symbol.iterator]() {
const iteratorPointer = wasmModule.vectorIteratorCreate(this.nativePointer);
if (this.is64Bit) {
while (true) {
const { isDone, value } = wasmModule.vectorIteratorInstanceNext(iteratorPointer);
yield value;
if (isDone) {
break;
}
}
}
else {
while (true) {
const { isDone, value } = wasmModule.vectorIteratorInstanceNext(iteratorPointer);
yield Math.fround(value);
if (isDone) {
break;
}
}
}
}
add(otherVector) {
return Vector.add(this, otherVector);
}
static add(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let options;
{
let isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(aVector);
if (isArrayIndexingEnabled === null) {
isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(bVector);
}
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const resultVector = Vector.create(aVector.dimensions, aVector.precision, options);
wasmModule.vectorStaticAdd(aVector.nativePointer, bVector.nativePointer, resultVector.nativePointer);
return resultVector;
}
arithmeticMean() {
let value = wasmModule.vectorInstanceArithmeticMean(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
average() {
return this.arithmeticMean();
}
avg() {
return this.arithmeticMean();
}
clone() {
let options;
{
const isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(this);
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
if (this.is64Bit) {
const array = this.toFloat64Array();
return Vector.create(array, options);
}
else {
const array = this.toFloat32Array();
return Vector.create(array, options);
}
}
cosineSimilarity(otherVector) {
return Vector.cosineSimilarity(this, otherVector);
}
static cosineSimilarity(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let value = wasmModule.vectorStaticCosineSimilarity(aVector.nativePointer, bVector.nativePointer);
if (!aVector.is64Bit) {
value = Math.fround(value);
}
return value;
}
static create(...args) {
___setIsConstructingClassInstance(true);
const vector = new Vector(...args);
___setIsConstructingClassInstance(false);
return vector;
}
div(otherVector) {
return Vector.div(this, otherVector);
}
static div(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let options;
{
let isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(aVector);
if (isArrayIndexingEnabled === null) {
isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(bVector);
}
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const resultVector = Vector.create(aVector.dimensions, aVector.precision, options);
wasmModule.vectorStaticDiv(aVector.nativePointer, bVector.nativePointer, resultVector.nativePointer);
return resultVector;
}
divide(otherVector) {
return Vector.divide(this, otherVector);
}
static divide(aVector, bVector) {
return Vector.div(aVector, bVector);
}
dot(otherVector) {
return Vector.dot(this, otherVector);
}
static dot(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let value = wasmModule.vectorStaticDot(aVector.nativePointer, bVector.nativePointer);
if (!aVector.is64Bit) {
value = Math.fround(value);
}
return value;
}
dotProduct(otherVector) {
return Vector.dotProduct(this, otherVector);
}
static dotProduct(aVector, bVector) {
return Vector.dot(aVector, bVector);
}
each(callback) {
this.forEach(callback);
}
eq(otherVector) {
return Vector.eq(this, otherVector);
}
static eq(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
const arrayBuffer = wasmModule.vectorStaticCmp(aVector.nativePointer, bVector.nativePointer);
const buffer = new Int8Array(arrayBuffer, 0, arrayBuffer.byteLength);
return buffer.reduce((values, value, index) => {
values[index] = value === 0;
return values;
}, (() => {
return new Array(buffer.length);
})());
}
equals(otherVector) {
return Vector.equals(this, otherVector);
}
static equals(aVector, bVector) {
return Vector.eq(aVector, bVector);
}
euclideanNorm() {
return this.pNorm(2.0);
}
fill(value) {
if (typeof value !== 'number' || !isNumberValid(value)) {
throw new TypeError('`value` must be a non-NaN finite number');
}
wasmModule.vectorInstanceFill(this.nativePointer, value);
return this;
}
forEach(callback) {
let i = 0;
for (const value of this) {
const index = i;
callback(value, index, this);
i++;
}
}
ge(otherVector) {
return Vector.ge(this, otherVector);
}
static ge(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
const arrayBuffer = wasmModule.vectorStaticCmp(aVector.nativePointer, bVector.nativePointer);
const buffer = new Int8Array(arrayBuffer, 0, arrayBuffer.byteLength);
return buffer.reduce((values, value, index) => {
values[index] = value === 1 || value === 0;
return values;
}, (() => {
return new Array(buffer.length);
})());
}
get(index) {
if (!Number.isInteger(index)) {
return null;
}
if (index < 0 || index > this.maxIndex) {
return null;
}
let value = wasmModule.vectorInstanceGetValue(this.nativePointer, index);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
geometricMean() {
let value = wasmModule.vectorInstanceGeometricMean(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
greaterThan(otherVector) {
return Vector.greaterThan(this, otherVector);
}
static greaterThan(aVector, bVector) {
return Vector.gt(aVector, bVector);
}
greaterThanOrEquals(otherVector) {
return Vector.greaterThanOrEquals(this, otherVector);
}
static greaterThanOrEquals(aVector, bVector) {
return Vector.ge(aVector, bVector);
}
gt(otherVector) {
return Vector.gt(this, otherVector);
}
static gt(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
const arrayBuffer = wasmModule.vectorStaticCmp(aVector.nativePointer, bVector.nativePointer);
const buffer = new Int8Array(arrayBuffer, 0, arrayBuffer.byteLength);
return buffer.reduce((values, value, index) => {
values[index] = value === 1;
return values;
}, (() => {
return new Array(buffer.length);
})());
}
idxmax() {
return this.indexOfMax();
}
idxmin() {
return this.indexOfMin();
}
indexOfMax() {
let value = wasmModule.vectorInstanceIndexOfMax(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
indexOfMin() {
let value = wasmModule.vectorInstanceIndexOfMin(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
infinityNorm() {
let value = wasmModule.vectorInstanceInfinityNorm(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
innerProduct(otherVector) {
return Vector.innerProduct(this, otherVector);
}
static innerProduct(aVector, bVector) {
return Vector.dot(aVector, bVector);
}
isBimodal() {
const type = this.modalityType();
return type === VectorModalityType.BIMODAL;
}
isMultimodal() {
const type = this.modalityType();
return type === VectorModalityType.MULTIMODAL;
}
isNullimodal() {
const type = this.modalityType();
return type === VectorModalityType.NULLIMODAL;
}
isUnimodal() {
const type = this.modalityType();
return type === VectorModalityType.UNIMODAL;
}
l1Norm() {
return this.pNorm(1.0);
}
l2Norm() {
return this.pNorm(2.0);
}
le(otherVector) {
return Vector.le(this, otherVector);
}
static le(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
const arrayBuffer = wasmModule.vectorStaticCmp(aVector.nativePointer, bVector.nativePointer);
const buffer = new Int8Array(arrayBuffer, 0, arrayBuffer.byteLength);
return buffer.reduce((values, value, index) => {
values[index] = value === -1 || value === 0;
return values;
}, (() => {
return new Array(buffer.length);
})());
}
lessThan(otherVector) {
return Vector.lessThan(this, otherVector);
}
static lessThan(aVector, bVector) {
return Vector.lt(aVector, bVector);
}
lessThanOrEquals(otherVector) {
return Vector.lessThanOrEquals(this, otherVector);
}
static lessThanOrEquals(aVector, bVector) {
return Vector.le(aVector, bVector);
}
lInfinityNorm() {
return this.infinityNorm();
}
lt(otherVector) {
return Vector.lt(this, otherVector);
}
static lt(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
const arrayBuffer = wasmModule.vectorStaticCmp(aVector.nativePointer, bVector.nativePointer);
const buffer = new Int8Array(arrayBuffer, 0, arrayBuffer.byteLength);
return buffer.reduce((values, value, index) => {
values[index] = value === -1;
return values;
}, (() => {
return new Array(buffer.length);
})());
}
manhattanNorm() {
return this.pNorm(1.0);
}
map(callback) {
let options;
{
const isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(this);
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const vector = Vector.create(this.dimensions, this.precision, options);
{
let i = 0;
for (const value of this) {
const index = i;
const newValue = callback(value, index, this);
if (typeof newValue !== 'number' || !isNumberValid(newValue)) {
throw new TypeError('`callback()` must return a non-NaN finite number');
}
vector.set(index, newValue);
i++;
}
}
return vector;
}
max() {
let value = wasmModule.vectorInstanceMax(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
maximum() {
return this.max();
}
maxNorm() {
return this.infinityNorm();
}
mean() {
return this.arithmeticMean();
}
min() {
let value = wasmModule.vectorInstanceMin(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
minimum() {
return this.min();
}
mod(otherVector) {
return Vector.mod(this, otherVector);
}
static mod(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let options;
{
let isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(aVector);
if (isArrayIndexingEnabled === null) {
isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(bVector);
}
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const resultVector = Vector.create(aVector.dimensions, aVector.precision, options);
wasmModule.vectorStaticMod(aVector.nativePointer, bVector.nativePointer, resultVector.nativePointer);
return resultVector;
}
modality() {
const values = wasmModule.vectorInstanceMode(this.nativePointer);
if (values.length === 1) {
let [value] = values;
assertOk(typeof value !== 'undefined');
if (!Number.isFinite(value)) {
return Object.freeze({
type: VectorModalityType.NULLIMODAL,
});
}
if (!this.is64Bit) {
value = Math.fround(value);
}
return Object.freeze({
type: VectorModalityType.UNIMODAL,
value,
});
}
else if (values.length === 2) {
let [valueA, valueB] = values;
assertOk(typeof valueA !== 'undefined' && typeof valueB !== 'undefined');
if (!this.is64Bit) {
valueA = Math.fround(valueA);
valueB = Math.fround(valueB);
}
return Object.freeze({
type: VectorModalityType.BIMODAL,
values: Object.freeze([valueA, valueB]),
});
}
else {
const newValues = (() => {
if (this.is64Bit) {
return values.reduce((values, value, index) => {
values[index] = value;
return values;
}, (() => {
return new Array(values.length);
})());
}
else {
return values.reduce((values, value, index) => {
value = Math.fround(value);
values[index] = value;
return values;
}, (() => {
return new Array(values.length);
})());
}
})();
return Object.freeze({
type: VectorModalityType.MULTIMODAL,
values: Object.freeze(newValues),
});
}
}
modalityType() {
const { type } = this.modality();
return type;
}
mode() {
const info = this.modality();
switch (info.type) {
case VectorModalityType.NULLIMODAL: {
return -Infinity;
}
case VectorModalityType.UNIMODAL: {
return info.value;
}
case VectorModalityType.BIMODAL: {
return info.values;
}
case VectorModalityType.MULTIMODAL: {
return info.values;
}
}
}
modulo(otherVector) {
return Vector.modulo(this, otherVector);
}
static modulo(aVector, bVector) {
return Vector.mod(aVector, bVector);
}
mul(otherVector) {
return Vector.mul(this, otherVector);
}
static mul(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let options;
{
let isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(aVector);
if (isArrayIndexingEnabled === null) {
isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(bVector);
}
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const resultVector = Vector.create(aVector.dimensions, aVector.precision, options);
wasmModule.vectorStaticMul(aVector.nativePointer, bVector.nativePointer, resultVector.nativePointer);
return resultVector;
}
multiply(otherVector) {
return Vector.multiply(this, otherVector);
}
static multiply(aVector, bVector) {
return Vector.mul(aVector, bVector);
}
ne(otherVector) {
return Vector.ne(this, otherVector);
}
static ne(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
const arrayBuffer = wasmModule.vectorStaticCmp(aVector.nativePointer, bVector.nativePointer);
const buffer = new Int8Array(arrayBuffer, 0, arrayBuffer.byteLength);
return buffer.reduce((values, value, index) => {
values[index] = value !== 0;
return values;
}, (() => {
return new Array(buffer.length);
})());
}
neg() {
let options;
{
const isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(this);
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const vector = Vector.create(this.dimensions, this.precision, options);
wasmModule.vectorInstanceNeg(this.nativePointer, vector.nativePointer);
return vector;
}
negate() {
return this.neg();
}
notEquals(otherVector) {
return Vector.notEquals(this, otherVector);
}
static notEquals(aVector, bVector) {
return Vector.ne(aVector, bVector);
}
static ones(dimensions, precision, options) {
const elementByteSize = convertPrecisionToElementByteSize(precision);
if (!Number.isInteger(dimensions) ||
dimensions < 1 ||
dimensions * elementByteSize > INT32_MAX_VALUE) {
throw new TypeError(`\`dimensions\` must be >= \`1\` and \`(dimensions * elementByteSize)\` must <= \`${INT32_MAX_VALUE}\``);
}
const vector = Vector.create(1, VectorPrecision.SINGLE, options);
const nativePointer = wasmModule.vectorStaticOnes(dimensions, elementByteSize);
vector.___nativePointer = nativePointer;
return vector;
}
pNorm(p) {
if (p !== 1.0 && p !== 2.0) {
throw new TypeError('`p` must be `1.00` or `2.00`');
}
let value = wasmModule.vectorInstancePNorm(this.nativePointer, p);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
scalarProduct(otherVector) {
return Vector.scalarProduct(this, otherVector);
}
static scalarProduct(aVector, bVector) {
return Vector.dot(aVector, bVector);
}
set(index, value) {
if (!Number.isInteger(index)) {
return false;
}
if (index < 0 || index > this.maxIndex) {
return false;
}
if (!this.is64Bit) {
value = Math.fround(value);
}
return wasmModule.vectorInstanceSetValue(this.nativePointer, index, value);
}
sub(otherVector) {
return Vector.sub(this, otherVector);
}
static sub(aVector, bVector) {
if (aVector.wasmModule !== bVector.wasmModule &&
aVector.wasmMemory !== bVector.wasmMemory) {
throw new TypeError('Can only operate on instances of `Vector` in the same memory space');
}
if (aVector.is64Bit !== bVector.is64Bit ||
aVector.dimensions !== bVector.dimensions) {
throw new TypeError('Can only operate on instances of `Vector` with the same dimensions and precision');
}
let options;
{
let isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(aVector);
if (isArrayIndexingEnabled === null) {
isArrayIndexingEnabled = ___getIsArrayIndexingEnabled(bVector);
}
if (isArrayIndexingEnabled === false) {
options = Object.assign({ ...options }, { disableArrayIndexing: true });
}
}
const resultVector = Vector.create(aVector.dimensions, aVector.precision, options);
wasmModule.vectorStaticSub(aVector.nativePointer, bVector.nativePointer, resultVector.nativePointer);
return resultVector;
}
subtract(otherVector) {
return Vector.subtract(this, otherVector);
}
static subtract(aVector, bVector) {
return Vector.sub(aVector, bVector);
}
sum() {
let value = wasmModule.vectorInstanceSum(this.nativePointer);
if (!this.is64Bit) {
value = Math.fround(value);
}
return value;
}
toArray() {
return Array.from(this);
}
toBuffer() {
const buffer = wasmModule.vectorInstanceToBuffer(this.nativePointer);
return new Uint8Array(buffer, 0, buffer.byteLength);
}
toFloat32Array() {
const array = new Float32Array(this.dimensions);
{
let i = 0;
for (const value of this) {
const index = i;
array[index] = Math.fround(value);
i++;
}
}
return array;
}
toFloat64Array() {
return Float64Array.from(this);
}
toJSON(_key) {
return this.toArray();
}
toString() {
return JSON.stringify(this);
}
valueOf() {
return `${this}`;
}
static zeros(dimensions, precision, options) {
return Vector.create(dimensions, precision, options);
}
}
Object.assign(Vector.prototype, {
[customInspectMethodKey]: function (_depth, options, inspect) {
return `Vek:Vector<${inspect([...this], options)}>`;
},
});
return { default: Vector, v, Vector, wasmMemory, wasmModule };
};
export { createClass, VectorModalityType, VectorPrecision, };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLWZhY3RvcnkubWpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3ZlY3Rvci1mYWN0b3J5Lm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQTtBQUd4QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0saUJBQWlCLENBQUE7QUFDMUMsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBdUI5QyxJQUFLLGtCQUtKO0FBTEQsV0FBSyxrQkFBa0I7SUFDckIsdUVBQWMsQ0FBQTtJQUNkLG1FQUFZLENBQUE7SUFDWixpRUFBVyxDQUFBO0lBQ1gsdUVBQVUsQ0FBQTtBQUNaLENBQUMsRUFMSSxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBS3RCO0FBRUQsSUFBSyxlQUdKO0FBSEQsV0FBSyxlQUFlO0lBQ2xCLHlEQUFVLENBQUE7SUFDVix5REFBVSxDQUFBO0FBQ1osQ0FBQyxFQUhJLGVBQWUsS0FBZixlQUFlLFFBR25CO0FBRUQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7QUFFbkMsTUFBTSxXQUFXLEdBQUcsS0FBSyxFQUFFLE9BQW1DLEVBQUUsRUFBRTtJQXlDaEUsTUFBTSxzQkFBc0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUN2Qyw0QkFBcUMsQ0FDdEMsQ0FBQTtJQUVELE1BQU0sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUU7UUFDakUsTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxNQUFzQyxDQUFBO1lBRTFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQTtZQUU5QixJQUFJLENBQUMsQ0FBQyxNQUFNLFlBQVksV0FBVyxDQUFDLE1BQU0s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