UNPKG

vek-engine

Version:

Efficient WebAssembly-based vector math engine for JavaScript/TypeScript

1,054 lines 149 kB
/** *********************************************************************** * 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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