numpy-ts 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/core/slicing.ts", "../src/core/dtype.ts", "../src/core/storage.ts", "../src/internal/compute.ts", "../src/ops/arithmetic.ts", "../src/core/broadcasting.ts", "../src/ops/comparison.ts", "../src/internal/indexing.ts", "../src/ops/reduction.ts", "../src/ops/shape.ts", "../src/ops/linalg.ts", "../src/ops/exponential.ts", "../src/ops/trig.ts", "../src/ops/hyperbolic.ts", "../src/ops/advanced.ts", "../src/core/ndarray.ts", "../src/io/npy/format.ts", "../src/io/npy/parser.ts", "../src/io/npy/serializer.ts", "../src/io/zip/types.ts", "../src/io/zip/reader.ts", "../src/io/npz/parser.ts", "../src/io/zip/writer.ts", "../src/io/npz/serializer.ts"],
4
- "sourcesContent": ["/**\n * numpy-ts - Complete NumPy implementation for TypeScript and JavaScript\n *\n * @module numpy-ts\n */\n\n// Core array functions\nexport {\n NDArray,\n zeros,\n ones,\n array,\n arange,\n linspace,\n logspace,\n geomspace,\n eye,\n empty,\n full,\n identity,\n asarray,\n copy,\n zeros_like,\n ones_like,\n empty_like,\n full_like,\n // New array creation functions\n asanyarray,\n ascontiguousarray,\n asfortranarray,\n diag,\n diagflat,\n frombuffer,\n fromfile,\n fromfunction,\n fromiter,\n fromstring,\n meshgrid,\n tri,\n tril,\n triu,\n vander,\n // Math functions\n sqrt,\n power,\n absolute,\n negative,\n sign,\n mod,\n floor_divide,\n positive,\n reciprocal,\n cbrt,\n fabs,\n divmod,\n square,\n remainder,\n heaviside,\n dot,\n trace,\n diagonal,\n kron,\n transpose,\n inner,\n outer,\n tensordot,\n einsum,\n // Trigonometric functions\n sin,\n cos,\n tan,\n arcsin,\n arccos,\n arctan,\n arctan2,\n hypot,\n degrees,\n radians,\n deg2rad,\n rad2deg,\n // Hyperbolic functions\n sinh,\n cosh,\n tanh,\n arcsinh,\n arccosh,\n arctanh,\n // Array manipulation\n swapaxes,\n moveaxis,\n concatenate,\n stack,\n vstack,\n hstack,\n dstack,\n split,\n array_split,\n vsplit,\n hsplit,\n tile,\n repeat,\n // New array manipulation functions\n ravel,\n reshape,\n squeeze,\n expand_dims,\n flip,\n fliplr,\n flipud,\n rot90,\n roll,\n rollaxis,\n atleast_1d,\n atleast_2d,\n atleast_3d,\n dsplit,\n column_stack,\n row_stack,\n resize,\n append,\n delete_ as delete,\n insert,\n pad,\n // Advanced\n broadcast_to,\n broadcast_arrays,\n broadcast_shapes,\n take,\n put,\n choose,\n array_equal,\n array_equiv,\n // Reduction functions\n cumsum,\n cumprod,\n ptp,\n median,\n percentile,\n quantile,\n average,\n // NaN-aware reduction functions\n nansum,\n nanprod,\n nanmean,\n nanvar,\n nanstd,\n nanmin,\n nanmax,\n nanargmin,\n nanargmax,\n nancumsum,\n nancumprod,\n nanmedian,\n} from './core/ndarray';\n\n// IO functions (environment-agnostic parsing/serialization)\n// These work with bytes (ArrayBuffer/Uint8Array), not files\nexport {\n // NPY format\n parseNpy,\n serializeNpy,\n parseNpyHeader,\n parseNpyData,\n UnsupportedDTypeError,\n InvalidNpyError,\n SUPPORTED_DTYPES,\n DTYPE_TO_DESCR,\n type NpyHeader,\n type NpyMetadata,\n type NpyVersion,\n // NPZ format\n parseNpz,\n parseNpzSync,\n loadNpz,\n loadNpzSync,\n serializeNpz,\n serializeNpzSync,\n type NpzParseOptions,\n type NpzParseResult,\n type NpzSerializeOptions,\n} from './io';\n\n// Version (replaced at build time from package.json)\n// In development/tests, use package.json directly; in production, use the replaced value\ndeclare const __VERSION_PLACEHOLDER__: string;\nexport const __version__ =\n typeof __VERSION_PLACEHOLDER__ !== 'undefined' ? __VERSION_PLACEHOLDER__ : '0.6.0'; // Fallback for development/tests\n", "/**\n * Slicing utilities for NumPy-compatible array indexing\n *\n * Supports Python-style slice syntax via strings: \"0:5\", \":\", \"::2\", \"-1\"\n */\n\n/**\n * Represents a parsed slice specification\n */\nexport interface SliceSpec {\n start: number | null;\n stop: number | null;\n step: number;\n isIndex: boolean; // true if this is a single index, not a slice\n}\n\n/**\n * Parse a slice string into a SliceSpec\n *\n * Supports:\n * - Single index: \"5\", \"-1\"\n * - Full slice: \"0:5\", \"2:8\"\n * - With step: \"0:10:2\", \"::2\"\n * - Partial: \"5:\", \":10\", \":\"\n * - Negative: \"-5:\", \":-2\", \"::-1\"\n *\n * @param sliceStr - String representation of slice (e.g., \"0:5\", \":\", \"::2\")\n * @returns Parsed slice specification\n *\n * @example\n * ```typescript\n * parseSlice(\"0:5\") // {start: 0, stop: 5, step: 1, isIndex: false}\n * parseSlice(\":\") // {start: null, stop: null, step: 1, isIndex: false}\n * parseSlice(\"::2\") // {start: null, stop: null, step: 2, isIndex: false}\n * parseSlice(\"-1\") // {start: -1, stop: null, step: 1, isIndex: true}\n * parseSlice(\"5\") // {start: 5, stop: null, step: 1, isIndex: true}\n * ```\n */\nexport function parseSlice(sliceStr: string): SliceSpec {\n // Check if it's a single index (no colons)\n if (!sliceStr.includes(':')) {\n // Reject decimal points - indices must be integers\n if (sliceStr.includes('.')) {\n throw new Error(`Invalid slice index: \"${sliceStr}\" (must be integer)`);\n }\n const index = parseInt(sliceStr, 10);\n if (isNaN(index)) {\n throw new Error(`Invalid slice index: \"${sliceStr}\"`);\n }\n return {\n start: index,\n stop: null,\n step: 1,\n isIndex: true,\n };\n }\n\n // Parse slice notation: start:stop:step\n const parts = sliceStr.split(':');\n\n if (parts.length > 3) {\n throw new Error(`Invalid slice notation: \"${sliceStr}\" (too many colons)`);\n }\n\n const start = parts[0] === '' ? null : parseInt(parts[0]!, 10);\n const stop = parts[1] === '' || parts[1] === undefined ? null : parseInt(parts[1], 10);\n const step = parts[2] === '' || parts[2] === undefined ? 1 : parseInt(parts[2], 10);\n\n // Validate parsed values\n if (start !== null && isNaN(start)) {\n throw new Error(`Invalid start index in slice: \"${sliceStr}\"`);\n }\n if (stop !== null && isNaN(stop)) {\n throw new Error(`Invalid stop index in slice: \"${sliceStr}\"`);\n }\n if (isNaN(step)) {\n throw new Error(`Invalid step in slice: \"${sliceStr}\"`);\n }\n if (step === 0) {\n throw new Error(`Slice step cannot be zero`);\n }\n\n return {\n start,\n stop,\n step,\n isIndex: false,\n };\n}\n\n/**\n * Normalize a slice specification to absolute indices\n *\n * Handles negative indices and defaults:\n * - Negative indices count from the end\n * - null start becomes 0 (or size-1 for negative step)\n * - null stop becomes size (or -1 for negative step)\n *\n * @param spec - Parsed slice specification\n * @param size - Size of the dimension being sliced\n * @returns Normalized slice with absolute start, stop, step\n *\n * @example\n * ```typescript\n * normalizeSlice({start: -1, stop: null, step: 1, isIndex: true}, 10)\n * // {start: 9, stop: 10, step: 1, isIndex: true}\n *\n * normalizeSlice({start: null, stop: -2, step: 1, isIndex: false}, 10)\n * // {start: 0, stop: 8, step: 1, isIndex: false}\n * ```\n */\nexport function normalizeSlice(\n spec: SliceSpec,\n size: number\n): { start: number; stop: number; step: number; isIndex: boolean } {\n let { start, stop } = spec;\n const { step, isIndex } = spec;\n\n // For single index, normalize and return\n if (isIndex) {\n if (start === null) {\n throw new Error('Index cannot be null');\n }\n const normalizedStart = start < 0 ? size + start : start;\n if (normalizedStart < 0 || normalizedStart >= size) {\n throw new Error(`Index ${start} is out of bounds for size ${size}`);\n }\n return {\n start: normalizedStart,\n stop: normalizedStart + 1,\n step: 1,\n isIndex: true,\n };\n }\n\n // Handle slice defaults based on step direction\n if (step > 0) {\n // Forward slice\n if (start === null) start = 0;\n if (stop === null) stop = size;\n } else {\n // Backward slice\n if (start === null) start = size - 1;\n if (stop === null) stop = -size - 1; // Will be normalized to before start\n }\n\n // Normalize negative indices\n if (start < 0) start = size + start;\n if (stop < 0) stop = size + stop;\n\n // Clamp to valid range\n start = Math.max(0, Math.min(start, size));\n stop = Math.max(-1, Math.min(stop, size)); // -1 allowed for backward slices\n\n return {\n start,\n stop,\n step,\n isIndex: false,\n };\n}\n\n/**\n * Compute the length of a slice result\n *\n * @param start - Normalized start index\n * @param stop - Normalized stop index\n * @param step - Step value\n * @returns Number of elements in the slice\n */\nexport function computeSliceLength(start: number, stop: number, step: number): number {\n if (step > 0) {\n if (start >= stop) return 0;\n return Math.ceil((stop - start) / step);\n } else {\n if (start <= stop) return 0;\n return Math.ceil((start - stop) / -step);\n }\n}\n\n/**\n * Parse multiple slice specifications for multi-dimensional indexing\n *\n * @param sliceStrs - Array of slice strings, one per dimension\n * @returns Array of parsed slice specifications\n *\n * @example\n * ```typescript\n * parseSlices([\"0:5\", \":\", \"::2\"])\n * // [\n * // {start: 0, stop: 5, step: 1, isIndex: false},\n * // {start: null, stop: null, step: 1, isIndex: false},\n * // {start: null, stop: null, step: 2, isIndex: false}\n * // ]\n * ```\n */\nexport function parseSlices(sliceStrs: string[]): SliceSpec[] {\n return sliceStrs.map((s) => parseSlice(s));\n}\n", "/**\n * DType (Data Type) system for numpy-ts\n *\n * Supports NumPy numeric types:\n * - Floating point: float32, float64\n * - Signed integers: int8, int16, int32, int64\n * - Unsigned integers: uint8, uint16, uint32, uint64\n * - Boolean: bool\n */\n\n/**\n * All supported dtypes\n */\nexport type DType =\n | 'float64'\n | 'float32'\n | 'int64'\n | 'int32'\n | 'int16'\n | 'int8'\n | 'uint64'\n | 'uint32'\n | 'uint16'\n | 'uint8'\n | 'bool';\n\n/**\n * TypedArray types for each dtype\n */\nexport type TypedArray =\n | Float64Array\n | Float32Array\n | BigInt64Array\n | Int32Array\n | Int16Array\n | Int8Array\n | BigUint64Array\n | Uint32Array\n | Uint16Array\n | Uint8Array;\n\n/**\n * Default dtype (matches NumPy)\n */\nexport const DEFAULT_DTYPE: DType = 'float64';\n\n/**\n * Get the TypedArray constructor for a given dtype\n */\nexport function getTypedArrayConstructor(dtype: DType): TypedArrayConstructor | null {\n switch (dtype) {\n case 'float64':\n return Float64Array;\n case 'float32':\n return Float32Array;\n case 'int64':\n return BigInt64Array;\n case 'int32':\n return Int32Array;\n case 'int16':\n return Int16Array;\n case 'int8':\n return Int8Array;\n case 'uint64':\n return BigUint64Array;\n case 'uint32':\n return Uint32Array;\n case 'uint16':\n return Uint16Array;\n case 'uint8':\n return Uint8Array;\n case 'bool':\n return Uint8Array; // bool is stored as uint8\n default:\n throw new Error(`Unknown dtype: ${dtype}`);\n }\n}\n\ntype TypedArrayConstructor =\n | Float64ArrayConstructor\n | Float32ArrayConstructor\n | BigInt64ArrayConstructor\n | Int32ArrayConstructor\n | Int16ArrayConstructor\n | Int8ArrayConstructor\n | BigUint64ArrayConstructor\n | Uint32ArrayConstructor\n | Uint16ArrayConstructor\n | Uint8ArrayConstructor;\n\n/**\n * Get the element size in bytes for a given dtype\n */\nexport function getDTypeSize(dtype: DType): number {\n switch (dtype) {\n case 'float64':\n case 'int64':\n case 'uint64':\n return 8;\n case 'float32':\n case 'int32':\n case 'uint32':\n return 4;\n case 'int16':\n case 'uint16':\n return 2;\n case 'int8':\n case 'uint8':\n case 'bool':\n return 1;\n default:\n throw new Error(`Unknown dtype: ${dtype}`);\n }\n}\n\n/**\n * Check if dtype is integer\n */\nexport function isIntegerDType(dtype: DType): boolean {\n return (\n dtype === 'int64' ||\n dtype === 'int32' ||\n dtype === 'int16' ||\n dtype === 'int8' ||\n dtype === 'uint64' ||\n dtype === 'uint32' ||\n dtype === 'uint16' ||\n dtype === 'uint8'\n );\n}\n\n/**\n * Check if dtype is floating point\n */\nexport function isFloatDType(dtype: DType): boolean {\n return dtype === 'float64' || dtype === 'float32';\n}\n\n/**\n * Check if dtype uses BigInt\n */\nexport function isBigIntDType(dtype: DType): boolean {\n return dtype === 'int64' || dtype === 'uint64';\n}\n\n/**\n * Infer dtype from JavaScript value\n */\nexport function inferDType(value: unknown): DType {\n if (typeof value === 'bigint') {\n return 'int64';\n } else if (typeof value === 'number') {\n // Check if integer\n if (Number.isInteger(value)) {\n // Choose appropriate integer type based on range\n if (value >= 0 && value <= 255) return 'uint8';\n if (value >= -128 && value <= 127) return 'int8';\n if (value >= 0 && value <= 65535) return 'uint16';\n if (value >= -32768 && value <= 32767) return 'int16';\n if (value >= 0 && value <= 4294967295) return 'uint32';\n if (value >= -2147483648 && value <= 2147483647) return 'int32';\n return 'float64'; // Fallback for large integers\n }\n return 'float64';\n } else if (typeof value === 'boolean') {\n return 'bool';\n }\n return DEFAULT_DTYPE;\n}\n\n/**\n * Promote two dtypes to a common dtype\n * Follows NumPy's type promotion rules\n */\nexport function promoteDTypes(dtype1: DType, dtype2: DType): DType {\n // Same dtype\n if (dtype1 === dtype2) return dtype1;\n\n // Boolean - promote to the other type\n if (dtype1 === 'bool') return dtype2;\n if (dtype2 === 'bool') return dtype1;\n\n // Float types - integer + float always promotes to float\n if (isFloatDType(dtype1) || isFloatDType(dtype2)) {\n // NumPy behavior: Promote to the float type\n // float64 always wins\n if (dtype1 === 'float64' || dtype2 === 'float64') return 'float64';\n\n // float32 with small integers (8, 16 bit) \u2192 float32\n // float32 with large integers (32, 64 bit) \u2192 float64 (precision safety)\n // This is because float32 has 24-bit mantissa, can't hold all int32 values\n if (dtype1 === 'float32') {\n const intDtype = dtype2;\n if (\n intDtype === 'int32' ||\n intDtype === 'int64' ||\n intDtype === 'uint32' ||\n intDtype === 'uint64'\n ) {\n return 'float64';\n }\n return 'float32';\n }\n if (dtype2 === 'float32') {\n const intDtype = dtype1;\n if (\n intDtype === 'int32' ||\n intDtype === 'int64' ||\n intDtype === 'uint32' ||\n intDtype === 'uint64'\n ) {\n return 'float64';\n }\n return 'float32';\n }\n\n // Both are float32\n return 'float32';\n }\n\n // Integer types - complex promotion rules\n const isSigned1 = dtype1.startsWith('int');\n const isSigned2 = dtype2.startsWith('int');\n const isUnsigned1 = dtype1.startsWith('uint');\n const isUnsigned2 = dtype2.startsWith('uint');\n\n // Get bit sizes\n const getSize = (dtype: DType): number => {\n if (dtype.includes('64')) return 64;\n if (dtype.includes('32')) return 32;\n if (dtype.includes('16')) return 16;\n if (dtype.includes('8')) return 8;\n return 0;\n };\n\n const size1 = getSize(dtype1);\n const size2 = getSize(dtype2);\n\n // Special case: int64 + uint64 \u2192 float64 (no larger int type available)\n if ((dtype1 === 'int64' && dtype2 === 'uint64') || (dtype1 === 'uint64' && dtype2 === 'int64')) {\n return 'float64';\n }\n\n // Mixing signed and unsigned of the same size: promote to larger signed type\n if (isSigned1 && isUnsigned2 && size1 === size2) {\n if (size1 === 8) return 'int16';\n if (size1 === 16) return 'int32';\n if (size1 === 32) return 'int64';\n }\n if (isUnsigned1 && isSigned2 && size1 === size2) {\n if (size2 === 8) return 'int16';\n if (size2 === 16) return 'int32';\n if (size2 === 32) return 'int64';\n }\n\n // Same signedness: promote to larger size\n if ((isSigned1 && isSigned2) || (isUnsigned1 && isUnsigned2)) {\n const maxSize = Math.max(size1, size2);\n if (isSigned1) {\n if (maxSize === 64) return 'int64';\n if (maxSize === 32) return 'int32';\n if (maxSize === 16) return 'int16';\n return 'int8';\n } else {\n if (maxSize === 64) return 'uint64';\n if (maxSize === 32) return 'uint32';\n if (maxSize === 16) return 'uint16';\n return 'uint8';\n }\n }\n\n // Different signedness, different sizes: promote to type that can hold both\n // NumPy behavior: If signed type is larger, use it; otherwise promote conservatively\n\n // If signed int is larger than unsigned int, signed int can hold unsigned\n if (isSigned1 && isUnsigned2) {\n if (size1 > size2) {\n // e.g., int16 + uint8 \u2192 int16, int32 + uint16 \u2192 int32\n return dtype1;\n }\n // Otherwise need larger signed type\n // e.g., int8 + uint16 \u2192 int32\n if (size2 === 8) return 'int16';\n if (size2 === 16) return 'int32';\n if (size2 === 32) return 'int64';\n return 'float64'; // uint64 with smaller signed \u2192 float64\n }\n\n if (isUnsigned1 && isSigned2) {\n if (size2 > size1) {\n // e.g., uint8 + int16 \u2192 int16, uint16 + int32 \u2192 int32\n return dtype2;\n }\n // Otherwise need larger signed type\n // e.g., uint16 + int8 \u2192 int32\n if (size1 === 8) return 'int16';\n if (size1 === 16) return 'int32';\n if (size1 === 32) return 'int64';\n return 'float64'; // uint64 with smaller signed \u2192 float64\n }\n\n // Fallback (shouldn't reach here if logic above is complete)\n return 'float64';\n}\n\n/**\n * Validate dtype string\n */\nexport function isValidDType(dtype: string): dtype is DType {\n const validDTypes: DType[] = [\n 'float64',\n 'float32',\n 'int64',\n 'int32',\n 'int16',\n 'int8',\n 'uint64',\n 'uint32',\n 'uint16',\n 'uint8',\n 'bool',\n ];\n return validDTypes.includes(dtype as DType);\n}\n\n/**\n * Convert value to the appropriate type for the given dtype\n */\nexport function castValue(value: number | bigint | boolean, dtype: DType): number | bigint {\n if (isBigIntDType(dtype)) {\n return BigInt(value as number | bigint);\n }\n if (dtype === 'bool') {\n return value ? 1 : 0;\n }\n return Number(value);\n}\n\n/**\n * Map our dtype to @stdlib's supported dtype\n * @stdlib doesn't support int64, uint64 natively, but does support bool\n */\nexport function toStdlibDType(dtype: DType): string {\n // Map int64/uint64 to generic (we manage the BigInt arrays ourselves)\n if (dtype === 'int64' || dtype === 'uint64') {\n return 'generic';\n }\n // All other dtypes (including bool) are supported by stdlib\n return dtype;\n}\n", "/**\n * ArrayStorage - Internal storage abstraction\n *\n * Stores array data directly using TypedArrays without external dependencies.\n *\n * @internal - This is not part of the public API\n */\n\nimport {\n type DType,\n type TypedArray,\n DEFAULT_DTYPE,\n getTypedArrayConstructor,\n isBigIntDType,\n} from './dtype';\n\n/**\n * Internal storage for NDArray data\n * Manages the underlying TypedArray and metadata\n */\nexport class ArrayStorage {\n // Underlying TypedArray data buffer\n private _data: TypedArray;\n // Array shape\n private _shape: readonly number[];\n // Strides for each dimension\n private _strides: readonly number[];\n // Offset into the data buffer\n private _offset: number;\n // Data type\n private _dtype: DType;\n\n constructor(\n data: TypedArray,\n shape: readonly number[],\n strides: readonly number[],\n offset: number,\n dtype: DType\n ) {\n this._data = data;\n this._shape = shape;\n this._strides = strides;\n this._offset = offset;\n this._dtype = dtype;\n }\n\n /**\n * Shape of the array\n */\n get shape(): readonly number[] {\n return this._shape;\n }\n\n /**\n * Number of dimensions\n */\n get ndim(): number {\n return this._shape.length;\n }\n\n /**\n * Total number of elements\n */\n get size(): number {\n return this._shape.reduce((a, b) => a * b, 1);\n }\n\n /**\n * Data type\n */\n get dtype(): DType {\n return this._dtype;\n }\n\n /**\n * Underlying data buffer\n */\n get data(): TypedArray {\n return this._data;\n }\n\n /**\n * Strides (steps in each dimension)\n */\n get strides(): readonly number[] {\n return this._strides;\n }\n\n /**\n * Offset into the data buffer\n */\n get offset(): number {\n return this._offset;\n }\n\n /**\n * Check if array is C-contiguous (row-major, no gaps)\n */\n get isCContiguous(): boolean {\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) return true;\n if (ndim === 1) return strides[0] === 1;\n\n // Check if strides match row-major order\n let expectedStride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n if (strides[i] !== expectedStride) return false;\n expectedStride *= shape[i]!;\n }\n return true;\n }\n\n /**\n * Check if array is F-contiguous (column-major, no gaps)\n */\n get isFContiguous(): boolean {\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) return true;\n if (ndim === 1) return strides[0] === 1;\n\n // Check if strides match column-major order\n let expectedStride = 1;\n for (let i = 0; i < ndim; i++) {\n if (strides[i] !== expectedStride) return false;\n expectedStride *= shape[i]!;\n }\n return true;\n }\n\n /**\n * Get element at linear index (respects strides and offset)\n */\n iget(linearIndex: number): number | bigint {\n // Convert linear index to multi-index, then to actual buffer position\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) {\n return this._data[this._offset]!;\n }\n\n // Convert linear index to multi-index in row-major order\n let remaining = linearIndex;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < ndim; i++) {\n // Compute size of remaining dimensions\n let dimSize = 1;\n for (let j = i + 1; j < ndim; j++) {\n dimSize *= shape[j]!;\n }\n const idx = Math.floor(remaining / dimSize);\n remaining = remaining % dimSize;\n bufferIndex += idx * strides[i]!;\n }\n\n return this._data[bufferIndex]!;\n }\n\n /**\n * Set element at linear index (respects strides and offset)\n */\n iset(linearIndex: number, value: number | bigint): void {\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) {\n (this._data as unknown as (number | bigint)[])[this._offset] = value;\n return;\n }\n\n let remaining = linearIndex;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < ndim; i++) {\n let dimSize = 1;\n for (let j = i + 1; j < ndim; j++) {\n dimSize *= shape[j]!;\n }\n const idx = Math.floor(remaining / dimSize);\n remaining = remaining % dimSize;\n bufferIndex += idx * strides[i]!;\n }\n\n (this._data as unknown as (number | bigint)[])[bufferIndex] = value;\n }\n\n /**\n * Get element at multi-index position\n */\n get(...indices: number[]): number | bigint {\n const strides = this._strides;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < indices.length; i++) {\n bufferIndex += indices[i]! * strides[i]!;\n }\n\n return this._data[bufferIndex]!;\n }\n\n /**\n * Set element at multi-index position\n */\n set(indices: number[], value: number | bigint): void {\n const strides = this._strides;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < indices.length; i++) {\n bufferIndex += indices[i]! * strides[i]!;\n }\n\n (this._data as unknown as (number | bigint)[])[bufferIndex] = value;\n }\n\n /**\n * Create a deep copy of this storage\n */\n copy(): ArrayStorage {\n const shape = Array.from(this._shape);\n const dtype = this._dtype;\n const size = this.size;\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot copy array with dtype ${dtype}`);\n }\n\n // Create new data buffer and copy\n const newData = new Constructor(size);\n\n if (this.isCContiguous && this._offset === 0) {\n // Fast path: direct copy\n if (isBigIntDType(dtype)) {\n const src = this._data as BigInt64Array | BigUint64Array;\n const dst = newData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n dst[i] = src[i]!;\n }\n } else {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>).set(\n this._data as Exclude<TypedArray, BigInt64Array | BigUint64Array>\n );\n }\n } else {\n // Slow path: respect strides\n if (isBigIntDType(dtype)) {\n const dst = newData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n dst[i] = this.iget(i) as bigint;\n }\n } else {\n for (let i = 0; i < size; i++) {\n newData[i] = this.iget(i) as number;\n }\n }\n }\n\n return new ArrayStorage(newData, shape, ArrayStorage._computeStrides(shape), 0, dtype);\n }\n\n /**\n * Create storage from TypedArray data\n */\n static fromData(\n data: TypedArray,\n shape: number[],\n dtype: DType,\n strides?: number[],\n offset?: number\n ): ArrayStorage {\n const finalStrides = strides ?? ArrayStorage._computeStrides(shape);\n const finalOffset = offset ?? 0;\n return new ArrayStorage(data, shape, finalStrides, finalOffset, dtype);\n }\n\n /**\n * Create storage with zeros\n */\n static zeros(shape: number[], dtype: DType = DEFAULT_DTYPE): ArrayStorage {\n const size = shape.reduce((a, b) => a * b, 1);\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${dtype}`);\n }\n\n const data = new Constructor(size);\n\n return new ArrayStorage(data, shape, ArrayStorage._computeStrides(shape), 0, dtype);\n }\n\n /**\n * Create storage with ones\n */\n static ones(shape: number[], dtype: DType = DEFAULT_DTYPE): ArrayStorage {\n const size = shape.reduce((a, b) => a * b, 1);\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${dtype}`);\n }\n\n const data = new Constructor(size);\n\n // Fill with ones using native fill (much faster than loop)\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array).fill(BigInt(1));\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>).fill(1);\n }\n\n return new ArrayStorage(data, shape, ArrayStorage._computeStrides(shape), 0, dtype);\n }\n\n /**\n * Compute strides for row-major (C-order) layout\n * @private\n */\n private static _computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n }\n}\n\n/**\n * Compute strides for a given shape (row-major order)\n * @internal\n */\nexport function computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n", "/**\n * Computation backend abstraction\n *\n * Internal module for element-wise and broadcast operations.\n * Provides a swappable backend for different computation strategies.\n *\n * @internal\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { promoteDTypes, isBigIntDType } from '../core/dtype';\n\n/**\n * Compute the broadcast shape of two arrays\n * Returns the shape that results from broadcasting a and b together\n * Throws if shapes are not compatible for broadcasting\n */\nexport function broadcastShapes(shapeA: readonly number[], shapeB: readonly number[]): number[] {\n const ndimA = shapeA.length;\n const ndimB = shapeB.length;\n const ndim = Math.max(ndimA, ndimB);\n const result = new Array(ndim);\n\n for (let i = 0; i < ndim; i++) {\n const dimA = i < ndim - ndimA ? 1 : shapeA[i - (ndim - ndimA)]!;\n const dimB = i < ndim - ndimB ? 1 : shapeB[i - (ndim - ndimB)]!;\n\n if (dimA === dimB) {\n result[i] = dimA;\n } else if (dimA === 1) {\n result[i] = dimB;\n } else if (dimB === 1) {\n result[i] = dimA;\n } else {\n throw new Error(\n `operands could not be broadcast together with shapes ${JSON.stringify(Array.from(shapeA))} ${JSON.stringify(Array.from(shapeB))}`\n );\n }\n }\n\n return result;\n}\n\n/**\n * Compute the strides for broadcasting an array to a target shape\n * Returns strides where dimensions that need broadcasting have stride 0\n */\nfunction broadcastStrides(\n shape: readonly number[],\n strides: readonly number[],\n targetShape: readonly number[]\n): number[] {\n const ndim = shape.length;\n const targetNdim = targetShape.length;\n const result = new Array(targetNdim).fill(0);\n\n // Align dimensions from the right\n for (let i = 0; i < ndim; i++) {\n const targetIdx = targetNdim - ndim + i;\n const dim = shape[i]!;\n const targetDim = targetShape[targetIdx]!;\n\n if (dim === targetDim) {\n // Same size, use original stride\n result[targetIdx] = strides[i]!;\n } else if (dim === 1) {\n // Broadcasting, stride is 0 (repeat along this dimension)\n result[targetIdx] = 0;\n } else {\n // This shouldn't happen if shapes were validated\n throw new Error('Invalid broadcast');\n }\n }\n\n return result;\n}\n\n/**\n * Create a broadcast view of an ArrayStorage\n * The returned storage shares data with the original but has different shape/strides\n */\nfunction broadcastTo(storage: ArrayStorage, targetShape: readonly number[]): ArrayStorage {\n const broadcastedStrides = broadcastStrides(storage.shape, storage.strides, targetShape);\n return ArrayStorage.fromData(\n storage.data,\n Array.from(targetShape),\n storage.dtype,\n broadcastedStrides,\n storage.offset\n );\n}\n\n/**\n * Perform element-wise operation with broadcasting\n *\n * NOTE: This is the slow path for broadcasting/non-contiguous arrays.\n * Fast paths for contiguous arrays are implemented directly in ops/arithmetic.ts\n *\n * @param a - First array storage\n * @param b - Second array storage\n * @param op - Operation to perform (a, b) => result\n * @param opName - Name of operation (for special handling)\n * @returns Result storage\n */\nexport function elementwiseBinaryOp(\n a: ArrayStorage,\n b: ArrayStorage,\n op: (a: number, b: number) => number,\n opName: string\n): ArrayStorage {\n // Compute broadcast shape\n const outputShape = broadcastShapes(a.shape, b.shape);\n\n // Create broadcast views\n const aBroadcast = broadcastTo(a, outputShape);\n const bBroadcast = broadcastTo(b, outputShape);\n\n // Determine output dtype using NumPy promotion rules\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, resultDtype);\n const resultData = result.data;\n const size = result.size;\n\n if (isBigIntDType(resultDtype)) {\n // BigInt arithmetic - no precision loss\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const aRaw = aBroadcast.iget(i);\n const bRaw = bBroadcast.iget(i);\n\n // Convert to BigInt - handle case where value is already BigInt\n const aVal = typeof aRaw === 'bigint' ? aRaw : BigInt(Math.round(aRaw));\n const bVal = typeof bRaw === 'bigint' ? bRaw : BigInt(Math.round(bRaw));\n\n // Use BigInt operations\n if (opName === 'add') {\n resultTyped[i] = aVal + bVal;\n } else if (opName === 'subtract') {\n resultTyped[i] = aVal - bVal;\n } else if (opName === 'multiply') {\n resultTyped[i] = aVal * bVal;\n } else if (opName === 'divide') {\n resultTyped[i] = aVal / bVal;\n } else {\n resultTyped[i] = BigInt(Math.round(op(Number(aVal), Number(bVal))));\n }\n }\n } else {\n // Regular numeric types (including float dtypes)\n // Need to convert BigInt values to Number if mixing dtypes\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n for (let i = 0; i < size; i++) {\n const aRaw = aBroadcast.iget(i);\n const bRaw = bBroadcast.iget(i);\n\n // Convert to Number if needed (handles BigInt \u2192 float promotion)\n const aVal = needsConversion && typeof aRaw === 'bigint' ? Number(aRaw) : Number(aRaw);\n const bVal = needsConversion && typeof bRaw === 'bigint' ? Number(bRaw) : Number(bRaw);\n\n resultData[i] = op(aVal, bVal);\n }\n }\n\n return result;\n}\n\n/**\n * Perform element-wise comparison with broadcasting\n * Returns boolean array (dtype: 'bool', stored as Uint8Array)\n */\nexport function elementwiseComparisonOp(\n a: ArrayStorage,\n b: ArrayStorage,\n op: (a: number, b: number) => boolean\n): ArrayStorage {\n // Compute broadcast shape\n const outputShape = broadcastShapes(a.shape, b.shape);\n\n // Create broadcast views\n const aBroadcast = broadcastTo(a, outputShape);\n const bBroadcast = broadcastTo(b, outputShape);\n\n // Get output shape\n const size = outputShape.reduce((a, b) => a * b, 1);\n\n // Create result array with bool dtype\n const resultData = new Uint8Array(size);\n\n // Check if we need to convert BigInt to Number for comparison\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n // Perform element-wise comparison\n for (let i = 0; i < size; i++) {\n const aRaw = aBroadcast.iget(i);\n const bRaw = bBroadcast.iget(i);\n\n // Convert BigInt to Number if needed\n const aVal = needsConversion && typeof aRaw === 'bigint' ? Number(aRaw) : Number(aRaw);\n const bVal = needsConversion && typeof bRaw === 'bigint' ? Number(bRaw) : Number(bRaw);\n\n resultData[i] = op(aVal, bVal) ? 1 : 0;\n }\n\n return ArrayStorage.fromData(resultData, outputShape, 'bool');\n}\n\n/**\n * Perform element-wise unary operation\n *\n * @param a - Input array storage\n * @param op - Operation to perform (x) => result\n * @param preserveDtype - If true, preserve input dtype; if false, promote to float64 (default: true)\n * @returns Result storage\n */\nexport function elementwiseUnaryOp(\n a: ArrayStorage,\n op: (x: number) => number,\n preserveDtype = true\n): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const size = a.size;\n\n // Determine output dtype\n // Math operations like sqrt may need float output even for integer input\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = preserveDtype ? dtype : isIntegerType ? 'float64' : dtype;\n\n // Create result storage\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n const inputData = a.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt input - convert to Number for operation, then convert back if preserving dtype\n if (isBigIntDType(resultDtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = Number(inputData[i]!);\n resultTyped[i] = BigInt(Math.round(op(val)));\n }\n } else {\n // BigInt input, float output\n for (let i = 0; i < size; i++) {\n resultData[i] = op(Number(inputData[i]!));\n }\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = op(Number(inputData[i]!));\n }\n }\n\n return result;\n}\n", "/**\n * Arithmetic operations\n *\n * Pure functions for element-wise arithmetic operations:\n * add, subtract, multiply, divide\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType, promoteDTypes } from '../core/dtype';\nimport { elementwiseBinaryOp } from '../internal/compute';\n\n/**\n * Helper: Check if two arrays can use the fast path\n * (both C-contiguous with same shape, no broadcasting needed)\n */\nfunction canUseFastPath(a: ArrayStorage, b: ArrayStorage): boolean {\n return (\n a.isCContiguous &&\n b.isCContiguous &&\n a.shape.length === b.shape.length &&\n a.shape.every((dim, i) => dim === b.shape[i])\n );\n}\n\n/**\n * Add two arrays or array and scalar\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage\n */\nexport function add(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return addScalar(a, b);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return addArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x + y, 'add');\n}\n\n/**\n * Fast path for adding two contiguous arrays\n * @private\n */\nfunction addArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) + (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! + bTyped[i]!;\n }\n }\n } else {\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? Number(aData[i]) : (aData[i] as number);\n const bVal = typeof bData[i] === 'bigint' ? Number(bData[i]) : (bData[i] as number);\n resultData[i] = aVal + bVal;\n }\n } else {\n // Pure numeric operations - fully optimizable\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) + (bData[i] as number);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Subtract two arrays or array and scalar\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage\n */\nexport function subtract(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return subtractScalar(a, b);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return subtractArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x - y, 'subtract');\n}\n\n/**\n * Fast path for subtracting two contiguous arrays\n * @private\n */\nfunction subtractArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) - (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! - bTyped[i]!;\n }\n }\n } else {\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? Number(aData[i]) : (aData[i] as number);\n const bVal = typeof bData[i] === 'bigint' ? Number(bData[i]) : (bData[i] as number);\n resultData[i] = aVal - bVal;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) - (bData[i] as number);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Multiply two arrays or array and scalar\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage\n */\nexport function multiply(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return multiplyScalar(a, b);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return multiplyArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x * y, 'multiply');\n}\n\n/**\n * Fast path for multiplying two contiguous arrays\n * @private\n */\nfunction multiplyArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) * (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! * bTyped[i]!;\n }\n }\n } else {\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? Number(aData[i]) : (aData[i] as number);\n const bVal = typeof bData[i] === 'bigint' ? Number(bData[i]) : (bData[i] as number);\n resultData[i] = aVal * bVal;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) * (bData[i] as number);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Divide two arrays or array and scalar\n *\n * NumPy behavior: Integer division always promotes to float\n * Type promotion rules:\n * - float64 + anything \u2192 float64\n * - float32 + integer \u2192 float32\n * - integer + integer \u2192 float64\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage with promoted float dtype\n */\nexport function divide(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return divideScalar(a, b);\n }\n\n // Determine result dtype using NumPy promotion rules\n const aIsFloat64 = a.dtype === 'float64';\n const bIsFloat64 = b.dtype === 'float64';\n const aIsFloat32 = a.dtype === 'float32';\n const bIsFloat32 = b.dtype === 'float32';\n\n // If either is float64, result is float64\n if (aIsFloat64 || bIsFloat64) {\n const aFloat = aIsFloat64 ? a : convertToFloatDType(a, 'float64');\n const bFloat = bIsFloat64 ? b : convertToFloatDType(b, 'float64');\n return elementwiseBinaryOp(aFloat, bFloat, (x, y) => x / y, 'divide');\n }\n\n // If either is float32, result is float32\n if (aIsFloat32 || bIsFloat32) {\n const aFloat = aIsFloat32 ? a : convertToFloatDType(a, 'float32');\n const bFloat = bIsFloat32 ? b : convertToFloatDType(b, 'float32');\n return elementwiseBinaryOp(aFloat, bFloat, (x, y) => x / y, 'divide');\n }\n\n // Both are integers, promote to float64\n const aFloat = convertToFloatDType(a, 'float64');\n const bFloat = convertToFloatDType(b, 'float64');\n return elementwiseBinaryOp(aFloat, bFloat, (x, y) => x / y, 'divide');\n}\n\n/**\n * Convert ArrayStorage to float dtype\n * @private\n */\nfunction convertToFloatDType(\n storage: ArrayStorage,\n targetDtype: 'float32' | 'float64'\n): ArrayStorage {\n const result = ArrayStorage.zeros(Array.from(storage.shape), targetDtype);\n const size = storage.size;\n const srcData = storage.data;\n const dstData = result.data;\n\n for (let i = 0; i < size; i++) {\n dstData[i] = Number(srcData[i]!);\n }\n\n return result;\n}\n\n/**\n * Add scalar to array (optimized path)\n * @private\n */\nfunction addScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - no precision loss\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! + scalarBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) + scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Subtract scalar from array (optimized path)\n * @private\n */\nfunction subtractScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - no precision loss\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! - scalarBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) - scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Multiply array by scalar (optimized path)\n * @private\n */\nfunction multiplyScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - no precision loss\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! * scalarBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) * scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Divide array by scalar (optimized path)\n * NumPy behavior: Integer division promotes to float64\n * @private\n */\nfunction divideScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // NumPy behavior: Integer division always promotes to float64\n // This allows representing inf/nan for division by zero\n // Bool is also promoted to float64 (NumPy behavior)\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = isIntegerType ? 'float64' : dtype;\n\n // Create result with promoted dtype\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // Convert BigInt to Number for division (promotes to float64)\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) / scalar;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) / scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Absolute value of each element\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage with absolute values\n */\nexport function absolute(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = thisTyped[i]!;\n resultTyped[i] = val < 0n ? -val : val;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.abs(Number(data[i]!));\n }\n }\n\n return result;\n}\n\n/**\n * Numerical negative (element-wise negation)\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage with negated values\n */\nexport function negative(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = -thisTyped[i]!;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = -Number(data[i]!);\n }\n }\n\n return result;\n}\n\n/**\n * Sign of each element (-1, 0, or 1)\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage with signs\n */\nexport function sign(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = thisTyped[i]!;\n resultTyped[i] = val > 0n ? 1n : val < 0n ? -1n : 0n;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]!);\n resultData[i] = val > 0 ? 1 : val < 0 ? -1 : 0;\n }\n }\n\n return result;\n}\n\n/**\n * Modulo operation (remainder after division)\n * NumPy behavior: Uses floor modulo (sign follows divisor), not JavaScript's truncate modulo\n * Preserves dtype for integer types\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Result storage with modulo values\n */\nexport function mod(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return modScalar(a, b);\n }\n // NumPy uses floor modulo: ((x % y) + y) % y for proper sign handling\n return elementwiseBinaryOp(a, b, (x, y) => ((x % y) + y) % y, 'mod');\n}\n\n/**\n * Modulo with scalar divisor (optimized path)\n * NumPy uses floor modulo: result has same sign as divisor\n * @private\n */\nfunction modScalar(storage: ArrayStorage, divisor: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - use floor modulo\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const divisorBig = BigInt(Math.round(divisor));\n for (let i = 0; i < size; i++) {\n const val = thisTyped[i]!;\n // Floor modulo for BigInt\n resultTyped[i] = ((val % divisorBig) + divisorBig) % divisorBig;\n }\n } else {\n // Regular numeric types - use floor modulo\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]!);\n // Floor modulo: ((x % y) + y) % y\n resultData[i] = ((val % divisor) + divisor) % divisor;\n }\n }\n\n return result;\n}\n\n/**\n * Floor division (division with result rounded down)\n * NumPy behavior: Preserves integer types\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Result storage with floor division values\n */\nexport function floorDivide(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return floorDivideScalar(a, b);\n }\n return elementwiseBinaryOp(a, b, (x, y) => Math.floor(x / y), 'floor_divide');\n}\n\n/**\n * Floor division with scalar divisor (optimized path)\n * @private\n */\nfunction floorDivideScalar(storage: ArrayStorage, divisor: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // NumPy behavior: floor_divide preserves integer types\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt floor division\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const divisorBig = BigInt(Math.round(divisor));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! / divisorBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.floor(Number(data[i]!) / divisor);\n }\n }\n\n return result;\n}\n\n/**\n * Unary positive (returns a copy of the array)\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage (copy of input)\n */\nexport function positive(a: ArrayStorage): ArrayStorage {\n // Positive is essentially a no-op that returns a copy\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n // Copy data\n for (let i = 0; i < size; i++) {\n resultData[i] = data[i]!;\n }\n\n return result;\n}\n\n/**\n * Reciprocal (1/x) of each element\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with reciprocal values\n */\nexport function reciprocal(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // NumPy behavior: reciprocal always promotes integers to float64\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = isIntegerType ? 'float64' : dtype;\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt input promotes to float64\n for (let i = 0; i < size; i++) {\n resultData[i] = 1.0 / Number(data[i]!);\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = 1.0 / Number(data[i]!);\n }\n }\n\n return result;\n}\n\n/**\n * Cube root of each element\n * NumPy behavior: Promotes integer types to float64\n *\n * @param a - Input array storage\n * @returns Result storage with cube root values\n */\nexport function cbrt(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // NumPy behavior: cbrt always promotes integers to float64\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = isIntegerType ? 'float64' : dtype;\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n // Handle all types uniformly - convert to number and apply Math.cbrt\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.cbrt(Number(data[i]!));\n }\n\n return result;\n}\n\n/**\n * Absolute value of each element, returning float\n * NumPy behavior: fabs always returns floating point\n *\n * @param a - Input array storage\n * @returns Result storage with absolute values as float\n */\nexport function fabs(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // fabs always returns float64, except for float32 which stays float32\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n // Handle all types uniformly\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.abs(Number(data[i]!));\n }\n\n return result;\n}\n\n/**\n * Returns both quotient and remainder (floor divide and modulo)\n * NumPy behavior: divmod(a, b) = (floor_divide(a, b), mod(a, b))\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Tuple of [quotient, remainder] storages\n */\nexport function divmod(a: ArrayStorage, b: ArrayStorage | number): [ArrayStorage, ArrayStorage] {\n const quotient = floorDivide(a, b);\n const remainder = mod(a, b);\n return [quotient, remainder];\n}\n\n/**\n * Element-wise square of each element\n * NumPy behavior: x**2\n *\n * @param a - Input array storage\n * @returns Result storage with squared values\n */\nexport function square(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const bigData = data as BigInt64Array | BigUint64Array;\n const bigResultData = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n bigResultData[i] = bigData[i]! * bigData[i]!;\n }\n } else {\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]!);\n resultData[i] = val * val;\n }\n }\n\n return result;\n}\n\n/**\n * Remainder of division (same as mod)\n * NumPy behavior: Same as mod, alias for compatibility\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Result storage with remainder values\n */\nexport function remainder(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n return mod(a, b);\n}\n\n/**\n * Heaviside step function\n * NumPy behavior:\n * heaviside(x1, x2) = 0 if x1 < 0\n * = x2 if x1 == 0\n * = 1 if x1 > 0\n *\n * @param x1 - Input array storage\n * @param x2 - Value to use when x1 == 0 (array storage or scalar)\n * @returns Result storage with heaviside values\n */\nexport function heaviside(x1: ArrayStorage, x2: ArrayStorage | number): ArrayStorage {\n const dtype = x1.dtype;\n const shape = Array.from(x1.shape);\n const size = x1.size;\n\n // Result is always float64\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (typeof x2 === 'number') {\n // Scalar x2\n for (let i = 0; i < size; i++) {\n const val = Number(x1.data[i]!);\n if (val < 0) {\n resultData[i] = 0;\n } else if (val === 0) {\n resultData[i] = x2;\n } else {\n resultData[i] = 1;\n }\n }\n } else {\n // Array x2 - needs to broadcast\n const x2Data = x2.data;\n const x2Shape = x2.shape;\n\n // Simple case: same shape\n if (shape.every((d, i) => d === x2Shape[i])) {\n for (let i = 0; i < size; i++) {\n const val = Number(x1.data[i]!);\n if (val < 0) {\n resultData[i] = 0;\n } else if (val === 0) {\n resultData[i] = Number(x2Data[i]!);\n } else {\n resultData[i] = 1;\n }\n }\n } else {\n // Broadcasting case - use elementwiseBinaryOp approach\n for (let i = 0; i < size; i++) {\n const val = Number(x1.data[i]!);\n // Simple broadcast: assume x2 is broadcastable to x1\n const x2Idx = i % x2.size;\n if (val < 0) {\n resultData[i] = 0;\n } else if (val === 0) {\n resultData[i] = Number(x2Data[x2Idx]!);\n } else {\n resultData[i] = 1;\n }\n }\n }\n }\n\n return result;\n}\n", "/**\n * Broadcasting utilities for NumPy-compatible array operations\n *\n * Implements NumPy broadcasting rules without external dependencies\n */\n\nimport { ArrayStorage } from './storage';\n\n/**\n * Check if two or more shapes are broadcast-compatible\n * and compute the resulting output shape\n *\n * @param shapes - Array of shapes to broadcast\n * @returns The broadcast output shape, or null if incompatible\n *\n * @example\n * ```typescript\n * computeBroadcastShape([[3, 4], [4]]); // [3, 4]\n * computeBroadcastShape([[3, 4], [3, 1]]); // [3, 4]\n * computeBroadcastShape([[3, 4], [5]]); // null (incompatible)\n * ```\n */\nexport function computeBroadcastShape(shapes: readonly number[][]): number[] | null {\n if (shapes.length === 0) {\n return [];\n }\n\n if (shapes.length === 1) {\n return Array.from(shapes[0]!);\n }\n\n // Find max number of dimensions\n const maxNdim = Math.max(...shapes.map((s) => s.length));\n const result = new Array(maxNdim);\n\n for (let i = 0; i < maxNdim; i++) {\n let dim = 1;\n for (const shape of shapes) {\n const shapeIdx = shape.length - maxNdim + i;\n const shapeDim = shapeIdx < 0 ? 1 : shape[shapeIdx]!;\n\n if (shapeDim === 1) {\n // Can be broadcast\n continue;\n } else if (dim === 1) {\n // First non-1 dimension\n dim = shapeDim;\n } else if (dim !== shapeDim) {\n // Incompatible\n return null;\n }\n }\n result[i] = dim;\n }\n\n return result;\n}\n\n/**\n * Check if two shapes are broadcast-compatible\n *\n * @param shape1 - First shape\n * @param shape2 - Second shape\n * @returns true if shapes can be broadcast together, false otherwise\n *\n * @example\n * ```typescript\n * areBroadcastable([3, 4], [4]); // true\n * areBroadcastable([3, 4], [3, 1]); // true\n * areBroadcastable([3, 4], [5]); // false\n * ```\n */\nexport function areBroadcastable(shape1: readonly number[], shape2: readonly number[]): boolean {\n return computeBroadcastShape([Array.from(shape1), Array.from(shape2)]) !== null;\n}\n\n/**\n * Compute the strides for broadcasting an array to a target shape\n * Returns strides where dimensions that need broadcasting have stride 0\n */\nfunction broadcastStrides(\n shape: readonly number[],\n strides: readonly number[],\n targetShape: readonly number[]\n): number[] {\n const ndim = shape.length;\n const targetNdim = targetShape.length;\n const result = new Array(targetNdim).fill(0);\n\n // Align dimensions from the right\n for (let i = 0; i < ndim; i++) {\n const targetIdx = targetNdim - ndim + i;\n const dim = shape[i]!;\n const targetDim = targetShape[targetIdx]!;\n\n if (dim === targetDim) {\n // Same size, use original stride\n result[targetIdx] = strides[i]!;\n } else if (dim === 1) {\n // Broadcasting, stride is 0 (repeat along this dimension)\n result[targetIdx] = 0;\n } else {\n // This shouldn't happen if shapes were validated\n throw new Error('Invalid broadcast');\n }\n }\n\n return result;\n}\n\n/**\n * Broadcast an ArrayStorage to a target shape\n * Returns a view with modified strides for broadcasting\n *\n * @param storage - The storage to broadcast\n * @param targetShape - The target shape to broadcast to\n * @returns A new ArrayStorage view with broadcasting strides\n */\nexport function broadcastTo(storage: ArrayStorage, targetShape: readonly number[]): ArrayStorage {\n const broadcastedStrides = broadcastStrides(storage.shape, storage.strides, targetShape);\n return ArrayStorage.fromData(\n storage.data,\n Array.from(targetShape),\n storage.dtype,\n broadcastedStrides,\n storage.offset\n );\n}\n\n/**\n * Broadcast multiple ArrayStorage objects to a common shape\n *\n * Returns views of the input arrays broadcast to the same shape.\n * Views share memory with the original arrays.\n *\n * @param storages - ArrayStorage objects to broadcast\n * @returns Array of broadcast ArrayStorage views\n * @throws Error if arrays have incompatible shapes\n */\nexport function broadcastArrays(storages: ArrayStorage[]): ArrayStorage[] {\n if (storages.length === 0) {\n return [];\n }\n\n if (storages.length === 1) {\n return storages;\n }\n\n // Compute broadcast shape\n const shapes = storages.map((s) => Array.from(s.shape));\n const targetShape = computeBroadcastShape(shapes);\n\n if (targetShape === null) {\n throw new Error(\n `operands could not be broadcast together with shapes ${shapes.map((s) => JSON.stringify(s)).join(' ')}`\n );\n }\n\n // Broadcast each storage to the target shape\n return storages.map((s) => broadcastTo(s, targetShape));\n}\n\n/**\n * Compute the broadcast shape for multiple shapes without creating arrays.\n * Returns the resulting shape if all shapes are broadcast-compatible.\n *\n * This is the NumPy-compatible function for computing broadcast shape.\n *\n * @param shapes - Variable number of shapes to broadcast\n * @returns The broadcast output shape\n * @throws Error if shapes are not broadcast-compatible\n *\n * @example\n * ```typescript\n * broadcastShapes([3, 4], [4]); // [3, 4]\n * broadcastShapes([3, 4], [3, 1]); // [3, 4]\n * broadcastShapes([3, 4], [5]); // Error\n * ```\n */\nexport function broadcastShapes(...shapes: readonly number[][]): number[] {\n const result = computeBroadcastShape(shapes);\n\n if (result === null) {\n const shapeStrs = shapes.map((s) => `(${s.join(',')})`).join(' ');\n throw new Error(\n `shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between ${shapeStrs}`\n );\n }\n\n return result;\n}\n\n/**\n * Generate a descriptive error message for broadcasting failures\n *\n * @param shapes - The incompatible shapes\n * @param operation - The operation being attempted (e.g., 'add', 'multiply')\n * @returns Error message string\n */\nexport function broadcastErrorMessage(shapes: readonly number[][], operation?: string): string {\n const opStr = operation ? ` for ${operation}` : '';\n const shapeStrs = shapes.map((s) => `(${s.join(',')})`).join(' ');\n return `operands could not be broadcast together${opStr} with shapes ${shapeStrs}`;\n}\n", "/**\n * Comparison operations\n *\n * Element-wise comparison operations that return boolean arrays:\n * greater, greater_equal, less, less_equal, equal, not_equal,\n * isclose, allclose\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType } from '../core/dtype';\nimport { elementwiseComparisonOp } from '../internal/compute';\nimport { computeBroadcastShape, broadcastTo } from '../core/broadcasting';\n\n/**\n * Element-wise greater than comparison (a > b)\n */\nexport function greater(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return greaterScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x > y);\n}\n\n/**\n * Element-wise greater than or equal comparison (a >= b)\n */\nexport function greaterEqual(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return greaterEqualScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x >= y);\n}\n\n/**\n * Element-wise less than comparison (a < b)\n */\nexport function less(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return lessScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x < y);\n}\n\n/**\n * Element-wise less than or equal comparison (a <= b)\n */\nexport function lessEqual(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return lessEqualScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x <= y);\n}\n\n/**\n * Element-wise equality comparison (a == b)\n */\nexport function equal(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return equalScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x === y);\n}\n\n/**\n * Element-wise inequality comparison (a != b)\n */\nexport function notEqual(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return notEqualScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x !== y);\n}\n\n/**\n * Element-wise \"close\" comparison with tolerance\n * Returns true where |a - b| <= atol + rtol * |b|\n */\nexport function isclose(\n a: ArrayStorage,\n b: ArrayStorage | number,\n rtol: number = 1e-5,\n atol: number = 1e-8\n): ArrayStorage {\n if (typeof b === 'number') {\n return iscloseScalar(a, b, rtol, atol);\n }\n return elementwiseComparisonOp(a, b, (x, y) => {\n const diff = Math.abs(x - y);\n const threshold = atol + rtol * Math.abs(y);\n return diff <= threshold;\n });\n}\n\n/**\n * Check if all elements are close (scalar result)\n * Returns true if all elements satisfy isclose condition\n */\nexport function allclose(\n a: ArrayStorage,\n b: ArrayStorage | number,\n rtol: number = 1e-5,\n atol: number = 1e-8\n): boolean {\n const closeResult = isclose(a, b, rtol, atol);\n const data = closeResult.data as Uint8Array;\n\n // Check if all values are 1 (true)\n for (let i = 0; i < closeResult.size; i++) {\n if (data[i] === 0) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Returns True if two arrays are element-wise equal within a tolerance.\n * Unlike array_equal, this function broadcasts the arrays before comparison.\n *\n * NumPy behavior: Broadcasts arrays before comparing, returns True if shapes\n * are broadcast-compatible and all elements are equal.\n *\n * @param a1 - First input array\n * @param a2 - Second input array\n * @returns True if arrays are equivalent (after broadcasting), False otherwise\n */\nexport function arrayEquiv(a1: ArrayStorage, a2: ArrayStorage): boolean {\n // Check if arrays can be broadcast together\n const shapes = [Array.from(a1.shape), Array.from(a2.shape)];\n const broadcastShape = computeBroadcastShape(shapes);\n\n if (broadcastShape === null) {\n // If shapes are incompatible for broadcasting, arrays are not equivalent\n return false;\n }\n\n // Broadcast both arrays to the common shape\n const b1 = broadcastTo(a1, broadcastShape);\n const b2 = broadcastTo(a2, broadcastShape);\n\n // Compare element by element using proper multi-dimensional indexing\n const ndim = broadcastShape.length;\n const size = broadcastShape.reduce((acc, d) => acc * d, 1);\n\n // Handle different dtypes\n const isBigInt1 = isBigIntDType(b1.dtype);\n const isBigInt2 = isBigIntDType(b2.dtype);\n\n // Iterate over all elements using multi-dimensional indices\n for (let flatIdx = 0; flatIdx < size; flatIdx++) {\n // Convert flat index to multi-dimensional indices\n let temp = flatIdx;\n const indices: number[] = new Array(ndim);\n for (let i = ndim - 1; i >= 0; i--) {\n indices[i] = temp % broadcastShape[i]!;\n temp = Math.floor(temp / broadcastShape[i]!);\n }\n\n // Get values using proper indexing\n const val1 = b1.get(...indices);\n const val2 = b2.get(...indices);\n\n // Compare values\n if (isBigInt1 || isBigInt2) {\n const v1 = typeof val1 === 'bigint' ? val1 : BigInt(Number(val1));\n const v2 = typeof val2 === 'bigint' ? val2 : BigInt(Number(val2));\n if (v1 !== v2) {\n return false;\n }\n } else {\n if (val1 !== val2) {\n return false;\n }\n }\n }\n\n return true;\n}\n\n// Scalar comparison optimized paths\n\nfunction greaterScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! > scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction greaterEqualScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! >= scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction lessScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! < scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction lessEqualScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! <= scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction equalScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n const dtype = storage.dtype;\n\n if (isBigIntDType(dtype)) {\n // BigInt comparison: convert scalar to BigInt\n const scalarBig = BigInt(Math.round(scalar));\n const typedData = thisData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < storage.size; i++) {\n data[i] = typedData[i]! === scalarBig ? 1 : 0;\n }\n } else {\n // Regular comparison\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! === scalar ? 1 : 0;\n }\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction notEqualScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! !== scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction iscloseScalar(\n storage: ArrayStorage,\n scalar: number,\n rtol: number,\n atol: number\n): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n const dtype = storage.dtype;\n\n if (isBigIntDType(dtype)) {\n // For BigInt, convert to Number for comparison\n const thisTyped = thisData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < storage.size; i++) {\n const a = Number(thisTyped[i]!);\n const diff = Math.abs(a - scalar);\n const threshold = atol + rtol * Math.abs(scalar);\n data[i] = diff <= threshold ? 1 : 0;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < storage.size; i++) {\n const a = Number(thisData[i]!);\n const diff = Math.abs(a - scalar);\n const threshold = atol + rtol * Math.abs(scalar);\n data[i] = diff <= threshold ? 1 : 0;\n }\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n", "/**\n * Indexing utilities for array operations\n * @internal\n */\n\n/**\n * Compute row-major strides for a given shape\n */\nexport function computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n\n/**\n * Convert multi-index to linear index in row-major order\n */\nexport function multiIndexToLinear(indices: number[], shape: readonly number[]): number {\n let linearIdx = 0;\n let stride = 1;\n for (let i = indices.length - 1; i >= 0; i--) {\n linearIdx += indices[i]! * stride;\n stride *= shape[i]!;\n }\n return linearIdx;\n}\n\n/**\n * Convert outer index and axis index to full multi-index\n * Used in reductions along a specific axis\n *\n * @param outerIdx - Linear index in the reduced (output) array\n * @param axis - The axis being reduced\n * @param axisIdx - Position along the reduction axis\n * @param shape - Original array shape\n * @returns Full multi-index in the original array\n */\nexport function outerIndexToMultiIndex(\n outerIdx: number,\n axis: number,\n axisIdx: number,\n shape: readonly number[]\n): number[] {\n const ndim = shape.length;\n const indices = new Array(ndim);\n const outputShape = Array.from(shape).filter((_, i) => i !== axis);\n\n // Convert outerIdx to multi-index in the output shape\n let remaining = outerIdx;\n for (let i = outputShape.length - 1; i >= 0; i--) {\n indices[i >= axis ? i + 1 : i] = remaining % outputShape[i]!;\n remaining = Math.floor(remaining / outputShape[i]!);\n }\n\n // Insert the axis index\n indices[axis] = axisIdx;\n return indices;\n}\n", "/**\n * Reduction operations (sum, mean, max, min)\n *\n * Pure functions for reducing arrays along axes.\n * @module ops/reduction\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType } from '../core/dtype';\nimport { outerIndexToMultiIndex, multiIndexToLinear } from '../internal/indexing';\n\n/**\n * Sum array elements over a given axis\n */\nexport function sum(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Sum all elements - return scalar\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n let total = BigInt(0);\n for (let i = 0; i < size; i++) {\n total += typedData[i]!;\n }\n return Number(total);\n } else {\n let total = 0;\n for (let i = 0; i < size; i++) {\n total += Number(data[i]!);\n }\n return total;\n }\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar - reuse scalar sum logic\n return sum(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumVal = BigInt(0);\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n sumVal += typedData[linearIdx]!;\n }\n resultTyped[outerIdx] = sumVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumVal = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n sumVal += Number(data[linearIdx]!);\n }\n resultData[outerIdx] = sumVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Compute the arithmetic mean along the specified axis\n * Note: mean() returns float64 for integer dtypes, matching NumPy behavior\n */\nexport function mean(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n\n if (axis === undefined) {\n return (sum(storage) as number) / storage.size;\n }\n\n // Normalize negative axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = shape.length + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= shape.length) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${shape.length}`);\n }\n\n const sumResult = sum(storage, axis, keepdims);\n if (typeof sumResult === 'number') {\n return sumResult / shape[normalizedAxis]!;\n }\n\n // Divide by the size of the reduced axis\n const divisor = shape[normalizedAxis]!;\n\n // For integer dtypes, mean returns float64 (matching NumPy behavior)\n let resultDtype = dtype;\n if (isBigIntDType(dtype) || dtype.startsWith('int') || dtype.startsWith('uint')) {\n resultDtype = 'float64';\n }\n\n const result = ArrayStorage.zeros(Array.from(sumResult.shape), resultDtype);\n const resultData = result.data;\n const sumData = sumResult.data;\n\n if (isBigIntDType(dtype)) {\n // Convert BigInt sum results to float for mean\n const sumTyped = sumData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < resultData.length; i++) {\n resultData[i] = Number(sumTyped[i]!) / divisor;\n }\n } else {\n for (let i = 0; i < resultData.length; i++) {\n resultData[i] = Number(sumData[i]!) / divisor;\n }\n }\n\n return result;\n}\n\n/**\n * Return the maximum along a given axis\n */\nexport function max(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Max of all elements - return scalar\n if (size === 0) {\n throw new Error('max of empty array');\n }\n\n let maxVal = data[0]!;\n for (let i = 1; i < size; i++) {\n if (data[i]! > maxVal) {\n maxVal = data[i]!;\n }\n }\n return Number(maxVal);\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return max(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let maxVal = typedData[firstIdx]!;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val > maxVal) {\n maxVal = val;\n }\n }\n resultTyped[outerIdx] = maxVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val > maxVal) {\n maxVal = val;\n }\n }\n resultData[outerIdx] = maxVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Product array elements over a given axis\n */\nexport function prod(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Product of all elements - return scalar\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n let product = BigInt(1);\n for (let i = 0; i < size; i++) {\n product *= typedData[i]!;\n }\n return Number(product);\n } else {\n let product = 1;\n for (let i = 0; i < size; i++) {\n product *= Number(data[i]!);\n }\n return product;\n }\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar - reuse scalar prod logic\n return prod(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let prodVal = BigInt(1);\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n prodVal *= typedData[linearIdx]!;\n }\n resultTyped[outerIdx] = prodVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let prodVal = 1;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n prodVal *= Number(data[linearIdx]!);\n }\n resultData[outerIdx] = prodVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Return the minimum along a given axis\n */\nexport function min(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Min of all elements - return scalar\n if (size === 0) {\n throw new Error('min of empty array');\n }\n\n let minVal = data[0]!;\n for (let i = 1; i < size; i++) {\n if (data[i]! < minVal) {\n minVal = data[i]!;\n }\n }\n return Number(minVal);\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return min(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let minVal = typedData[firstIdx]!;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val < minVal) {\n minVal = val;\n }\n }\n resultTyped[outerIdx] = minVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val < minVal) {\n minVal = val;\n }\n }\n resultData[outerIdx] = minVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Return the indices of the minimum values along a given axis\n */\nexport function argmin(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Argmin of all elements - return scalar index\n if (size === 0) {\n throw new Error('argmin of empty array');\n }\n\n let minVal = data[0]!;\n let minIdx = 0;\n for (let i = 1; i < size; i++) {\n if (data[i]! < minVal) {\n minVal = data[i]!;\n minIdx = i;\n }\n }\n return minIdx;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return argmin(storage);\n }\n\n // Create result storage with int32 dtype (indices are always integers)\n const result = ArrayStorage.zeros(outputShape, 'int32');\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let minVal = typedData[firstIdx]!;\n let minAxisIdx = 0;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val < minVal) {\n minVal = val;\n minAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = minAxisIdx;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n let minAxisIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val < minVal) {\n minVal = val;\n minAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = minAxisIdx;\n }\n }\n\n return result;\n}\n\n/**\n * Return the indices of the maximum values along a given axis\n */\nexport function argmax(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Argmax of all elements - return scalar index\n if (size === 0) {\n throw new Error('argmax of empty array');\n }\n\n let maxVal = data[0]!;\n let maxIdx = 0;\n for (let i = 1; i < size; i++) {\n if (data[i]! > maxVal) {\n maxVal = data[i]!;\n maxIdx = i;\n }\n }\n return maxIdx;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return argmax(storage);\n }\n\n // Create result storage with int32 dtype (indices are always integers)\n const result = ArrayStorage.zeros(outputShape, 'int32');\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let maxVal = typedData[firstIdx]!;\n let maxAxisIdx = 0;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val > maxVal) {\n maxVal = val;\n maxAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = maxAxisIdx;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n let maxAxisIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val > maxVal) {\n maxVal = val;\n maxAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = maxAxisIdx;\n }\n }\n\n return result;\n}\n\n/**\n * Compute the variance along the specified axis\n * @param storage - Input array storage\n * @param axis - Axis along which to compute variance\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - Keep dimensions (default: false)\n */\nexport function variance(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n // Compute mean\n const meanResult = mean(storage, axis, keepdims);\n\n if (axis === undefined) {\n // Variance of all elements - return scalar\n const meanVal = meanResult as number;\n let sumSqDiff = 0;\n\n for (let i = 0; i < size; i++) {\n const diff = Number(data[i]!) - meanVal;\n sumSqDiff += diff * diff;\n }\n\n return sumSqDiff / (size - ddof);\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const meanArray = meanResult as ArrayStorage;\n const meanData = meanArray.data;\n\n // Compute output shape (same as mean's output shape)\n const outputShape = keepdims\n ? meanArray.shape\n : Array.from(shape).filter((_, i) => i !== normalizedAxis);\n\n // Result is always float64 for variance\n const result = ArrayStorage.zeros(Array.from(outputShape), 'float64');\n const resultData = result.data;\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n // Compute variance for each position\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumSqDiff = 0;\n const meanVal = Number(meanData[outerIdx]!);\n\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const diff = Number(data[linearIdx]!) - meanVal;\n sumSqDiff += diff * diff;\n }\n\n resultData[outerIdx] = sumSqDiff / (axisSize - ddof);\n }\n\n return result;\n}\n\n/**\n * Compute the standard deviation along the specified axis\n * @param storage - Input array storage\n * @param axis - Axis along which to compute std\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - Keep dimensions (default: false)\n */\nexport function std(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const varResult = variance(storage, axis, ddof, keepdims);\n\n if (typeof varResult === 'number') {\n return Math.sqrt(varResult);\n }\n\n // Apply sqrt element-wise\n const result = ArrayStorage.zeros(Array.from(varResult.shape), 'float64');\n const varData = varResult.data;\n const resultData = result.data;\n\n for (let i = 0; i < varData.length; i++) {\n resultData[i] = Math.sqrt(Number(varData[i]!));\n }\n\n return result;\n}\n\n/**\n * Test whether all array elements along a given axis evaluate to True\n */\nexport function all(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | boolean {\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Test all elements\n for (let i = 0; i < size; i++) {\n if (!data[i]) {\n return false;\n }\n }\n return true;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return all(storage);\n }\n\n // Create result storage with bool dtype\n const result = ArrayStorage.zeros(outputShape, 'bool');\n const resultData = result.data as Uint8Array;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let allTrue = true;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n if (!data[linearIdx]) {\n allTrue = false;\n break;\n }\n }\n resultData[outerIdx] = allTrue ? 1 : 0;\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'bool');\n }\n\n return result;\n}\n\n/**\n * Test whether any array elements along a given axis evaluate to True\n */\nexport function any(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | boolean {\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Test all elements\n for (let i = 0; i < size; i++) {\n if (data[i]) {\n return true;\n }\n }\n return false;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return any(storage);\n }\n\n // Create result storage with bool dtype\n const result = ArrayStorage.zeros(outputShape, 'bool');\n const resultData = result.data as Uint8Array;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let anyTrue = false;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n if (data[linearIdx]) {\n anyTrue = true;\n break;\n }\n }\n resultData[outerIdx] = anyTrue ? 1 : 0;\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'bool');\n }\n\n return result;\n}\n\n/**\n * Return cumulative sum of elements along a given axis\n */\nexport function cumsum(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumsum\n const size = storage.size;\n const resultData = new Float64Array(size);\n let sum = 0;\n for (let i = 0; i < size; i++) {\n sum += Number(data[i]);\n resultData[i] = sum;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumsum along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n // Determine position along axis\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = Number(data[i]);\n } else {\n // Add previous element along axis\n resultData[i] = resultData[i - axisStride]! + Number(data[i]);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Return cumulative product of elements along a given axis\n */\nexport function cumprod(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumprod\n const size = storage.size;\n const resultData = new Float64Array(size);\n let prod = 1;\n for (let i = 0; i < size; i++) {\n prod *= Number(data[i]);\n resultData[i] = prod;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumprod along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n // Determine position along axis\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = Number(data[i]);\n } else {\n // Multiply by previous element along axis\n resultData[i] = resultData[i - axisStride]! * Number(data[i]);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Peak to peak (maximum - minimum) value along a given axis\n */\nexport function ptp(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const maxResult = max(storage, axis, keepdims);\n const minResult = min(storage, axis, keepdims);\n\n if (typeof maxResult === 'number' && typeof minResult === 'number') {\n return maxResult - minResult;\n }\n\n // Both are arrays, subtract element-wise\n const maxStorage = maxResult as ArrayStorage;\n const minStorage = minResult as ArrayStorage;\n const maxData = maxStorage.data;\n const minData = minStorage.data;\n const resultData = new Float64Array(maxStorage.size);\n\n for (let i = 0; i < maxStorage.size; i++) {\n resultData[i] = Number(maxData[i]) - Number(minData[i]);\n }\n\n return ArrayStorage.fromData(resultData, [...maxStorage.shape], 'float64');\n}\n\n/**\n * Compute the median along the specified axis\n */\nexport function median(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n return quantile(storage, 0.5, axis, keepdims);\n}\n\n/**\n * Compute the q-th percentile of data along specified axis\n */\nexport function percentile(\n storage: ArrayStorage,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n return quantile(storage, q / 100, axis, keepdims);\n}\n\n/**\n * Compute the q-th quantile of data along specified axis\n */\nexport function quantile(\n storage: ArrayStorage,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n if (q < 0 || q > 1) {\n throw new Error('Quantile must be between 0 and 1');\n }\n\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Compute quantile over all elements\n const values: number[] = [];\n for (let i = 0; i < storage.size; i++) {\n values.push(Number(data[i]));\n }\n values.sort((a, b) => a - b);\n\n const n = values.length;\n const idx = q * (n - 1);\n const lower = Math.floor(idx);\n const upper = Math.ceil(idx);\n\n if (lower === upper) {\n return values[lower]!;\n }\n\n // Linear interpolation\n const frac = idx - lower;\n return values[lower]! * (1 - frac) + values[upper]! * frac;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return quantile(storage, q);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Collect values along axis\n const values: number[] = [];\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n values.push(Number(data[linearIdx]));\n }\n values.sort((a, b) => a - b);\n\n const n = values.length;\n const idx = q * (n - 1);\n const lower = Math.floor(idx);\n const upper = Math.ceil(idx);\n\n if (lower === upper) {\n resultData[outerIdx] = values[lower]!;\n } else {\n // Linear interpolation\n const frac = idx - lower;\n resultData[outerIdx] = values[lower]! * (1 - frac) + values[upper]! * frac;\n }\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute the weighted average along the specified axis\n */\nexport function average(\n storage: ArrayStorage,\n axis?: number,\n weights?: ArrayStorage,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (weights === undefined) {\n // Unweighted average is just mean\n return mean(storage, axis, keepdims);\n }\n\n if (axis === undefined) {\n // Compute weighted average over all elements\n let sumWeightedValues = 0;\n let sumWeights = 0;\n const weightData = weights.data;\n\n for (let i = 0; i < storage.size; i++) {\n const w = Number(weightData[i % weights.size]);\n sumWeightedValues += Number(data[i]) * w;\n sumWeights += w;\n }\n\n return sumWeights === 0 ? NaN : sumWeightedValues / sumWeights;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return average(storage, undefined, weights);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const weightData = weights.data;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumWeightedValues = 0;\n let sumWeights = 0;\n\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const w = Number(weightData[axisIdx % weights.size]);\n sumWeightedValues += Number(data[linearIdx]) * w;\n sumWeights += w;\n }\n\n resultData[outerIdx] = sumWeights === 0 ? NaN : sumWeightedValues / sumWeights;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n// ============================================================================\n// NaN-aware reduction functions\n// ============================================================================\n\n/**\n * Return sum of elements, treating NaNs as zero\n */\nexport function nansum(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let total = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total += val;\n }\n }\n return total;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nansum(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let total = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total += val;\n }\n }\n resultData[outerIdx] = total;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Return product of elements, treating NaNs as one\n */\nexport function nanprod(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let total = 1;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total *= val;\n }\n }\n return total;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanprod(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let total = 1;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total *= val;\n }\n }\n resultData[outerIdx] = total;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute mean ignoring NaN values\n */\nexport function nanmean(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let total = 0;\n let count = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n return count === 0 ? NaN : total / count;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmean(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let total = 0;\n let count = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n resultData[outerIdx] = count === 0 ? NaN : total / count;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute variance ignoring NaN values\n */\nexport function nanvar(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // First pass: compute mean\n let total = 0;\n let count = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n if (count - ddof <= 0) return NaN;\n const meanVal = total / count;\n\n // Second pass: compute sum of squared deviations\n let sumSq = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n sumSq += (val - meanVal) ** 2;\n }\n }\n return sumSq / (count - ddof);\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanvar(storage, undefined, ddof);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // First pass: compute mean\n let total = 0;\n let count = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n\n if (count - ddof <= 0) {\n resultData[outerIdx] = NaN;\n continue;\n }\n\n const meanVal = total / count;\n\n // Second pass: compute sum of squared deviations\n let sumSq = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n sumSq += (val - meanVal) ** 2;\n }\n }\n resultData[outerIdx] = sumSq / (count - ddof);\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute standard deviation ignoring NaN values\n */\nexport function nanstd(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const varResult = nanvar(storage, axis, ddof, keepdims);\n if (typeof varResult === 'number') {\n return Math.sqrt(varResult);\n }\n const varStorage = varResult as ArrayStorage;\n const resultData = new Float64Array(varStorage.size);\n for (let i = 0; i < varStorage.size; i++) {\n resultData[i] = Math.sqrt(Number(varStorage.data[i]));\n }\n return ArrayStorage.fromData(resultData, [...varStorage.shape], 'float64');\n}\n\n/**\n * Return minimum ignoring NaN values\n */\nexport function nanmin(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let minVal = Infinity;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n }\n }\n return minVal === Infinity ? NaN : minVal;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmin(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n }\n }\n resultData[outerIdx] = minVal === Infinity ? NaN : minVal;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Return maximum ignoring NaN values\n */\nexport function nanmax(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let maxVal = -Infinity;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n }\n }\n return maxVal === -Infinity ? NaN : maxVal;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmax(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n }\n }\n resultData[outerIdx] = maxVal === -Infinity ? NaN : maxVal;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Return indices of minimum value, ignoring NaNs\n */\nexport function nanargmin(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let minVal = Infinity;\n let minIdx = -1;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n minIdx = i;\n }\n }\n return minIdx;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanargmin(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Int32Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n let minIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n minIdx = axisIdx;\n }\n }\n resultData[outerIdx] = minIdx;\n }\n\n return ArrayStorage.fromData(resultData, outputShape, 'int32');\n}\n\n/**\n * Return indices of maximum value, ignoring NaNs\n */\nexport function nanargmax(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let maxVal = -Infinity;\n let maxIdx = -1;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n maxIdx = i;\n }\n }\n return maxIdx;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanargmax(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Int32Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n let maxIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n maxIdx = axisIdx;\n }\n }\n resultData[outerIdx] = maxIdx;\n }\n\n return ArrayStorage.fromData(resultData, outputShape, 'int32');\n}\n\n/**\n * Return cumulative sum, treating NaNs as zero\n */\nexport function nancumsum(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumsum\n const size = storage.size;\n const resultData = new Float64Array(size);\n let sum = 0;\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n sum += val;\n }\n resultData[i] = sum;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumsum along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n const val = Number(data[i]);\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = isNaN(val) ? 0 : val;\n } else {\n resultData[i] = resultData[i - axisStride]! + (isNaN(val) ? 0 : val);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Return cumulative product, treating NaNs as one\n */\nexport function nancumprod(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumprod\n const size = storage.size;\n const resultData = new Float64Array(size);\n let prod = 1;\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n prod *= val;\n }\n resultData[i] = prod;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumprod along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n const val = Number(data[i]);\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = isNaN(val) ? 1 : val;\n } else {\n resultData[i] = resultData[i - axisStride]! * (isNaN(val) ? 1 : val);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Compute median ignoring NaN values\n */\nexport function nanmedian(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Collect non-NaN values\n const values: number[] = [];\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n values.push(val);\n }\n }\n\n if (values.length === 0) return NaN;\n\n values.sort((a, b) => a - b);\n const n = values.length;\n const mid = Math.floor(n / 2);\n\n if (n % 2 === 0) {\n return (values[mid - 1]! + values[mid]!) / 2;\n }\n return values[mid]!;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmedian(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Collect non-NaN values along axis\n const values: number[] = [];\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n values.push(val);\n }\n }\n\n if (values.length === 0) {\n resultData[outerIdx] = NaN;\n continue;\n }\n\n values.sort((a, b) => a - b);\n const n = values.length;\n const mid = Math.floor(n / 2);\n\n if (n % 2 === 0) {\n resultData[outerIdx] = (values[mid - 1]! + values[mid]!) / 2;\n } else {\n resultData[outerIdx] = values[mid]!;\n }\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n", "/**\n * Shape manipulation operations\n *\n * Pure functions for reshaping, transposing, and manipulating array dimensions.\n * @module ops/shape\n */\n\nimport { ArrayStorage, computeStrides } from '../core/storage';\nimport { getTypedArrayConstructor, isBigIntDType, type TypedArray } from '../core/dtype';\n\n/**\n * Reshape array to a new shape\n * Returns a view if array is C-contiguous, otherwise copies data\n */\nexport function reshape(storage: ArrayStorage, newShape: number[]): ArrayStorage {\n const size = storage.size;\n const dtype = storage.dtype;\n\n // Check if -1 is in the shape (infer dimension)\n const negIndex = newShape.indexOf(-1);\n let finalShape: number[];\n\n if (negIndex !== -1) {\n // Infer the dimension at negIndex\n const knownSize = newShape.reduce((acc, dim, i) => (i === negIndex ? acc : acc * dim), 1);\n const inferredDim = size / knownSize;\n\n if (!Number.isInteger(inferredDim)) {\n throw new Error(\n `cannot reshape array of size ${size} into shape ${JSON.stringify(newShape)}`\n );\n }\n\n finalShape = newShape.map((dim, i) => (i === negIndex ? inferredDim : dim));\n } else {\n finalShape = newShape;\n }\n\n // Validate that the new shape has the same total size\n const newSize = finalShape.reduce((a, b) => a * b, 1);\n if (newSize !== size) {\n throw new Error(\n `cannot reshape array of size ${size} into shape ${JSON.stringify(finalShape)}`\n );\n }\n\n // Fast path: if array is C-contiguous, create a view (no copy)\n if (storage.isCContiguous) {\n const data = storage.data;\n return ArrayStorage.fromData(data, finalShape, dtype, computeStrides(finalShape), 0);\n }\n\n // Slow path: array is not contiguous, must copy data first\n // Create contiguous copy, then reshape\n const contiguousCopy = storage.copy(); // copy() creates C-contiguous array\n const data = contiguousCopy.data;\n return ArrayStorage.fromData(data, finalShape, dtype, computeStrides(finalShape), 0);\n}\n\n/**\n * Return a flattened copy of the array\n * Creates 1D array containing all elements in row-major order\n * Always returns a copy (matching NumPy behavior)\n */\nexport function flatten(storage: ArrayStorage): ArrayStorage {\n const size = storage.size;\n const dtype = storage.dtype;\n const Constructor = getTypedArrayConstructor(dtype);\n\n if (!Constructor) {\n throw new Error(`Cannot flatten array with dtype ${dtype}`);\n }\n\n // Fast path: if array is C-contiguous, just copy the underlying data\n if (storage.isCContiguous) {\n const data = storage.data;\n const newData = data.slice(storage.offset, storage.offset + size);\n return ArrayStorage.fromData(newData as TypedArray, [size], dtype, [1], 0);\n }\n\n // Slow path: non-contiguous array, copy using iget (flat index)\n // This is much faster than recursive get(...indices) calls\n const newData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n for (let i = 0; i < size; i++) {\n const value = storage.iget(i);\n if (isBigInt) {\n (newData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(newData, [size], dtype, [1], 0);\n}\n\n/**\n * Return a flattened array (view when possible, otherwise copy)\n * Returns a view if array is C-contiguous, otherwise copies data\n */\nexport function ravel(storage: ArrayStorage): ArrayStorage {\n const size = storage.size;\n const dtype = storage.dtype;\n\n // Fast path: if array is C-contiguous, create a view (no copy needed)\n if (storage.isCContiguous) {\n const data = storage.data;\n return ArrayStorage.fromData(data, [size], dtype, [1], 0);\n }\n\n // Slow path: array is not contiguous, must copy like flatten()\n return flatten(storage);\n}\n\n/**\n * Transpose array (permute dimensions)\n * Returns a view with transposed dimensions\n */\nexport function transpose(storage: ArrayStorage, axes?: number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n let permutation: number[];\n\n if (axes === undefined) {\n // Default: reverse all dimensions\n permutation = Array.from({ length: ndim }, (_, i) => ndim - 1 - i);\n } else {\n // Validate axes\n if (axes.length !== ndim) {\n throw new Error(`axes must have length ${ndim}, got ${axes.length}`);\n }\n\n // Check that axes is a valid permutation\n const seen = new Set<number>();\n for (const axis of axes) {\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n if (seen.has(normalizedAxis)) {\n throw new Error(`repeated axis in transpose`);\n }\n seen.add(normalizedAxis);\n }\n\n permutation = axes.map((ax) => (ax < 0 ? ndim + ax : ax));\n }\n\n // Compute new shape and strides\n const newShape = permutation.map((i) => shape[i]!);\n const oldStrides = Array.from(strides);\n const newStrides = permutation.map((i) => oldStrides[i]!);\n\n // Create transposed view\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n}\n\n/**\n * Remove axes of length 1\n * Returns a view with specified dimensions removed\n */\nexport function squeeze(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n if (axis === undefined) {\n // Remove all axes with size 1\n const newShape: number[] = [];\n const newStrides: number[] = [];\n\n for (let i = 0; i < ndim; i++) {\n if (shape[i] !== 1) {\n newShape.push(shape[i]!);\n newStrides.push(strides[i]!);\n }\n }\n\n // If all dimensions were 1, result would be a scalar (0-d array)\n // For now, keep at least one dimension\n if (newShape.length === 0) {\n newShape.push(1);\n newStrides.push(1);\n }\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n } else {\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Check that the axis has size 1\n if (shape[normalizedAxis] !== 1) {\n throw new Error(\n `cannot select an axis which has size not equal to one (axis ${axis} has size ${shape[normalizedAxis]})`\n );\n }\n\n // Remove the specified axis\n const newShape: number[] = [];\n const newStrides: number[] = [];\n\n for (let i = 0; i < ndim; i++) {\n if (i !== normalizedAxis) {\n newShape.push(shape[i]!);\n newStrides.push(strides[i]!);\n }\n }\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n }\n}\n\n/**\n * Expand the shape by inserting a new axis of length 1\n * Returns a view with additional dimension\n */\nexport function expandDims(storage: ArrayStorage, axis: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n // Normalize axis (can be from -ndim-1 to ndim)\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + axis + 1;\n }\n\n if (normalizedAxis < 0 || normalizedAxis > ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim + 1}`);\n }\n\n // Insert 1 at the specified position\n const newShape = [...Array.from(shape)];\n newShape.splice(normalizedAxis, 0, 1);\n\n // Insert a stride at the new axis position\n // The stride for a dimension of size 1 doesn't matter, but conventionally\n // it should be the product of all dimensions to its right\n const newStrides = [...Array.from(strides)];\n const insertedStride =\n normalizedAxis < ndim ? strides[normalizedAxis]! * (shape[normalizedAxis] || 1) : 1;\n newStrides.splice(normalizedAxis, 0, insertedStride);\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n}\n\n/**\n * Swap two axes of an array\n * Returns a view with axes swapped\n */\nexport function swapaxes(storage: ArrayStorage, axis1: number, axis2: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n // Normalize axes\n let normalizedAxis1 = axis1 < 0 ? ndim + axis1 : axis1;\n let normalizedAxis2 = axis2 < 0 ? ndim + axis2 : axis2;\n\n if (normalizedAxis1 < 0 || normalizedAxis1 >= ndim) {\n throw new Error(`axis1 ${axis1} is out of bounds for array of dimension ${ndim}`);\n }\n if (normalizedAxis2 < 0 || normalizedAxis2 >= ndim) {\n throw new Error(`axis2 ${axis2} is out of bounds for array of dimension ${ndim}`);\n }\n\n // If same axis, return a view without change\n if (normalizedAxis1 === normalizedAxis2) {\n return ArrayStorage.fromData(\n data,\n Array.from(shape),\n dtype,\n Array.from(strides),\n storage.offset\n );\n }\n\n // Swap shape and strides\n const newShape = Array.from(shape);\n const newStrides = Array.from(strides);\n\n [newShape[normalizedAxis1], newShape[normalizedAxis2]] = [\n newShape[normalizedAxis2]!,\n newShape[normalizedAxis1]!,\n ];\n [newStrides[normalizedAxis1], newStrides[normalizedAxis2]] = [\n newStrides[normalizedAxis2]!,\n newStrides[normalizedAxis1]!,\n ];\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n}\n\n/**\n * Move axes to new positions\n * Returns a view with axes moved\n */\nexport function moveaxis(\n storage: ArrayStorage,\n source: number | number[],\n destination: number | number[]\n): ArrayStorage {\n const ndim = storage.ndim;\n\n // Convert to arrays\n const sourceArr = Array.isArray(source) ? source : [source];\n const destArr = Array.isArray(destination) ? destination : [destination];\n\n if (sourceArr.length !== destArr.length) {\n throw new Error('source and destination must have the same number of elements');\n }\n\n // Normalize axes\n const normalizedSource = sourceArr.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`source axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n });\n\n const normalizedDest = destArr.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`destination axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n });\n\n // Check for duplicate source/dest axes\n if (new Set(normalizedSource).size !== normalizedSource.length) {\n throw new Error('repeated axis in source');\n }\n if (new Set(normalizedDest).size !== normalizedDest.length) {\n throw new Error('repeated axis in destination');\n }\n\n // Build permutation\n // Start with axes not in source\n const order: number[] = [];\n for (let i = 0; i < ndim; i++) {\n if (!normalizedSource.includes(i)) {\n order.push(i);\n }\n }\n\n // Insert source axes at destination positions\n for (let i = 0; i < normalizedSource.length; i++) {\n const dst = normalizedDest[i]!;\n order.splice(dst, 0, normalizedSource[i]!);\n }\n\n return transpose(storage, order);\n}\n\n/**\n * Concatenate arrays along an axis\n */\nexport function concatenate(storages: ArrayStorage[], axis: number = 0): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to concatenate');\n }\n\n if (storages.length === 1) {\n return storages[0]!.copy();\n }\n\n const first = storages[0]!;\n const ndim = first.ndim;\n const dtype = first.dtype;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Validate shapes: all arrays must have same shape except along axis\n for (let i = 1; i < storages.length; i++) {\n const s = storages[i]!;\n if (s.ndim !== ndim) {\n throw new Error('all the input arrays must have same number of dimensions');\n }\n for (let d = 0; d < ndim; d++) {\n if (d !== normalizedAxis && s.shape[d] !== first.shape[d]) {\n throw new Error(\n `all the input array dimensions except for the concatenation axis must match exactly`\n );\n }\n }\n }\n\n // Calculate output shape\n const outputShape = Array.from(first.shape);\n let totalAlongAxis = first.shape[normalizedAxis]!;\n for (let i = 1; i < storages.length; i++) {\n totalAlongAxis += storages[i]!.shape[normalizedAxis]!;\n }\n outputShape[normalizedAxis] = totalAlongAxis;\n\n // Create output array\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot concatenate arrays with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // Copy data from each input array\n let offset = 0;\n for (const storage of storages) {\n const axisSize = storage.shape[normalizedAxis]!;\n copyToOutput(storage, outputData, outputShape, outputStrides, normalizedAxis, offset, dtype);\n offset += axisSize;\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Helper to copy data into concatenated output\n */\nfunction copyToOutput(\n source: ArrayStorage,\n outputData: TypedArray,\n _outputShape: number[],\n outputStrides: number[],\n axis: number,\n axisOffset: number,\n dtype: string\n): void {\n const sourceShape = source.shape;\n const ndim = sourceShape.length;\n const sourceSize = source.size;\n const isBigInt = dtype === 'int64' || dtype === 'uint64';\n\n // Fast path: if concatenating along axis 0 and both are C-contiguous,\n // we can do bulk copy\n if (axis === 0 && source.isCContiguous && ndim > 0) {\n // Calculate the starting position in output array\n const outputOffset = axisOffset * outputStrides[0]!;\n const sourceData = source.data;\n const start = source.offset;\n const end = start + sourceSize;\n\n // Bulk copy the entire source array\n // @ts-expect-error - TypedArray.set() works with any typed array subarray\n outputData.set(sourceData.subarray(start, end), outputOffset);\n return;\n }\n\n // Optimized path for axis=1 (common for hstack): copy row by row\n if (axis === 1 && ndim === 2 && source.isCContiguous) {\n const rows = sourceShape[0]!;\n const cols = sourceShape[1]!;\n const outputCols = _outputShape[1]!;\n const sourceData = source.data;\n const sourceStart = source.offset;\n\n for (let row = 0; row < rows; row++) {\n const sourceRowStart = sourceStart + row * cols;\n const outputRowStart = row * outputCols + axisOffset;\n // @ts-expect-error - TypedArray.set() works with any typed array subarray\n outputData.set(sourceData.subarray(sourceRowStart, sourceRowStart + cols), outputRowStart);\n }\n return;\n }\n\n // Slow path: element-by-element copy using flat indices (iget)\n // Optimized to avoid array spread and pre-compute base offset\n const indices = new Array(ndim).fill(0);\n const baseOutputOffset = axisOffset * outputStrides[axis]!;\n\n for (let i = 0; i < sourceSize; i++) {\n // Get value from source using flat index\n const value = source.iget(i);\n\n // Compute output index more efficiently\n let outputIdx = baseOutputOffset;\n for (let d = 0; d < ndim; d++) {\n outputIdx += indices[d]! * outputStrides[d]!;\n }\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outputIdx] =\n value as number;\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n indices[d]++;\n if (indices[d]! < sourceShape[d]!) {\n break;\n }\n indices[d] = 0;\n }\n }\n}\n\n/**\n * Stack arrays along a new axis\n */\nexport function stack(storages: ArrayStorage[], axis: number = 0): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n const first = storages[0]!;\n const shape = first.shape;\n const ndim = first.ndim;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + 1 + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis > ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim + 1}`);\n }\n\n // Validate shapes: all arrays must have exact same shape\n for (let i = 1; i < storages.length; i++) {\n const s = storages[i]!;\n if (s.ndim !== ndim) {\n throw new Error('all input arrays must have the same shape');\n }\n for (let d = 0; d < ndim; d++) {\n if (s.shape[d] !== shape[d]) {\n throw new Error('all input arrays must have the same shape');\n }\n }\n }\n\n // Expand dims on each array, then concatenate\n const expanded = storages.map((s) => expandDims(s, normalizedAxis));\n return concatenate(expanded, normalizedAxis);\n}\n\n/**\n * Stack arrays vertically (row-wise)\n * vstack is equivalent to concatenation along the first axis after\n * 1-D arrays of shape (N,) have been reshaped to (1,N)\n */\nexport function vstack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // For 1D arrays, reshape to (1, N) first\n const prepared = storages.map((s) => {\n if (s.ndim === 1) {\n return reshape(s, [1, s.shape[0]!]);\n }\n return s;\n });\n\n return concatenate(prepared, 0);\n}\n\n/**\n * Stack arrays horizontally (column-wise)\n * hstack is equivalent to concatenation along the second axis,\n * except for 1-D arrays where it concatenates along the first axis\n */\nexport function hstack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // Check if all arrays are 1D\n const allOneDim = storages.every((s) => s.ndim === 1);\n\n if (allOneDim) {\n // For 1D arrays, concatenate along axis 0\n return concatenate(storages, 0);\n }\n\n // For higher-dimensional arrays, concatenate along axis 1\n return concatenate(storages, 1);\n}\n\n/**\n * Stack arrays depth-wise (along third axis)\n * dstack is equivalent to concatenation along the third axis after\n * 2-D arrays of shape (M,N) have been reshaped to (M,N,1) and\n * 1-D arrays of shape (N,) have been reshaped to (1,N,1)\n */\nexport function dstack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // Prepare arrays\n const prepared = storages.map((s) => {\n if (s.ndim === 1) {\n // Reshape (N,) to (1, N, 1)\n return reshape(expandDims(reshape(s, [1, s.shape[0]!]), 2), [1, s.shape[0]!, 1]);\n } else if (s.ndim === 2) {\n // Reshape (M, N) to (M, N, 1)\n return expandDims(s, 2);\n }\n return s;\n });\n\n return concatenate(prepared, 2);\n}\n\n/**\n * Split array into sub-arrays\n */\nexport function split(\n storage: ArrayStorage,\n indicesOrSections: number | number[],\n axis: number = 0\n): ArrayStorage[] {\n const shape = storage.shape;\n const ndim = shape.length;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n\n let splitIndices: number[];\n\n if (typeof indicesOrSections === 'number') {\n // Split into N equal sections\n if (axisSize % indicesOrSections !== 0) {\n throw new Error(`array split does not result in an equal division`);\n }\n const sectionSize = axisSize / indicesOrSections;\n splitIndices = [];\n for (let i = 1; i < indicesOrSections; i++) {\n splitIndices.push(i * sectionSize);\n }\n } else {\n // Split at specified indices\n splitIndices = indicesOrSections;\n }\n\n return splitAtIndices(storage, splitIndices, normalizedAxis);\n}\n\n/**\n * Split array into sub-arrays (allows unequal splits)\n */\nexport function arraySplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[],\n axis: number = 0\n): ArrayStorage[] {\n const shape = storage.shape;\n const ndim = shape.length;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n\n let splitIndices: number[];\n\n if (typeof indicesOrSections === 'number') {\n // Split into N sections (may be unequal)\n const numSections = indicesOrSections;\n const sectionSize = Math.floor(axisSize / numSections);\n const remainder = axisSize % numSections;\n\n splitIndices = [];\n let offset = 0;\n for (let i = 0; i < numSections - 1; i++) {\n offset += sectionSize + (i < remainder ? 1 : 0);\n splitIndices.push(offset);\n }\n } else {\n // Split at specified indices\n splitIndices = indicesOrSections;\n }\n\n return splitAtIndices(storage, splitIndices, normalizedAxis);\n}\n\n/**\n * Helper to split array at specified indices\n */\nfunction splitAtIndices(storage: ArrayStorage, indices: number[], axis: number): ArrayStorage[] {\n const shape = storage.shape;\n const axisSize = shape[axis]!;\n\n // Add boundaries\n const boundaries = [0, ...indices, axisSize];\n const result: ArrayStorage[] = [];\n\n for (let i = 0; i < boundaries.length - 1; i++) {\n const start = boundaries[i]!;\n const end = boundaries[i + 1]!;\n\n if (start > end) {\n throw new Error('split indices must be in ascending order');\n }\n\n // Create slice\n const sliceShape = Array.from(shape);\n sliceShape[axis] = end - start;\n\n // Calculate new offset and strides\n const newOffset = storage.offset + start * storage.strides[axis]!;\n\n result.push(\n ArrayStorage.fromData(\n storage.data,\n sliceShape,\n storage.dtype,\n Array.from(storage.strides),\n newOffset\n )\n );\n }\n\n return result;\n}\n\n/**\n * Split array vertically (row-wise)\n */\nexport function vsplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[]\n): ArrayStorage[] {\n if (storage.ndim < 2) {\n throw new Error('vsplit only works on arrays of 2 or more dimensions');\n }\n return arraySplit(storage, indicesOrSections, 0);\n}\n\n/**\n * Split array horizontally (column-wise)\n */\nexport function hsplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[]\n): ArrayStorage[] {\n if (storage.ndim < 1) {\n throw new Error('hsplit only works on arrays of 1 or more dimensions');\n }\n // For 1D arrays, split along axis 0; for higher dims, split along axis 1\n const axis = storage.ndim === 1 ? 0 : 1;\n return arraySplit(storage, indicesOrSections, axis);\n}\n\n/**\n * Tile array by repeating along each axis\n */\nexport function tile(storage: ArrayStorage, reps: number | number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n // Normalize reps to array\n const repsArr = Array.isArray(reps) ? reps : [reps];\n\n // Pad reps or shape to match dimensions\n const maxDim = Math.max(ndim, repsArr.length);\n const paddedShape = new Array(maxDim).fill(1);\n const paddedReps = new Array(maxDim).fill(1);\n\n // Fill from the right\n for (let i = 0; i < ndim; i++) {\n paddedShape[maxDim - ndim + i] = shape[i]!;\n }\n for (let i = 0; i < repsArr.length; i++) {\n paddedReps[maxDim - repsArr.length + i] = repsArr[i]!;\n }\n\n // Calculate output shape\n const outputShape = paddedShape.map((s, i) => s * paddedReps[i]!);\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot tile array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // If we need to expand dimensions of input, reshape it\n let expandedStorage = storage;\n if (ndim < maxDim) {\n expandedStorage = reshape(storage, paddedShape);\n }\n\n const isBigInt = dtype === 'int64' || dtype === 'uint64';\n const expandedStrides = expandedStorage.strides;\n\n // Fill output by iterating through all output positions\n const outputIndices = new Array(maxDim).fill(0);\n\n for (let i = 0; i < outputSize; i++) {\n // Compute source flat index directly (wrap around for tiling)\n let sourceFlatIdx = expandedStorage.offset;\n for (let d = 0; d < maxDim; d++) {\n const sourceIdx = outputIndices[d]! % paddedShape[d]!;\n sourceFlatIdx += sourceIdx * expandedStrides[d]!;\n }\n\n // Read value directly from flat index\n const value = expandedStorage.data[sourceFlatIdx];\n\n // Write to output using direct index calculation\n let outputIdx = 0;\n for (let d = 0; d < maxDim; d++) {\n outputIdx += outputIndices[d]! * outputStrides[d]!;\n }\n\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outputIdx] =\n value as number;\n }\n\n // Increment indices\n for (let d = maxDim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < outputShape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Repeat elements of an array\n */\nexport function repeat(\n storage: ArrayStorage,\n repeats: number | number[],\n axis?: number\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n const size = storage.size;\n\n if (axis === undefined) {\n // Flatten and repeat each element\n const flatSize = size;\n const repeatsArr = Array.isArray(repeats) ? repeats : new Array(flatSize).fill(repeats);\n\n if (repeatsArr.length !== flatSize) {\n throw new Error(\n `operands could not be broadcast together with shape (${flatSize},) (${repeatsArr.length},)`\n );\n }\n\n const outputSize = repeatsArr.reduce((a, b) => a + b, 0);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot repeat array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n let outIdx = 0;\n for (let i = 0; i < flatSize; i++) {\n const value = storage.iget(i);\n const rep = repeatsArr[i]!;\n for (let r = 0; r < rep; r++) {\n if (dtype === 'int64' || dtype === 'uint64') {\n (outputData as BigInt64Array | BigUint64Array)[outIdx++] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx++] =\n value as number;\n }\n }\n }\n\n return ArrayStorage.fromData(outputData, [outputSize], dtype);\n }\n\n // Repeat along specified axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const repeatsArr = Array.isArray(repeats) ? repeats : new Array(axisSize).fill(repeats);\n\n if (repeatsArr.length !== axisSize) {\n throw new Error(\n `operands could not be broadcast together with shape (${axisSize},) (${repeatsArr.length},)`\n );\n }\n\n // Calculate output shape\n const outputShape = Array.from(shape);\n outputShape[normalizedAxis] = repeatsArr.reduce((a, b) => a + b, 0);\n\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot repeat array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // Iterate through source and write repeated values\n const sourceIndices = new Array(ndim).fill(0);\n const isBigInt = dtype === 'int64' || dtype === 'uint64';\n\n // Track cumulative positions along axis\n const axisPositions: number[] = [0];\n for (let i = 0; i < axisSize; i++) {\n axisPositions.push(axisPositions[i]! + repeatsArr[i]!);\n }\n\n for (let i = 0; i < size; i++) {\n // Use iget for flat index access instead of get(...indices)\n const value = storage.iget(i);\n const axisIdx = sourceIndices[normalizedAxis]!;\n const rep = repeatsArr[axisIdx]!;\n\n // Calculate base output index (without axis component)\n let baseOutIdx = 0;\n for (let d = 0; d < ndim; d++) {\n if (d !== normalizedAxis) {\n baseOutIdx += sourceIndices[d]! * outputStrides[d]!;\n }\n }\n\n // Write repeated values\n const axisStride = outputStrides[normalizedAxis]!;\n const axisStart = axisPositions[axisIdx]!;\n for (let r = 0; r < rep; r++) {\n const outIdx = baseOutIdx + (axisStart + r) * axisStride;\n\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx] =\n value as number;\n }\n }\n\n // Increment source indices\n for (let d = ndim - 1; d >= 0; d--) {\n sourceIndices[d]++;\n if (sourceIndices[d]! < shape[d]!) {\n break;\n }\n sourceIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Reverse the order of elements in an array along given axis\n */\nexport function flip(storage: ArrayStorage, axis?: number | number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n const size = storage.size;\n\n // Determine which axes to flip\n let axesToFlip: Set<number>;\n if (axis === undefined) {\n // Flip all axes\n axesToFlip = new Set(Array.from({ length: ndim }, (_, i) => i));\n } else if (typeof axis === 'number') {\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n axesToFlip = new Set([normalizedAxis]);\n } else {\n axesToFlip = new Set(\n axis.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n })\n );\n }\n\n // Create output array\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot flip array with dtype ${dtype}`);\n }\n const outputData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n // Fast path for 1D arrays\n if (ndim === 1 && storage.isCContiguous) {\n const sourceData = storage.data;\n const start = storage.offset;\n for (let i = 0; i < size; i++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = sourceData[\n start + size - 1 - i\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = sourceData[\n start + size - 1 - i\n ] as number;\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n\n // Fast path for 2D arrays\n if (ndim === 2 && storage.isCContiguous) {\n const rows = shape[0]!;\n const cols = shape[1]!;\n const sourceData = storage.data;\n const start = storage.offset;\n\n // Flipping both axes - reverse entire array\n if (axesToFlip.size === 2) {\n for (let i = 0; i < size; i++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = sourceData[\n start + size - 1 - i\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = sourceData[\n start + size - 1 - i\n ] as number;\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n\n if (axesToFlip.size === 1) {\n if (axesToFlip.has(0)) {\n // Flip rows: copy rows in reverse order\n for (let r = 0; r < rows; r++) {\n const sourceRowStart = start + (rows - 1 - r) * cols;\n const outputRowStart = r * cols;\n for (let c = 0; c < cols; c++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputRowStart + c] = sourceData[\n sourceRowStart + c\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[\n outputRowStart + c\n ] = sourceData[sourceRowStart + c] as number;\n }\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n } else if (axesToFlip.has(1)) {\n // Flip columns: reverse each row\n for (let r = 0; r < rows; r++) {\n const sourceRowStart = start + r * cols;\n const outputRowStart = r * cols;\n for (let c = 0; c < cols; c++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputRowStart + c] = sourceData[\n sourceRowStart + cols - 1 - c\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[\n outputRowStart + c\n ] = sourceData[sourceRowStart + cols - 1 - c] as number;\n }\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n }\n }\n\n // General path: element-by-element copy\n const sourceIndices = new Array(ndim);\n const outputIndices = new Array(ndim).fill(0);\n\n for (let i = 0; i < size; i++) {\n // Compute source indices by flipping the specified axes\n for (let d = 0; d < ndim; d++) {\n sourceIndices[d] = axesToFlip.has(d) ? shape[d]! - 1 - outputIndices[d]! : outputIndices[d];\n }\n\n // Get value from source\n let sourceOffset = storage.offset;\n for (let d = 0; d < ndim; d++) {\n sourceOffset += sourceIndices[d]! * storage.strides[d]!;\n }\n const value = storage.data[sourceOffset];\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n\n // Increment output indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < shape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n}\n\n/**\n * Rotate array by 90 degrees in the plane specified by axes\n */\nexport function rot90(\n storage: ArrayStorage,\n k: number = 1,\n axes: [number, number] = [0, 1]\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n if (ndim < 2) {\n throw new Error('Input must be at least 2-D');\n }\n\n // Normalize axes\n const axis0 = axes[0] < 0 ? ndim + axes[0] : axes[0];\n const axis1 = axes[1] < 0 ? ndim + axes[1] : axes[1];\n\n if (axis0 < 0 || axis0 >= ndim || axis1 < 0 || axis1 >= ndim) {\n throw new Error(`Axes are out of bounds for array of dimension ${ndim}`);\n }\n\n if (axis0 === axis1) {\n throw new Error('Axes must be different');\n }\n\n // Normalize k to 0-3\n k = ((k % 4) + 4) % 4;\n\n if (k === 0) {\n return storage.copy();\n }\n\n // Optimized: do the rotation in one pass instead of k iterations\n // k=1: flip axis1, transpose\n // k=2: flip both axes\n // k=3: flip axis0, transpose\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot rotate array with dtype ${dtype}`);\n }\n\n const outputShape = [...shape];\n if (k === 1 || k === 3) {\n // Swap dimensions for axis0 and axis1\n [outputShape[axis0], outputShape[axis1]] = [outputShape[axis1]!, outputShape[axis0]!];\n }\n\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n const isBigInt = isBigIntDType(dtype);\n\n const indices = new Array(ndim).fill(0);\n const sourceIndices = new Array(ndim);\n\n for (let i = 0; i < storage.size; i++) {\n // Transform indices based on k\n for (let d = 0; d < ndim; d++) {\n sourceIndices[d] = indices[d];\n }\n\n let outIdx0, outIdx1;\n if (k === 1) {\n // 90 degrees: flip axis1, then transpose\n outIdx0 = shape[axis1]! - 1 - indices[axis1]!;\n outIdx1 = indices[axis0];\n } else if (k === 2) {\n // 180 degrees: flip both axes\n outIdx0 = shape[axis0]! - 1 - indices[axis0]!;\n outIdx1 = shape[axis1]! - 1 - indices[axis1]!;\n sourceIndices[axis0] = outIdx0;\n sourceIndices[axis1] = outIdx1;\n } else {\n // k === 3, 270 degrees: flip axis0, then transpose\n outIdx0 = indices[axis1];\n outIdx1 = shape[axis0]! - 1 - indices[axis0]!;\n }\n\n if (k !== 2) {\n sourceIndices[axis0] = outIdx0;\n sourceIndices[axis1] = outIdx1;\n }\n\n // Compute output offset\n let outputOffset = 0;\n for (let d = 0; d < ndim; d++) {\n outputOffset += sourceIndices[d]! * outputStrides[d]!;\n }\n\n // Get source value\n const value = storage.iget(i);\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputOffset] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outputOffset] =\n value as number;\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n indices[d]++;\n if (indices[d]! < shape[d]!) {\n break;\n }\n indices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Roll array elements along a given axis\n */\nexport function roll(\n storage: ArrayStorage,\n shift: number | number[],\n axis?: number | number[]\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n const size = storage.size;\n\n // Handle no axis case - roll as flattened array\n if (axis === undefined) {\n const flatShift = Array.isArray(shift) ? shift.reduce((a, b) => a + b, 0) : shift;\n const flatStorage = flatten(storage);\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot roll array with dtype ${dtype}`);\n }\n const outputData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n for (let i = 0; i < size; i++) {\n const sourceIdx = (((i - flatShift) % size) + size) % size;\n const value = flatStorage.iget(sourceIdx);\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n // Reshape back to original shape\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n\n // Handle axis specified case\n const shifts = Array.isArray(shift) ? shift : [shift];\n const axes = Array.isArray(axis) ? axis : [axis];\n\n if (shifts.length !== axes.length) {\n throw new Error('shift and axis must have the same length');\n }\n\n // Normalize axes\n const normalizedAxes = axes.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n });\n\n // Create output array\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot roll array with dtype ${dtype}`);\n }\n const outputData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n // Iterate through all output positions\n const outputIndices = new Array(ndim).fill(0);\n\n for (let i = 0; i < size; i++) {\n // Compute source indices by rolling back\n const sourceIndices = [...outputIndices];\n for (let j = 0; j < normalizedAxes.length; j++) {\n const ax = normalizedAxes[j]!;\n const axisSize = shape[ax]!;\n const sh = shifts[j]!;\n sourceIndices[ax] = (((sourceIndices[ax]! - sh) % axisSize) + axisSize) % axisSize;\n }\n\n // Get value from source\n let sourceOffset = storage.offset;\n for (let d = 0; d < ndim; d++) {\n sourceOffset += sourceIndices[d]! * storage.strides[d]!;\n }\n const value = storage.data[sourceOffset];\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n\n // Increment output indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < shape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n}\n\n/**\n * Roll the specified axis backwards until it lies in a given position\n */\nexport function rollaxis(storage: ArrayStorage, axis: number, start: number = 0): ArrayStorage {\n const ndim = storage.ndim;\n\n // Normalize axis\n let normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Normalize start\n let normalizedStart = start < 0 ? ndim + start : start;\n if (normalizedStart < 0 || normalizedStart > ndim) {\n throw new Error(`start ${start} is out of bounds`);\n }\n\n if (normalizedAxis < normalizedStart) {\n normalizedStart--;\n }\n\n if (normalizedAxis === normalizedStart) {\n return ArrayStorage.fromData(\n storage.data,\n Array.from(storage.shape),\n storage.dtype,\n Array.from(storage.strides),\n storage.offset\n );\n }\n\n return moveaxis(storage, normalizedAxis, normalizedStart);\n}\n\n/**\n * Split array along third axis (depth)\n */\nexport function dsplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[]\n): ArrayStorage[] {\n if (storage.ndim < 3) {\n throw new Error('dsplit only works on arrays of 3 or more dimensions');\n }\n return arraySplit(storage, indicesOrSections, 2);\n}\n\n/**\n * Stack 1-D arrays as columns into a 2-D array\n */\nexport function columnStack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // If all arrays are 1D, reshape them to column vectors\n const prepared = storages.map((s) => {\n if (s.ndim === 1) {\n return reshape(s, [s.shape[0]!, 1]);\n }\n return s;\n });\n\n return hstack(prepared);\n}\n\n/**\n * Stack arrays in sequence vertically (row_stack is an alias for vstack)\n */\nexport const rowStack = vstack;\n\n/**\n * Resize array to new shape (returns new array, may repeat or truncate)\n */\nexport function resize(storage: ArrayStorage, newShape: number[]): ArrayStorage {\n const dtype = storage.dtype;\n const newSize = newShape.reduce((a, b) => a * b, 1);\n const oldSize = storage.size;\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot resize array with dtype ${dtype}`);\n }\n const outputData = new Constructor(newSize);\n const isBigInt = isBigIntDType(dtype);\n\n // Fill output by cycling through source data\n for (let i = 0; i < newSize; i++) {\n const sourceIdx = i % oldSize;\n const value = storage.iget(sourceIdx);\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, newShape, dtype);\n}\n\n/**\n * Convert arrays to at least 1D\n */\nexport function atleast1d(storages: ArrayStorage[]): ArrayStorage[] {\n return storages.map((s) => {\n if (s.ndim === 0) {\n // 0-D array -> 1-D with one element\n return reshape(s, [1]);\n }\n return s;\n });\n}\n\n/**\n * Convert arrays to at least 2D\n */\nexport function atleast2d(storages: ArrayStorage[]): ArrayStorage[] {\n return storages.map((s) => {\n if (s.ndim === 0) {\n return reshape(s, [1, 1]);\n } else if (s.ndim === 1) {\n return reshape(s, [1, s.shape[0]!]);\n }\n return s;\n });\n}\n\n/**\n * Convert arrays to at least 3D\n */\nexport function atleast3d(storages: ArrayStorage[]): ArrayStorage[] {\n return storages.map((s) => {\n if (s.ndim === 0) {\n return reshape(s, [1, 1, 1]);\n } else if (s.ndim === 1) {\n return reshape(s, [1, s.shape[0]!, 1]);\n } else if (s.ndim === 2) {\n return reshape(s, [s.shape[0]!, s.shape[1]!, 1]);\n }\n return s;\n });\n}\n", "/**\n * Linear algebra operations\n *\n * Pure functions for matrix operations (matmul, etc.).\n * @module ops/linalg\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { promoteDTypes } from '../core/dtype';\nimport * as shapeOps from './shape';\n\n/**\n * BLAS-like types for matrix operations\n */\ntype Layout = 'row-major' | 'column-major';\ntype Transpose = 'no-transpose' | 'transpose';\n\n/**\n * Double-precision general matrix multiply (DGEMM)\n *\n * Full BLAS-compatible implementation without external dependencies.\n * Performs: C = alpha * op(A) * op(B) + beta * C\n *\n * Supports all combinations of:\n * - Row-major and column-major layouts\n * - Transpose and no-transpose operations\n * - Arbitrary alpha and beta scalars\n *\n * Uses specialized loops for each case to avoid function call overhead.\n *\n * @internal\n */\nfunction dgemm(\n layout: Layout,\n transA: Transpose,\n transB: Transpose,\n M: number, // rows of op(A) and C\n N: number, // cols of op(B) and C\n K: number, // cols of op(A) and rows of op(B)\n alpha: number, // scalar alpha\n A: Float64Array, // matrix A\n lda: number, // leading dimension of A\n B: Float64Array, // matrix B\n ldb: number, // leading dimension of B\n beta: number, // scalar beta\n C: Float64Array, // matrix C (output)\n ldc: number // leading dimension of C\n): void {\n // Apply beta scaling to C first\n if (beta === 0) {\n for (let i = 0; i < M * N; i++) {\n C[i] = 0;\n }\n } else if (beta !== 1) {\n for (let i = 0; i < M * N; i++) {\n C[i] = (C[i] ?? 0) * beta;\n }\n }\n\n // Select specialized loop based on layout and transpose modes\n // This avoids function call overhead in the hot loop\n const isRowMajor = layout === 'row-major';\n const transposeA = transA === 'transpose';\n const transposeB = transB === 'transpose';\n\n if (isRowMajor && !transposeA && !transposeB) {\n // Row-major, no transpose (most common case)\n // C[i,j] = sum_k A[i,k] * B[k,j]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (isRowMajor && transposeA && !transposeB) {\n // Row-major, A transposed\n // C[i,j] = sum_k A[k,i] * B[k,j]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (isRowMajor && !transposeA && transposeB) {\n // Row-major, B transposed\n // C[i,j] = sum_k A[i,k] * B[j,k]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (isRowMajor && transposeA && transposeB) {\n // Row-major, both transposed\n // C[i,j] = sum_k A[k,i] * B[j,k]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (!isRowMajor && !transposeA && !transposeB) {\n // Column-major, no transpose\n // C[i,j] = sum_k A[i,k] * B[k,j]\n // Column-major: A[i,k] = A[k*lda + i], C[i,j] = C[j*ldc + i]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n } else if (!isRowMajor && transposeA && !transposeB) {\n // Column-major, A transposed\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n } else if (!isRowMajor && !transposeA && transposeB) {\n // Column-major, B transposed\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n } else {\n // Column-major, both transposed\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n }\n}\n\n/**\n * Dot product of two arrays (fully NumPy-compatible)\n *\n * Behavior depends on input dimensions:\n * - 0D \u00B7 0D: Multiply scalars \u2192 scalar\n * - 0D \u00B7 ND or ND \u00B7 0D: Element-wise multiply \u2192 ND\n * - 1D \u00B7 1D: Inner product \u2192 scalar\n * - 2D \u00B7 2D: Matrix multiplication \u2192 2D\n * - 2D \u00B7 1D: Matrix-vector product \u2192 1D\n * - 1D \u00B7 2D: Vector-matrix product \u2192 1D\n * - ND \u00B7 1D (N\u22652): Sum product over last axis of a \u2192 (N-1)D\n * - 1D \u00B7 ND (N\u22652): Sum product over first axis of b \u2192 (N-1)D\n * - ND \u00B7 MD (N,M\u22652): Sum product over last axis of a and second-to-last of b \u2192 (N+M-2)D\n *\n * For 2D\u00B72D, prefer using matmul() instead.\n */\nexport function dot(a: ArrayStorage, b: ArrayStorage): ArrayStorage | number | bigint {\n const aDim = a.ndim;\n const bDim = b.ndim;\n\n // Case 0: Scalar (0D) cases - treat as multiplication\n if (aDim === 0 || bDim === 0) {\n // Get scalar values\n const aVal = aDim === 0 ? a.get() : null;\n const bVal = bDim === 0 ? b.get() : null;\n\n if (aDim === 0 && bDim === 0) {\n // Both scalars: multiply them\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n return aVal * bVal;\n }\n return Number(aVal) * Number(bVal);\n } else if (aDim === 0) {\n // a is scalar, b is array: scalar * array (element-wise)\n // Equivalent to multiply(a, b)\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([...b.shape], resultDtype);\n for (let i = 0; i < b.size; i++) {\n const bData = b.data[i + b.offset];\n if (typeof aVal === 'bigint' && typeof bData === 'bigint') {\n result.data[i] = aVal * bData;\n } else {\n result.data[i] = Number(aVal) * Number(bData);\n }\n }\n return result;\n } else {\n // b is scalar, a is array: array * scalar (element-wise)\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([...a.shape], resultDtype);\n for (let i = 0; i < a.size; i++) {\n const aData = a.data[i + a.offset];\n if (typeof aData === 'bigint' && typeof bVal === 'bigint') {\n result.data[i] = aData * bVal;\n } else {\n result.data[i] = Number(aData) * Number(bVal);\n }\n }\n return result;\n }\n }\n\n // Case 1: Both 1D -> scalar (inner product)\n if (aDim === 1 && bDim === 1) {\n if (a.shape[0] !== b.shape[0]) {\n throw new Error(`dot: incompatible shapes (${a.shape[0]},) and (${b.shape[0]},)`);\n }\n const n = a.shape[0]!;\n let sum = 0;\n for (let i = 0; i < n; i++) {\n const aVal = a.get(i);\n const bVal = b.get(i);\n // Handle BigInt\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n return sum;\n }\n\n // Case 2: Both 2D -> matrix multiplication (delegate to matmul)\n if (aDim === 2 && bDim === 2) {\n return matmul(a, b);\n }\n\n // Case 3: 2D \u00B7 1D -> matrix-vector product (returns 1D)\n if (aDim === 2 && bDim === 1) {\n const [m, k] = a.shape;\n const n = b.shape[0]!;\n if (k !== n) {\n throw new Error(`dot: incompatible shapes (${m},${k}) and (${n},)`);\n }\n\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([m!], resultDtype);\n\n for (let i = 0; i < m!; i++) {\n let sum = 0;\n for (let j = 0; j < k!; j++) {\n const aVal = a.get(i, j);\n const bVal = b.get(j);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set([i], sum);\n }\n\n return result;\n }\n\n // Case 4: 1D \u00B7 2D -> vector-matrix product (returns 1D)\n if (aDim === 1 && bDim === 2) {\n const m = a.shape[0]!;\n const [k, n] = b.shape;\n if (m !== k) {\n throw new Error(`dot: incompatible shapes (${m},) and (${k},${n})`);\n }\n\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([n!], resultDtype);\n\n for (let j = 0; j < n!; j++) {\n let sum = 0;\n for (let i = 0; i < m; i++) {\n const aVal = a.get(i);\n const bVal = b.get(i, j);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set([j], sum);\n }\n\n return result;\n }\n\n // Case 5: ND \u00B7 1D (N > 2) -> sum product over last axis, result is (N-1)D\n if (aDim > 2 && bDim === 1) {\n const lastDimA = a.shape[aDim - 1]!;\n const bSize = b.shape[0]!;\n if (lastDimA !== bSize) {\n throw new Error(`dot: incompatible shapes ${JSON.stringify(a.shape)} and (${bSize},)`);\n }\n\n // Result shape is a.shape[:-1]\n const resultShape = [...a.shape.slice(0, -1)];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n // Iterate over all positions in result\n const resultSize = resultShape.reduce((acc, dim) => acc * dim, 1);\n for (let i = 0; i < resultSize; i++) {\n let sum = 0;\n // Compute multi-dimensional index for result\n let temp = i;\n const resultIdx: number[] = [];\n for (let d = resultShape.length - 1; d >= 0; d--) {\n resultIdx[d] = temp % resultShape[d]!;\n temp = Math.floor(temp / resultShape[d]!);\n }\n\n // Sum over the last dimension of a\n for (let k = 0; k < lastDimA; k++) {\n const aIdx = [...resultIdx, k];\n const aVal = a.get(...aIdx);\n const bVal = b.get(k);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set(resultIdx, sum);\n }\n\n return result;\n }\n\n // Case 6: 1D \u00B7 ND (N > 2) -> sum product over SECOND axis of b, result is (b.shape[0], b.shape[2:])\n // Actually for 1D\u00B73D: sum over axis 1 of b\n // For general case: need to handle this more carefully\n if (aDim === 1 && bDim > 2) {\n const aSize = a.shape[0]!;\n // For 1D (size K) \u00B7 ND, we contract over axis 1 of b (which should have size K)\n const contractAxisB = 1;\n const contractDimB = b.shape[contractAxisB]!;\n\n if (aSize !== contractDimB) {\n throw new Error(`dot: incompatible shapes (${aSize},) and ${JSON.stringify(b.shape)}`);\n }\n\n // Result shape: b.shape[0:1] + b.shape[2:]\n // For (K,) \u00B7 (L, K, M, N, ...) -> (L, M, N, ...)\n const resultShape = [...b.shape.slice(0, contractAxisB), ...b.shape.slice(contractAxisB + 1)];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n // Compute using multi-dimensional indices\n const resultSize = resultShape.reduce((acc, dim) => acc * dim, 1);\n for (let i = 0; i < resultSize; i++) {\n // Convert flat index to multi-dim result index\n let temp = i;\n const resultIdx: number[] = [];\n for (let d = resultShape.length - 1; d >= 0; d--) {\n resultIdx[d] = temp % resultShape[d]!;\n temp = Math.floor(temp / resultShape[d]!);\n }\n\n // Build b index by inserting the contract dimension\n // result[i,j,...] corresponds to b[i, :, j, ...]\n const bIdxBefore = resultIdx.slice(0, contractAxisB);\n const bIdxAfter = resultIdx.slice(contractAxisB);\n\n let sum = 0;\n for (let k = 0; k < aSize; k++) {\n const aVal = a.get(k);\n const bIdx = [...bIdxBefore, k, ...bIdxAfter];\n const bVal = b.get(...bIdx);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set(resultIdx, sum);\n }\n\n return result;\n }\n\n // Case 7: ND \u00B7 MD (N,M \u2265 2, not both 2) -> general tensor contraction\n // Result shape: a.shape[:-1] + b.shape[:-2] + b.shape[-1:]\n if (aDim >= 2 && bDim >= 2 && !(aDim === 2 && bDim === 2)) {\n const lastDimA = a.shape[aDim - 1]!;\n const secondLastDimB = b.shape[bDim - 2]!;\n\n if (lastDimA !== secondLastDimB) {\n throw new Error(\n `dot: incompatible shapes ${JSON.stringify(a.shape)} and ${JSON.stringify(b.shape)}`\n );\n }\n\n // Build result shape\n const resultShape = [...a.shape.slice(0, -1), ...b.shape.slice(0, -2), b.shape[bDim - 1]!];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n const aOuterSize = a.shape.slice(0, -1).reduce((acc, dim) => acc * dim, 1);\n const bOuterSize = b.shape.slice(0, -2).reduce((acc, dim) => acc * dim, 1);\n const bLastDim = b.shape[bDim - 1]!;\n const contractionDim = lastDimA;\n\n // Iterate: result[i, j, k] = sum_m a[i, m] * b[j, m, k]\n for (let i = 0; i < aOuterSize; i++) {\n for (let j = 0; j < bOuterSize; j++) {\n for (let k = 0; k < bLastDim; k++) {\n let sum = 0;\n for (let m = 0; m < contractionDim; m++) {\n // Get a[i, m] - need to convert flat index i to multi-dim\n const aIdx = i * contractionDim + m;\n const aVal = a.data[aIdx + a.offset];\n\n // Get b[j, m, k] - need multi-dim indexing\n const bIdx = j * contractionDim * bLastDim + m * bLastDim + k;\n const bVal = b.data[bIdx + b.offset];\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n\n // Set result at the appropriate position\n const resultIdx = i * bOuterSize * bLastDim + j * bLastDim + k;\n result.data[resultIdx] = sum;\n }\n }\n }\n\n return result;\n }\n\n // Should never reach here - all cases covered\n throw new Error(`dot: unexpected combination of dimensions ${aDim}D \u00B7 ${bDim}D`);\n}\n\n/**\n * Matrix multiplication\n * Requires 2D arrays with compatible shapes\n *\n * Automatically detects transposed/non-contiguous arrays via strides\n * and uses appropriate DGEMM transpose parameters.\n *\n * Note: Currently uses float64 precision for all operations.\n * Integer inputs are promoted to float64 (matching NumPy behavior).\n */\nexport function matmul(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n if (a.ndim !== 2 || b.ndim !== 2) {\n throw new Error('matmul requires 2D arrays');\n }\n\n const [m = 0, k = 0] = a.shape;\n const [k2 = 0, n = 0] = b.shape;\n\n if (k !== k2) {\n throw new Error(`matmul shape mismatch: (${m},${k}) @ (${k2},${n})`);\n }\n\n // Determine result dtype (promote inputs, but use float64 for integer types)\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const computeDtype =\n resultDtype.startsWith('int') || resultDtype.startsWith('uint') || resultDtype === 'bool'\n ? 'float64'\n : resultDtype;\n\n // For now, we only support float64 matmul (using dgemm)\n // TODO: Add float32 support using sgemm\n if (computeDtype !== 'float64') {\n throw new Error(`matmul currently only supports float64, got ${computeDtype}`);\n }\n\n // Convert inputs to Float64Array if needed\n let aData =\n a.dtype === 'float64'\n ? (a.data as Float64Array)\n : Float64Array.from(Array.from(a.data as ArrayLike<number>).map(Number));\n let bData =\n b.dtype === 'float64'\n ? (b.data as Float64Array)\n : Float64Array.from(Array.from(b.data as ArrayLike<number>).map(Number));\n\n // Handle offset for sliced arrays (views)\n // If the array has an offset, we need to pass the subarray starting from that offset\n if (a.offset > 0) {\n aData = aData.subarray(a.offset) as Float64Array;\n }\n if (b.offset > 0) {\n bData = bData.subarray(b.offset) as Float64Array;\n }\n\n // Detect array layout from strides\n // Row-major (C-contiguous): row stride > col stride\n // Transposed (F-contiguous or transposed view): col stride > row stride\n const [aStrideRow = 0, aStrideCol = 0] = a.strides;\n const [bStrideRow = 0, bStrideCol = 0] = b.strides;\n\n // Determine if arrays are effectively transposed\n // For a normal MxK array: strides are [K, 1] (row stride = K cols)\n // For a transposed KxM array (viewed as MxK): strides are [1, M] (col stride > row stride)\n const aIsTransposed = aStrideCol > aStrideRow;\n const bIsTransposed = bStrideCol > bStrideRow;\n\n const transA: Transpose = aIsTransposed ? 'transpose' : 'no-transpose';\n const transB: Transpose = bIsTransposed ? 'transpose' : 'no-transpose';\n\n // Determine leading dimensions based on memory layout\n // Leading dimension is the stride of the major dimension in memory\n let lda: number;\n let ldb: number;\n\n if (aIsTransposed) {\n // Array is stored with columns contiguous (F-order or transposed)\n // The leading dimension is how many elements to skip between columns\n lda = aStrideCol;\n } else {\n // Array is row-major (C-order)\n // The leading dimension is the row stride (number of elements per row)\n lda = aStrideRow;\n }\n\n if (bIsTransposed) {\n ldb = bStrideCol;\n } else {\n ldb = bStrideRow;\n }\n\n // Create result array (always row-major)\n const result = ArrayStorage.zeros([m, n], 'float64');\n\n // Call dgemm with detected transpose flags and leading dimensions\n dgemm(\n 'row-major',\n transA,\n transB,\n m,\n n,\n k,\n 1.0, // alpha\n aData,\n lda, // leading dimension of a (accounts for actual memory layout)\n bData,\n ldb, // leading dimension of b (accounts for actual memory layout)\n 0.0, // beta\n result.data as Float64Array,\n n // ldc (result is always row-major with n cols)\n );\n\n return result;\n}\n\n/**\n * Sum along the diagonal of a 2D array\n *\n * Computes the trace (sum of diagonal elements) of a matrix.\n * For non-square matrices, sums along the diagonal up to min(rows, cols).\n *\n * @param a - Input 2D array\n * @returns Sum of diagonal elements\n */\nexport function trace(a: ArrayStorage): number | bigint {\n if (a.ndim !== 2) {\n throw new Error(`trace requires 2D array, got ${a.ndim}D`);\n }\n\n const [rows = 0, cols = 0] = a.shape;\n const diagLen = Math.min(rows, cols);\n\n let sum: number | bigint = 0;\n\n for (let i = 0; i < diagLen; i++) {\n const val = a.get(i, i);\n if (typeof val === 'bigint') {\n sum = (typeof sum === 'bigint' ? sum : BigInt(sum)) + val;\n } else {\n sum = (typeof sum === 'bigint' ? Number(sum) : sum) + val;\n }\n }\n\n return sum;\n}\n\n/**\n * Permute the dimensions of an array\n *\n * Standalone version of NDArray.transpose() method.\n * Returns a view with axes permuted.\n *\n * @param a - Input array\n * @param axes - Optional permutation of axes (defaults to reverse order)\n * @returns Transposed view\n */\nexport function transpose(a: ArrayStorage, axes?: number[]): ArrayStorage {\n return shapeOps.transpose(a, axes);\n}\n\n/**\n * Inner product of two arrays\n *\n * Computes sum product over the LAST axes of both a and b.\n * - 1D \u00B7 1D: Same as dot (ordinary inner product) \u2192 scalar\n * - ND \u00B7 MD: Contracts last dimension of each \u2192 (*a.shape[:-1], *b.shape[:-1])\n *\n * Different from dot: always uses last axis of BOTH arrays.\n *\n * @param a - First array\n * @param b - Second array\n * @returns Inner product result\n */\nexport function inner(a: ArrayStorage, b: ArrayStorage): ArrayStorage | number | bigint {\n const aDim = a.ndim;\n const bDim = b.ndim;\n\n // Last dimensions must match\n const aLastDim = a.shape[aDim - 1]!;\n const bLastDim = b.shape[bDim - 1]!;\n\n if (aLastDim !== bLastDim) {\n throw new Error(\n `inner: incompatible shapes - last dimensions ${aLastDim} and ${bLastDim} don't match`\n );\n }\n\n // Special case: both 1D -> scalar\n if (aDim === 1 && bDim === 1) {\n return dot(a, b) as number;\n }\n\n // General case: result shape is a.shape[:-1] + b.shape[:-1]\n const resultShape = [...a.shape.slice(0, -1), ...b.shape.slice(0, -1)];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n const aOuterSize = aDim === 1 ? 1 : a.shape.slice(0, -1).reduce((acc, dim) => acc * dim, 1);\n const bOuterSize = bDim === 1 ? 1 : b.shape.slice(0, -1).reduce((acc, dim) => acc * dim, 1);\n const contractionDim = aLastDim;\n\n // Compute: result[i, j] = sum_k a[i, k] * b[j, k]\n for (let i = 0; i < aOuterSize; i++) {\n for (let j = 0; j < bOuterSize; j++) {\n let sum = 0;\n for (let k = 0; k < contractionDim; k++) {\n // Get a[i, k] and b[j, k]\n const aIdx = aDim === 1 ? k : i * contractionDim + k;\n const bIdx = bDim === 1 ? k : j * contractionDim + k;\n const aVal = a.data[aIdx + a.offset];\n const bVal = b.data[bIdx + b.offset];\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n\n // Set result\n if (resultShape.length === 0) {\n // Scalar result\n return sum;\n }\n const resultIdx = aOuterSize === 1 ? j : i * bOuterSize + j;\n result.data[resultIdx] = sum;\n }\n }\n\n return result;\n}\n\n/**\n * Outer product of two vectors\n *\n * Computes out[i, j] = a[i] * b[j]\n * Input arrays are flattened if not 1D.\n *\n * @param a - First input (flattened to 1D)\n * @param b - Second input (flattened to 1D)\n * @returns 2D array of shape (a.size, b.size)\n */\nexport function outer(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n // Flatten inputs to 1D\n const aFlat = a.ndim === 1 ? a : shapeOps.ravel(a);\n const bFlat = b.ndim === 1 ? b : shapeOps.ravel(b);\n\n const m = aFlat.size;\n const n = bFlat.size;\n\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([m, n], resultDtype);\n\n // Compute outer product: result[i,j] = a[i] * b[j]\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n const aVal = aFlat.get(i);\n const bVal = bFlat.get(j);\n\n let product;\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n product = aVal * bVal;\n } else {\n product = Number(aVal) * Number(bVal);\n }\n\n result.set([i, j], product);\n }\n }\n\n return result;\n}\n\n/**\n * Tensor dot product along specified axes\n *\n * Computes sum product over specified axes.\n *\n * @param a - First array\n * @param b - Second array\n * @param axes - Axes to contract:\n * - Integer N: Contract last N axes of a with first N of b\n * - [a_axes, b_axes]: Contract specified axes\n * @returns Tensor dot product\n */\nexport function tensordot(\n a: ArrayStorage,\n b: ArrayStorage,\n axes: number | [number[], number[]]\n): ArrayStorage | number | bigint {\n let aAxes: number[];\n let bAxes: number[];\n\n if (typeof axes === 'number') {\n // Contract last N axes of a with first N of b\n const N = axes;\n if (N < 0) {\n throw new Error('tensordot: axes must be non-negative');\n }\n if (N > a.ndim || N > b.ndim) {\n throw new Error('tensordot: axes exceeds array dimensions');\n }\n\n // Last N axes of a\n aAxes = Array.from({ length: N }, (_, i) => a.ndim - N + i);\n // First N axes of b\n bAxes = Array.from({ length: N }, (_, i) => i);\n } else {\n [aAxes, bAxes] = axes;\n if (aAxes.length !== bAxes.length) {\n throw new Error('tensordot: axes lists must have same length');\n }\n }\n\n // Validate axes and check dimension compatibility\n for (let i = 0; i < aAxes.length; i++) {\n const aAxis = aAxes[i]!;\n const bAxis = bAxes[i]!;\n if (aAxis < 0 || aAxis >= a.ndim || bAxis < 0 || bAxis >= b.ndim) {\n throw new Error('tensordot: axis out of bounds');\n }\n if (a.shape[aAxis] !== b.shape[bAxis]) {\n throw new Error(\n `tensordot: shape mismatch on axes ${aAxis} and ${bAxis}: ${a.shape[aAxis]} != ${b.shape[bAxis]}`\n );\n }\n }\n\n // Separate axes into contracted and free axes\n const aFreeAxes: number[] = [];\n const bFreeAxes: number[] = [];\n\n for (let i = 0; i < a.ndim; i++) {\n if (!aAxes.includes(i)) {\n aFreeAxes.push(i);\n }\n }\n for (let i = 0; i < b.ndim; i++) {\n if (!bAxes.includes(i)) {\n bFreeAxes.push(i);\n }\n }\n\n // Build result shape: free axes of a + free axes of b\n const resultShape = [\n ...aFreeAxes.map((ax) => a.shape[ax]!),\n ...bFreeAxes.map((ax) => b.shape[ax]!),\n ];\n\n // Special case: no free axes (full contraction) -> scalar result\n if (resultShape.length === 0) {\n let sum = 0;\n // Iterate over all combinations of contracted axes\n const contractSize = aAxes.map((ax) => a.shape[ax]!).reduce((acc, dim) => acc * dim, 1);\n\n for (let i = 0; i < contractSize; i++) {\n // Convert flat index to contracted indices\n let temp = i;\n const contractedIdx: number[] = new Array(aAxes.length);\n for (let j = aAxes.length - 1; j >= 0; j--) {\n const ax = aAxes[j]!;\n contractedIdx[j] = temp % a.shape[ax]!;\n temp = Math.floor(temp / a.shape[ax]!);\n }\n\n // Build full indices for a and b\n const aIdx: number[] = new Array(a.ndim);\n const bIdx: number[] = new Array(b.ndim);\n\n for (let j = 0; j < aAxes.length; j++) {\n aIdx[aAxes[j]!] = contractedIdx[j]!;\n }\n for (let j = 0; j < bAxes.length; j++) {\n bIdx[bAxes[j]!] = contractedIdx[j]!;\n }\n\n const aVal = a.get(...aIdx);\n const bVal = b.get(...bIdx);\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n return sum;\n }\n\n // General case: with free axes\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n const resultSize = resultShape.reduce((acc, dim) => acc * dim, 1);\n const contractSize = aAxes.map((ax) => a.shape[ax]!).reduce((acc, dim) => acc * dim, 1);\n\n // Iterate over all result positions\n for (let resIdx = 0; resIdx < resultSize; resIdx++) {\n // Convert flat result index to multi-dimensional\n let temp = resIdx;\n const resultIndices: number[] = [];\n for (let i = resultShape.length - 1; i >= 0; i--) {\n resultIndices[i] = temp % resultShape[i]!;\n temp = Math.floor(temp / resultShape[i]!);\n }\n\n // Extract indices for a's free axes and b's free axes\n const aFreeIndices = resultIndices.slice(0, aFreeAxes.length);\n const bFreeIndices = resultIndices.slice(aFreeAxes.length);\n\n let sum = 0;\n\n // Sum over all contracted axes\n for (let c = 0; c < contractSize; c++) {\n // Convert flat contracted index to multi-dimensional\n temp = c;\n const contractedIndices: number[] = [];\n for (let i = aAxes.length - 1; i >= 0; i--) {\n const ax = aAxes[i]!;\n contractedIndices[i] = temp % a.shape[ax]!;\n temp = Math.floor(temp / a.shape[ax]!);\n }\n\n // Build full indices for a and b\n const aFullIdx: number[] = new Array(a.ndim);\n const bFullIdx: number[] = new Array(b.ndim);\n\n // Fill in free axes\n for (let i = 0; i < aFreeAxes.length; i++) {\n aFullIdx[aFreeAxes[i]!] = aFreeIndices[i]!;\n }\n for (let i = 0; i < bFreeAxes.length; i++) {\n bFullIdx[bFreeAxes[i]!] = bFreeIndices[i]!;\n }\n\n // Fill in contracted axes\n for (let i = 0; i < aAxes.length; i++) {\n aFullIdx[aAxes[i]!] = contractedIndices[i]!;\n bFullIdx[bAxes[i]!] = contractedIndices[i]!;\n }\n\n const aVal = a.get(...aFullIdx);\n const bVal = b.get(...bFullIdx);\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n\n result.set(resultIndices, sum);\n }\n\n return result;\n}\n\n/**\n * Extract a diagonal or construct a diagonal array.\n *\n * NumPy behavior:\n * - For 2D arrays: extract the k-th diagonal\n * - For ND arrays (N >= 2): extract diagonal from the axes specified\n * - Returns a view when possible, copy otherwise\n *\n * @param a - Input array (must be at least 2D)\n * @param offset - Offset of the diagonal from the main diagonal (default: 0)\n * - offset > 0: diagonal above main diagonal\n * - offset < 0: diagonal below main diagonal\n * @param axis1 - First axis for ND arrays (default: 0)\n * @param axis2 - Second axis for ND arrays (default: 1)\n * @returns Array containing the diagonal elements\n */\nexport function diagonal(\n a: ArrayStorage,\n offset: number = 0,\n axis1: number = 0,\n axis2: number = 1\n): ArrayStorage {\n const shape = a.shape;\n const ndim = shape.length;\n\n if (ndim < 2) {\n throw new Error('diagonal requires an array of at least two dimensions');\n }\n\n // Normalize negative axes\n const ax1 = axis1 < 0 ? ndim + axis1 : axis1;\n const ax2 = axis2 < 0 ? ndim + axis2 : axis2;\n\n if (ax1 < 0 || ax1 >= ndim || ax2 < 0 || ax2 >= ndim) {\n throw new Error('axis out of bounds');\n }\n\n if (ax1 === ax2) {\n throw new Error('axis1 and axis2 cannot be the same');\n }\n\n // Get dimensions of the two axes\n const dim1 = shape[ax1]!;\n const dim2 = shape[ax2]!;\n\n // Calculate diagonal length\n let diagLen: number;\n if (offset >= 0) {\n diagLen = Math.max(0, Math.min(dim1, dim2 - offset));\n } else {\n diagLen = Math.max(0, Math.min(dim1 + offset, dim2));\n }\n\n // Build output shape: remove axis1 and axis2, append diagLen\n const outShape: number[] = [];\n for (let i = 0; i < ndim; i++) {\n if (i !== ax1 && i !== ax2) {\n outShape.push(shape[i]!);\n }\n }\n outShape.push(diagLen);\n\n // Create output array\n const result = ArrayStorage.zeros(outShape, a.dtype);\n\n // Extract diagonal elements\n // We need to iterate over all combinations of indices for other dimensions\n const otherDims = shape.filter((_, i) => i !== ax1 && i !== ax2);\n const otherSize = otherDims.reduce((acc, d) => acc * d, 1);\n\n for (let otherIdx = 0; otherIdx < otherSize; otherIdx++) {\n // Convert flat index to multi-dimensional indices for \"other\" dimensions\n let temp = otherIdx;\n const otherIndices: number[] = [];\n for (let i = otherDims.length - 1; i >= 0; i--) {\n otherIndices.unshift(temp % otherDims[i]!);\n temp = Math.floor(temp / otherDims[i]!);\n }\n\n // Extract diagonal for this slice\n for (let d = 0; d < diagLen; d++) {\n // Build source indices\n const srcIndices: number[] = new Array(ndim);\n let otherIdx2 = 0;\n for (let i = 0; i < ndim; i++) {\n if (i === ax1) {\n srcIndices[i] = offset >= 0 ? d : d - offset;\n } else if (i === ax2) {\n srcIndices[i] = offset >= 0 ? d + offset : d;\n } else {\n srcIndices[i] = otherIndices[otherIdx2++]!;\n }\n }\n\n // Build destination indices\n const dstIndices = [...otherIndices, d];\n\n // Copy element\n const value = a.get(...srcIndices);\n result.set(dstIndices, value);\n }\n }\n\n return result;\n}\n\n/**\n * Einstein summation convention\n *\n * Performs tensor contractions and reductions using Einstein summation notation.\n *\n * Examples:\n * - 'ij,jk->ik': matrix multiplication\n * - 'i,i->': dot product (inner product)\n * - 'ij->ji': transpose\n * - 'ii->': trace\n * - 'ij->j': sum over first axis\n * - 'ijk,ikl->ijl': batched matrix multiplication\n *\n * @param subscripts - Einstein summation subscripts (e.g., 'ij,jk->ik')\n * @param operands - Input arrays\n * @returns Result of the Einstein summation\n */\nexport function einsum(\n subscripts: string,\n ...operands: ArrayStorage[]\n): ArrayStorage | number | bigint {\n // Parse the subscripts\n const arrowMatch = subscripts.indexOf('->');\n\n let inputSubscripts: string;\n let outputSubscript: string;\n\n if (arrowMatch === -1) {\n // Implicit output: collect unique indices not repeated\n inputSubscripts = subscripts;\n outputSubscript = inferOutputSubscript(inputSubscripts);\n } else {\n inputSubscripts = subscripts.slice(0, arrowMatch);\n outputSubscript = subscripts.slice(arrowMatch + 2);\n }\n\n // Parse input subscripts into individual operand subscripts\n const operandSubscripts = inputSubscripts.split(',').map((s) => s.trim());\n\n if (operandSubscripts.length !== operands.length) {\n throw new Error(\n `einsum: expected ${operandSubscripts.length} operands, got ${operands.length}`\n );\n }\n\n // Validate subscripts and build index dimension map\n const indexDims = new Map<string, number>();\n\n for (let i = 0; i < operands.length; i++) {\n const sub = operandSubscripts[i]!;\n const op = operands[i]!;\n\n if (sub.length !== op.ndim) {\n throw new Error(\n `einsum: operand ${i} has ${op.ndim} dimensions but subscript '${sub}' has ${sub.length} indices`\n );\n }\n\n for (let j = 0; j < sub.length; j++) {\n const idx = sub[j]!;\n const dim = op.shape[j]!;\n\n if (indexDims.has(idx)) {\n if (indexDims.get(idx) !== dim) {\n throw new Error(\n `einsum: size mismatch for index '${idx}': ${indexDims.get(idx)} vs ${dim}`\n );\n }\n } else {\n indexDims.set(idx, dim);\n }\n }\n }\n\n // Validate output subscript\n for (const idx of outputSubscript) {\n if (!indexDims.has(idx)) {\n throw new Error(`einsum: output subscript contains unknown index '${idx}'`);\n }\n }\n\n // Identify summation indices (in inputs but not in output)\n const outputIndices = new Set(outputSubscript);\n const allInputIndices = new Set<string>();\n for (const sub of operandSubscripts) {\n for (const idx of sub) {\n allInputIndices.add(idx);\n }\n }\n\n const sumIndices: string[] = [];\n for (const idx of allInputIndices) {\n if (!outputIndices.has(idx)) {\n sumIndices.push(idx);\n }\n }\n\n // ========================================\n // FAST PATHS: Detect common patterns and delegate to optimized implementations\n // ========================================\n\n // Pattern: Matrix multiplication \"ij,jk->ik\" or similar\n if (operands.length === 2 && operandSubscripts.length === 2) {\n const [sub1, sub2] = operandSubscripts;\n const [op1, op2] = operands;\n\n // Check for matmul pattern: two 2D arrays, one shared index\n if (\n sub1!.length === 2 &&\n sub2!.length === 2 &&\n outputSubscript.length === 2 &&\n op1!.ndim === 2 &&\n op2!.ndim === 2\n ) {\n const [i1, j1] = [sub1![0]!, sub1![1]!];\n const [i2, j2] = [sub2![0]!, sub2![1]!];\n const [o1, o2] = [outputSubscript[0]!, outputSubscript[1]!];\n\n // Pattern: \"ij,jk->ik\" (standard matmul)\n if (i1 === o1 && j2 === o2 && j1 === i2 && sumIndices.length === 1 && sumIndices[0] === j1) {\n return matmul(op1!, op2!);\n }\n\n // Pattern: \"ik,kj->ij\" (matmul with different index names)\n if (i1 === o1 && j2 === o2 && j1 === i2 && sumIndices.length === 1 && sumIndices[0] === j1) {\n return matmul(op1!, op2!);\n }\n\n // Pattern: \"ji,jk->ik\" (transpose A then multiply)\n if (j1 === o1 && j2 === o2 && i1 === i2 && sumIndices.length === 1 && sumIndices[0] === i1) {\n const op1T = transpose(op1!);\n return matmul(op1T, op2!);\n }\n\n // Pattern: \"ij,kj->ik\" (transpose B then multiply)\n if (i1 === o1 && i2 === o2 && j1 === j2 && sumIndices.length === 1 && sumIndices[0] === j1) {\n const op2T = transpose(op2!);\n return matmul(op1!, op2T);\n }\n }\n\n // Check for dot product pattern: two 1D arrays \"i,i->\" or \"i,i->scalar\"\n if (\n sub1!.length === 1 &&\n sub2!.length === 1 &&\n sub1 === sub2 &&\n outputSubscript.length === 0 &&\n op1!.ndim === 1 &&\n op2!.ndim === 1\n ) {\n return computeEinsumScalar(operands, operandSubscripts, sumIndices, indexDims);\n }\n\n // Check for outer product pattern: \"i,j->ij\"\n if (\n sub1 &&\n sub2 &&\n sub1.length === 1 &&\n sub2.length === 1 &&\n outputSubscript.length === 2 &&\n outputSubscript === sub1 + sub2 &&\n sumIndices.length === 0 &&\n op1!.ndim === 1 &&\n op2!.ndim === 1\n ) {\n return outer(op1!, op2!);\n }\n }\n\n // Pattern: Single operand trace \"ii->\"\n if (operands.length === 1 && operandSubscripts[0]!.length === 2 && outputSubscript.length === 0) {\n const sub = operandSubscripts[0]!;\n if (sub[0] === sub[1]) {\n // This is a trace operation\n const op = operands[0]!;\n if (op.ndim === 2) {\n return computeEinsumScalar(operands, operandSubscripts, sumIndices, indexDims);\n }\n }\n }\n\n // ========================================\n // END FAST PATHS - Fall through to generic implementation\n // ========================================\n\n // Build output shape\n const outputShape = Array.from(outputSubscript).map((idx) => indexDims.get(idx)!);\n\n // Special case: scalar output\n if (outputShape.length === 0) {\n return computeEinsumScalar(operands, operandSubscripts, sumIndices, indexDims);\n }\n\n // Determine result dtype\n let resultDtype = operands[0]!.dtype;\n for (let i = 1; i < operands.length; i++) {\n resultDtype = promoteDTypes(resultDtype, operands[i]!.dtype);\n }\n\n // Create output array\n const result = ArrayStorage.zeros(outputShape, resultDtype);\n\n // Compute output size\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n\n // Compute sum range\n let sumSize = 1;\n for (const idx of sumIndices) {\n sumSize *= indexDims.get(idx)!;\n }\n\n // Iterate over all output positions\n for (let outIdx = 0; outIdx < outputSize; outIdx++) {\n // Convert flat index to multi-dimensional output index\n const outMultiIdx = flatToMulti(outIdx, outputShape);\n\n // Build index assignment for output indices\n const indexValues = new Map<string, number>();\n for (let i = 0; i < outputSubscript.length; i++) {\n indexValues.set(outputSubscript[i]!, outMultiIdx[i]!);\n }\n\n // Sum over summation indices\n let sum = 0;\n for (let sumIdx = 0; sumIdx < sumSize; sumIdx++) {\n // Assign values to summation indices\n let temp = sumIdx;\n for (let i = sumIndices.length - 1; i >= 0; i--) {\n const idx = sumIndices[i]!;\n const dim = indexDims.get(idx)!;\n indexValues.set(idx, temp % dim);\n temp = Math.floor(temp / dim);\n }\n\n // Compute product of all operand values\n let product = 1;\n for (let i = 0; i < operands.length; i++) {\n const op = operands[i]!;\n const sub = operandSubscripts[i]!;\n\n // Build operand index\n const opIdx: number[] = [];\n for (const idx of sub) {\n opIdx.push(indexValues.get(idx)!);\n }\n\n const val = op.get(...opIdx);\n product *= Number(val);\n }\n\n sum += product;\n }\n\n result.set(outMultiIdx, sum);\n }\n\n return result;\n}\n\n/**\n * Infer output subscript for implicit einsum notation\n * @private\n */\nfunction inferOutputSubscript(inputSubscripts: string): string {\n // Count occurrences of each index\n const counts = new Map<string, number>();\n const operandSubscripts = inputSubscripts.split(',');\n\n for (const sub of operandSubscripts) {\n for (const idx of sub.trim()) {\n counts.set(idx, (counts.get(idx) || 0) + 1);\n }\n }\n\n // Output contains indices that appear exactly once, sorted alphabetically\n const outputIndices: string[] = [];\n for (const [idx, count] of counts) {\n if (count === 1) {\n outputIndices.push(idx);\n }\n }\n\n return outputIndices.sort().join('');\n}\n\n/**\n * Compute einsum result when output is a scalar\n * @private\n */\nfunction computeEinsumScalar(\n operands: ArrayStorage[],\n operandSubscripts: string[],\n sumIndices: string[],\n indexDims: Map<string, number>\n): number {\n // All indices are summation indices\n let sumSize = 1;\n for (const idx of sumIndices) {\n sumSize *= indexDims.get(idx)!;\n }\n\n let sum = 0;\n\n for (let sumIdx = 0; sumIdx < sumSize; sumIdx++) {\n // Assign values to summation indices\n const indexValues = new Map<string, number>();\n let temp = sumIdx;\n for (let i = sumIndices.length - 1; i >= 0; i--) {\n const idx = sumIndices[i]!;\n const dim = indexDims.get(idx)!;\n indexValues.set(idx, temp % dim);\n temp = Math.floor(temp / dim);\n }\n\n // Compute product of all operand values\n let product = 1;\n for (let i = 0; i < operands.length; i++) {\n const op = operands[i]!;\n const sub = operandSubscripts[i]!;\n\n // Build operand index\n const opIdx: number[] = [];\n for (const idx of sub) {\n opIdx.push(indexValues.get(idx)!);\n }\n\n const val = op.get(...opIdx);\n product *= Number(val);\n }\n\n sum += product;\n }\n\n return sum;\n}\n\n/**\n * Convert flat index to multi-dimensional index\n * @private\n */\nfunction flatToMulti(flatIdx: number, shape: number[]): number[] {\n const result: number[] = new Array(shape.length);\n let temp = flatIdx;\n\n for (let i = shape.length - 1; i >= 0; i--) {\n result[i] = temp % shape[i]!;\n temp = Math.floor(temp / shape[i]!);\n }\n\n return result;\n}\n\n/**\n * Kronecker product of two arrays.\n *\n * Computes the Kronecker product, a composite array made of blocks of the\n * second array scaled by the elements of the first.\n *\n * NumPy behavior:\n * - If both inputs are vectors (1D), output is also a vector\n * - If both inputs are 2D matrices, output shape is (m1*m2, n1*n2)\n * - General case: broadcasts shapes then computes block product\n *\n * @param a - First input array\n * @param b - Second input array\n * @returns Kronecker product of a and b\n */\nexport function kron(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const aShape = a.shape;\n const bShape = b.shape;\n const aNdim = aShape.length;\n const bNdim = bShape.length;\n\n // Promote dtypes\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n\n // Determine output shape\n const ndim = Math.max(aNdim, bNdim);\n const outShape: number[] = new Array(ndim);\n\n // Pad shapes with ones on the left if needed\n const aPadded: number[] = new Array(ndim).fill(1);\n const bPadded: number[] = new Array(ndim).fill(1);\n\n for (let i = 0; i < aNdim; i++) {\n aPadded[ndim - aNdim + i] = aShape[i]!;\n }\n for (let i = 0; i < bNdim; i++) {\n bPadded[ndim - bNdim + i] = bShape[i]!;\n }\n\n // Output shape is element-wise product\n for (let i = 0; i < ndim; i++) {\n outShape[i] = aPadded[i]! * bPadded[i]!;\n }\n\n // Create result array\n const result = ArrayStorage.zeros(outShape, resultDtype);\n\n // Compute total number of elements in each array\n const aSize = aShape.reduce((acc, d) => acc * d, 1);\n const bSize = bShape.reduce((acc, d) => acc * d, 1);\n\n // Nested loop approach: for each element in a, scale all of b\n for (let aIdx = 0; aIdx < aSize; aIdx++) {\n // Convert flat index to multi-dimensional index for a\n let temp = aIdx;\n const aIndices: number[] = new Array(aNdim);\n for (let i = aNdim - 1; i >= 0; i--) {\n aIndices[i] = temp % aShape[i]!;\n temp = Math.floor(temp / aShape[i]!);\n }\n\n // Pad aIndices to match ndim\n const aIndicesPadded: number[] = new Array(ndim).fill(0);\n for (let i = 0; i < aNdim; i++) {\n aIndicesPadded[ndim - aNdim + i] = aIndices[i]!;\n }\n\n const aVal = a.get(...aIndices);\n\n // For each element in b\n for (let bIdx = 0; bIdx < bSize; bIdx++) {\n // Convert flat index to multi-dimensional index for b\n let temp2 = bIdx;\n const bIndices: number[] = new Array(bNdim);\n for (let i = bNdim - 1; i >= 0; i--) {\n bIndices[i] = temp2 % bShape[i]!;\n temp2 = Math.floor(temp2 / bShape[i]!);\n }\n\n // Pad bIndices to match ndim\n const bIndicesPadded: number[] = new Array(ndim).fill(0);\n for (let i = 0; i < bNdim; i++) {\n bIndicesPadded[ndim - bNdim + i] = bIndices[i]!;\n }\n\n const bVal = b.get(...bIndices);\n\n // Compute output index: each dimension is aIdx*bDim + bIdx\n const outIndices: number[] = new Array(ndim);\n for (let i = 0; i < ndim; i++) {\n outIndices[i] = aIndicesPadded[i]! * bPadded[i]! + bIndicesPadded[i]!;\n }\n\n // Compute product and store\n const product =\n typeof aVal === 'bigint' || typeof bVal === 'bigint'\n ? BigInt(Number(aVal)) * BigInt(Number(bVal))\n : Number(aVal) * Number(bVal);\n\n result.set(outIndices, product);\n }\n }\n\n return result;\n}\n", "/**\n * Exponential, logarithmic, and power operations\n *\n * Pure functions for element-wise exponential operations:\n * exp, log, sqrt, power, etc.\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { elementwiseUnaryOp, elementwiseBinaryOp } from '../internal/compute';\nimport { isBigIntDType } from '../core/dtype';\n\n/**\n * Square root of each element\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with sqrt applied\n */\nexport function sqrt(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.sqrt, false); // false = promote integers to float64\n}\n\n/**\n * Raise elements to power\n * NumPy behavior: Promotes to float64 for integer types with non-integer exponents\n *\n * @param a - Base array storage\n * @param b - Exponent (array storage or scalar)\n * @returns Result storage with power applied\n */\nexport function power(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return powerScalar(a, b);\n }\n return elementwiseBinaryOp(a, b, Math.pow, 'power');\n}\n\n/**\n * Power with scalar exponent (optimized path)\n * @private\n */\nfunction powerScalar(storage: ArrayStorage, exponent: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // NumPy behavior: integer ** integer stays integer if exponent >= 0\n // integer ** negative or float exponent promotes to float64\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const needsFloatPromotion = isIntegerType && (exponent < 0 || !Number.isInteger(exponent));\n const resultDtype = needsFloatPromotion ? 'float64' : dtype;\n\n // Create result with appropriate dtype\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n if (isBigIntDType(resultDtype) && Number.isInteger(exponent) && exponent >= 0) {\n // BigInt ** positive integer stays BigInt\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! ** BigInt(exponent);\n }\n } else {\n // BigInt ** negative or float promotes to float64\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.pow(Number(data[i]!), exponent);\n }\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.pow(Number(data[i]!), exponent);\n }\n }\n\n return result;\n}\n", "/**\n * Trigonometric operations\n *\n * Pure functions for element-wise trigonometric operations:\n * sin, cos, tan, arcsin, arccos, arctan, arctan2, hypot, degrees, radians\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { elementwiseUnaryOp } from '../internal/compute';\nimport { isBigIntDType } from '../core/dtype';\n\n/**\n * Sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Result storage with sin applied\n */\nexport function sin(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.sin, false);\n}\n\n/**\n * Cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Result storage with cos applied\n */\nexport function cos(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.cos, false);\n}\n\n/**\n * Tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Result storage with tan applied\n */\nexport function tan(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.tan, false);\n}\n\n/**\n * Inverse sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values in range [-1, 1])\n * @returns Result storage with arcsin applied (radians)\n */\nexport function arcsin(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.asin, false);\n}\n\n/**\n * Inverse cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values in range [-1, 1])\n * @returns Result storage with arccos applied (radians)\n */\nexport function arccos(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.acos, false);\n}\n\n/**\n * Inverse tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with arctan applied (radians)\n */\nexport function arctan(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.atan, false);\n}\n\n/**\n * Element-wise arc tangent of x1/x2 choosing the quadrant correctly.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param x1 - y-coordinates\n * @param x2 - x-coordinates (array storage or scalar)\n * @returns Angle in radians between -\u03C0 and \u03C0\n */\nexport function arctan2(x1: ArrayStorage, x2: ArrayStorage | number): ArrayStorage {\n if (typeof x2 === 'number') {\n return arctan2Scalar(x1, x2);\n }\n return arctan2Array(x1, x2);\n}\n\n/**\n * arctan2 with array x2 (always returns float64 for non-float32 inputs)\n * @private\n */\nfunction arctan2Array(x1: ArrayStorage, x2: ArrayStorage): ArrayStorage {\n const shape = Array.from(x1.shape);\n const size = x1.size;\n const dtype1 = x1.dtype;\n const dtype2 = x2.dtype;\n\n // Always promote to float64 for arctan2 (matching NumPy behavior)\n // Only preserve float32 if both inputs are float32\n const resultDtype = dtype1 === 'float32' && dtype2 === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n for (let i = 0; i < size; i++) {\n const val1 = isBigIntDType(dtype1) ? Number(x1.data[i]!) : Number(x1.data[i]!);\n const val2 = isBigIntDType(dtype2) ? Number(x2.data[i]!) : Number(x2.data[i]!);\n resultData[i] = Math.atan2(val1, val2);\n }\n\n return result;\n}\n\n/**\n * arctan2 with scalar x2 (optimized path)\n * @private\n */\nfunction arctan2Scalar(storage: ArrayStorage, x2: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Always promote to float64 for trig operations\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.atan2(Number(data[i]!), x2);\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.atan2(Number(data[i]!), x2);\n }\n }\n\n return result;\n}\n\n/**\n * Given the \"legs\" of a right triangle, return its hypotenuse.\n * Equivalent to sqrt(x1**2 + x2**2), element-wise.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param x1 - First leg\n * @param x2 - Second leg (array storage or scalar)\n * @returns Hypotenuse\n */\nexport function hypot(x1: ArrayStorage, x2: ArrayStorage | number): ArrayStorage {\n if (typeof x2 === 'number') {\n return hypotScalar(x1, x2);\n }\n return hypotArray(x1, x2);\n}\n\n/**\n * hypot with array x2 (always returns float64 for non-float32 inputs)\n * @private\n */\nfunction hypotArray(x1: ArrayStorage, x2: ArrayStorage): ArrayStorage {\n const shape = Array.from(x1.shape);\n const size = x1.size;\n const dtype1 = x1.dtype;\n const dtype2 = x2.dtype;\n\n // Always promote to float64 for hypot (matching NumPy behavior)\n // Only preserve float32 if both inputs are float32\n const resultDtype = dtype1 === 'float32' && dtype2 === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n for (let i = 0; i < size; i++) {\n const val1 = isBigIntDType(dtype1) ? Number(x1.data[i]!) : Number(x1.data[i]!);\n const val2 = isBigIntDType(dtype2) ? Number(x2.data[i]!) : Number(x2.data[i]!);\n resultData[i] = Math.hypot(val1, val2);\n }\n\n return result;\n}\n\n/**\n * hypot with scalar x2 (optimized path)\n * @private\n */\nfunction hypotScalar(storage: ArrayStorage, x2: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Always promote to float64 for trig operations\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.hypot(Number(data[i]!), x2);\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.hypot(Number(data[i]!), x2);\n }\n }\n\n return result;\n}\n\n/**\n * Convert angles from radians to degrees.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Angles in degrees\n */\nexport function degrees(a: ArrayStorage): ArrayStorage {\n const factor = 180 / Math.PI;\n return elementwiseUnaryOp(a, (x) => x * factor, false);\n}\n\n/**\n * Convert angles from degrees to radians.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in degrees)\n * @returns Angles in radians\n */\nexport function radians(a: ArrayStorage): ArrayStorage {\n const factor = Math.PI / 180;\n return elementwiseUnaryOp(a, (x) => x * factor, false);\n}\n\n/**\n * Convert angles from degrees to radians (alias for radians).\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in degrees)\n * @returns Angles in radians\n */\nexport function deg2rad(a: ArrayStorage): ArrayStorage {\n return radians(a);\n}\n\n/**\n * Convert angles from radians to degrees (alias for degrees).\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Angles in degrees\n */\nexport function rad2deg(a: ArrayStorage): ArrayStorage {\n return degrees(a);\n}\n", "/**\n * Hyperbolic operations\n *\n * Pure functions for element-wise hyperbolic operations:\n * sinh, cosh, tanh, arcsinh, arccosh, arctanh\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { elementwiseUnaryOp } from '../internal/compute';\n\n/**\n * Hyperbolic sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with sinh applied\n */\nexport function sinh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.sinh, false);\n}\n\n/**\n * Hyperbolic cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with cosh applied\n */\nexport function cosh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.cosh, false);\n}\n\n/**\n * Hyperbolic tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with tanh applied\n */\nexport function tanh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.tanh, false);\n}\n\n/**\n * Inverse hyperbolic sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with arcsinh applied\n */\nexport function arcsinh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.asinh, false);\n}\n\n/**\n * Inverse hyperbolic cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values >= 1)\n * @returns Result storage with arccosh applied\n */\nexport function arccosh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.acosh, false);\n}\n\n/**\n * Inverse hyperbolic tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values in range (-1, 1))\n * @returns Result storage with arctanh applied\n */\nexport function arctanh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.atanh, false);\n}\n", "/**\n * Advanced array operations\n *\n * Broadcasting, indexing, and comparison functions.\n * @module ops/advanced\n */\n\nimport { ArrayStorage, computeStrides } from '../core/storage';\nimport { getTypedArrayConstructor, isBigIntDType, type TypedArray } from '../core/dtype';\nimport { computeBroadcastShape, broadcastTo, broadcastShapes } from '../core/broadcasting';\n\n/**\n * Broadcast an array to a given shape\n * Returns a read-only view on the original array\n */\nexport function broadcast_to(storage: ArrayStorage, targetShape: number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const targetNdim = targetShape.length;\n\n if (targetNdim < ndim) {\n throw new Error(`input operand has more dimensions than allowed by the axis remapping`);\n }\n\n // Validate that broadcasting is possible\n const broadcastedShape = computeBroadcastShape([Array.from(shape), targetShape]);\n if (broadcastedShape === null) {\n throw new Error(\n `operands could not be broadcast together with shape (${shape.join(',')}) (${targetShape.join(',')})`\n );\n }\n\n // Check result matches target\n for (let i = 0; i < targetNdim; i++) {\n if (broadcastedShape[i] !== targetShape[i]) {\n throw new Error(\n `operands could not be broadcast together with shape (${shape.join(',')}) (${targetShape.join(',')})`\n );\n }\n }\n\n return broadcastTo(storage, targetShape);\n}\n\n/**\n * Broadcast multiple arrays to a common shape\n * Returns views on the original arrays\n */\nexport function broadcast_arrays(storages: ArrayStorage[]): ArrayStorage[] {\n if (storages.length === 0) {\n return [];\n }\n\n if (storages.length === 1) {\n return [storages[0]!];\n }\n\n // Compute broadcast shape\n const shapes = storages.map((s) => Array.from(s.shape));\n const targetShape = computeBroadcastShape(shapes);\n\n if (targetShape === null) {\n throw new Error(\n `operands could not be broadcast together with shapes ${shapes.map((s) => `(${s.join(',')})`).join(' ')}`\n );\n }\n\n // Broadcast each array to the target shape\n return storages.map((s) => broadcastTo(s, targetShape));\n}\n\n/**\n * Compute the broadcast shape for multiple shapes\n * Re-export from core/broadcasting for convenience\n */\nexport { broadcastShapes as broadcast_shapes };\n\n/**\n * Take elements from an array along an axis\n */\nexport function take(storage: ArrayStorage, indices: number[], axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n if (axis === undefined) {\n // Flatten and take\n const flatSize = storage.size;\n\n // Validate indices\n for (const idx of indices) {\n const normalizedIdx = idx < 0 ? flatSize + idx : idx;\n if (normalizedIdx < 0 || normalizedIdx >= flatSize) {\n throw new Error(`index ${idx} is out of bounds for axis 0 with size ${flatSize}`);\n }\n }\n\n // Create output array\n const outputSize = indices.length;\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot take from array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n for (let i = 0; i < outputSize; i++) {\n let idx = indices[i]!;\n if (idx < 0) idx = flatSize + idx;\n const value = storage.iget(idx);\n\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, [outputSize], dtype);\n }\n\n // Take along specified axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n\n // Validate indices\n for (const idx of indices) {\n const normalizedIdx = idx < 0 ? axisSize + idx : idx;\n if (normalizedIdx < 0 || normalizedIdx >= axisSize) {\n throw new Error(\n `index ${idx} is out of bounds for axis ${normalizedAxis} with size ${axisSize}`\n );\n }\n }\n\n // Calculate output shape\n const outputShape = Array.from(shape);\n outputShape[normalizedAxis] = indices.length;\n\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot take from array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // Iterate through output positions\n const outputIndices = new Array(ndim).fill(0);\n for (let i = 0; i < outputSize; i++) {\n // Compute source index\n const sourceIndices = [...outputIndices];\n let targetIdx = outputIndices[normalizedAxis]!;\n let sourceAxisIdx = indices[targetIdx]!;\n if (sourceAxisIdx < 0) sourceAxisIdx = axisSize + sourceAxisIdx;\n sourceIndices[normalizedAxis] = sourceAxisIdx;\n\n const value = storage.get(...sourceIndices);\n\n // Write to output\n let outIdx = 0;\n for (let d = 0; d < ndim; d++) {\n outIdx += outputIndices[d]! * outputStrides[d]!;\n }\n\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[outIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx] = value as number;\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < outputShape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Put values at specified indices (modifies array in-place)\n */\nexport function put(\n storage: ArrayStorage,\n indices: number[],\n values: ArrayStorage | number | bigint\n): void {\n const flatSize = storage.size;\n const dtype = storage.dtype;\n\n // Get values to put\n let valueArray: (number | bigint)[];\n if (typeof values === 'number' || typeof values === 'bigint') {\n valueArray = new Array(indices.length).fill(values);\n } else {\n // Extract values from storage\n valueArray = [];\n for (let i = 0; i < values.size; i++) {\n valueArray.push(values.iget(i));\n }\n // Broadcast values if needed\n if (valueArray.length === 1) {\n valueArray = new Array(indices.length).fill(valueArray[0]);\n } else if (valueArray.length !== indices.length) {\n // Tile values to match indices length\n const original = [...valueArray];\n valueArray = [];\n for (let i = 0; i < indices.length; i++) {\n valueArray.push(original[i % original.length]!);\n }\n }\n }\n\n // Put values at indices\n for (let i = 0; i < indices.length; i++) {\n let idx = indices[i]!;\n if (idx < 0) idx = flatSize + idx;\n\n if (idx < 0 || idx >= flatSize) {\n throw new Error(`index ${indices[i]} is out of bounds for axis 0 with size ${flatSize}`);\n }\n\n let value = valueArray[i]!;\n\n // Convert value to appropriate type\n if (isBigIntDType(dtype)) {\n if (typeof value !== 'bigint') {\n value = BigInt(Math.round(Number(value)));\n }\n } else {\n if (typeof value === 'bigint') {\n value = Number(value);\n }\n }\n\n storage.iset(idx, value);\n }\n}\n\n/**\n * Construct array from index array and choices\n */\nexport function choose(indexStorage: ArrayStorage, choices: ArrayStorage[]): ArrayStorage {\n if (choices.length === 0) {\n throw new Error('choices cannot be empty');\n }\n\n const indexShape = indexStorage.shape;\n const numChoices = choices.length;\n const dtype = choices[0]!.dtype;\n\n // Validate that all choices have compatible shapes\n const shapes = choices.map((c) => Array.from(c.shape));\n shapes.unshift(Array.from(indexShape));\n const broadcastedShape = computeBroadcastShape(shapes);\n\n if (broadcastedShape === null) {\n throw new Error('operands could not be broadcast together');\n }\n\n // Broadcast index array and choices to common shape\n const broadcastedIndex = broadcastTo(indexStorage, broadcastedShape);\n const broadcastedChoices = choices.map((c) => broadcastTo(c, broadcastedShape));\n\n // Create output array\n const outputSize = broadcastedShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot choose with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n // Fill output\n for (let i = 0; i < outputSize; i++) {\n const choiceIdx = Number(broadcastedIndex.iget(i));\n\n if (choiceIdx < 0 || choiceIdx >= numChoices) {\n throw new Error(`index ${choiceIdx} is out of bounds for axis 0 with size ${numChoices}`);\n }\n\n const value = broadcastedChoices[choiceIdx]!.iget(i);\n\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, broadcastedShape, dtype);\n}\n\n/**\n * Check if two arrays are element-wise equal\n */\nexport function array_equal(a: ArrayStorage, b: ArrayStorage, equal_nan: boolean = false): boolean {\n // Check shapes match\n if (a.ndim !== b.ndim) {\n return false;\n }\n\n for (let i = 0; i < a.ndim; i++) {\n if (a.shape[i] !== b.shape[i]) {\n return false;\n }\n }\n\n // Check all elements\n const size = a.size;\n for (let i = 0; i < size; i++) {\n const aVal = a.iget(i);\n const bVal = b.iget(i);\n\n // Handle NaN comparison\n if (equal_nan) {\n const aIsNaN = typeof aVal === 'number' && Number.isNaN(aVal);\n const bIsNaN = typeof bVal === 'number' && Number.isNaN(bVal);\n if (aIsNaN && bIsNaN) {\n continue;\n }\n }\n\n if (aVal !== bVal) {\n return false;\n }\n }\n\n return true;\n}\n", "/**\n * NDArray - NumPy-compatible multidimensional array\n *\n * Core array class providing NumPy-like API\n */\n\nimport { parseSlice, normalizeSlice } from './slicing';\nimport {\n type DType,\n type TypedArray,\n DEFAULT_DTYPE,\n getTypedArrayConstructor,\n isBigIntDType,\n} from './dtype';\nimport { ArrayStorage } from './storage';\nimport * as arithmeticOps from '../ops/arithmetic';\nimport * as comparisonOps from '../ops/comparison';\nimport * as reductionOps from '../ops/reduction';\nimport * as shapeOps from '../ops/shape';\nimport * as linalgOps from '../ops/linalg';\nimport * as exponentialOps from '../ops/exponential';\nimport * as trigOps from '../ops/trig';\nimport * as hyperbolicOps from '../ops/hyperbolic';\nimport * as advancedOps from '../ops/advanced';\n\nexport class NDArray {\n // Internal storage\n private _storage: ArrayStorage;\n // Track if this array is a view of another array\n private _base?: NDArray;\n\n constructor(storage: ArrayStorage, base?: NDArray) {\n this._storage = storage;\n this._base = base;\n }\n\n /**\n * Get internal storage (for ops modules)\n * @internal\n */\n get storage(): ArrayStorage {\n return this._storage;\n }\n\n /**\n * Create NDArray from storage (for ops modules)\n * @internal\n */\n static _fromStorage(storage: ArrayStorage, base?: NDArray): NDArray {\n return new NDArray(storage, base);\n }\n\n // NumPy properties\n get shape(): readonly number[] {\n return this._storage.shape;\n }\n\n get ndim(): number {\n return this._storage.ndim;\n }\n\n get size(): number {\n return this._storage.size;\n }\n\n get dtype(): string {\n return this._storage.dtype;\n }\n\n get data(): TypedArray {\n return this._storage.data;\n }\n\n get strides(): readonly number[] {\n return this._storage.strides;\n }\n\n /**\n * Array flags (similar to NumPy's flags)\n * Provides information about memory layout\n */\n get flags(): {\n C_CONTIGUOUS: boolean;\n F_CONTIGUOUS: boolean;\n OWNDATA: boolean;\n } {\n return {\n C_CONTIGUOUS: this._storage.isCContiguous,\n F_CONTIGUOUS: this._storage.isFContiguous,\n OWNDATA: this._base === undefined, // True if we own data, false if we're a view\n };\n }\n\n /**\n * Base array if this is a view, null if this array owns its data\n * Similar to NumPy's base attribute\n */\n get base(): NDArray | null {\n return this._base ?? null;\n }\n\n /**\n * Get a single element from the array\n * @param indices - Array of indices, one per dimension (e.g., [0, 1] for 2D array)\n * @returns The element value (BigInt for int64/uint64, number otherwise)\n */\n get(indices: number[]): number | bigint {\n // Validate number of indices\n if (indices.length !== this.ndim) {\n throw new Error(\n `Index has ${indices.length} dimensions, but array has ${this.ndim} dimensions`\n );\n }\n\n // Normalize negative indices\n const normalizedIndices = indices.map((idx, dim) => {\n let normalized = idx;\n if (normalized < 0) {\n normalized = this.shape[dim]! + normalized;\n }\n // Validate bounds\n if (normalized < 0 || normalized >= this.shape[dim]!) {\n throw new Error(\n `Index ${idx} is out of bounds for axis ${dim} with size ${this.shape[dim]}`\n );\n }\n return normalized;\n });\n\n return this._storage.get(...normalizedIndices);\n }\n\n /**\n * Set a single element in the array\n * @param indices - Array of indices, one per dimension (e.g., [0, 1] for 2D array)\n * @param value - Value to set (will be converted to array's dtype)\n */\n set(indices: number[], value: number | bigint): void {\n // Validate number of indices\n if (indices.length !== this.ndim) {\n throw new Error(\n `Index has ${indices.length} dimensions, but array has ${this.ndim} dimensions`\n );\n }\n\n // Normalize negative indices\n const normalizedIndices = indices.map((idx, dim) => {\n let normalized = idx;\n if (normalized < 0) {\n normalized = this.shape[dim]! + normalized;\n }\n // Validate bounds\n if (normalized < 0 || normalized >= this.shape[dim]!) {\n throw new Error(\n `Index ${idx} is out of bounds for axis ${dim} with size ${this.shape[dim]}`\n );\n }\n return normalized;\n });\n\n // Convert value to appropriate type based on dtype\n const currentDtype = this.dtype as DType;\n let convertedValue: number | bigint;\n\n if (isBigIntDType(currentDtype)) {\n // Convert to BigInt for BigInt dtypes\n convertedValue = typeof value === 'bigint' ? value : BigInt(Math.round(value));\n } else if (currentDtype === 'bool') {\n // Convert to 0 or 1 for bool dtype\n convertedValue = value ? 1 : 0;\n } else {\n // Convert to number for all other dtypes\n convertedValue = Number(value);\n }\n\n this._storage.set(normalizedIndices, convertedValue);\n }\n\n /**\n * Return a deep copy of the array\n */\n copy(): NDArray {\n return new NDArray(this._storage.copy());\n }\n\n /**\n * Cast array to a different dtype\n * @param dtype - Target dtype\n * @param copy - If false and dtype matches, return self; otherwise create copy (default: true)\n * @returns Array with specified dtype\n */\n astype(dtype: DType, copy: boolean = true): NDArray {\n const currentDtype = this.dtype as DType;\n\n // If dtype matches and copy=false, return self\n if (currentDtype === dtype && !copy) {\n return this;\n }\n\n // If dtype matches and copy=true, create a copy\n if (currentDtype === dtype && copy) {\n return this.copy();\n }\n\n // Need to convert dtype\n const shape = Array.from(this.shape);\n const size = this.size;\n\n // Get TypedArray constructor for conversion\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot convert to dtype ${dtype}`);\n }\n const newData = new Constructor(size);\n const oldData = this.data;\n\n // Handle BigInt to other types\n if (isBigIntDType(currentDtype) && !isBigIntDType(dtype)) {\n const typedOldData = oldData as BigInt64Array | BigUint64Array;\n if (dtype === 'bool') {\n for (let i = 0; i < size; i++) {\n (newData as Uint8Array)[i] = typedOldData[i] !== BigInt(0) ? 1 : 0;\n }\n } else {\n for (let i = 0; i < size; i++) {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Number(\n typedOldData[i]\n );\n }\n }\n }\n // Handle other types to BigInt\n else if (!isBigIntDType(currentDtype) && isBigIntDType(dtype)) {\n const typedOldData = oldData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n (newData as BigInt64Array | BigUint64Array)[i] = BigInt(\n Math.round(Number(typedOldData[i]))\n );\n }\n }\n // Handle other types to bool\n else if (dtype === 'bool') {\n const typedOldData = oldData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n (newData as Uint8Array)[i] = typedOldData[i] !== 0 ? 1 : 0;\n }\n }\n // Handle bool to other types\n else if (currentDtype === 'bool' && !isBigIntDType(dtype)) {\n const typedOldData = oldData as Uint8Array;\n for (let i = 0; i < size; i++) {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = typedOldData[i]!;\n }\n }\n // Handle regular numeric conversions\n else if (!isBigIntDType(currentDtype) && !isBigIntDType(dtype)) {\n const typedOldData = oldData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = typedOldData[i]!;\n }\n }\n // Handle BigInt to BigInt conversions (int64 <-> uint64)\n else {\n const typedOldData = oldData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n (newData as BigInt64Array | BigUint64Array)[i] = typedOldData[i]!;\n }\n }\n\n const storage = ArrayStorage.fromData(newData, shape, dtype);\n return new NDArray(storage);\n }\n\n // Arithmetic operations\n /**\n * Element-wise addition\n * @param other - Array or scalar to add\n * @returns Result of addition with broadcasting\n */\n add(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.add(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise subtraction\n * @param other - Array or scalar to subtract\n * @returns Result of subtraction with broadcasting\n */\n subtract(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.subtract(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise multiplication\n * @param other - Array or scalar to multiply\n * @returns Result of multiplication with broadcasting\n */\n multiply(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.multiply(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise division\n * @param other - Array or scalar to divide by\n * @returns Result of division with broadcasting\n */\n divide(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.divide(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise modulo operation\n * @param other - Array or scalar divisor\n * @returns Remainder after division\n */\n mod(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.mod(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise floor division\n * @param other - Array or scalar to divide by\n * @returns Floor of the quotient\n */\n floor_divide(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.floorDivide(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Numerical positive (element-wise +x)\n * @returns Copy of the array\n */\n positive(): NDArray {\n const resultStorage = arithmeticOps.positive(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise reciprocal (1/x)\n * @returns New array with reciprocals\n */\n reciprocal(): NDArray {\n const resultStorage = arithmeticOps.reciprocal(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Mathematical operations\n /**\n * Square root of each element\n * Promotes integer types to float64\n * @returns New array with square roots\n */\n sqrt(): NDArray {\n const resultStorage = exponentialOps.sqrt(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Raise elements to power\n * @param exponent - Power to raise to (array or scalar)\n * @returns New array with powered values\n */\n power(exponent: NDArray | number): NDArray {\n const exponentStorage = typeof exponent === 'number' ? exponent : exponent._storage;\n const resultStorage = exponentialOps.power(this._storage, exponentStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Absolute value of each element\n * @returns New array with absolute values\n */\n absolute(): NDArray {\n const resultStorage = arithmeticOps.absolute(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Numerical negative (element-wise negation)\n * @returns New array with negated values\n */\n negative(): NDArray {\n const resultStorage = arithmeticOps.negative(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Sign of each element (-1, 0, or 1)\n * @returns New array with signs\n */\n sign(): NDArray {\n const resultStorage = arithmeticOps.sign(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Trigonometric operations\n /**\n * Sine of each element (in radians)\n * Promotes integer types to float64\n * @returns New array with sine values\n */\n sin(): NDArray {\n const resultStorage = trigOps.sin(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Cosine of each element (in radians)\n * Promotes integer types to float64\n * @returns New array with cosine values\n */\n cos(): NDArray {\n const resultStorage = trigOps.cos(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Tangent of each element (in radians)\n * Promotes integer types to float64\n * @returns New array with tangent values\n */\n tan(): NDArray {\n const resultStorage = trigOps.tan(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse sine of each element\n * Promotes integer types to float64\n * @returns New array with arcsin values (radians)\n */\n arcsin(): NDArray {\n const resultStorage = trigOps.arcsin(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse cosine of each element\n * Promotes integer types to float64\n * @returns New array with arccos values (radians)\n */\n arccos(): NDArray {\n const resultStorage = trigOps.arccos(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse tangent of each element\n * Promotes integer types to float64\n * @returns New array with arctan values (radians)\n */\n arctan(): NDArray {\n const resultStorage = trigOps.arctan(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise arc tangent of this/other choosing the quadrant correctly\n * @param other - x-coordinates (array or scalar)\n * @returns Angle in radians between -\u03C0 and \u03C0\n */\n arctan2(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = trigOps.arctan2(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Given the \"legs\" of a right triangle, return its hypotenuse\n * Equivalent to sqrt(this**2 + other**2), element-wise\n * @param other - Second leg (array or scalar)\n * @returns Hypotenuse values\n */\n hypot(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = trigOps.hypot(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Convert angles from radians to degrees\n * @returns New array with angles in degrees\n */\n degrees(): NDArray {\n const resultStorage = trigOps.degrees(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Convert angles from degrees to radians\n * @returns New array with angles in radians\n */\n radians(): NDArray {\n const resultStorage = trigOps.radians(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Hyperbolic operations\n /**\n * Hyperbolic sine of each element\n * Promotes integer types to float64\n * @returns New array with sinh values\n */\n sinh(): NDArray {\n const resultStorage = hyperbolicOps.sinh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Hyperbolic cosine of each element\n * Promotes integer types to float64\n * @returns New array with cosh values\n */\n cosh(): NDArray {\n const resultStorage = hyperbolicOps.cosh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Hyperbolic tangent of each element\n * Promotes integer types to float64\n * @returns New array with tanh values\n */\n tanh(): NDArray {\n const resultStorage = hyperbolicOps.tanh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse hyperbolic sine of each element\n * Promotes integer types to float64\n * @returns New array with arcsinh values\n */\n arcsinh(): NDArray {\n const resultStorage = hyperbolicOps.arcsinh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse hyperbolic cosine of each element\n * Promotes integer types to float64\n * @returns New array with arccosh values\n */\n arccosh(): NDArray {\n const resultStorage = hyperbolicOps.arccosh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse hyperbolic tangent of each element\n * Promotes integer types to float64\n * @returns New array with arctanh values\n */\n arctanh(): NDArray {\n const resultStorage = hyperbolicOps.arctanh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Comparison operations\n /**\n * Element-wise greater than comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n greater(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.greater(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise greater than or equal comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n greater_equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.greaterEqual(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise less than comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n less(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.less(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise less than or equal comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n less_equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.lessEqual(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise equality comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.equal(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise not equal comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n not_equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.notEqual(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise comparison with tolerance\n * Returns True where |a - b| <= (atol + rtol * |b|)\n * @param other - Value or array to compare with\n * @param rtol - Relative tolerance (default: 1e-5)\n * @param atol - Absolute tolerance (default: 1e-8)\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n isclose(other: NDArray | number, rtol: number = 1e-5, atol: number = 1e-8): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.isclose(this._storage, otherStorage, rtol, atol);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise comparison with tolerance\n * Returns True where |a - b| <= (atol + rtol * |b|)\n * @param other - Value or array to compare with\n * @param rtol - Relative tolerance (default: 1e-5)\n * @param atol - Absolute tolerance (default: 1e-8)\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n allclose(other: NDArray | number, rtol: number = 1e-5, atol: number = 1e-8): boolean {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n return comparisonOps.allclose(this._storage, otherStorage, rtol, atol);\n }\n\n // Reductions\n /**\n * Sum array elements over a given axis\n * @param axis - Axis along which to sum. If undefined, sum all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Sum of array elements, or array of sums along axis\n */\n sum(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.sum(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the arithmetic mean along the specified axis\n * @param axis - Axis along which to compute mean. If undefined, compute mean of all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Mean of array elements, or array of means along axis\n *\n * Note: mean() returns float64 for integer dtypes, matching NumPy behavior\n */\n mean(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.mean(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the maximum along a given axis\n * @param axis - Axis along which to compute maximum. If undefined, compute maximum of all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Maximum of array elements, or array of maximums along axis\n */\n max(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.max(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the minimum along a given axis\n * @param axis - Axis along which to compute minimum. If undefined, compute minimum of all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Minimum of array elements, or array of minimums along axis\n */\n min(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.min(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Product of array elements over a given axis\n * @param axis - Axis along which to compute the product. If undefined, product of all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Product of array elements, or array of products along axis\n */\n prod(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.prod(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Indices of the minimum values along an axis\n * @param axis - Axis along which to find minimum indices. If undefined, index of global minimum.\n * @returns Indices of minimum values\n */\n argmin(axis?: number): NDArray | number {\n const result = reductionOps.argmin(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Indices of the maximum values along an axis\n * @param axis - Axis along which to find maximum indices. If undefined, index of global maximum.\n * @returns Indices of maximum values\n */\n argmax(axis?: number): NDArray | number {\n const result = reductionOps.argmax(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute variance along the specified axis\n * @param axis - Axis along which to compute variance. If undefined, variance of all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Variance of array elements\n */\n var(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.variance(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute standard deviation along the specified axis\n * @param axis - Axis along which to compute std. If undefined, std of all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Standard deviation of array elements\n */\n std(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.std(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Test whether all array elements along a given axis evaluate to True\n * @param axis - Axis along which to perform logical AND. If undefined, test all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Boolean or array of booleans\n */\n all(axis?: number, keepdims: boolean = false): NDArray | boolean {\n const result = reductionOps.all(this._storage, axis, keepdims);\n return typeof result === 'boolean' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Test whether any array elements along a given axis evaluate to True\n * @param axis - Axis along which to perform logical OR. If undefined, test all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Boolean or array of booleans\n */\n any(axis?: number, keepdims: boolean = false): NDArray | boolean {\n const result = reductionOps.any(this._storage, axis, keepdims);\n return typeof result === 'boolean' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the cumulative sum of elements along a given axis\n * @param axis - Axis along which to compute cumsum. If undefined, compute over flattened array.\n * @returns Array with cumulative sums\n */\n cumsum(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumsum(this._storage, axis));\n }\n\n /**\n * Return the cumulative product of elements along a given axis\n * @param axis - Axis along which to compute cumprod. If undefined, compute over flattened array.\n * @returns Array with cumulative products\n */\n cumprod(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumprod(this._storage, axis));\n }\n\n /**\n * Peak to peak (maximum - minimum) value along a given axis\n * @param axis - Axis along which to compute ptp. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Range of values\n */\n ptp(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.ptp(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the median along the specified axis\n * @param axis - Axis along which to compute median. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median of array elements\n */\n median(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.median(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the q-th percentile of the data along the specified axis\n * @param q - Percentile to compute (0-100)\n * @param axis - Axis along which to compute percentile. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Percentile of array elements\n */\n percentile(q: number, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.percentile(this._storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the q-th quantile of the data along the specified axis\n * @param q - Quantile to compute (0-1)\n * @param axis - Axis along which to compute quantile. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Quantile of array elements\n */\n quantile(q: number, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.quantile(this._storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the weighted average along the specified axis\n * @param weights - Array of weights (optional)\n * @param axis - Axis along which to compute average. If undefined, compute over all elements.\n * @returns Weighted average of array elements\n */\n average(weights?: NDArray, axis?: number): NDArray | number {\n const result = reductionOps.average(this._storage, axis, weights?.storage);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the sum of array elements, treating NaNs as zero\n * @param axis - Axis along which to compute sum. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Sum of array elements ignoring NaNs\n */\n nansum(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nansum(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the product of array elements, treating NaNs as ones\n * @param axis - Axis along which to compute product. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Product of array elements ignoring NaNs\n */\n nanprod(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanprod(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the arithmetic mean, ignoring NaNs\n * @param axis - Axis along which to compute mean. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Mean of array elements ignoring NaNs\n */\n nanmean(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmean(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the variance, ignoring NaNs\n * @param axis - Axis along which to compute variance. If undefined, compute over all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Variance of array elements ignoring NaNs\n */\n nanvar(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanvar(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the standard deviation, ignoring NaNs\n * @param axis - Axis along which to compute std. If undefined, compute over all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Standard deviation of array elements ignoring NaNs\n */\n nanstd(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanstd(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return minimum of an array or minimum along an axis, ignoring NaNs\n * @param axis - Axis along which to compute minimum. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Minimum of array elements ignoring NaNs\n */\n nanmin(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmin(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return maximum of an array or maximum along an axis, ignoring NaNs\n * @param axis - Axis along which to compute maximum. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Maximum of array elements ignoring NaNs\n */\n nanmax(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmax(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the indices of the minimum values, ignoring NaNs\n * @param axis - Axis along which to find minimum indices. If undefined, index of global minimum.\n * @returns Indices of minimum values ignoring NaNs\n */\n nanargmin(axis?: number): NDArray | number {\n const result = reductionOps.nanargmin(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the indices of the maximum values, ignoring NaNs\n * @param axis - Axis along which to find maximum indices. If undefined, index of global maximum.\n * @returns Indices of maximum values ignoring NaNs\n */\n nanargmax(axis?: number): NDArray | number {\n const result = reductionOps.nanargmax(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the cumulative sum of elements, treating NaNs as zero\n * @param axis - Axis along which to compute cumsum. If undefined, compute over flattened array.\n * @returns Array with cumulative sums ignoring NaNs\n */\n nancumsum(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumsum(this._storage, axis));\n }\n\n /**\n * Return the cumulative product of elements, treating NaNs as one\n * @param axis - Axis along which to compute cumprod. If undefined, compute over flattened array.\n * @returns Array with cumulative products ignoring NaNs\n */\n nancumprod(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumprod(this._storage, axis));\n }\n\n /**\n * Compute the median, ignoring NaNs\n * @param axis - Axis along which to compute median. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median of array elements ignoring NaNs\n */\n nanmedian(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmedian(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n // Shape manipulation\n /**\n * Reshape array to a new shape\n * Returns a new array with the specified shape\n * @param shape - New shape (must be compatible with current size)\n * @returns Reshaped array\n */\n reshape(...shape: number[]): NDArray {\n const newShape = shape.length === 1 && Array.isArray(shape[0]) ? shape[0] : shape;\n const resultStorage = shapeOps.reshape(this._storage, newShape);\n const isView = resultStorage.data === this.data;\n const base = isView ? (this._base ?? this) : undefined;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Return a flattened copy of the array\n * @returns 1D array containing all elements\n */\n flatten(): NDArray {\n const resultStorage = shapeOps.flatten(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Return a flattened array (view when possible, otherwise copy)\n * @returns 1D array containing all elements\n */\n ravel(): NDArray {\n const resultStorage = shapeOps.ravel(this._storage);\n const isView = resultStorage.data === this.data;\n const base = isView ? (this._base ?? this) : undefined;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Transpose array (permute dimensions)\n * @param axes - Permutation of axes. If undefined, reverse the dimensions\n * @returns Transposed array (always a view)\n */\n transpose(axes?: number[]): NDArray {\n const resultStorage = shapeOps.transpose(this._storage, axes);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Remove axes of length 1\n * @param axis - Axis to squeeze. If undefined, squeeze all axes of length 1\n * @returns Array with specified dimensions removed (always a view)\n */\n squeeze(axis?: number): NDArray {\n const resultStorage = shapeOps.squeeze(this._storage, axis);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Expand the shape by inserting a new axis of length 1\n * @param axis - Position where new axis is placed\n * @returns Array with additional dimension (always a view)\n */\n expand_dims(axis: number): NDArray {\n const resultStorage = shapeOps.expandDims(this._storage, axis);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Swap two axes of an array\n * @param axis1 - First axis\n * @param axis2 - Second axis\n * @returns Array with swapped axes (always a view)\n */\n swapaxes(axis1: number, axis2: number): NDArray {\n const resultStorage = shapeOps.swapaxes(this._storage, axis1, axis2);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Move axes to new positions\n * @param source - Original positions of axes to move\n * @param destination - New positions for axes\n * @returns Array with moved axes (always a view)\n */\n moveaxis(source: number | number[], destination: number | number[]): NDArray {\n const resultStorage = shapeOps.moveaxis(this._storage, source, destination);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Repeat elements of an array\n * @param repeats - Number of repetitions for each element\n * @param axis - Axis along which to repeat (if undefined, flattens first)\n * @returns New array with repeated elements\n */\n repeat(repeats: number | number[], axis?: number): NDArray {\n const resultStorage = shapeOps.repeat(this._storage, repeats, axis);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Take elements from array along an axis\n * @param indices - Indices of elements to take\n * @param axis - Axis along which to take (if undefined, flattens first)\n * @returns New array with selected elements\n */\n take(indices: number[], axis?: number): NDArray {\n const resultStorage = advancedOps.take(this._storage, indices, axis);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Put values at specified indices (modifies array in-place)\n * @param indices - Indices at which to place values\n * @param values - Values to put\n */\n put(indices: number[], values: NDArray | number | bigint): void {\n const valuesStorage = values instanceof NDArray ? values._storage : values;\n advancedOps.put(this._storage, indices, valuesStorage);\n }\n\n // Linear algebra operations\n /**\n * Matrix multiplication\n * @param other - Array to multiply with\n * @returns Result of matrix multiplication\n */\n matmul(other: NDArray): NDArray {\n const resultStorage = linalgOps.matmul(this._storage, other._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Dot product (matching NumPy behavior)\n * @param other - Array to dot with\n * @returns Result of dot product (scalar or array depending on dimensions)\n */\n dot(other: NDArray): NDArray | number | bigint {\n const result = linalgOps.dot(this._storage, other._storage);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n }\n\n /**\n * Sum of diagonal elements (trace)\n * @returns Sum of diagonal elements\n */\n trace(): number | bigint {\n return linalgOps.trace(this._storage);\n }\n\n /**\n * Inner product (contracts over last axes of both arrays)\n * @param other - Array to compute inner product with\n * @returns Inner product result\n */\n inner(other: NDArray): NDArray | number | bigint {\n const result = linalgOps.inner(this._storage, other._storage);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n }\n\n /**\n * Outer product (flattens inputs then computes a[i]*b[j])\n * @param other - Array to compute outer product with\n * @returns 2D outer product matrix\n */\n outer(other: NDArray): NDArray {\n const result = linalgOps.outer(this._storage, other._storage);\n return NDArray._fromStorage(result);\n }\n\n /**\n * Tensor dot product along specified axes\n * @param other - Array to contract with\n * @param axes - Axes to contract (integer or [a_axes, b_axes])\n * @returns Tensor dot product result\n */\n tensordot(other: NDArray, axes: number | [number[], number[]] = 2): NDArray | number | bigint {\n const result = linalgOps.tensordot(this._storage, other._storage, axes);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n }\n\n // Additional arithmetic operations\n\n /**\n * Element-wise cube root\n * Promotes integer types to float64\n * @returns New array with cube root values\n */\n cbrt(): NDArray {\n const resultStorage = arithmeticOps.cbrt(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise absolute value (always returns float)\n * @returns New array with absolute values as float\n */\n fabs(): NDArray {\n const resultStorage = arithmeticOps.fabs(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Returns both quotient and remainder (floor divide and modulo)\n * @param divisor - Array or scalar divisor\n * @returns Tuple of [quotient, remainder] arrays\n */\n divmod(divisor: NDArray | number): [NDArray, NDArray] {\n const divisorStorage = typeof divisor === 'number' ? divisor : divisor._storage;\n const [quotientStorage, remainderStorage] = arithmeticOps.divmod(this._storage, divisorStorage);\n return [NDArray._fromStorage(quotientStorage), NDArray._fromStorage(remainderStorage)];\n }\n\n /**\n * Element-wise square (x**2)\n * @returns New array with squared values\n */\n square(): NDArray {\n const resultStorage = arithmeticOps.square(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise remainder (same as mod)\n * @param divisor - Array or scalar divisor\n * @returns New array with remainder values\n */\n remainder(divisor: NDArray | number): NDArray {\n const divisorStorage = typeof divisor === 'number' ? divisor : divisor._storage;\n const resultStorage = arithmeticOps.remainder(this._storage, divisorStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Heaviside step function\n * @param x2 - Value to use when this array element is 0\n * @returns New array with heaviside values\n */\n heaviside(x2: NDArray | number): NDArray {\n const x2Storage = typeof x2 === 'number' ? x2 : x2._storage;\n const resultStorage = arithmeticOps.heaviside(this._storage, x2Storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Slicing\n /**\n * Slice the array using NumPy-style string syntax\n *\n * @param sliceStrs - Slice specifications, one per dimension\n * @returns Sliced view of the array\n */\n slice(...sliceStrs: string[]): NDArray {\n if (sliceStrs.length === 0) {\n return this;\n }\n\n if (sliceStrs.length > this.ndim) {\n throw new Error(\n `Too many indices for array: array is ${this.ndim}-dimensional, but ${sliceStrs.length} were indexed`\n );\n }\n\n // Parse slice strings and normalize them\n const sliceSpecs = sliceStrs.map((str, i) => {\n const spec = parseSlice(str);\n const normalized = normalizeSlice(spec, this.shape[i]!);\n return normalized;\n });\n\n // Pad with full slices for remaining dimensions\n while (sliceSpecs.length < this.ndim) {\n sliceSpecs.push({\n start: 0,\n stop: this.shape[sliceSpecs.length]!,\n step: 1,\n isIndex: false,\n });\n }\n\n // Calculate new shape and strides\n const newShape: number[] = [];\n const newStrides: number[] = [];\n let newOffset = this._storage.offset;\n\n for (let i = 0; i < sliceSpecs.length; i++) {\n const spec = sliceSpecs[i]!;\n const stride = this._storage.strides[i]!;\n\n // Update offset based on start position\n newOffset += spec.start * stride;\n\n if (!spec.isIndex) {\n // Calculate size of this dimension\n // For positive step: (stop - start) / step\n // For negative step: (start - stop) / |step| (since we go from high to low)\n let dimSize: number;\n if (spec.step > 0) {\n dimSize = Math.max(0, Math.ceil((spec.stop - spec.start) / spec.step));\n } else {\n // Negative step: iterate from start down to (but not including) stop\n dimSize = Math.max(0, Math.ceil((spec.start - spec.stop) / Math.abs(spec.step)));\n }\n newShape.push(dimSize);\n newStrides.push(stride * spec.step);\n }\n // If isIndex is true, this dimension is removed (scalar indexing)\n }\n\n // Create sliced view\n const slicedStorage = ArrayStorage.fromData(\n this._storage.data,\n newShape,\n this._storage.dtype,\n newStrides,\n newOffset\n );\n\n const base = this._base ?? this;\n return new NDArray(slicedStorage, base);\n }\n\n // Convenience methods\n /**\n * Get a single row (convenience method)\n * @param i - Row index\n * @returns Row as 1D or (n-1)D array\n */\n\n row(i: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('row() requires at least 2 dimensions');\n }\n return this.slice(String(i), ':');\n }\n\n /**\n * Get a single column (convenience method)\n * @param j - Column index\n * @returns Column as 1D or (n-1)D array\n */\n col(j: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('col() requires at least 2 dimensions');\n }\n return this.slice(':', String(j));\n }\n\n /**\n * Get a range of rows (convenience method)\n * @param start - Start row index\n * @param stop - Stop row index (exclusive)\n * @returns Rows as array\n */\n rows(start: number, stop: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('rows() requires at least 2 dimensions');\n }\n return this.slice(`${start}:${stop}`, ':');\n }\n\n /**\n * Get a range of columns (convenience method)\n * @param start - Start column index\n * @param stop - Stop column index (exclusive)\n * @returns Columns as array\n */\n cols(start: number, stop: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('cols() requires at least 2 dimensions');\n }\n return this.slice(':', `${start}:${stop}`);\n }\n\n // String representation\n /**\n * String representation of the array\n * @returns String describing the array shape and dtype\n */\n toString(): string {\n return `NDArray(shape=${JSON.stringify(this.shape)}, dtype=${this.dtype})`;\n }\n\n /**\n * Convert to nested JavaScript array\n * @returns Nested JavaScript array representation\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n toArray(): any {\n // Handle 0-dimensional arrays (scalars)\n if (this.ndim === 0) {\n return this._storage.iget(0);\n }\n\n const shape = this.shape;\n const ndim = shape.length;\n\n // Recursive function to build nested array\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const buildNestedArray = (indices: number[], dim: number): any => {\n if (dim === ndim) {\n return this._storage.get(...indices);\n }\n\n const arr = [];\n for (let i = 0; i < shape[dim]!; i++) {\n indices[dim] = i;\n arr.push(buildNestedArray(indices, dim + 1));\n }\n return arr;\n };\n\n return buildNestedArray(new Array(ndim), 0);\n }\n}\n\n// Creation functions\n\n/**\n * Create array of zeros\n * @param shape - Shape of the array\n * @param dtype - Data type (default: float64)\n * @returns Array filled with zeros\n */\nexport function zeros(shape: number[], dtype: DType = DEFAULT_DTYPE): NDArray {\n const storage = ArrayStorage.zeros(shape, dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array of ones\n * @param shape - Shape of the array\n * @param dtype - Data type (default: float64)\n * @returns Array filled with ones\n */\nexport function ones(shape: number[], dtype: DType = DEFAULT_DTYPE): NDArray {\n const storage = ArrayStorage.ones(shape, dtype);\n return new NDArray(storage);\n}\n\n/**\n * Helper to infer shape from nested arrays\n */\nfunction inferShape(data: unknown): number[] {\n const shape: number[] = [];\n let current = data;\n while (Array.isArray(current)) {\n shape.push(current.length);\n current = current[0];\n }\n return shape;\n}\n\n/**\n * Helper to check if data contains BigInt values\n */\nfunction containsBigInt(data: unknown): boolean {\n if (typeof data === 'bigint') return true;\n if (Array.isArray(data)) {\n return data.some((item) => containsBigInt(item));\n }\n return false;\n}\n\n/**\n * Helper to flatten nested arrays keeping BigInt values\n */\nfunction flattenKeepBigInt(data: unknown): unknown[] {\n const result: unknown[] = [];\n function flatten(arr: unknown): void {\n if (Array.isArray(arr)) {\n arr.forEach((item) => flatten(item));\n } else {\n result.push(arr);\n }\n }\n flatten(data);\n return result;\n}\n\n/**\n * Create array from nested JavaScript arrays\n * @param data - Nested arrays or existing NDArray\n * @param dtype - Data type (optional, will be inferred if not provided)\n * @returns New NDArray\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function array(data: any, dtype?: DType): NDArray {\n // If data is already an NDArray, optionally convert dtype\n if (data instanceof NDArray) {\n if (!dtype || data.dtype === dtype) {\n return data.copy();\n }\n return data.astype(dtype);\n }\n\n const hasBigInt = containsBigInt(data);\n\n // Infer shape from nested arrays\n const shape = inferShape(data);\n const size = shape.reduce((a: number, b: number) => a * b, 1);\n\n // Determine dtype\n let actualDtype = dtype;\n if (!actualDtype) {\n if (hasBigInt) {\n actualDtype = 'int64';\n } else {\n actualDtype = DEFAULT_DTYPE;\n }\n }\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(actualDtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${actualDtype}`);\n }\n\n const typedData = new Constructor(size);\n const flatData = flattenKeepBigInt(data);\n\n // Fill the typed array\n if (isBigIntDType(actualDtype)) {\n const bigintData = typedData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = flatData[i];\n bigintData[i] = typeof val === 'bigint' ? val : BigInt(Math.round(Number(val)));\n }\n } else if (actualDtype === 'bool') {\n const boolData = typedData as Uint8Array;\n for (let i = 0; i < size; i++) {\n boolData[i] = flatData[i] ? 1 : 0;\n }\n } else {\n const numData = typedData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n const val = flatData[i];\n numData[i] = typeof val === 'bigint' ? Number(val) : Number(val);\n }\n }\n\n const storage = ArrayStorage.fromData(typedData, shape, actualDtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with evenly spaced values within a given interval\n * Similar to Python's range() but returns array\n * @param start - Start value (or stop if only one argument)\n * @param stop - Stop value (exclusive)\n * @param step - Step between values (default: 1)\n * @param dtype - Data type (default: float64)\n * @returns Array of evenly spaced values\n */\nexport function arange(\n start: number,\n stop?: number,\n step: number = 1,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n let actualStart = start;\n let actualStop = stop;\n\n if (stop === undefined) {\n actualStart = 0;\n actualStop = start;\n }\n\n if (actualStop === undefined) {\n throw new Error('stop is required');\n }\n\n const length = Math.max(0, Math.ceil((actualStop - actualStart) / step));\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create arange array with dtype ${dtype}`);\n }\n\n const data = new Constructor(length);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < length; i++) {\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(actualStart + i * step));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < length; i++) {\n (data as Uint8Array)[i] = actualStart + i * step !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < length; i++) {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = actualStart + i * step;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [length], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with evenly spaced values over a specified interval\n * @param start - Starting value\n * @param stop - Ending value (inclusive)\n * @param num - Number of samples (default: 50)\n * @param dtype - Data type (default: float64)\n * @returns Array of evenly spaced values\n */\nexport function linspace(\n start: number,\n stop: number,\n num: number = 50,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n if (num < 0) {\n throw new Error('num must be non-negative');\n }\n\n if (num === 0) {\n return array([], dtype);\n }\n\n if (num === 1) {\n return array([start], dtype);\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create linspace array with dtype ${dtype}`);\n }\n\n const data = new Constructor(num);\n const step = (stop - start) / (num - 1);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < num; i++) {\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(start + i * step));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < num; i++) {\n (data as Uint8Array)[i] = start + i * step !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < num; i++) {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = start + i * step;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [num], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with logarithmically spaced values\n * Returns num samples, equally spaced on a log scale from base^start to base^stop\n * @param start - base^start is the starting value\n * @param stop - base^stop is the ending value\n * @param num - Number of samples (default: 50)\n * @param base - Base of the log space (default: 10.0)\n * @param dtype - Data type (default: float64)\n * @returns Array of logarithmically spaced values\n */\nexport function logspace(\n start: number,\n stop: number,\n num: number = 50,\n base: number = 10.0,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n if (num < 0) {\n throw new Error('num must be non-negative');\n }\n\n if (num === 0) {\n return array([], dtype);\n }\n\n if (num === 1) {\n return array([Math.pow(base, start)], dtype);\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create logspace array with dtype ${dtype}`);\n }\n\n const data = new Constructor(num);\n const step = (stop - start) / (num - 1);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < num; i++) {\n const exponent = start + i * step;\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(Math.pow(base, exponent)));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < num; i++) {\n const exponent = start + i * step;\n (data as Uint8Array)[i] = Math.pow(base, exponent) !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < num; i++) {\n const exponent = start + i * step;\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Math.pow(base, exponent);\n }\n }\n\n const storage = ArrayStorage.fromData(data, [num], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with geometrically spaced values\n * Returns num samples, equally spaced on a log scale (geometric progression)\n * @param start - Starting value\n * @param stop - Ending value\n * @param num - Number of samples (default: 50)\n * @param dtype - Data type (default: float64)\n * @returns Array of geometrically spaced values\n */\nexport function geomspace(\n start: number,\n stop: number,\n num: number = 50,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n if (num < 0) {\n throw new Error('num must be non-negative');\n }\n\n if (start === 0 || stop === 0) {\n throw new Error('Geometric sequence cannot include zero');\n }\n\n if (num === 0) {\n return array([], dtype);\n }\n\n if (num === 1) {\n return array([start], dtype);\n }\n\n const signStart = Math.sign(start);\n const signStop = Math.sign(stop);\n\n if (signStart !== signStop) {\n throw new Error('Geometric sequence cannot contain both positive and negative values');\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create geomspace array with dtype ${dtype}`);\n }\n\n const data = new Constructor(num);\n const logStart = Math.log(Math.abs(start));\n const logStop = Math.log(Math.abs(stop));\n const step = (logStop - logStart) / (num - 1);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < num; i++) {\n const value = signStart * Math.exp(logStart + i * step);\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(value));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < num; i++) {\n const value = signStart * Math.exp(logStart + i * step);\n (data as Uint8Array)[i] = value !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < num; i++) {\n const value = signStart * Math.exp(logStart + i * step);\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [num], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create identity matrix\n * @param n - Number of rows\n * @param m - Number of columns (default: n)\n * @param k - Index of diagonal (0 for main diagonal, positive for upper, negative for lower)\n * @param dtype - Data type (default: float64)\n * @returns Identity matrix\n */\nexport function eye(n: number, m?: number, k: number = 0, dtype: DType = DEFAULT_DTYPE): NDArray {\n const cols = m ?? n;\n const result = zeros([n, cols], dtype);\n const data = result.data;\n\n if (isBigIntDType(dtype)) {\n const typedData = data as unknown as BigInt64Array | BigUint64Array;\n for (let i = 0; i < n; i++) {\n const j = i + k;\n if (j >= 0 && j < cols) {\n typedData[i * cols + j] = BigInt(1);\n }\n }\n } else {\n const typedData = data as unknown as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < n; i++) {\n const j = i + k;\n if (j >= 0 && j < cols) {\n typedData[i * cols + j] = 1;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Create an uninitialized array\n * Note: TypedArrays are zero-initialized by default in JavaScript\n * @param shape - Shape of the array\n * @param dtype - Data type (default: float64)\n * @returns Uninitialized array\n */\nexport function empty(shape: number[], dtype: DType = DEFAULT_DTYPE): NDArray {\n return zeros(shape, dtype);\n}\n\n/**\n * Create array filled with a constant value\n * @param shape - Shape of the array\n * @param fill_value - Value to fill the array with\n * @param dtype - Data type (optional, inferred from fill_value if not provided)\n * @returns Array filled with the constant value\n */\nexport function full(\n shape: number[],\n fill_value: number | bigint | boolean,\n dtype?: DType\n): NDArray {\n let actualDtype = dtype;\n if (!actualDtype) {\n if (typeof fill_value === 'bigint') {\n actualDtype = 'int64';\n } else if (typeof fill_value === 'boolean') {\n actualDtype = 'bool';\n } else if (Number.isInteger(fill_value)) {\n actualDtype = 'int32';\n } else {\n actualDtype = DEFAULT_DTYPE;\n }\n }\n\n const Constructor = getTypedArrayConstructor(actualDtype);\n if (!Constructor) {\n throw new Error(`Cannot create full array with dtype ${actualDtype}`);\n }\n const size = shape.reduce((a, b) => a * b, 1);\n const data = new Constructor(size);\n\n if (isBigIntDType(actualDtype)) {\n const bigintValue =\n typeof fill_value === 'bigint' ? fill_value : BigInt(Math.round(Number(fill_value)));\n (data as BigInt64Array | BigUint64Array).fill(bigintValue);\n } else if (actualDtype === 'bool') {\n (data as Uint8Array).fill(fill_value ? 1 : 0);\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>).fill(Number(fill_value));\n }\n\n const storage = ArrayStorage.fromData(data, shape, actualDtype);\n return new NDArray(storage);\n}\n\n/**\n * Create a square identity matrix\n * @param n - Size of the square matrix\n * @param dtype - Data type (default: float64)\n * @returns n\u00D7n identity matrix\n */\nexport function identity(n: number, dtype: DType = DEFAULT_DTYPE): NDArray {\n return eye(n, n, 0, dtype);\n}\n\n/**\n * Convert input to an ndarray\n * @param a - Input data (array-like or NDArray)\n * @param dtype - Data type (optional)\n * @returns NDArray representation of the input\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function asarray(a: NDArray | any, dtype?: DType): NDArray {\n if (a instanceof NDArray) {\n if (!dtype || a.dtype === dtype) {\n return a;\n }\n return a.astype(dtype);\n }\n return array(a, dtype);\n}\n\n/**\n * Create a deep copy of an array\n * @param a - Array to copy\n * @returns Deep copy of the array\n */\nexport function copy(a: NDArray): NDArray {\n return a.copy();\n}\n\n/**\n * Create array of zeros with the same shape as another array\n * @param a - Array to match shape from\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Array of zeros\n */\nexport function zeros_like(a: NDArray, dtype?: DType): NDArray {\n return zeros(Array.from(a.shape), dtype ?? (a.dtype as DType));\n}\n\n/**\n * Create array of ones with the same shape as another array\n * @param a - Array to match shape from\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Array of ones\n */\nexport function ones_like(a: NDArray, dtype?: DType): NDArray {\n return ones(Array.from(a.shape), dtype ?? (a.dtype as DType));\n}\n\n/**\n * Create uninitialized array with the same shape as another array\n * @param a - Array to match shape from\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Uninitialized array\n */\nexport function empty_like(a: NDArray, dtype?: DType): NDArray {\n return empty(Array.from(a.shape), dtype ?? (a.dtype as DType));\n}\n\n/**\n * Create array filled with a constant value, same shape as another array\n * @param a - Array to match shape from\n * @param fill_value - Value to fill with\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Filled array\n */\nexport function full_like(\n a: NDArray,\n fill_value: number | bigint | boolean,\n dtype?: DType\n): NDArray {\n return full(Array.from(a.shape), fill_value, dtype ?? (a.dtype as DType));\n}\n\n/**\n * Convert input to an ndarray (alias for asarray for compatibility)\n * In numpy-ts, this behaves the same as asarray since we don't have subclasses\n * @param a - Input data\n * @param dtype - Data type (optional)\n * @returns NDArray\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function asanyarray(a: NDArray | any, dtype?: DType): NDArray {\n return asarray(a, dtype);\n}\n\n/**\n * Return a contiguous array (ndim >= 1) in memory (C order)\n * Since our arrays are already C-contiguous in memory, this either\n * returns the input unchanged or creates a contiguous copy\n * @param a - Input data\n * @param dtype - Data type (optional)\n * @returns Contiguous array in C order\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function ascontiguousarray(a: NDArray | any, dtype?: DType): NDArray {\n const arr = asarray(a, dtype);\n if (arr.flags.C_CONTIGUOUS) {\n return arr;\n }\n return arr.copy();\n}\n\n/**\n * Return an array laid out in Fortran order in memory\n * Note: numpy-ts uses C-order internally, so this creates a copy\n * that is equivalent to the Fortran-ordered layout\n * @param a - Input data\n * @param dtype - Data type (optional)\n * @returns Array (copy in C order, as Fortran order is not supported)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function asfortranarray(a: NDArray | any, dtype?: DType): NDArray {\n const arr = asarray(a, dtype);\n // We always return C-contiguous arrays, so just return a copy\n return arr.copy();\n}\n\n/**\n * Extract a diagonal or construct a diagonal array\n * @param v - Input array (if 2D, extract diagonal; if 1D, construct diagonal matrix)\n * @param k - Diagonal offset (default 0 is main diagonal, positive above, negative below)\n * @returns Diagonal elements as 1D array, or 2D diagonal matrix\n */\nexport function diag(v: NDArray, k: number = 0): NDArray {\n if (v.ndim === 1) {\n // Construct diagonal matrix from 1D array\n const n = v.size;\n const size = n + Math.abs(k);\n const result = zeros([size, size], v.dtype as DType);\n\n for (let i = 0; i < n; i++) {\n const row = k >= 0 ? i : i - k;\n const col = k >= 0 ? i + k : i;\n result.set([row, col], v.get([i]) as number);\n }\n return result;\n } else if (v.ndim === 2) {\n // Extract diagonal from 2D array\n const [rows, cols] = v.shape;\n let startRow: number, startCol: number, diagLength: number;\n\n if (k >= 0) {\n startRow = 0;\n startCol = k;\n diagLength = Math.min(rows!, cols! - k);\n } else {\n startRow = -k;\n startCol = 0;\n diagLength = Math.min(rows! + k, cols!);\n }\n\n if (diagLength <= 0) {\n return zeros([0], v.dtype as DType);\n }\n\n const Constructor = getTypedArrayConstructor(v.dtype as DType);\n const data = new Constructor!(diagLength);\n\n for (let i = 0; i < diagLength; i++) {\n const val = v.get([startRow + i, startCol + i]);\n if (isBigIntDType(v.dtype as DType)) {\n (data as BigInt64Array | BigUint64Array)[i] =\n typeof val === 'bigint' ? val : BigInt(val as number);\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = val as number;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [diagLength], v.dtype as DType);\n return new NDArray(storage);\n } else {\n throw new Error('Input must be 1-D or 2-D');\n }\n}\n\n/**\n * Create a 2-D array with the flattened input as a diagonal\n * @param v - Input array (will be flattened)\n * @param k - Diagonal offset (default 0)\n * @returns 2D diagonal matrix\n */\nexport function diagflat(v: NDArray, k: number = 0): NDArray {\n const flat = v.flatten();\n return diag(flat, k);\n}\n\n/**\n * Construct an array by executing a function over each coordinate\n * @param fn - Function that takes coordinate indices and returns value\n * @param shape - Shape of output array\n * @param dtype - Data type (default: float64)\n * @returns Array with values computed from function\n */\nexport function fromfunction(\n fn: (...indices: number[]) => number | bigint | boolean,\n shape: number[],\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n const size = shape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${dtype}`);\n }\n const data = new Constructor(size);\n const ndim = shape.length;\n const indices = new Array(ndim).fill(0);\n\n for (let i = 0; i < size; i++) {\n const value = fn(...indices);\n\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array)[i] =\n typeof value === 'bigint' ? value : BigInt(Number(value));\n } else if (dtype === 'bool') {\n (data as Uint8Array)[i] = value ? 1 : 0;\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Number(value);\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n indices[d]++;\n if (indices[d]! < shape[d]!) {\n break;\n }\n indices[d] = 0;\n }\n }\n\n const storage = ArrayStorage.fromData(data, shape, dtype);\n return new NDArray(storage);\n}\n\n/**\n * Return coordinate matrices from coordinate vectors\n * @param arrays - 1D coordinate arrays\n * @param indexing - 'xy' (Cartesian, default) or 'ij' (matrix indexing)\n * @returns Array of coordinate grids\n */\nexport function meshgrid(...args: (NDArray | { indexing?: 'xy' | 'ij' })[]): NDArray[] {\n // Parse arguments - last arg might be options\n let arrays: NDArray[] = [];\n let indexing: 'xy' | 'ij' = 'xy';\n\n for (const arg of args) {\n if (arg instanceof NDArray) {\n arrays.push(arg);\n } else if (typeof arg === 'object' && 'indexing' in arg) {\n indexing = arg.indexing || 'xy';\n }\n }\n\n if (arrays.length === 0) {\n return [];\n }\n\n if (arrays.length === 1) {\n return [arrays[0]!.copy()];\n }\n\n // Get sizes\n const sizes = arrays.map((a) => a.size);\n\n // For 'xy' indexing, swap first two dimensions\n if (indexing === 'xy' && arrays.length >= 2) {\n arrays = [arrays[1]!, arrays[0]!, ...arrays.slice(2)];\n [sizes[0], sizes[1]] = [sizes[1]!, sizes[0]!];\n }\n\n // Output shape is the combination of all input sizes\n const outputShape = sizes;\n const ndim = outputShape.length;\n\n const results: NDArray[] = [];\n\n for (let i = 0; i < arrays.length; i++) {\n const inputArr = arrays[i]!;\n const inputSize = inputArr.size;\n\n // Build the shape for broadcasting this array\n const broadcastShape: number[] = new Array(ndim).fill(1);\n broadcastShape[i] = inputSize;\n\n // Reshape and broadcast\n const reshaped = inputArr.reshape(...broadcastShape);\n const resultStorage = advancedOps.broadcast_to(reshaped.storage, outputShape);\n const result = NDArray._fromStorage(resultStorage.copy()); // copy to make contiguous\n results.push(result);\n }\n\n // For 'xy' indexing, swap back the first two results\n if (indexing === 'xy' && results.length >= 2) {\n [results[0], results[1]] = [results[1]!, results[0]!];\n }\n\n return results;\n}\n\n/**\n * An array with ones at and below the given diagonal and zeros elsewhere\n * @param N - Number of rows\n * @param M - Number of columns (default: N)\n * @param k - Diagonal offset (default 0)\n * @param dtype - Data type (default: float64)\n * @returns Triangular array\n */\nexport function tri(N: number, M?: number, k: number = 0, dtype: DType = DEFAULT_DTYPE): NDArray {\n const cols = M ?? N;\n const result = zeros([N, cols], dtype);\n\n for (let i = 0; i < N; i++) {\n for (let j = 0; j <= i + k && j < cols; j++) {\n if (j >= 0) {\n result.set([i, j], 1);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Lower triangle of an array\n * @param m - Input array\n * @param k - Diagonal above which to zero elements (default 0)\n * @returns Copy with upper triangle zeroed\n */\nexport function tril(m: NDArray, k: number = 0): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must have at least 2 dimensions');\n }\n\n const result = m.copy();\n const shape = result.shape;\n const rows = shape[shape.length - 2]!;\n const cols = shape[shape.length - 1]!;\n\n // Handle multi-dimensional arrays\n const outerSize = shape.slice(0, -2).reduce((a, b) => a * b, 1);\n\n for (let outer = 0; outer < outerSize; outer++) {\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n if (j > i + k) {\n // Build the indices array\n const indices: number[] = [];\n let temp = outer;\n for (let d = shape.length - 3; d >= 0; d--) {\n indices.unshift(temp % shape[d]!);\n temp = Math.floor(temp / shape[d]!);\n }\n indices.push(i, j);\n result.set(indices, 0);\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Upper triangle of an array\n * @param m - Input array\n * @param k - Diagonal below which to zero elements (default 0)\n * @returns Copy with lower triangle zeroed\n */\nexport function triu(m: NDArray, k: number = 0): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must have at least 2 dimensions');\n }\n\n const result = m.copy();\n const shape = result.shape;\n const rows = shape[shape.length - 2]!;\n const cols = shape[shape.length - 1]!;\n\n // Handle multi-dimensional arrays\n const outerSize = shape.slice(0, -2).reduce((a, b) => a * b, 1);\n\n for (let outer = 0; outer < outerSize; outer++) {\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n if (j < i + k) {\n // Build the indices array\n const indices: number[] = [];\n let temp = outer;\n for (let d = shape.length - 3; d >= 0; d--) {\n indices.unshift(temp % shape[d]!);\n temp = Math.floor(temp / shape[d]!);\n }\n indices.push(i, j);\n result.set(indices, 0);\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Generate a Vandermonde matrix\n * @param x - Input 1D array\n * @param N - Number of columns (default: length of x)\n * @param increasing - Order of powers (default: false, highest powers first)\n * @returns Vandermonde matrix\n */\nexport function vander(x: NDArray, N?: number, increasing: boolean = false): NDArray {\n if (x.ndim !== 1) {\n throw new Error('Input must be 1-D');\n }\n\n const len = x.size;\n const cols = N ?? len;\n\n if (cols < 0) {\n throw new Error('N must be non-negative');\n }\n\n const result = zeros([len, cols], x.dtype as DType);\n\n for (let i = 0; i < len; i++) {\n const val = x.get([i]) as number;\n for (let j = 0; j < cols; j++) {\n const power = increasing ? j : cols - 1 - j;\n result.set([i, j], Math.pow(val, power));\n }\n }\n\n return result;\n}\n\n/**\n * Interpret a buffer as a 1-dimensional array\n * @param buffer - Buffer-like object (ArrayBuffer, TypedArray, or DataView)\n * @param dtype - Data type (default: float64)\n * @param count - Number of items to read (-1 means all)\n * @param offset - Start reading from this byte offset\n * @returns NDArray from buffer data\n */\nexport function frombuffer(\n buffer: ArrayBuffer | ArrayBufferView,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1,\n offset: number = 0\n): NDArray {\n let arrayBuffer: ArrayBufferLike;\n let byteOffset = offset;\n\n if (buffer instanceof ArrayBuffer) {\n arrayBuffer = buffer;\n } else {\n // It's a TypedArray or DataView\n arrayBuffer = buffer.buffer;\n byteOffset += buffer.byteOffset;\n }\n\n const bytesPerElement = getBytesPerElement(dtype);\n const availableBytes = arrayBuffer.byteLength - byteOffset;\n const maxElements = Math.floor(availableBytes / bytesPerElement);\n const numElements = count < 0 ? maxElements : Math.min(count, maxElements);\n\n if (numElements <= 0) {\n return array([], dtype);\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Unsupported dtype: ${dtype}`);\n }\n\n // Create a view into the buffer\n const data = new Constructor(arrayBuffer as ArrayBuffer, byteOffset, numElements);\n const storage = ArrayStorage.fromData(data as TypedArray, [numElements], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Construct an array by executing a function over each coordinate.\n * Note: This is a JS implementation - fromfile for actual files isn't directly applicable in browser JS.\n * This function creates an array from an iterable or callable.\n * @param file - In JS context, this is an iterable yielding values\n * @param dtype - Data type\n * @param count - Number of items to read (-1 means all)\n * @returns NDArray from the iterable\n */\nexport function fromfile(\n file: Iterable<number | bigint>,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1\n): NDArray {\n // In JavaScript, we interpret this as reading from an iterable\n const values: Array<number | bigint> = [];\n let i = 0;\n\n for (const val of file) {\n if (count >= 0 && i >= count) break;\n values.push(val);\n i++;\n }\n\n return array(values, dtype);\n}\n\n/**\n * Create a new 1-dimensional array from an iterable object\n * @param iter - Iterable object\n * @param dtype - Data type\n * @param count - Number of items to read (-1 means all)\n * @returns NDArray from the iterable\n */\nexport function fromiter(\n iter: Iterable<number | bigint>,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1\n): NDArray {\n const values: Array<number | bigint> = [];\n let i = 0;\n\n for (const val of iter) {\n if (count >= 0 && i >= count) break;\n values.push(val);\n i++;\n }\n\n return array(values, dtype);\n}\n\n/**\n * Create a new 1-dimensional array from text string\n * @param string - Input string containing numbers separated by whitespace or separator\n * @param dtype - Data type (default: float64)\n * @param count - Number of items to read (-1 means all)\n * @param sep - Separator between values (default: any whitespace)\n * @returns NDArray from parsed string\n */\nexport function fromstring(\n string: string,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1,\n sep: string = ''\n): NDArray {\n // Split the string by separator (or whitespace if sep is empty)\n let parts: string[];\n if (sep === '') {\n parts = string.trim().split(/\\s+/);\n } else {\n parts = string.split(sep);\n }\n\n // Parse values\n const values: Array<number | bigint> = [];\n let i = 0;\n for (const part of parts) {\n if (count >= 0 && i >= count) break;\n const trimmed = part.trim();\n if (trimmed === '') continue;\n\n if (isBigIntDType(dtype)) {\n values.push(BigInt(trimmed));\n } else {\n values.push(parseFloat(trimmed));\n }\n i++;\n }\n\n return array(values, dtype);\n}\n\n/**\n * Helper to get bytes per element for a dtype\n */\nfunction getBytesPerElement(dtype: DType): number {\n switch (dtype) {\n case 'int8':\n case 'uint8':\n case 'bool':\n return 1;\n case 'int16':\n case 'uint16':\n return 2;\n case 'int32':\n case 'uint32':\n case 'float32':\n return 4;\n case 'int64':\n case 'uint64':\n case 'float64':\n return 8;\n default:\n return 8;\n }\n}\n\n// Mathematical functions (standalone)\n\n/**\n * Element-wise square root\n * @param x - Input array\n * @returns Array of square roots\n */\nexport function sqrt(x: NDArray): NDArray {\n return x.sqrt();\n}\n\n/**\n * Element-wise power\n * @param x - Base array\n * @param exponent - Exponent (array or scalar)\n * @returns Array of x raised to exponent\n */\nexport function power(x: NDArray, exponent: NDArray | number): NDArray {\n return x.power(exponent);\n}\n\n/**\n * Element-wise absolute value\n * @param x - Input array\n * @returns Array of absolute values\n */\nexport function absolute(x: NDArray): NDArray {\n return x.absolute();\n}\n\n/**\n * Element-wise negation\n * @param x - Input array\n * @returns Array of negated values\n */\nexport function negative(x: NDArray): NDArray {\n return x.negative();\n}\n\n/**\n * Element-wise sign (-1, 0, or 1)\n * @param x - Input array\n * @returns Array of signs\n */\nexport function sign(x: NDArray): NDArray {\n return x.sign();\n}\n\n/**\n * Element-wise modulo\n * @param x - Dividend array\n * @param divisor - Divisor (array or scalar)\n * @returns Remainder after division\n */\nexport function mod(x: NDArray, divisor: NDArray | number): NDArray {\n return x.mod(divisor);\n}\n\n/**\n * Element-wise floor division\n * @param x - Dividend array\n * @param divisor - Divisor (array or scalar)\n * @returns Floor of the quotient\n */\nexport function floor_divide(x: NDArray, divisor: NDArray | number): NDArray {\n return x.floor_divide(divisor);\n}\n\n/**\n * Element-wise positive (unary +)\n * @param x - Input array\n * @returns Copy of the array\n */\nexport function positive(x: NDArray): NDArray {\n return x.positive();\n}\n\n/**\n * Element-wise reciprocal (1/x)\n * @param x - Input array\n * @returns Array of reciprocals\n */\nexport function reciprocal(x: NDArray): NDArray {\n return x.reciprocal();\n}\n\n/**\n * Dot product of two arrays\n *\n * Fully NumPy-compatible. Behavior depends on input dimensions:\n * - 0D \u00B7 0D: Multiply scalars \u2192 scalar\n * - 0D \u00B7 ND or ND \u00B7 0D: Element-wise multiply \u2192 ND\n * - 1D \u00B7 1D: Inner product \u2192 scalar\n * - 2D \u00B7 2D: Matrix multiplication \u2192 2D\n * - 2D \u00B7 1D: Matrix-vector product \u2192 1D\n * - 1D \u00B7 2D: Vector-matrix product \u2192 1D\n * - ND \u00B7 1D (N>2): Sum over last axis \u2192 (N-1)D\n * - 1D \u00B7 ND (N>2): Sum over first axis \u2192 (N-1)D\n * - ND \u00B7 MD (N,M\u22652): Tensor contraction \u2192 (N+M-2)D\n *\n * @param a - First array\n * @param b - Second array\n * @returns Result of dot product\n */\nexport function dot(a: NDArray, b: NDArray): NDArray | number | bigint {\n return a.dot(b);\n}\n\n/**\n * Sum of diagonal elements\n *\n * @param a - Input 2D array\n * @returns Sum of diagonal elements\n */\nexport function trace(a: NDArray): number | bigint {\n return a.trace();\n}\n\n/**\n * Extract a diagonal from a matrix or N-D array\n *\n * @param a - Input array (must be at least 2D)\n * @param offset - Offset of the diagonal from the main diagonal (default: 0)\n * @param axis1 - First axis (default: 0)\n * @param axis2 - Second axis (default: 1)\n * @returns Array containing the diagonal elements\n */\nexport function diagonal(\n a: NDArray,\n offset: number = 0,\n axis1: number = 0,\n axis2: number = 1\n): NDArray {\n const resultStorage = linalgOps.diagonal(a.storage, offset, axis1, axis2);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Kronecker product of two arrays\n *\n * @param a - First input array\n * @param b - Second input array\n * @returns Kronecker product of a and b\n */\nexport function kron(a: NDArray, b: NDArray): NDArray {\n const resultStorage = linalgOps.kron(a.storage, b.storage);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Permute array dimensions\n *\n * @param a - Input array\n * @param axes - Optional permutation of axes (defaults to reverse order)\n * @returns Transposed view\n */\nexport function transpose(a: NDArray, axes?: number[]): NDArray {\n return a.transpose(axes);\n}\n\n/**\n * Inner product of two arrays\n *\n * Contracts over last axes of both arrays.\n * Result shape: (*a.shape[:-1], *b.shape[:-1])\n *\n * @param a - First array\n * @param b - Second array\n * @returns Inner product result\n */\nexport function inner(a: NDArray, b: NDArray): NDArray | number | bigint {\n return a.inner(b);\n}\n\n/**\n * Outer product of two arrays\n *\n * Flattens inputs then computes result[i,j] = a[i] * b[j]\n *\n * @param a - First array\n * @param b - Second array\n * @returns 2D outer product matrix\n */\nexport function outer(a: NDArray, b: NDArray): NDArray {\n return a.outer(b);\n}\n\n/**\n * Tensor dot product along specified axes\n *\n * @param a - First array\n * @param b - Second array\n * @param axes - Axes to contract (integer or [a_axes, b_axes])\n * @returns Tensor dot product\n */\nexport function tensordot(\n a: NDArray,\n b: NDArray,\n axes: number | [number[], number[]] = 2\n): NDArray | number | bigint {\n return a.tensordot(b, axes);\n}\n\n// Trigonometric functions (standalone)\n\n/**\n * Element-wise sine\n * @param x - Input array (angles in radians)\n * @returns Array of sine values\n */\nexport function sin(x: NDArray): NDArray {\n return x.sin();\n}\n\n/**\n * Element-wise cosine\n * @param x - Input array (angles in radians)\n * @returns Array of cosine values\n */\nexport function cos(x: NDArray): NDArray {\n return x.cos();\n}\n\n/**\n * Element-wise tangent\n * @param x - Input array (angles in radians)\n * @returns Array of tangent values\n */\nexport function tan(x: NDArray): NDArray {\n return x.tan();\n}\n\n/**\n * Element-wise inverse sine\n * @param x - Input array (values in range [-1, 1])\n * @returns Array of angles in radians\n */\nexport function arcsin(x: NDArray): NDArray {\n return x.arcsin();\n}\n\n/**\n * Element-wise inverse cosine\n * @param x - Input array (values in range [-1, 1])\n * @returns Array of angles in radians\n */\nexport function arccos(x: NDArray): NDArray {\n return x.arccos();\n}\n\n/**\n * Element-wise inverse tangent\n * @param x - Input array\n * @returns Array of angles in radians\n */\nexport function arctan(x: NDArray): NDArray {\n return x.arctan();\n}\n\n/**\n * Element-wise arc tangent of x1/x2 choosing the quadrant correctly\n * @param x1 - y-coordinates\n * @param x2 - x-coordinates (array or scalar)\n * @returns Angles in radians between -\u03C0 and \u03C0\n */\nexport function arctan2(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.arctan2(x2);\n}\n\n/**\n * Given the \"legs\" of a right triangle, return its hypotenuse\n * Equivalent to sqrt(x1**2 + x2**2), element-wise\n * @param x1 - First leg\n * @param x2 - Second leg (array or scalar)\n * @returns Hypotenuse values\n */\nexport function hypot(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.hypot(x2);\n}\n\n/**\n * Convert angles from radians to degrees\n * @param x - Input array (angles in radians)\n * @returns Angles in degrees\n */\nexport function degrees(x: NDArray): NDArray {\n return x.degrees();\n}\n\n/**\n * Convert angles from degrees to radians\n * @param x - Input array (angles in degrees)\n * @returns Angles in radians\n */\nexport function radians(x: NDArray): NDArray {\n return x.radians();\n}\n\n/**\n * Convert angles from degrees to radians (alias for radians)\n * @param x - Input array (angles in degrees)\n * @returns Angles in radians\n */\nexport function deg2rad(x: NDArray): NDArray {\n return x.radians();\n}\n\n/**\n * Convert angles from radians to degrees (alias for degrees)\n * @param x - Input array (angles in radians)\n * @returns Angles in degrees\n */\nexport function rad2deg(x: NDArray): NDArray {\n return x.degrees();\n}\n\n// Hyperbolic functions (standalone)\n\n/**\n * Element-wise hyperbolic sine\n * @param x - Input array\n * @returns Array of sinh values\n */\nexport function sinh(x: NDArray): NDArray {\n return x.sinh();\n}\n\n/**\n * Element-wise hyperbolic cosine\n * @param x - Input array\n * @returns Array of cosh values\n */\nexport function cosh(x: NDArray): NDArray {\n return x.cosh();\n}\n\n/**\n * Element-wise hyperbolic tangent\n * @param x - Input array\n * @returns Array of tanh values\n */\nexport function tanh(x: NDArray): NDArray {\n return x.tanh();\n}\n\n/**\n * Element-wise inverse hyperbolic sine\n * @param x - Input array\n * @returns Array of arcsinh values\n */\nexport function arcsinh(x: NDArray): NDArray {\n return x.arcsinh();\n}\n\n/**\n * Element-wise inverse hyperbolic cosine\n * @param x - Input array (values >= 1)\n * @returns Array of arccosh values\n */\nexport function arccosh(x: NDArray): NDArray {\n return x.arccosh();\n}\n\n/**\n * Element-wise inverse hyperbolic tangent\n * @param x - Input array (values in range (-1, 1))\n * @returns Array of arctanh values\n */\nexport function arctanh(x: NDArray): NDArray {\n return x.arctanh();\n}\n\n// ========================================\n// Array Manipulation Functions\n// ========================================\n\n/**\n * Swap two axes of an array\n *\n * @param a - Input array\n * @param axis1 - First axis\n * @param axis2 - Second axis\n * @returns View with axes swapped\n */\nexport function swapaxes(a: NDArray, axis1: number, axis2: number): NDArray {\n return a.swapaxes(axis1, axis2);\n}\n\n/**\n * Move axes to new positions\n *\n * @param a - Input array\n * @param source - Original positions of axes to move\n * @param destination - New positions for axes\n * @returns View with axes moved\n */\nexport function moveaxis(\n a: NDArray,\n source: number | number[],\n destination: number | number[]\n): NDArray {\n return a.moveaxis(source, destination);\n}\n\n/**\n * Concatenate arrays along an existing axis\n *\n * @param arrays - Arrays to concatenate\n * @param axis - Axis along which to concatenate (default: 0)\n * @returns Concatenated array\n */\nexport function concatenate(arrays: NDArray[], axis: number = 0): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to concatenate');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.concatenate(storages, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays along a new axis\n *\n * @param arrays - Arrays to stack (must have same shape)\n * @param axis - Axis in the result array along which to stack (default: 0)\n * @returns Stacked array\n */\nexport function stack(arrays: NDArray[], axis: number = 0): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.stack(storages, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays vertically (row-wise)\n *\n * @param arrays - Arrays to stack\n * @returns Vertically stacked array\n */\nexport function vstack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.vstack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays horizontally (column-wise)\n *\n * @param arrays - Arrays to stack\n * @returns Horizontally stacked array\n */\nexport function hstack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.hstack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays depth-wise (along third axis)\n *\n * @param arrays - Arrays to stack\n * @returns Depth-stacked array\n */\nexport function dstack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.dstack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Split array into multiple sub-arrays\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of equal sections or indices where to split\n * @param axis - Axis along which to split (default: 0)\n * @returns List of sub-arrays\n */\nexport function split(\n a: NDArray,\n indicesOrSections: number | number[],\n axis: number = 0\n): NDArray[] {\n const storages = shapeOps.split(a.storage, indicesOrSections, axis);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Split array into multiple sub-arrays (allows unequal splits)\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of sections or indices where to split\n * @param axis - Axis along which to split (default: 0)\n * @returns List of sub-arrays\n */\nexport function array_split(\n a: NDArray,\n indicesOrSections: number | number[],\n axis: number = 0\n): NDArray[] {\n const storages = shapeOps.arraySplit(a.storage, indicesOrSections, axis);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Split array vertically (row-wise)\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of sections or indices where to split\n * @returns List of sub-arrays\n */\nexport function vsplit(a: NDArray, indicesOrSections: number | number[]): NDArray[] {\n const storages = shapeOps.vsplit(a.storage, indicesOrSections);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Split array horizontally (column-wise)\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of sections or indices where to split\n * @returns List of sub-arrays\n */\nexport function hsplit(a: NDArray, indicesOrSections: number | number[]): NDArray[] {\n const storages = shapeOps.hsplit(a.storage, indicesOrSections);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Tile array by repeating along each axis\n *\n * @param a - Input array\n * @param reps - Number of repetitions along each axis\n * @returns Tiled array\n */\nexport function tile(a: NDArray, reps: number | number[]): NDArray {\n const resultStorage = shapeOps.tile(a.storage, reps);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Repeat elements of an array\n *\n * @param a - Input array\n * @param repeats - Number of repetitions for each element\n * @param axis - Axis along which to repeat (if undefined, flattens first)\n * @returns Array with repeated elements\n */\nexport function repeat(a: NDArray, repeats: number | number[], axis?: number): NDArray {\n return a.repeat(repeats, axis);\n}\n\n/**\n * Return a contiguous flattened array\n *\n * @param a - Input array\n * @returns Flattened 1-D array (view if possible)\n */\nexport function ravel(a: NDArray): NDArray {\n return a.ravel();\n}\n\n/**\n * Reshape array to new shape\n *\n * @param a - Input array\n * @param newShape - New shape\n * @returns Reshaped array (view if possible)\n */\nexport function reshape(a: NDArray, newShape: number[]): NDArray {\n return a.reshape(...newShape);\n}\n\n/**\n * Remove axes of length 1\n *\n * @param a - Input array\n * @param axis - Axis to squeeze (optional, squeezes all if not specified)\n * @returns Squeezed array (view)\n */\nexport function squeeze(a: NDArray, axis?: number): NDArray {\n return a.squeeze(axis);\n}\n\n/**\n * Expand the shape of an array by inserting a new axis\n *\n * @param a - Input array\n * @param axis - Position where new axis should be inserted\n * @returns Array with expanded shape (view)\n */\nexport function expand_dims(a: NDArray, axis: number): NDArray {\n return a.expand_dims(axis);\n}\n\n/**\n * Reverse the order of elements along the given axis\n *\n * @param m - Input array\n * @param axis - Axis or axes to flip (flips all if undefined)\n * @returns Flipped array\n */\nexport function flip(m: NDArray, axis?: number | number[]): NDArray {\n const resultStorage = shapeOps.flip(m.storage, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Flip array in the left/right direction (reverse along axis 1)\n *\n * @param m - Input array (must be at least 2-D)\n * @returns Flipped array\n */\nexport function fliplr(m: NDArray): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must be at least 2-D');\n }\n return flip(m, 1);\n}\n\n/**\n * Flip array in the up/down direction (reverse along axis 0)\n *\n * @param m - Input array (must be at least 2-D)\n * @returns Flipped array\n */\nexport function flipud(m: NDArray): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must be at least 2-D');\n }\n return flip(m, 0);\n}\n\n/**\n * Rotate array by 90 degrees\n *\n * @param m - Input array\n * @param k - Number of times to rotate (default 1)\n * @param axes - The axes to rotate in (default [0, 1])\n * @returns Rotated array\n */\nexport function rot90(m: NDArray, k: number = 1, axes: [number, number] = [0, 1]): NDArray {\n const resultStorage = shapeOps.rot90(m.storage, k, axes);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Roll array elements along a given axis\n *\n * @param a - Input array\n * @param shift - Number of positions to shift\n * @param axis - Axis along which to roll (rolls flattened array if undefined)\n * @returns Rolled array\n */\nexport function roll(a: NDArray, shift: number | number[], axis?: number | number[]): NDArray {\n const resultStorage = shapeOps.roll(a.storage, shift, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Roll the specified axis backwards until it lies in a given position\n *\n * @param a - Input array\n * @param axis - The axis to roll backwards\n * @param start - Position to roll to (default 0)\n * @returns Array with rolled axis (view)\n */\nexport function rollaxis(a: NDArray, axis: number, start: number = 0): NDArray {\n const resultStorage = shapeOps.rollaxis(a.storage, axis, start);\n return NDArray._fromStorage(resultStorage, a.base ?? a);\n}\n\n/**\n * Convert inputs to arrays with at least 1 dimension\n *\n * @param arrays - Input arrays\n * @returns Arrays with at least 1 dimension\n */\nexport function atleast_1d(...arrays: NDArray[]): NDArray | NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = shapeOps.atleast1d(storages);\n const results = resultStorages.map((s, i) => {\n if (s === storages[i]) {\n return arrays[i]!;\n }\n return NDArray._fromStorage(s);\n });\n return results.length === 1 ? results[0]! : results;\n}\n\n/**\n * Convert inputs to arrays with at least 2 dimensions\n *\n * @param arrays - Input arrays\n * @returns Arrays with at least 2 dimensions\n */\nexport function atleast_2d(...arrays: NDArray[]): NDArray | NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = shapeOps.atleast2d(storages);\n const results = resultStorages.map((s, i) => {\n if (s === storages[i]) {\n return arrays[i]!;\n }\n return NDArray._fromStorage(s);\n });\n return results.length === 1 ? results[0]! : results;\n}\n\n/**\n * Convert inputs to arrays with at least 3 dimensions\n *\n * @param arrays - Input arrays\n * @returns Arrays with at least 3 dimensions\n */\nexport function atleast_3d(...arrays: NDArray[]): NDArray | NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = shapeOps.atleast3d(storages);\n const results = resultStorages.map((s, i) => {\n if (s === storages[i]) {\n return arrays[i]!;\n }\n return NDArray._fromStorage(s);\n });\n return results.length === 1 ? results[0]! : results;\n}\n\n/**\n * Split array along third axis (depth)\n *\n * @param ary - Input array (must be at least 3-D)\n * @param indices_or_sections - Number of sections or indices where to split\n * @returns List of sub-arrays\n */\nexport function dsplit(ary: NDArray, indices_or_sections: number | number[]): NDArray[] {\n const storages = shapeOps.dsplit(ary.storage, indices_or_sections);\n return storages.map((s) => NDArray._fromStorage(s, ary.base ?? ary));\n}\n\n/**\n * Stack 1-D arrays as columns into a 2-D array\n *\n * @param arrays - 1-D arrays to stack\n * @returns 2-D array with inputs as columns\n */\nexport function column_stack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.columnStack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays in sequence vertically (alias for vstack)\n *\n * @param arrays - Arrays to stack\n * @returns Vertically stacked array\n */\nexport function row_stack(arrays: NDArray[]): NDArray {\n return vstack(arrays);\n}\n\n/**\n * Return a new array with the given shape (repeating data if needed)\n *\n * @param a - Input array\n * @param new_shape - New shape\n * @returns Resized array\n */\nexport function resize(a: NDArray, new_shape: number[]): NDArray {\n const resultStorage = shapeOps.resize(a.storage, new_shape);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Append values to the end of an array\n *\n * @param arr - Input array\n * @param values - Values to append\n * @param axis - Axis along which to append (flattens if undefined)\n * @returns Array with values appended\n */\nexport function append(\n arr: NDArray,\n values: NDArray | ArrayLike<number | bigint> | number,\n axis?: number\n): NDArray {\n // Convert values to NDArray if needed\n const valArray =\n values instanceof NDArray\n ? values\n : array(values as ArrayLike<number | bigint> | number, arr.dtype as DType);\n\n if (axis === undefined) {\n // Flatten both and concatenate\n const flatArr = arr.flatten();\n const flatValues = valArray.flatten();\n return concatenate([flatArr, flatValues]);\n }\n\n // Concatenate along specified axis\n return concatenate([arr, valArray], axis);\n}\n\n/**\n * Return a new array with sub-arrays along an axis deleted\n *\n * @param arr - Input array\n * @param obj - Indices to delete\n * @param axis - Axis along which to delete (flattens if undefined)\n * @returns Array with elements deleted\n */\n\nexport function delete_(arr: NDArray, obj: number | number[], axis?: number): NDArray {\n const dtype = arr.dtype as DType;\n\n if (axis === undefined) {\n // Delete from flattened array\n const flat = arr.flatten();\n const indices = Array.isArray(obj) ? obj : [obj];\n const normalizedIndices = indices.map((i) => (i < 0 ? flat.size + i : i));\n const keepIndices: number[] = [];\n\n for (let i = 0; i < flat.size; i++) {\n if (!normalizedIndices.includes(i)) {\n keepIndices.push(i);\n }\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n const data = new Constructor!(keepIndices.length);\n\n for (let i = 0; i < keepIndices.length; i++) {\n const val = flat.get([keepIndices[i]!]);\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array)[i] =\n typeof val === 'bigint' ? val : BigInt(val as number);\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = val as number;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [keepIndices.length], dtype);\n return new NDArray(storage);\n }\n\n // Delete along specified axis\n const shape = arr.shape;\n const ndim = shape.length;\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const indices = Array.isArray(obj) ? obj : [obj];\n const normalizedIndices = new Set(indices.map((i) => (i < 0 ? axisSize + i : i)));\n\n // Build slices to keep\n const keepRanges: [number, number][] = [];\n let start = 0;\n\n for (let i = 0; i <= axisSize; i++) {\n if (normalizedIndices.has(i) || i === axisSize) {\n if (i > start) {\n keepRanges.push([start, i]);\n }\n start = i + 1;\n }\n }\n\n if (keepRanges.length === 0) {\n // Delete all elements along this axis\n const newShape = [...shape];\n newShape[normalizedAxis] = 0;\n return zeros(newShape, dtype);\n }\n\n // Split and concatenate the kept parts\n const parts: NDArray[] = [];\n for (const [rangeStart, rangeEnd] of keepRanges) {\n // Create a slice for this range\n const slices: string[] = shape.map(() => ':');\n slices[normalizedAxis] = `${rangeStart}:${rangeEnd}`;\n parts.push(arr.slice(...slices));\n }\n\n return concatenate(parts, normalizedAxis);\n}\n\n/**\n * Insert values along the given axis before the given indices\n *\n * @param arr - Input array\n * @param obj - Index before which to insert\n * @param values - Values to insert\n * @param axis - Axis along which to insert (flattens if undefined)\n * @returns Array with values inserted\n */\nexport function insert(\n arr: NDArray,\n obj: number,\n values: NDArray | ArrayLike<number | bigint> | number,\n axis?: number\n): NDArray {\n // Convert values to NDArray if needed\n const valArray =\n values instanceof NDArray\n ? values\n : array(values as ArrayLike<number | bigint> | number, arr.dtype as DType);\n\n if (axis === undefined) {\n // Insert into flattened array\n const flat = arr.flatten();\n const flatValues = valArray.flatten();\n const idx = obj < 0 ? flat.size + obj : obj;\n\n if (idx < 0 || idx > flat.size) {\n throw new Error(`index ${obj} is out of bounds for array of size ${flat.size}`);\n }\n\n const before = idx > 0 ? flat.slice(`0:${idx}`) : null;\n const after = idx < flat.size ? flat.slice(`${idx}:`) : null;\n\n const parts: NDArray[] = [];\n if (before) parts.push(before);\n parts.push(flatValues);\n if (after) parts.push(after);\n\n return concatenate(parts);\n }\n\n // Insert along specified axis\n const shape = arr.shape;\n const ndim = shape.length;\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const idx = obj < 0 ? axisSize + obj : obj;\n\n if (idx < 0 || idx > axisSize) {\n throw new Error(`index ${obj} is out of bounds for axis ${axis} with size ${axisSize}`);\n }\n\n const parts: NDArray[] = [];\n\n if (idx > 0) {\n const slices: string[] = shape.map(() => ':');\n slices[normalizedAxis] = `0:${idx}`;\n parts.push(arr.slice(...slices));\n }\n\n parts.push(valArray);\n\n if (idx < axisSize) {\n const slices: string[] = shape.map(() => ':');\n slices[normalizedAxis] = `${idx}:`;\n parts.push(arr.slice(...slices));\n }\n\n return concatenate(parts, normalizedAxis);\n}\n\n/**\n * Pad an array\n *\n * @param array - Input array\n * @param pad_width - Number of values padded to edges of each axis\n * @param mode - Padding mode ('constant', 'edge', 'reflect', 'symmetric', 'wrap')\n * @param constant_values - Value for constant padding (default 0)\n * @returns Padded array\n */\nexport function pad(\n arr: NDArray,\n pad_width: number | [number, number] | Array<[number, number]>,\n mode: 'constant' | 'edge' | 'reflect' | 'symmetric' | 'wrap' = 'constant',\n constant_values: number = 0\n): NDArray {\n const shape = arr.shape;\n const ndim = shape.length;\n const dtype = arr.dtype as DType;\n\n // Normalize pad_width to [[before, after], ...] for each axis\n let padWidths: Array<[number, number]>;\n if (typeof pad_width === 'number') {\n padWidths = shape.map(() => [pad_width, pad_width] as [number, number]);\n } else if (Array.isArray(pad_width) && typeof pad_width[0] === 'number') {\n // Single [before, after] pair for all axes\n padWidths = shape.map(() => pad_width as [number, number]);\n } else {\n padWidths = pad_width as Array<[number, number]>;\n }\n\n if (padWidths.length !== ndim) {\n throw new Error(`pad_width must have ${ndim} elements`);\n }\n\n // Calculate new shape\n const newShape = shape.map((s, i) => s + padWidths[i]![0] + padWidths[i]![1]);\n const newSize = newShape.reduce((a, b) => a * b, 1);\n\n const Constructor = getTypedArrayConstructor(dtype);\n const outputData = new Constructor!(newSize);\n const isBigInt = isBigIntDType(dtype);\n\n // Initialize with constant value for constant mode\n if (mode === 'constant') {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array).fill(BigInt(constant_values));\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>).fill(constant_values);\n }\n }\n\n // Copy original data to center\n const outputIndices = new Array(ndim).fill(0);\n\n for (let i = 0; i < newSize; i++) {\n // Check if this position is in the original data region\n let inOriginal = true;\n const sourceIndices: number[] = [];\n\n for (let d = 0; d < ndim; d++) {\n const [padBefore] = padWidths[d]!;\n const srcIdx = outputIndices[d]! - padBefore;\n if (srcIdx < 0 || srcIdx >= shape[d]!) {\n inOriginal = false;\n break;\n }\n sourceIndices.push(srcIdx);\n }\n\n let value: number | bigint;\n\n if (inOriginal) {\n // Get from original array\n value = arr.get(sourceIndices) as number | bigint;\n } else if (mode === 'constant') {\n // Already filled with constant\n // Increment indices and continue\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < newShape[d]!) break;\n outputIndices[d] = 0;\n }\n continue;\n } else {\n // Calculate source index based on mode\n const mappedIndices: number[] = [];\n for (let d = 0; d < ndim; d++) {\n const [padBefore] = padWidths[d]!;\n let srcIdx = outputIndices[d]! - padBefore;\n const axisSize = shape[d]!;\n\n if (srcIdx < 0) {\n if (mode === 'edge') {\n srcIdx = 0;\n } else if (mode === 'reflect') {\n srcIdx = -srcIdx;\n if (srcIdx >= axisSize) srcIdx = axisSize - 1;\n } else if (mode === 'symmetric') {\n srcIdx = -srcIdx - 1;\n if (srcIdx >= axisSize) srcIdx = axisSize - 1;\n if (srcIdx < 0) srcIdx = 0;\n } else if (mode === 'wrap') {\n srcIdx = ((srcIdx % axisSize) + axisSize) % axisSize;\n }\n } else if (srcIdx >= axisSize) {\n if (mode === 'edge') {\n srcIdx = axisSize - 1;\n } else if (mode === 'reflect') {\n srcIdx = 2 * axisSize - srcIdx - 2;\n if (srcIdx < 0) srcIdx = 0;\n } else if (mode === 'symmetric') {\n srcIdx = 2 * axisSize - srcIdx - 1;\n if (srcIdx < 0) srcIdx = 0;\n } else if (mode === 'wrap') {\n srcIdx = srcIdx % axisSize;\n }\n }\n\n mappedIndices.push(Math.max(0, Math.min(axisSize - 1, srcIdx)));\n }\n value = arr.get(mappedIndices) as number | bigint;\n }\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] =\n typeof value === 'bigint' ? value : BigInt(Number(value));\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Number(value);\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < newShape[d]!) break;\n outputIndices[d] = 0;\n }\n }\n\n const storage = ArrayStorage.fromData(outputData, newShape, dtype);\n return new NDArray(storage);\n}\n\n// ========================================\n// Advanced Functions\n// ========================================\n\n/**\n * Broadcast an array to a given shape\n *\n * @param a - Input array\n * @param shape - Target shape\n * @returns View broadcast to target shape\n */\nexport function broadcast_to(a: NDArray, shape: number[]): NDArray {\n const resultStorage = advancedOps.broadcast_to(a.storage, shape);\n return NDArray._fromStorage(resultStorage, a.base ?? a);\n}\n\n/**\n * Broadcast arrays to a common shape\n *\n * @param arrays - Arrays to broadcast\n * @returns Arrays broadcast to common shape\n */\nexport function broadcast_arrays(...arrays: NDArray[]): NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = advancedOps.broadcast_arrays(storages);\n return resultStorages.map((s, i) => NDArray._fromStorage(s, arrays[i]!.base ?? arrays[i]!));\n}\n\n/**\n * Compute the broadcast shape for multiple shapes\n *\n * Returns the resulting shape if all shapes are broadcast-compatible.\n * Throws an error if shapes are not broadcast-compatible.\n *\n * @param shapes - Variable number of shapes to broadcast\n * @returns The broadcast output shape\n * @throws Error if shapes are not broadcast-compatible\n */\nexport function broadcast_shapes(...shapes: number[][]): number[] {\n return advancedOps.broadcast_shapes(...shapes);\n}\n\n/**\n * Take elements from an array along an axis\n *\n * @param a - Input array\n * @param indices - Indices of elements to take\n * @param axis - Axis along which to take (if undefined, flattens first)\n * @returns Array with selected elements\n */\nexport function take(a: NDArray, indices: number[], axis?: number): NDArray {\n return a.take(indices, axis);\n}\n\n/**\n * Put values at specified indices (modifies array in-place)\n *\n * @param a - Target array\n * @param indices - Indices at which to place values\n * @param values - Values to put\n */\nexport function put(a: NDArray, indices: number[], values: NDArray | number | bigint): void {\n a.put(indices, values);\n}\n\n/**\n * Construct array from index array and choices\n *\n * @param a - Index array (integer indices into choices)\n * @param choices - Arrays to choose from\n * @returns Array constructed from choices\n */\nexport function choose(a: NDArray, choices: NDArray[]): NDArray {\n const choiceStorages = choices.map((c) => c.storage);\n const resultStorage = advancedOps.choose(a.storage, choiceStorages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Check if two arrays are element-wise equal\n *\n * @param a - First array\n * @param b - Second array\n * @param equal_nan - Whether to consider NaN equal to NaN (default: false)\n * @returns True if arrays are equal element-wise\n */\nexport function array_equal(a: NDArray, b: NDArray, equal_nan: boolean = false): boolean {\n return advancedOps.array_equal(a.storage, b.storage, equal_nan);\n}\n\n/**\n * Returns True if two arrays are element-wise equal within a tolerance.\n * Unlike array_equal, this function broadcasts the arrays before comparison.\n *\n * @param a1 - First input array\n * @param a2 - Second input array\n * @returns True if arrays are equivalent (after broadcasting)\n */\nexport function array_equiv(a1: NDArray, a2: NDArray): boolean {\n return comparisonOps.arrayEquiv(a1.storage, a2.storage);\n}\n\n// ============================================================================\n// Top-level Reduction Functions\n// ============================================================================\n\n/**\n * Return the cumulative sum of the elements along a given axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, flattened array is used.\n * @returns Array with cumulative sums\n */\nexport function cumsum(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumsum(a.storage, axis));\n}\n\n/**\n * Return the cumulative product of the elements along a given axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, flattened array is used.\n * @returns Array with cumulative products\n */\nexport function cumprod(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumprod(a.storage, axis));\n}\n\n/**\n * Peak to peak (maximum - minimum) value along a given axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Peak to peak value(s)\n */\nexport function ptp(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.ptp(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the median along the specified axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median value(s)\n */\nexport function median(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.median(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the q-th percentile of the data along the specified axis.\n * @param a - Input array\n * @param q - Percentile (0-100)\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Percentile value(s)\n */\nexport function percentile(\n a: NDArray,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.percentile(a.storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the q-th quantile of the data along the specified axis.\n * @param a - Input array\n * @param q - Quantile (0-1)\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Quantile value(s)\n */\nexport function quantile(\n a: NDArray,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.quantile(a.storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the weighted average along the specified axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param weights - Array of weights (must be same shape as array along specified axis)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Weighted average value(s)\n */\nexport function average(\n a: NDArray,\n axis?: number,\n weights?: NDArray,\n keepdims: boolean = false\n): NDArray | number {\n const weightsStorage = weights ? weights.storage : undefined;\n const result = reductionOps.average(a.storage, axis, weightsStorage, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n// ============================================================================\n// NaN-aware Reduction Functions\n// ============================================================================\n\n/**\n * Return the sum of array elements over a given axis, treating NaNs as zero.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Sum value(s)\n */\nexport function nansum(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nansum(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return the product of array elements over a given axis, treating NaNs as one.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Product value(s)\n */\nexport function nanprod(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanprod(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the arithmetic mean along the specified axis, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Mean value(s)\n */\nexport function nanmean(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmean(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the variance along the specified axis, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param ddof - Delta degrees of freedom (default 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Variance value(s)\n */\nexport function nanvar(\n a: NDArray,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.nanvar(a.storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the standard deviation along the specified axis, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param ddof - Delta degrees of freedom (default 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Standard deviation value(s)\n */\nexport function nanstd(\n a: NDArray,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.nanstd(a.storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return minimum of an array, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Minimum value(s)\n */\nexport function nanmin(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmin(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return maximum of an array, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Maximum value(s)\n */\nexport function nanmax(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmax(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return indices of the minimum value, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Index/indices of minimum value(s)\n */\nexport function nanargmin(a: NDArray, axis?: number): NDArray | number {\n const result = reductionOps.nanargmin(a.storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return indices of the maximum value, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Index/indices of maximum value(s)\n */\nexport function nanargmax(a: NDArray, axis?: number): NDArray | number {\n const result = reductionOps.nanargmax(a.storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return cumulative sum of elements, treating NaNs as zero.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Array with cumulative sums\n */\nexport function nancumsum(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumsum(a.storage, axis));\n}\n\n/**\n * Return cumulative product of elements, treating NaNs as one.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Array with cumulative products\n */\nexport function nancumprod(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumprod(a.storage, axis));\n}\n\n/**\n * Compute the median, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median value(s)\n */\nexport function nanmedian(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmedian(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n// ========================================\n// Arithmetic Functions (Additional)\n// ========================================\n\n/**\n * Element-wise cube root\n *\n * @param x - Input array\n * @returns Array with cube root of each element\n */\nexport function cbrt(x: NDArray): NDArray {\n return x.cbrt();\n}\n\n/**\n * Element-wise absolute value (always returns float)\n *\n * @param x - Input array\n * @returns Array with absolute values as float\n */\nexport function fabs(x: NDArray): NDArray {\n return x.fabs();\n}\n\n/**\n * Returns both quotient and remainder (floor divide and modulo)\n *\n * @param x - Dividend array\n * @param y - Divisor (array or scalar)\n * @returns Tuple of [quotient, remainder] arrays\n */\nexport function divmod(x: NDArray, y: NDArray | number): [NDArray, NDArray] {\n return x.divmod(y);\n}\n\n/**\n * Element-wise square (x**2)\n *\n * @param x - Input array\n * @returns Array with squared values\n */\nexport function square(x: NDArray): NDArray {\n return x.square();\n}\n\n/**\n * Element-wise remainder (same as mod)\n *\n * @param x - Dividend array\n * @param y - Divisor (array or scalar)\n * @returns Array with remainder values\n */\nexport function remainder(x: NDArray, y: NDArray | number): NDArray {\n return x.remainder(y);\n}\n\n/**\n * Heaviside step function\n *\n * @param x1 - Input array\n * @param x2 - Value to use when x1 is 0\n * @returns Array with heaviside values (0 if x1 < 0, x2 if x1 == 0, 1 if x1 > 0)\n */\nexport function heaviside(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.heaviside(x2);\n}\n\n// ========================================\n// Linear Algebra Functions (Additional)\n// ========================================\n\n/**\n * Einstein summation convention\n *\n * Performs tensor contractions and reductions using Einstein notation.\n *\n * @param subscripts - Einstein summation subscripts (e.g., 'ij,jk->ik')\n * @param operands - Input arrays\n * @returns Result of the Einstein summation\n *\n * @example\n * // Matrix multiplication\n * einsum('ij,jk->ik', a, b)\n *\n * @example\n * // Inner product\n * einsum('i,i->', a, b)\n *\n * @example\n * // Trace\n * einsum('ii->', a)\n */\nexport function einsum(subscripts: string, ...operands: NDArray[]): NDArray | number | bigint {\n const storages = operands.map((op) => op.storage);\n const result = linalgOps.einsum(subscripts, ...storages);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n}\n", "/**\n * NPY file format constants and type definitions\n *\n * NPY is NumPy's native binary format for storing arrays.\n * Spec: https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html\n */\n\nimport type { DType } from '../../core/dtype';\n\n/**\n * NPY magic number: \\x93NUMPY (6 bytes)\n */\nexport const NPY_MAGIC = new Uint8Array([0x93, 0x4e, 0x55, 0x4d, 0x50, 0x59]);\n\n/**\n * Supported NPY format versions\n * - v1.0: 2-byte header length (max 65535 bytes)\n * - v2.0: 4-byte header length (max 4GB)\n * - v3.0: allows UTF-8 in description (same as v2 otherwise)\n *\n * We read v1, v2, and v3; we write v2 only\n */\nexport interface NpyVersion {\n major: number;\n minor: number;\n}\n\n/**\n * NPY header information\n */\nexport interface NpyHeader {\n /** Data type descriptor (e.g., '<f8', '>i4') */\n descr: string;\n /** Whether array is Fortran-contiguous (column-major) */\n fortran_order: boolean;\n /** Array shape */\n shape: number[];\n}\n\n/**\n * Parsed NPY metadata including version\n */\nexport interface NpyMetadata {\n version: NpyVersion;\n header: NpyHeader;\n /** Byte offset where data starts */\n dataOffset: number;\n}\n\n/**\n * Result of parsing an NPY header descriptor to our DType\n */\nexport interface DTypeParseResult {\n dtype: DType;\n /** Whether the data needs byte swapping (big-endian on little-endian or vice versa) */\n needsByteSwap: boolean;\n /** Element size in bytes */\n itemsize: number;\n}\n\n/**\n * All dtypes we support\n */\nexport const SUPPORTED_DTYPES: DType[] = [\n 'float64',\n 'float32',\n 'int64',\n 'int32',\n 'int16',\n 'int8',\n 'uint64',\n 'uint32',\n 'uint16',\n 'uint8',\n 'bool',\n];\n\n/**\n * Detect system endianness\n */\nexport function isSystemLittleEndian(): boolean {\n const buffer = new ArrayBuffer(2);\n new DataView(buffer).setInt16(0, 256, true);\n return new Int16Array(buffer)[0] === 256;\n}\n\n/**\n * NPY descriptor to DType mapping\n *\n * NumPy descriptors follow the format: <endian><type><size>\n * - Endian: '<' little, '>' big, '=' native, '|' not applicable (1-byte types)\n * - Type: 'f' float, 'i' signed int, 'u' unsigned int, 'b' bool, 'c' complex, etc.\n * - Size: byte size (1, 2, 4, 8)\n */\nconst DESCR_TO_DTYPE: Record<string, DType> = {\n // Float types\n f8: 'float64',\n f4: 'float32',\n // Signed integer types\n i8: 'int64',\n i4: 'int32',\n i2: 'int16',\n i1: 'int8',\n // Unsigned integer types\n u8: 'uint64',\n u4: 'uint32',\n u2: 'uint16',\n u1: 'uint8',\n // Boolean\n b1: 'bool',\n};\n\n/**\n * DType to NPY descriptor mapping (for serialization)\n * We always write little-endian\n */\nexport const DTYPE_TO_DESCR: Record<DType, string> = {\n float64: '<f8',\n float32: '<f4',\n int64: '<i8',\n int32: '<i4',\n int16: '<i2',\n int8: '|i1',\n uint64: '<u8',\n uint32: '<u4',\n uint16: '<u2',\n uint8: '|u1',\n bool: '|b1',\n};\n\n/**\n * Unsupported dtype types (for error messages)\n */\nexport const UNSUPPORTED_DTYPE_PATTERNS: Record<string, string> = {\n c: 'complex numbers',\n S: 'byte strings',\n U: 'Unicode strings',\n O: 'Python objects',\n V: 'structured arrays (void)',\n M: 'datetime64',\n m: 'timedelta64',\n};\n\n/**\n * Parse a NumPy dtype descriptor string to our DType\n *\n * @param descr - NumPy descriptor like '<f8', '>i4', '|b1'\n * @returns Parsed result with dtype and byte order info\n * @throws Error if dtype is not supported\n */\nexport function parseDescriptor(descr: string): DTypeParseResult {\n // Handle structured dtypes (tuples/lists) - not supported\n if (descr.startsWith('[') || descr.startsWith('(')) {\n throw new UnsupportedDTypeError(`Structured/compound dtypes are not supported: ${descr}`);\n }\n\n // Extract endianness, type, and size\n let endian = '';\n let typeAndSize = descr;\n\n // Check for endian prefix\n if (descr[0] === '<' || descr[0] === '>' || descr[0] === '=' || descr[0] === '|') {\n endian = descr[0];\n typeAndSize = descr.slice(1);\n }\n\n // Check for unsupported types\n const typeChar = typeAndSize[0];\n if (typeChar && typeChar in UNSUPPORTED_DTYPE_PATTERNS) {\n throw new UnsupportedDTypeError(\n `Unsupported dtype: ${UNSUPPORTED_DTYPE_PATTERNS[typeChar]} (${descr}). ` +\n `Use the 'force' parameter to skip arrays with unsupported dtypes.`\n );\n }\n\n // Look up in our mapping\n const dtype = DESCR_TO_DTYPE[typeAndSize];\n if (!dtype) {\n throw new UnsupportedDTypeError(\n `Unknown or unsupported dtype descriptor: ${descr}. ` +\n `Supported types: ${SUPPORTED_DTYPES.join(', ')}. ` +\n `Use the 'force' parameter to skip arrays with unsupported dtypes.`\n );\n }\n\n // Determine if byte swapping is needed\n const isLittleEndian = isSystemLittleEndian();\n const dataIsLittleEndian = endian === '<' || endian === '|' || (endian === '=' && isLittleEndian);\n const dataIsBigEndian = endian === '>' || (endian === '=' && !isLittleEndian);\n\n // We need to byte swap if:\n // - Data is big-endian and system is little-endian\n // - Data is little-endian and system is big-endian\n // But only for multi-byte types\n const itemsize = parseInt(typeAndSize.slice(1), 10);\n const needsByteSwap =\n itemsize > 1 &&\n ((dataIsBigEndian && isLittleEndian) || (dataIsLittleEndian && !isLittleEndian));\n\n return {\n dtype,\n needsByteSwap,\n itemsize,\n };\n}\n\n/**\n * Custom error for unsupported dtypes\n */\nexport class UnsupportedDTypeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UnsupportedDTypeError';\n }\n}\n\n/**\n * Custom error for invalid NPY format\n */\nexport class InvalidNpyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidNpyError';\n }\n}\n", "/**\n * NPY file parser\n *\n * Parses NumPy .npy files (both v1 and v2/v3 formats) into NDArray objects.\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { ArrayStorage } from '../../core/storage';\nimport { getTypedArrayConstructor, isBigIntDType, type DType } from '../../core/dtype';\nimport {\n NPY_MAGIC,\n parseDescriptor,\n InvalidNpyError,\n type NpyHeader,\n type NpyMetadata,\n} from './format';\n\n/**\n * Parse an NPY file from a Uint8Array or ArrayBuffer\n *\n * @param buffer - The NPY file contents\n * @returns An NDArray containing the parsed data\n * @throws InvalidNpyError if the file format is invalid\n * @throws UnsupportedDTypeError if the dtype is not supported\n */\nexport function parseNpy(buffer: ArrayBuffer | Uint8Array): NDArray {\n const bytes = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n const metadata = parseNpyHeader(bytes);\n return parseNpyData(bytes, metadata);\n}\n\n/**\n * Parse just the NPY header without reading the data\n *\n * @param bytes - The NPY file bytes\n * @returns Parsed metadata including version, header, and data offset\n */\nexport function parseNpyHeader(bytes: Uint8Array): NpyMetadata {\n // Check minimum size\n if (bytes.length < 10) {\n throw new InvalidNpyError('File too small to be a valid NPY file');\n }\n\n // Verify magic number\n for (let i = 0; i < NPY_MAGIC.length; i++) {\n if (bytes[i] !== NPY_MAGIC[i]) {\n throw new InvalidNpyError('Invalid NPY magic number');\n }\n }\n\n // Read version\n const major = bytes[6]!;\n const minor = bytes[7]!;\n\n if (major !== 1 && major !== 2 && major !== 3) {\n throw new InvalidNpyError(`Unsupported NPY version: ${major}.${minor}`);\n }\n\n // Read header length\n let headerLen: number;\n let headerStart: number;\n\n if (major === 1) {\n // v1.0: 2-byte little-endian header length\n headerLen = bytes[8]! | (bytes[9]! << 8);\n headerStart = 10;\n } else {\n // v2.0 and v3.0: 4-byte little-endian header length\n headerLen = bytes[8]! | (bytes[9]! << 8) | (bytes[10]! << 16) | (bytes[11]! << 24);\n headerStart = 12;\n }\n\n // Read header string\n const headerEnd = headerStart + headerLen;\n if (bytes.length < headerEnd) {\n throw new InvalidNpyError('File truncated: header extends beyond file');\n }\n\n const headerBytes = bytes.slice(headerStart, headerEnd);\n const headerStr = new TextDecoder('utf-8').decode(headerBytes).trim();\n\n // Parse header dictionary\n const header = parseHeaderDict(headerStr);\n\n return {\n version: { major, minor },\n header,\n dataOffset: headerEnd,\n };\n}\n\n/**\n * Parse the data section of an NPY file given parsed metadata\n */\nexport function parseNpyData(bytes: Uint8Array, metadata: NpyMetadata): NDArray {\n const { header, dataOffset } = metadata;\n\n // Parse dtype descriptor\n const { dtype, needsByteSwap, itemsize } = parseDescriptor(header.descr);\n\n // Calculate expected data size\n const numElements = header.shape.reduce((a, b) => a * b, 1);\n const expectedBytes = numElements * itemsize;\n const actualBytes = bytes.length - dataOffset;\n\n if (actualBytes < expectedBytes) {\n throw new InvalidNpyError(\n `File truncated: expected ${expectedBytes} bytes of data, got ${actualBytes}`\n );\n }\n\n // Extract data buffer - create a copy to ensure we have a plain ArrayBuffer\n const dataBuffer = new ArrayBuffer(expectedBytes);\n const dataView = new Uint8Array(dataBuffer);\n dataView.set(bytes.subarray(dataOffset, dataOffset + expectedBytes));\n\n // Create typed array from data\n const typedData = createTypedArray(dataBuffer, dtype, numElements, needsByteSwap, itemsize);\n\n // Handle Fortran order (column-major)\n // NumPy stores data in row-major (C order) by default\n // If fortran_order is true, we need to adjust\n let shape = header.shape;\n let storage: ArrayStorage;\n\n if (header.fortran_order && shape.length > 1) {\n // For Fortran order, we can either:\n // 1. Transpose the shape and data (requires copy)\n // 2. Use column-major strides (creates a view)\n // We'll transpose to convert to C-order for consistency\n const reversedShape = [...shape].reverse();\n const tempStorage = ArrayStorage.fromData(typedData, reversedShape, dtype);\n\n // Transpose to get correct C-order layout\n storage = transposeStorage(tempStorage, reversedShape);\n shape = header.shape; // Use original shape after transpose\n } else {\n storage = ArrayStorage.fromData(typedData, [...shape], dtype);\n }\n\n return new NDArray(storage);\n}\n\n/**\n * Parse the Python dictionary header string\n */\nfunction parseHeaderDict(headerStr: string): NpyHeader {\n // Header is a Python dict literal like:\n // {'descr': '<f8', 'fortran_order': False, 'shape': (3, 4), }\n\n // Simple regex-based parser for the specific format\n const descrMatch = headerStr.match(/'descr'\\s*:\\s*'([^']+)'/);\n const fortranMatch = headerStr.match(/'fortran_order'\\s*:\\s*(True|False)/);\n const shapeMatch = headerStr.match(/'shape'\\s*:\\s*\\(([^)]*)\\)/);\n\n if (!descrMatch || !fortranMatch || !shapeMatch) {\n throw new InvalidNpyError(`Failed to parse NPY header: ${headerStr}`);\n }\n\n const descr = descrMatch[1]!;\n const fortran_order = fortranMatch[1] === 'True';\n\n // Parse shape tuple\n const shapeStr = shapeMatch[1]!.trim();\n let shape: number[];\n\n if (shapeStr === '') {\n // Scalar: shape is ()\n shape = [];\n } else {\n // Parse comma-separated integers\n shape = shapeStr\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s !== '')\n .map((s) => {\n const n = parseInt(s, 10);\n if (isNaN(n)) {\n throw new InvalidNpyError(`Invalid shape value: ${s}`);\n }\n return n;\n });\n }\n\n return { descr, fortran_order, shape };\n}\n\n/**\n * Create a typed array from raw bytes with optional byte swapping\n */\nfunction createTypedArray(\n buffer: ArrayBuffer,\n dtype: DType,\n numElements: number,\n needsByteSwap: boolean,\n itemsize: number\n):\n | Float64Array\n | Float32Array\n | BigInt64Array\n | Int32Array\n | Int16Array\n | Int8Array\n | BigUint64Array\n | Uint32Array\n | Uint16Array\n | Uint8Array {\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new InvalidNpyError(`Cannot create array for dtype: ${dtype}`);\n }\n\n if (!needsByteSwap) {\n // Fast path: no byte swapping needed\n return new Constructor(buffer, 0, numElements);\n }\n\n // Slow path: need to byte swap\n const bytes = new Uint8Array(buffer);\n const swapped = new Uint8Array(buffer.byteLength);\n\n for (let i = 0; i < numElements; i++) {\n const start = i * itemsize;\n // Reverse bytes for this element\n for (let j = 0; j < itemsize; j++) {\n swapped[start + j] = bytes[start + itemsize - 1 - j]!;\n }\n }\n\n return new Constructor(swapped.buffer, 0, numElements);\n}\n\n/**\n * Transpose storage to convert from Fortran to C order\n */\nfunction transposeStorage(storage: ArrayStorage, shape: readonly number[]): ArrayStorage {\n const ndim = shape.length;\n const size = storage.size;\n const dtype = storage.dtype;\n const Constructor = getTypedArrayConstructor(dtype);\n\n if (!Constructor) {\n throw new InvalidNpyError(`Cannot create array for dtype: ${dtype}`);\n }\n\n const newData = new Constructor(size);\n const newShape = [...shape].reverse();\n\n // Compute strides for both orderings\n const oldStrides = computeStrides(shape);\n const newStrides = computeStrides(newShape);\n\n // Copy data with transposition\n const indices = new Array(ndim).fill(0);\n\n for (let linearIdx = 0; linearIdx < size; linearIdx++) {\n // Get multi-index in old layout\n let remaining = linearIdx;\n for (let i = 0; i < ndim; i++) {\n const dimSize = oldStrides[i]!;\n indices[i] = Math.floor(remaining / dimSize);\n remaining = remaining % dimSize;\n }\n\n // Compute new linear index (reverse indices for transpose)\n let newLinearIdx = 0;\n for (let i = 0; i < ndim; i++) {\n newLinearIdx += indices[ndim - 1 - i]! * newStrides[i]!;\n }\n\n // Copy value\n if (isBigIntDType(dtype)) {\n (newData as BigInt64Array | BigUint64Array)[newLinearIdx] = storage.iget(linearIdx) as bigint;\n } else {\n (newData as Exclude<typeof newData, BigInt64Array | BigUint64Array>)[newLinearIdx] =\n storage.iget(linearIdx) as number;\n }\n }\n\n return ArrayStorage.fromData(newData, newShape, dtype);\n}\n\n/**\n * Compute C-order strides for a shape\n */\nfunction computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n", "/**\n * NPY file serializer\n *\n * Serializes NDArray objects to NumPy .npy format (v3.0).\n * Always writes in little-endian, C-contiguous order.\n *\n * v3.0 is identical to v2.0 but allows UTF-8 in dtype descriptions.\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { getDTypeSize, isBigIntDType, type DType } from '../../core/dtype';\nimport { NPY_MAGIC, DTYPE_TO_DESCR, isSystemLittleEndian } from './format';\n\n/**\n * Serialize an NDArray to NPY format (v3.0)\n *\n * @param arr - The NDArray to serialize\n * @returns A Uint8Array containing the NPY file data\n */\nexport function serializeNpy(arr: NDArray): Uint8Array {\n const shape = arr.shape;\n const dtype = arr.dtype as DType;\n\n // Build header dictionary string\n const descr = DTYPE_TO_DESCR[dtype];\n const shapeStr =\n shape.length === 0 ? '()' : shape.length === 1 ? `(${shape[0]},)` : `(${shape.join(', ')})`;\n\n // Python dict format: {'descr': '<f8', 'fortran_order': False, 'shape': (3, 4), }\n let headerDict = `{'descr': '${descr}', 'fortran_order': False, 'shape': ${shapeStr}, }`;\n\n // Header must be padded to 64-byte alignment (including magic, version, header_len)\n // v3.0 uses 4 bytes for header length (same as v2.0)\n // Total prefix is 6 (magic) + 2 (version) + 4 (header_len) = 12 bytes\n // Header string + newline should make total divisible by 64\n const PREFIX_LEN = 12;\n const totalBeforeData = PREFIX_LEN + headerDict.length + 1; // +1 for trailing newline\n const padding = (64 - (totalBeforeData % 64)) % 64;\n headerDict = headerDict + ' '.repeat(padding) + '\\n';\n\n const headerBytes = new TextEncoder().encode(headerDict);\n const headerLen = headerBytes.length;\n\n // Calculate data size\n const numElements = arr.size;\n const itemsize = getDTypeSize(dtype);\n const dataSize = numElements * itemsize;\n\n // Allocate output buffer\n const totalSize = PREFIX_LEN + headerLen + dataSize;\n const output = new Uint8Array(totalSize);\n\n // Write magic number\n output.set(NPY_MAGIC, 0);\n\n // Write version (3.0)\n output[6] = 3;\n output[7] = 0;\n\n // Write header length (4-byte little-endian)\n output[8] = headerLen & 0xff;\n output[9] = (headerLen >> 8) & 0xff;\n output[10] = (headerLen >> 16) & 0xff;\n output[11] = (headerLen >> 24) & 0xff;\n\n // Write header string\n output.set(headerBytes, PREFIX_LEN);\n\n // Write data\n const dataOffset = PREFIX_LEN + headerLen;\n writeArrayData(arr, output.subarray(dataOffset), itemsize);\n\n return output;\n}\n\n/**\n * Write array data to the output buffer\n */\nfunction writeArrayData(arr: NDArray, output: Uint8Array, itemsize: number): void {\n const dtype = arr.dtype as DType;\n const size = arr.size;\n const isLittleEndian = isSystemLittleEndian();\n const isBigInt = isBigIntDType(dtype);\n\n // Get raw data - need to handle non-contiguous arrays\n const storage = arr['_storage']; // Access private member\n const isCContiguous = storage.isCContiguous && storage.offset === 0;\n\n if (isCContiguous && isLittleEndian) {\n // Fast path: just copy the underlying buffer\n const srcData = storage.data;\n const srcBytes = new Uint8Array(srcData.buffer, srcData.byteOffset, size * itemsize);\n output.set(srcBytes);\n } else {\n // Slow path: element by element copy with potential byte swapping\n const dataView = new DataView(output.buffer, output.byteOffset, output.byteLength);\n\n for (let i = 0; i < size; i++) {\n const value = storage.iget(i);\n const offset = i * itemsize;\n\n if (isBigInt) {\n // Write BigInt as little-endian\n writeBigInt64LE(dataView, offset, value as bigint, dtype === 'uint64');\n } else {\n // Write number as little-endian\n writeNumberLE(dataView, offset, value as number, dtype);\n }\n }\n }\n}\n\n/**\n * Write a BigInt as little-endian\n */\nfunction writeBigInt64LE(view: DataView, offset: number, value: bigint, unsigned: boolean): void {\n if (unsigned) {\n view.setBigUint64(offset, value, true);\n } else {\n view.setBigInt64(offset, value, true);\n }\n}\n\n/**\n * Write a number as little-endian\n */\nfunction writeNumberLE(view: DataView, offset: number, value: number, dtype: DType): void {\n switch (dtype) {\n case 'float64':\n view.setFloat64(offset, value, true);\n break;\n case 'float32':\n view.setFloat32(offset, value, true);\n break;\n case 'int32':\n view.setInt32(offset, value, true);\n break;\n case 'int16':\n view.setInt16(offset, value, true);\n break;\n case 'int8':\n view.setInt8(offset, value);\n break;\n case 'uint32':\n view.setUint32(offset, value, true);\n break;\n case 'uint16':\n view.setUint16(offset, value, true);\n break;\n case 'uint8':\n case 'bool':\n view.setUint8(offset, value);\n break;\n default:\n throw new Error(`Unsupported dtype for serialization: ${dtype}`);\n }\n}\n", "/**\n * ZIP file format types and constants\n */\n\n/**\n * ZIP local file header signature\n */\nexport const ZIP_LOCAL_SIGNATURE = 0x04034b50;\n\n/**\n * ZIP central directory header signature\n */\nexport const ZIP_CENTRAL_SIGNATURE = 0x02014b50;\n\n/**\n * ZIP end of central directory signature\n */\nexport const ZIP_END_SIGNATURE = 0x06054b50;\n\n/**\n * Compression methods\n */\nexport const ZIP_STORED = 0; // No compression\nexport const ZIP_DEFLATED = 8; // DEFLATE compression\n\n/**\n * Entry in a ZIP file\n */\nexport interface ZipEntry {\n /** File name */\n name: string;\n /** Uncompressed data */\n data: Uint8Array;\n /** Compression method used */\n compressionMethod: number;\n /** CRC-32 checksum */\n crc32: number;\n /** Compressed size */\n compressedSize: number;\n /** Uncompressed size */\n uncompressedSize: number;\n}\n\n/**\n * Raw entry as read from ZIP (before decompression)\n */\nexport interface RawZipEntry {\n /** File name */\n name: string;\n /** Compressed data */\n compressedData: Uint8Array;\n /** Compression method */\n compressionMethod: number;\n /** CRC-32 checksum */\n crc32: number;\n /** Compressed size */\n compressedSize: number;\n /** Uncompressed size */\n uncompressedSize: number;\n}\n\n/**\n * CRC-32 lookup table\n */\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[i] = c;\n }\n return table;\n})();\n\n/**\n * Calculate CRC-32 checksum\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i++) {\n crc = CRC32_TABLE[(crc ^ data[i]!) & 0xff]! ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n", "/**\n * Minimal ZIP file reader\n *\n * Reads ZIP files with STORED or DEFLATE compression.\n * Uses the Compression Streams API (built into modern browsers and Node.js 18+).\n */\n\nimport {\n ZIP_LOCAL_SIGNATURE,\n ZIP_END_SIGNATURE,\n ZIP_STORED,\n ZIP_DEFLATED,\n type RawZipEntry,\n} from './types';\n\n/**\n * Read a ZIP file and return its entries\n *\n * @param buffer - ZIP file contents\n * @returns Map of file names to their uncompressed data\n */\nexport async function readZip(buffer: ArrayBuffer | Uint8Array): Promise<Map<string, Uint8Array>> {\n const entries = parseZipEntries(buffer);\n const result = new Map<string, Uint8Array>();\n\n for (const entry of entries) {\n const data = await decompressEntry(entry);\n result.set(entry.name, data);\n }\n\n return result;\n}\n\n/**\n * Synchronously read a ZIP file (only works for STORED entries)\n *\n * @param buffer - ZIP file contents\n * @returns Map of file names to their uncompressed data\n * @throws Error if any entry uses compression\n */\nexport function readZipSync(buffer: ArrayBuffer | Uint8Array): Map<string, Uint8Array> {\n const entries = parseZipEntries(buffer);\n const result = new Map<string, Uint8Array>();\n\n for (const entry of entries) {\n if (entry.compressionMethod !== ZIP_STORED) {\n throw new Error(\n `Cannot read compressed entry synchronously: ${entry.name}. ` +\n `Use readZip() (async) for DEFLATE-compressed files.`\n );\n }\n result.set(entry.name, entry.compressedData);\n }\n\n return result;\n}\n\n/**\n * Central directory entry info\n */\ninterface CentralDirEntry {\n name: string;\n compressionMethod: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n localHeaderOffset: number;\n}\n\n/**\n * Parse ZIP entries without decompressing\n *\n * Uses central directory for reliable size information, as some ZIP writers\n * (including Python's zipfile module used by NumPy) set local header sizes to\n * 0xFFFFFFFF when streaming.\n */\nfunction parseZipEntries(buffer: ArrayBuffer | Uint8Array): RawZipEntry[] {\n const bytes = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const entries: RawZipEntry[] = [];\n\n // Find end of central directory\n let eocdOffset = -1;\n for (let i = bytes.length - 22; i >= 0; i--) {\n if (view.getUint32(i, true) === ZIP_END_SIGNATURE) {\n eocdOffset = i;\n break;\n }\n }\n\n if (eocdOffset === -1) {\n throw new Error('Invalid ZIP file: end of central directory not found');\n }\n\n // Read central directory location\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n const numEntries = view.getUint16(eocdOffset + 10, true);\n\n // Parse central directory entries first to get reliable sizes\n const centralEntries: CentralDirEntry[] = [];\n let cdOffset = centralDirOffset;\n\n for (let i = 0; i < numEntries; i++) {\n const signature = view.getUint32(cdOffset, true);\n if (signature !== 0x02014b50) {\n // Central directory signature\n break;\n }\n\n const compressionMethod = view.getUint16(cdOffset + 10, true);\n const crc32 = view.getUint32(cdOffset + 16, true);\n const compressedSize = view.getUint32(cdOffset + 20, true);\n const uncompressedSize = view.getUint32(cdOffset + 24, true);\n const fileNameLength = view.getUint16(cdOffset + 28, true);\n const extraFieldLength = view.getUint16(cdOffset + 30, true);\n const commentLength = view.getUint16(cdOffset + 32, true);\n const localHeaderOffset = view.getUint32(cdOffset + 42, true);\n\n const fileNameBytes = bytes.slice(cdOffset + 46, cdOffset + 46 + fileNameLength);\n const fileName = new TextDecoder('utf-8').decode(fileNameBytes);\n\n centralEntries.push({\n name: fileName,\n compressionMethod,\n crc32,\n compressedSize,\n uncompressedSize,\n localHeaderOffset,\n });\n\n cdOffset = cdOffset + 46 + fileNameLength + extraFieldLength + commentLength;\n }\n\n // Now extract data using local headers for data location, but central directory for sizes\n for (const ce of centralEntries) {\n const localOffset = ce.localHeaderOffset;\n const signature = view.getUint32(localOffset, true);\n\n if (signature !== ZIP_LOCAL_SIGNATURE) {\n throw new Error(`Invalid local file header at offset ${localOffset}`);\n }\n\n const fileNameLength = view.getUint16(localOffset + 26, true);\n const extraFieldLength = view.getUint16(localOffset + 28, true);\n\n const dataStart = localOffset + 30 + fileNameLength + extraFieldLength;\n const compressedData = bytes.slice(dataStart, dataStart + ce.compressedSize);\n\n entries.push({\n name: ce.name,\n compressedData,\n compressionMethod: ce.compressionMethod,\n crc32: ce.crc32,\n compressedSize: ce.compressedSize,\n uncompressedSize: ce.uncompressedSize,\n });\n }\n\n return entries;\n}\n\n/**\n * Decompress a single ZIP entry\n */\nasync function decompressEntry(entry: RawZipEntry): Promise<Uint8Array> {\n if (entry.compressionMethod === ZIP_STORED) {\n return entry.compressedData;\n }\n\n if (entry.compressionMethod === ZIP_DEFLATED) {\n return await inflateRaw(entry.compressedData);\n }\n\n throw new Error(`Unsupported compression method: ${entry.compressionMethod}`);\n}\n\n/**\n * Decompress raw DEFLATE data using DecompressionStream\n */\nasync function inflateRaw(data: Uint8Array): Promise<Uint8Array> {\n // Check if DecompressionStream is available\n if (typeof DecompressionStream === 'undefined') {\n throw new Error(\n 'DecompressionStream is not available. ' +\n 'This environment does not support the Compression Streams API. ' +\n 'Please use a modern browser or Node.js 18+.'\n );\n }\n\n // DEFLATE in ZIP is \"raw\" DEFLATE (no zlib header)\n // DecompressionStream expects the \"deflate-raw\" format\n const ds = new DecompressionStream('deflate-raw');\n\n // Create a copy to ensure we have a clean ArrayBuffer (avoids SharedArrayBuffer issues)\n const dataCopy = new Uint8Array(data.length);\n dataCopy.set(data);\n\n const writer = ds.writable.getWriter();\n void writer.write(dataCopy);\n void writer.close();\n\n const reader = ds.readable.getReader();\n const chunks: Uint8Array[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Concatenate chunks\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n", "/**\n * NPZ file parser\n *\n * NPZ is a ZIP archive containing multiple .npy files.\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { parseNpy } from '../npy/parser';\nimport { UnsupportedDTypeError } from '../npy/format';\nimport { readZip, readZipSync } from '../zip/reader';\n\n/**\n * Options for parsing NPZ files\n */\nexport interface NpzParseOptions {\n /**\n * If true, skip arrays with unsupported dtypes instead of throwing an error.\n * Skipped arrays will not be included in the result.\n * Default: false\n */\n force?: boolean;\n}\n\n/**\n * Result of parsing an NPZ file\n */\nexport interface NpzParseResult {\n /** Successfully parsed arrays */\n arrays: Map<string, NDArray>;\n /** Names of arrays that were skipped due to unsupported dtypes (only when force=true) */\n skipped: string[];\n /** Error messages for skipped arrays */\n errors: Map<string, string>;\n}\n\n/**\n * Parse an NPZ file from bytes\n *\n * @param buffer - The NPZ file contents\n * @param options - Parse options\n * @returns Promise resolving to parsed arrays\n */\nexport async function parseNpz(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): Promise<NpzParseResult> {\n const force = options.force ?? false;\n const files = await readZip(buffer);\n return parseNpzFromFiles(files, force);\n}\n\n/**\n * Synchronously parse an NPZ file (only works if not DEFLATE compressed)\n *\n * @param buffer - The NPZ file contents\n * @param options - Parse options\n * @returns Parsed arrays\n */\nexport function parseNpzSync(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): NpzParseResult {\n const force = options.force ?? false;\n const files = readZipSync(buffer);\n return parseNpzFromFiles(files, force);\n}\n\n/**\n * Parse NPZ from already-extracted files\n */\nfunction parseNpzFromFiles(files: Map<string, Uint8Array>, force: boolean): NpzParseResult {\n const arrays = new Map<string, NDArray>();\n const skipped: string[] = [];\n const errors = new Map<string, string>();\n\n for (const [fileName, data] of files) {\n // NPZ entries should have .npy extension\n if (!fileName.endsWith('.npy')) {\n continue;\n }\n\n // Extract array name (remove .npy extension)\n const name = fileName.slice(0, -4);\n\n try {\n const arr = parseNpy(data);\n arrays.set(name, arr);\n } catch (error) {\n if (error instanceof UnsupportedDTypeError && force) {\n // Skip this array but continue processing others\n skipped.push(name);\n errors.set(name, error.message);\n } else {\n // Re-throw all other errors, or UnsupportedDTypeError if force is false\n throw error;\n }\n }\n }\n\n return { arrays, skipped, errors };\n}\n\n/**\n * Convenience function to get arrays as a plain object\n *\n * @param buffer - The NPZ file contents\n * @param options - Parse options\n * @returns Promise resolving to object with array names as keys\n */\nexport async function loadNpz(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): Promise<Record<string, NDArray>> {\n const result = await parseNpz(buffer, options);\n return Object.fromEntries(result.arrays);\n}\n\n/**\n * Synchronous version of loadNpz\n */\nexport function loadNpzSync(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): Record<string, NDArray> {\n const result = parseNpzSync(buffer, options);\n return Object.fromEntries(result.arrays);\n}\n", "/**\n * Minimal ZIP file writer\n *\n * Creates ZIP files with optional DEFLATE compression.\n * Uses the Compression Streams API (built into modern browsers and Node.js 18+).\n */\n\nimport {\n ZIP_LOCAL_SIGNATURE,\n ZIP_CENTRAL_SIGNATURE,\n ZIP_END_SIGNATURE,\n ZIP_STORED,\n ZIP_DEFLATED,\n crc32,\n} from './types';\n\n/**\n * Options for writing a ZIP file\n */\nexport interface ZipWriteOptions {\n /** Whether to compress files (default: false for NPZ compatibility) */\n compress?: boolean;\n}\n\n/**\n * Create a ZIP file from a map of file names to data\n *\n * @param files - Map of file names to their data\n * @param options - Write options\n * @returns ZIP file as Uint8Array\n */\nexport async function writeZip(\n files: Map<string, Uint8Array>,\n options: ZipWriteOptions = {}\n): Promise<Uint8Array> {\n const compress = options.compress ?? false;\n const entries: {\n name: string;\n data: Uint8Array;\n compressedData: Uint8Array;\n crc: number;\n compressionMethod: number;\n offset: number;\n }[] = [];\n\n // Prepare entries\n for (const [name, data] of files) {\n const crc = crc32(data);\n let compressedData: Uint8Array;\n let compressionMethod: number;\n\n if (compress) {\n compressedData = await deflateRaw(data);\n // Only use compression if it actually makes the data smaller\n if (compressedData.length < data.length) {\n compressionMethod = ZIP_DEFLATED;\n } else {\n compressedData = data;\n compressionMethod = ZIP_STORED;\n }\n } else {\n compressedData = data;\n compressionMethod = ZIP_STORED;\n }\n\n entries.push({\n name,\n data,\n compressedData,\n crc,\n compressionMethod,\n offset: 0, // Will be set during writing\n });\n }\n\n // Calculate total size\n let localHeadersSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n localHeadersSize += 30 + nameBytes.length + entry.compressedData.length;\n }\n\n let centralDirSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n centralDirSize += 46 + nameBytes.length;\n }\n\n const eocdSize = 22;\n const totalSize = localHeadersSize + centralDirSize + eocdSize;\n\n // Allocate buffer\n const output = new Uint8Array(totalSize);\n const view = new DataView(output.buffer);\n\n // Write local file headers and data\n let offset = 0;\n for (const entry of entries) {\n entry.offset = offset;\n offset = writeLocalHeader(output, view, offset, entry);\n }\n\n // Write central directory\n const centralDirOffset = offset;\n for (const entry of entries) {\n offset = writeCentralHeader(output, view, offset, entry);\n }\n\n // Write end of central directory\n writeEndOfCentralDirectory(view, offset, entries.length, centralDirSize, centralDirOffset);\n\n return output;\n}\n\n/**\n * Create a ZIP file synchronously (no compression)\n *\n * @param files - Map of file names to their data\n * @returns ZIP file as Uint8Array\n */\nexport function writeZipSync(files: Map<string, Uint8Array>): Uint8Array {\n const entries: {\n name: string;\n data: Uint8Array;\n compressedData: Uint8Array;\n crc: number;\n compressionMethod: number;\n offset: number;\n }[] = [];\n\n // Prepare entries (no compression in sync mode)\n for (const [name, data] of files) {\n const crc = crc32(data);\n entries.push({\n name,\n data,\n compressedData: data,\n crc,\n compressionMethod: ZIP_STORED,\n offset: 0,\n });\n }\n\n // Calculate total size\n let localHeadersSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n localHeadersSize += 30 + nameBytes.length + entry.compressedData.length;\n }\n\n let centralDirSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n centralDirSize += 46 + nameBytes.length;\n }\n\n const eocdSize = 22;\n const totalSize = localHeadersSize + centralDirSize + eocdSize;\n\n // Allocate buffer\n const output = new Uint8Array(totalSize);\n const view = new DataView(output.buffer);\n\n // Write local file headers and data\n let offset = 0;\n for (const entry of entries) {\n entry.offset = offset;\n offset = writeLocalHeader(output, view, offset, entry);\n }\n\n // Write central directory\n const centralDirOffset = offset;\n for (const entry of entries) {\n offset = writeCentralHeader(output, view, offset, entry);\n }\n\n // Write end of central directory\n writeEndOfCentralDirectory(view, offset, entries.length, centralDirSize, centralDirOffset);\n\n return output;\n}\n\n/**\n * Write a local file header and data\n */\nfunction writeLocalHeader(\n output: Uint8Array,\n view: DataView,\n offset: number,\n entry: {\n name: string;\n compressedData: Uint8Array;\n data: Uint8Array;\n crc: number;\n compressionMethod: number;\n }\n): number {\n const nameBytes = new TextEncoder().encode(entry.name);\n\n // Signature\n view.setUint32(offset, ZIP_LOCAL_SIGNATURE, true);\n offset += 4;\n\n // Version needed to extract (2.0 for DEFLATE)\n view.setUint16(offset, entry.compressionMethod === ZIP_DEFLATED ? 20 : 10, true);\n offset += 2;\n\n // General purpose bit flag\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Compression method\n view.setUint16(offset, entry.compressionMethod, true);\n offset += 2;\n\n // Last mod time (use a fixed value)\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Last mod date (use a fixed value)\n view.setUint16(offset, 0x21, true); // Jan 1, 1980\n offset += 2;\n\n // CRC-32\n view.setUint32(offset, entry.crc, true);\n offset += 4;\n\n // Compressed size\n view.setUint32(offset, entry.compressedData.length, true);\n offset += 4;\n\n // Uncompressed size\n view.setUint32(offset, entry.data.length, true);\n offset += 4;\n\n // File name length\n view.setUint16(offset, nameBytes.length, true);\n offset += 2;\n\n // Extra field length\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // File name\n output.set(nameBytes, offset);\n offset += nameBytes.length;\n\n // File data\n output.set(entry.compressedData, offset);\n offset += entry.compressedData.length;\n\n return offset;\n}\n\n/**\n * Write a central directory header\n */\nfunction writeCentralHeader(\n output: Uint8Array,\n view: DataView,\n offset: number,\n entry: {\n name: string;\n compressedData: Uint8Array;\n data: Uint8Array;\n crc: number;\n compressionMethod: number;\n offset: number;\n }\n): number {\n const nameBytes = new TextEncoder().encode(entry.name);\n\n // Signature\n view.setUint32(offset, ZIP_CENTRAL_SIGNATURE, true);\n offset += 4;\n\n // Version made by\n view.setUint16(offset, 20, true);\n offset += 2;\n\n // Version needed to extract\n view.setUint16(offset, entry.compressionMethod === ZIP_DEFLATED ? 20 : 10, true);\n offset += 2;\n\n // General purpose bit flag\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Compression method\n view.setUint16(offset, entry.compressionMethod, true);\n offset += 2;\n\n // Last mod time\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Last mod date\n view.setUint16(offset, 0x21, true);\n offset += 2;\n\n // CRC-32\n view.setUint32(offset, entry.crc, true);\n offset += 4;\n\n // Compressed size\n view.setUint32(offset, entry.compressedData.length, true);\n offset += 4;\n\n // Uncompressed size\n view.setUint32(offset, entry.data.length, true);\n offset += 4;\n\n // File name length\n view.setUint16(offset, nameBytes.length, true);\n offset += 2;\n\n // Extra field length\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // File comment length\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Disk number start\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Internal file attributes\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // External file attributes\n view.setUint32(offset, 0, true);\n offset += 4;\n\n // Relative offset of local header\n view.setUint32(offset, entry.offset, true);\n offset += 4;\n\n // File name\n output.set(nameBytes, offset);\n offset += nameBytes.length;\n\n return offset;\n}\n\n/**\n * Write end of central directory record\n */\nfunction writeEndOfCentralDirectory(\n view: DataView,\n offset: number,\n numEntries: number,\n centralDirSize: number,\n centralDirOffset: number\n): void {\n // Signature\n view.setUint32(offset, ZIP_END_SIGNATURE, true);\n offset += 4;\n\n // Number of this disk\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Disk where central directory starts\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Number of central directory records on this disk\n view.setUint16(offset, numEntries, true);\n offset += 2;\n\n // Total number of central directory records\n view.setUint16(offset, numEntries, true);\n offset += 2;\n\n // Size of central directory\n view.setUint32(offset, centralDirSize, true);\n offset += 4;\n\n // Offset of central directory\n view.setUint32(offset, centralDirOffset, true);\n offset += 4;\n\n // Comment length\n view.setUint16(offset, 0, true);\n}\n\n/**\n * Compress data using raw DEFLATE\n */\nasync function deflateRaw(data: Uint8Array): Promise<Uint8Array> {\n // Check if CompressionStream is available\n if (typeof CompressionStream === 'undefined') {\n throw new Error(\n 'CompressionStream is not available. ' +\n 'This environment does not support the Compression Streams API. ' +\n 'Please use a modern browser or Node.js 18+.'\n );\n }\n\n const cs = new CompressionStream('deflate-raw');\n\n // Create a copy to ensure we have a clean ArrayBuffer (avoids SharedArrayBuffer issues)\n const dataCopy = new Uint8Array(data.length);\n dataCopy.set(data);\n\n const writer = cs.writable.getWriter();\n void writer.write(dataCopy);\n void writer.close();\n\n const reader = cs.readable.getReader();\n const chunks: Uint8Array[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Concatenate chunks\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n", "/**\n * NPZ file serializer\n *\n * Serializes multiple NDArrays to NPZ format (ZIP archive of .npy files).\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { serializeNpy } from '../npy/serializer';\nimport { writeZip, writeZipSync } from '../zip/writer';\n\n/**\n * Input type for arrays - supports:\n * - Array of NDArrays (positional, named arr_0, arr_1, etc.)\n * - Map of names to NDArrays\n * - Object with names as keys\n */\nexport type NpzArraysInput = NDArray[] | Map<string, NDArray> | Record<string, NDArray>;\n\n/**\n * Options for serializing NPZ files\n */\nexport interface NpzSerializeOptions {\n /**\n * Whether to compress the NPZ file using DEFLATE.\n * Default: false (matches np.savez behavior; use true for np.savez_compressed behavior)\n */\n compress?: boolean;\n}\n\n/**\n * Serialize multiple arrays to NPZ format\n *\n * @param arrays - Arrays to save. Can be:\n * - An array of NDArrays (named arr_0, arr_1, etc. like np.savez positional args)\n * - A Map of names to NDArrays\n * - An object with names as keys (like np.savez keyword args)\n * @param options - Serialization options\n * @returns Promise resolving to NPZ file as Uint8Array\n *\n * @example\n * // Positional arrays (named arr_0, arr_1)\n * await serializeNpz([arr1, arr2])\n *\n * // Named arrays\n * await serializeNpz({ x: arr1, y: arr2 })\n */\nexport async function serializeNpz(\n arrays: NpzArraysInput,\n options: NpzSerializeOptions = {}\n): Promise<Uint8Array> {\n const files = prepareNpzFiles(arrays);\n return writeZip(files, { compress: options.compress ?? false });\n}\n\n/**\n * Synchronously serialize multiple arrays to NPZ format (no compression)\n *\n * @param arrays - Arrays to save (same input types as serializeNpz)\n * @returns NPZ file as Uint8Array\n */\nexport function serializeNpzSync(arrays: NpzArraysInput): Uint8Array {\n const files = prepareNpzFiles(arrays);\n return writeZipSync(files);\n}\n\n/**\n * Prepare NPY files for ZIP packaging\n */\nfunction prepareNpzFiles(arrays: NpzArraysInput): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n\n // Handle array input (positional arrays get named arr_0, arr_1, etc.)\n if (Array.isArray(arrays)) {\n for (let i = 0; i < arrays.length; i++) {\n const arr = arrays[i]!;\n const npyData = serializeNpy(arr);\n files.set(`arr_${i}.npy`, npyData);\n }\n return files;\n }\n\n // Handle both Map and plain object\n const entries = arrays instanceof Map ? arrays.entries() : Object.entries(arrays);\n\n for (const [name, arr] of entries) {\n // Validate array name\n if (typeof name !== 'string' || name.length === 0) {\n throw new Error('Array names must be non-empty strings');\n }\n\n // Serialize to NPY format\n const npyData = serializeNpy(arr);\n\n // Add .npy extension\n const fileName = name.endsWith('.npy') ? name : `${name}.npy`;\n files.set(fileName, npyData);\n }\n\n return files;\n}\n"],
5
- "mappings": "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",
6
- "names": ["index_exports", "__export", "DTYPE_TO_DESCR", "InvalidNpyError", "NDArray", "SUPPORTED_DTYPES", "UnsupportedDTypeError", "__version__", "absolute", "append", "arange", "arccos", "arccosh", "arcsin", "arcsinh", "arctan", "arctan2", "arctanh", "array", "array_equal", "array_equiv", "array_split", "asanyarray", "asarray", "ascontiguousarray", "asfortranarray", "atleast_1d", "atleast_2d", "atleast_3d", "average", "broadcast_arrays", "broadcast_shapes", "broadcast_to", "cbrt", "choose", "column_stack", "concatenate", "copy", "cos", "cosh", "cumprod", "cumsum", "deg2rad", "degrees", "delete_", "diag", "diagflat", "diagonal", "divmod", "dot", "dsplit", "dstack", "einsum", "empty", "empty_like", "expand_dims", "eye", "fabs", "flip", "fliplr", "flipud", "floor_divide", "frombuffer", "fromfile", "fromfunction", "fromiter", "fromstring", "full", "full_like", "geomspace", "heaviside", "hsplit", "hstack", "hypot", "identity", "inner", "insert", "kron", "linspace", "loadNpz", "loadNpzSync", "logspace", "median", "meshgrid", "mod", "moveaxis", "nanargmax", "nanargmin", "nancumprod", "nancumsum", "nanmax", "nanmean", "nanmedian", "nanmin", "nanprod", "nanstd", "nansum", "nanvar", "negative", "ones", "ones_like", "outer", "pad", "parseNpy", "parseNpyData", "parseNpyHeader", "parseNpz", "parseNpzSync", "percentile", "positive", "power", "ptp", "put", "quantile", "rad2deg", "radians", "ravel", "reciprocal", "remainder", "repeat", "reshape", "resize", "roll", "rollaxis", "rot90", "row_stack", "serializeNpy", "serializeNpz", "serializeNpzSync", "sign", "sin", "sinh", "split", "sqrt", "square", "squeeze", "stack", "swapaxes", "take", "tan", "tanh", "tensordot", "tile", "trace", "transpose", "tri", "tril", "triu", "vander", "vsplit", "vstack", "zeros", "zeros_like", "__toCommonJS", "parseSlice", "sliceStr", "index", "parts", "start", "stop", "step", "normalizeSlice", "spec", "size", "isIndex", "normalizedStart", "DEFAULT_DTYPE", "getTypedArrayConstructor", "dtype", "getDTypeSize", "isFloatDType", "dtype", "isBigIntDType", "promoteDTypes", "dtype1", "dtype2", "isFloatDType", "intDtype", "isSigned1", "isSigned2", "isUnsigned1", "isUnsigned2", "getSize", "dtype", "size1", "size2", "maxSize", "ArrayStorage", "_ArrayStorage", "data", "shape", "strides", "offset", "dtype", "a", "b", "ndim", "expectedStride", "i", "linearIndex", "remaining", "bufferIndex", "dimSize", "j", "idx", "value", "indices", "size", "Constructor", "getTypedArrayConstructor", "newData", "isBigIntDType", "src", "dst", "finalStrides", "finalOffset", "DEFAULT_DTYPE", "stride", "computeStrides", "broadcastShapes", "shapeA", "shapeB", "ndimA", "ndimB", "ndim", "result", "dimA", "dimB", "broadcastStrides", "shape", "strides", "targetShape", "targetNdim", "targetIdx", "dim", "targetDim", "broadcastTo", "storage", "broadcastedStrides", "ArrayStorage", "elementwiseBinaryOp", "a", "b", "op", "opName", "outputShape", "aBroadcast", "bBroadcast", "resultDtype", "promoteDTypes", "resultData", "size", "isBigIntDType", "resultTyped", "i", "aRaw", "bRaw", "aVal", "bVal", "needsConversion", "elementwiseComparisonOp", "elementwiseUnaryOp", "preserveDtype", "dtype", "inputData", "val", "canUseFastPath", "a", "b", "dim", "i", "add", "addScalar", "addArraysFast", "elementwiseBinaryOp", "x", "y", "dtype", "promoteDTypes", "result", "ArrayStorage", "size", "aData", "bData", "resultData", "isBigIntDType", "resultTyped", "aVal", "bVal", "aTyped", "bTyped", "subtract", "subtractScalar", "subtractArraysFast", "multiply", "multiplyScalar", "multiplyArraysFast", "divide", "divideScalar", "aIsFloat64", "bIsFloat64", "aIsFloat32", "bIsFloat32", "aFloat", "convertToFloatDType", "bFloat", "storage", "targetDtype", "srcData", "dstData", "scalar", "shape", "data", "thisTyped", "scalarBig", "resultDtype", "absolute", "val", "negative", "sign", "mod", "modScalar", "divisor", "divisorBig", "floorDivide", "floorDivideScalar", "positive", "reciprocal", "cbrt", "fabs", "divmod", "quotient", "remainder", "square", "bigData", "bigResultData", "heaviside", "x1", "x2", "x2Data", "x2Shape", "d", "x2Idx", "computeBroadcastShape", "shapes", "maxNdim", "s", "result", "i", "dim", "shape", "shapeIdx", "shapeDim", "broadcastStrides", "shape", "strides", "targetShape", "ndim", "targetNdim", "result", "targetIdx", "dim", "targetDim", "broadcastTo", "storage", "broadcastedStrides", "ArrayStorage", "broadcastShapes", "shapes", "result", "computeBroadcastShape", "shapeStrs", "s", "greater", "a", "b", "greaterScalar", "elementwiseComparisonOp", "x", "y", "greaterEqual", "greaterEqualScalar", "less", "lessScalar", "lessEqual", "lessEqualScalar", "equal", "equalScalar", "notEqual", "notEqualScalar", "isclose", "rtol", "atol", "iscloseScalar", "diff", "threshold", "allclose", "closeResult", "data", "arrayEquiv", "a1", "a2", "shapes", "broadcastShape", "computeBroadcastShape", "b1", "broadcastTo", "b2", "ndim", "size", "acc", "d", "isBigInt1", "isBigIntDType", "isBigInt2", "flatIdx", "temp", "indices", "i", "val1", "val2", "v1", "v2", "storage", "scalar", "thisData", "ArrayStorage", "dtype", "scalarBig", "typedData", "thisTyped", "multiIndexToLinear", "indices", "shape", "linearIdx", "stride", "i", "outerIndexToMultiIndex", "outerIdx", "axis", "axisIdx", "ndim", "outputShape", "_", "remaining", "sum", "storage", "axis", "keepdims", "dtype", "shape", "ndim", "size", "data", "isBigIntDType", "typedData", "total", "i", "normalizedAxis", "outputShape", "_", "result", "ArrayStorage", "resultData", "axisSize", "outerSize", "a", "b", "resultTyped", "outerIdx", "sumVal", "axisIdx", "inputIndices", "outerIndexToMultiIndex", "linearIdx", "multiIndexToLinear", "keepdimsShape", "mean", "sumResult", "divisor", "resultDtype", "sumData", "sumTyped", "max", "maxVal", "firstIndices", "firstIdx", "val", "prod", "product", "prodVal", "min", "minVal", "argmin", "minIdx", "minAxisIdx", "argmax", "maxIdx", "maxAxisIdx", "variance", "ddof", "meanResult", "meanVal", "sumSqDiff", "diff", "meanArray", "meanData", "std", "varResult", "varData", "all", "allTrue", "any", "anyTrue", "cumsum", "strides", "stride", "totalSize", "axisStride", "cumprod", "ptp", "maxResult", "minResult", "maxStorage", "minStorage", "maxData", "minData", "median", "quantile", "percentile", "q", "values", "n", "idx", "lower", "upper", "frac", "average", "weights", "sumWeightedValues", "sumWeights", "weightData", "w", "nansum", "nanprod", "nanmean", "count", "nanvar", "sumSq", "nanstd", "varStorage", "nanmin", "nanmax", "nanargmin", "nanargmax", "nancumsum", "nancumprod", "nanmedian", "mid", "reshape", "storage", "newShape", "size", "dtype", "negIndex", "finalShape", "knownSize", "acc", "dim", "i", "inferredDim", "a", "b", "data", "ArrayStorage", "computeStrides", "flatten", "Constructor", "getTypedArrayConstructor", "newData", "isBigInt", "isBigIntDType", "value", "ravel", "transpose", "axes", "shape", "ndim", "strides", "permutation", "_", "seen", "axis", "normalizedAxis", "ax", "oldStrides", "newStrides", "squeeze", "expandDims", "insertedStride", "swapaxes", "axis1", "axis2", "normalizedAxis1", "normalizedAxis2", "moveaxis", "source", "destination", "sourceArr", "destArr", "normalizedSource", "normalized", "normalizedDest", "order", "dst", "concatenate", "storages", "first", "s", "outputShape", "totalAlongAxis", "outputSize", "outputData", "outputStrides", "offset", "axisSize", "copyToOutput", "_outputShape", "axisOffset", "sourceShape", "sourceSize", "outputOffset", "sourceData", "start", "end", "rows", "cols", "outputCols", "sourceStart", "row", "sourceRowStart", "outputRowStart", "indices", "baseOutputOffset", "outputIdx", "d", "stack", "expanded", "vstack", "prepared", "hstack", "dstack", "split", "indicesOrSections", "splitIndices", "sectionSize", "splitAtIndices", "arraySplit", "numSections", "remainder", "boundaries", "result", "sliceShape", "newOffset", "vsplit", "hsplit", "tile", "reps", "repsArr", "maxDim", "paddedShape", "paddedReps", "expandedStorage", "expandedStrides", "outputIndices", "sourceFlatIdx", "sourceIdx", "repeat", "repeats", "flatSize", "repeatsArr", "outIdx", "rep", "r", "sourceIndices", "axisPositions", "axisIdx", "baseOutIdx", "axisStride", "axisStart", "flip", "axesToFlip", "c", "sourceOffset", "rot90", "k", "axis0", "outIdx0", "outIdx1", "roll", "shift", "flatShift", "flatStorage", "shifts", "normalizedAxes", "j", "sh", "rollaxis", "normalizedStart", "dsplit", "columnStack", "resize", "storage", "newShape", "dtype", "newSize", "a", "b", "oldSize", "Constructor", "getTypedArrayConstructor", "outputData", "isBigInt", "isBigIntDType", "i", "sourceIdx", "value", "ArrayStorage", "atleast1d", "storages", "s", "reshape", "atleast2d", "atleast3d", "dgemm", "layout", "transA", "transB", "M", "N", "K", "alpha", "A", "lda", "B", "ldb", "beta", "C", "ldc", "i", "isRowMajor", "transposeA", "transposeB", "j", "sum", "k", "dot", "a", "b", "aDim", "bDim", "aVal", "bVal", "resultDtype", "promoteDTypes", "result", "ArrayStorage", "bData", "aData", "n", "matmul", "m", "lastDimA", "bSize", "resultShape", "resultSize", "acc", "dim", "temp", "resultIdx", "d", "aIdx", "aSize", "contractAxisB", "contractDimB", "bIdxBefore", "bIdxAfter", "bIdx", "secondLastDimB", "aOuterSize", "bOuterSize", "bLastDim", "contractionDim", "k2", "computeDtype", "aStrideRow", "aStrideCol", "bStrideRow", "bStrideCol", "aIsTransposed", "bIsTransposed", "trace", "rows", "cols", "diagLen", "val", "transpose", "axes", "inner", "aLastDim", "outer", "aFlat", "ravel", "bFlat", "product", "tensordot", "aAxes", "bAxes", "_", "aAxis", "bAxis", "aFreeAxes", "bFreeAxes", "ax", "contractSize", "contractedIdx", "resIdx", "resultIndices", "aFreeIndices", "bFreeIndices", "c", "contractedIndices", "aFullIdx", "bFullIdx", "diagonal", "offset", "axis1", "axis2", "shape", "ndim", "ax1", "ax2", "dim1", "dim2", "outShape", "otherDims", "otherSize", "otherIdx", "otherIndices", "srcIndices", "otherIdx2", "dstIndices", "value", "einsum", "subscripts", "operands", "arrowMatch", "inputSubscripts", "outputSubscript", "inferOutputSubscript", "operandSubscripts", "s", "indexDims", "sub", "op", "idx", "outputIndices", "allInputIndices", "sumIndices", "sub1", "sub2", "op1", "op2", "i1", "j1", "i2", "j2", "o1", "o2", "op1T", "op2T", "computeEinsumScalar", "outputShape", "outputSize", "sumSize", "outIdx", "outMultiIdx", "flatToMulti", "indexValues", "sumIdx", "opIdx", "counts", "count", "flatIdx", "kron", "aShape", "bShape", "aNdim", "bNdim", "aPadded", "bPadded", "aIndices", "aIndicesPadded", "temp2", "bIndices", "bIndicesPadded", "outIndices", "sqrt", "a", "elementwiseUnaryOp", "power", "b", "powerScalar", "elementwiseBinaryOp", "storage", "exponent", "dtype", "shape", "data", "size", "resultDtype", "result", "ArrayStorage", "resultData", "isBigIntDType", "thisTyped", "resultTyped", "i", "sin", "a", "elementwiseUnaryOp", "cos", "tan", "arcsin", "arccos", "arctan", "arctan2", "x1", "x2", "arctan2Scalar", "arctan2Array", "shape", "size", "dtype1", "dtype2", "resultDtype", "result", "ArrayStorage", "resultData", "i", "val1", "isBigIntDType", "val2", "storage", "dtype", "data", "hypot", "hypotScalar", "hypotArray", "degrees", "factor", "x", "radians", "sinh", "a", "elementwiseUnaryOp", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", "broadcast_to", "storage", "targetShape", "shape", "ndim", "targetNdim", "broadcastedShape", "computeBroadcastShape", "broadcastTo", "broadcast_arrays", "storages", "shapes", "s", "take", "storage", "indices", "axis", "shape", "ndim", "dtype", "flatSize", "idx", "normalizedIdx", "outputSize", "Constructor", "getTypedArrayConstructor", "outputData", "i", "value", "isBigIntDType", "ArrayStorage", "normalizedAxis", "axisSize", "outputShape", "a", "b", "outputStrides", "computeStrides", "outputIndices", "sourceIndices", "targetIdx", "sourceAxisIdx", "outIdx", "d", "put", "values", "valueArray", "original", "choose", "indexStorage", "choices", "indexShape", "numChoices", "shapes", "c", "broadcastedShape", "computeBroadcastShape", "broadcastedIndex", "broadcastTo", "broadcastedChoices", "choiceIdx", "array_equal", "equal_nan", "size", "aVal", "bVal", "aIsNaN", "bIsNaN", "NDArray", "_NDArray", "storage", "base", "indices", "normalizedIndices", "idx", "dim", "normalized", "value", "currentDtype", "convertedValue", "isBigIntDType", "dtype", "copy", "shape", "size", "Constructor", "getTypedArrayConstructor", "newData", "oldData", "typedOldData", "i", "ArrayStorage", "other", "otherStorage", "resultStorage", "add", "subtract", "multiply", "divide", "mod", "floorDivide", "positive", "reciprocal", "sqrt", "exponent", "exponentStorage", "power", "absolute", "negative", "sign", "sin", "cos", "tan", "arcsin", "arccos", "arctan", "arctan2", "hypot", "degrees", "radians", "sinh", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", "greater", "greaterEqual", "less", "lessEqual", "equal", "notEqual", "rtol", "atol", "isclose", "allclose", "axis", "keepdims", "result", "sum", "mean", "max", "min", "prod", "argmin", "argmax", "ddof", "variance", "std", "all", "any", "cumsum", "cumprod", "ptp", "median", "q", "percentile", "quantile", "weights", "average", "nansum", "nanprod", "nanmean", "nanvar", "nanstd", "nanmin", "nanmax", "nanargmin", "nanargmax", "nancumsum", "nancumprod", "nanmedian", "newShape", "reshape", "flatten", "ravel", "axes", "transpose", "squeeze", "expandDims", "axis1", "axis2", "swapaxes", "source", "destination", "moveaxis", "repeats", "repeat", "take", "values", "valuesStorage", "put", "matmul", "dot", "trace", "inner", "outer", "tensordot", "cbrt", "fabs", "divisor", "divisorStorage", "quotientStorage", "remainderStorage", "divmod", "square", "remainder", "x2", "x2Storage", "heaviside", "sliceStrs", "sliceSpecs", "str", "spec", "parseSlice", "normalizeSlice", "newStrides", "newOffset", "stride", "dimSize", "slicedStorage", "j", "start", "stop", "ndim", "buildNestedArray", "arr", "zeros", "DEFAULT_DTYPE", "ones", "inferShape", "data", "current", "containsBigInt", "item", "flattenKeepBigInt", "array", "hasBigInt", "a", "b", "actualDtype", "typedData", "flatData", "bigintData", "val", "boolData", "numData", "arange", "step", "actualStart", "actualStop", "length", "linspace", "num", "logspace", "geomspace", "signStart", "signStop", "logStart", "eye", "n", "m", "k", "cols", "empty", "full", "fill_value", "bigintValue", "identity", "asarray", "zeros_like", "ones_like", "empty_like", "full_like", "asanyarray", "ascontiguousarray", "asfortranarray", "diag", "v", "row", "col", "rows", "startRow", "startCol", "diagLength", "diagflat", "flat", "fromfunction", "fn", "d", "meshgrid", "args", "arrays", "indexing", "arg", "sizes", "outputShape", "results", "inputArr", "inputSize", "broadcastShape", "reshaped", "broadcast_to", "tri", "N", "M", "tril", "outerSize", "temp", "triu", "vander", "x", "increasing", "len", "frombuffer", "buffer", "count", "offset", "arrayBuffer", "byteOffset", "bytesPerElement", "getBytesPerElement", "availableBytes", "maxElements", "numElements", "fromfile", "file", "fromiter", "iter", "fromstring", "string", "sep", "parts", "part", "trimmed", "floor_divide", "diagonal", "kron", "x1", "deg2rad", "rad2deg", "concatenate", "storages", "stack", "vstack", "hstack", "dstack", "split", "indicesOrSections", "s", "array_split", "arraySplit", "vsplit", "hsplit", "tile", "reps", "expand_dims", "flip", "fliplr", "flipud", "rot90", "roll", "shift", "rollaxis", "atleast_1d", "atleast1d", "atleast_2d", "atleast2d", "atleast_3d", "atleast3d", "dsplit", "ary", "indices_or_sections", "column_stack", "columnStack", "row_stack", "resize", "new_shape", "append", "valArray", "flatArr", "flatValues", "delete_", "obj", "keepIndices", "normalizedAxis", "axisSize", "keepRanges", "rangeStart", "rangeEnd", "slices", "insert", "before", "after", "pad", "pad_width", "mode", "constant_values", "padWidths", "newSize", "outputData", "isBigInt", "outputIndices", "inOriginal", "sourceIndices", "padBefore", "srcIdx", "mappedIndices", "broadcast_arrays", "broadcast_shapes", "shapes", "broadcastShapes", "choose", "choices", "choiceStorages", "c", "array_equal", "equal_nan", "array_equiv", "a1", "a2", "arrayEquiv", "weightsStorage", "y", "einsum", "subscripts", "operands", "op", "NPY_MAGIC", "SUPPORTED_DTYPES", "isSystemLittleEndian", "buffer", "DESCR_TO_DTYPE", "DTYPE_TO_DESCR", "UNSUPPORTED_DTYPE_PATTERNS", "parseDescriptor", "descr", "UnsupportedDTypeError", "endian", "typeAndSize", "typeChar", "dtype", "isLittleEndian", "dataIsLittleEndian", "dataIsBigEndian", "itemsize", "needsByteSwap", "message", "InvalidNpyError", "parseNpy", "buffer", "bytes", "metadata", "parseNpyHeader", "parseNpyData", "InvalidNpyError", "i", "NPY_MAGIC", "major", "minor", "headerLen", "headerStart", "headerEnd", "headerBytes", "headerStr", "header", "parseHeaderDict", "dataOffset", "dtype", "needsByteSwap", "itemsize", "parseDescriptor", "numElements", "a", "b", "expectedBytes", "actualBytes", "dataBuffer", "typedData", "createTypedArray", "shape", "storage", "reversedShape", "tempStorage", "ArrayStorage", "transposeStorage", "NDArray", "descrMatch", "fortranMatch", "shapeMatch", "descr", "fortran_order", "shapeStr", "s", "n", "Constructor", "getTypedArrayConstructor", "swapped", "start", "j", "ndim", "size", "newData", "newShape", "oldStrides", "computeStrides", "newStrides", "indices", "linearIdx", "remaining", "dimSize", "newLinearIdx", "isBigIntDType", "strides", "stride", "serializeNpy", "arr", "shape", "dtype", "descr", "DTYPE_TO_DESCR", "shapeStr", "headerDict", "PREFIX_LEN", "padding", "headerBytes", "headerLen", "numElements", "itemsize", "getDTypeSize", "dataSize", "totalSize", "output", "NPY_MAGIC", "dataOffset", "writeArrayData", "size", "isLittleEndian", "isSystemLittleEndian", "isBigInt", "isBigIntDType", "storage", "srcData", "srcBytes", "dataView", "i", "value", "offset", "writeBigInt64LE", "writeNumberLE", "view", "unsigned", "CRC32_TABLE", "table", "i", "c", "j", "crc32", "data", "crc", "readZip", "buffer", "entries", "parseZipEntries", "result", "entry", "data", "decompressEntry", "readZipSync", "bytes", "view", "eocdOffset", "i", "centralDirOffset", "numEntries", "centralEntries", "cdOffset", "compressionMethod", "crc32", "compressedSize", "uncompressedSize", "fileNameLength", "extraFieldLength", "commentLength", "localHeaderOffset", "fileNameBytes", "fileName", "ce", "localOffset", "dataStart", "compressedData", "inflateRaw", "ds", "dataCopy", "writer", "reader", "chunks", "done", "value", "totalLength", "sum", "chunk", "offset", "parseNpz", "buffer", "options", "force", "files", "readZip", "parseNpzFromFiles", "parseNpzSync", "readZipSync", "arrays", "skipped", "errors", "fileName", "data", "name", "arr", "parseNpy", "error", "UnsupportedDTypeError", "loadNpz", "result", "loadNpzSync", "writeZip", "files", "options", "compress", "entries", "name", "data", "crc", "crc32", "compressedData", "compressionMethod", "deflateRaw", "localHeadersSize", "entry", "nameBytes", "centralDirSize", "totalSize", "output", "view", "offset", "writeLocalHeader", "centralDirOffset", "writeCentralHeader", "writeEndOfCentralDirectory", "writeZipSync", "numEntries", "cs", "dataCopy", "writer", "reader", "chunks", "done", "value", "totalLength", "sum", "chunk", "result", "serializeNpz", "arrays", "options", "files", "prepareNpzFiles", "writeZip", "serializeNpzSync", "writeZipSync", "i", "arr", "npyData", "serializeNpy", "entries", "name", "fileName", "__version__"]
3
+ "sources": ["../src/index.ts", "../src/core/slicing.ts", "../src/core/dtype.ts", "../src/core/storage.ts", "../src/internal/compute.ts", "../src/ops/arithmetic.ts", "../src/core/broadcasting.ts", "../src/ops/comparison.ts", "../src/internal/indexing.ts", "../src/ops/reduction.ts", "../src/ops/shape.ts", "../src/ops/linalg.ts", "../src/ops/exponential.ts", "../src/ops/trig.ts", "../src/ops/hyperbolic.ts", "../src/ops/advanced.ts", "../src/ops/bitwise.ts", "../src/core/ndarray.ts", "../src/io/npy/format.ts", "../src/io/npy/parser.ts", "../src/io/npy/serializer.ts", "../src/io/zip/types.ts", "../src/io/zip/reader.ts", "../src/io/npz/parser.ts", "../src/io/zip/writer.ts", "../src/io/npz/serializer.ts"],
4
+ "sourcesContent": ["/**\n * numpy-ts - Complete NumPy implementation for TypeScript and JavaScript\n *\n * @module numpy-ts\n */\n\n// Core array functions\nexport {\n NDArray,\n zeros,\n ones,\n array,\n arange,\n linspace,\n logspace,\n geomspace,\n eye,\n empty,\n full,\n identity,\n asarray,\n copy,\n zeros_like,\n ones_like,\n empty_like,\n full_like,\n // New array creation functions\n asanyarray,\n ascontiguousarray,\n asfortranarray,\n diag,\n diagflat,\n frombuffer,\n fromfile,\n fromfunction,\n fromiter,\n fromstring,\n meshgrid,\n tri,\n tril,\n triu,\n vander,\n // Math functions\n sqrt,\n power,\n absolute,\n negative,\n sign,\n mod,\n floor_divide,\n positive,\n reciprocal,\n cbrt,\n fabs,\n divmod,\n square,\n remainder,\n heaviside,\n dot,\n trace,\n diagonal,\n kron,\n transpose,\n inner,\n outer,\n tensordot,\n einsum,\n // Trigonometric functions\n sin,\n cos,\n tan,\n arcsin,\n arccos,\n arctan,\n arctan2,\n hypot,\n degrees,\n radians,\n deg2rad,\n rad2deg,\n // Hyperbolic functions\n sinh,\n cosh,\n tanh,\n arcsinh,\n arccosh,\n arctanh,\n // Array manipulation\n swapaxes,\n moveaxis,\n concatenate,\n stack,\n vstack,\n hstack,\n dstack,\n split,\n array_split,\n vsplit,\n hsplit,\n tile,\n repeat,\n // New array manipulation functions\n ravel,\n reshape,\n squeeze,\n expand_dims,\n flip,\n fliplr,\n flipud,\n rot90,\n roll,\n rollaxis,\n atleast_1d,\n atleast_2d,\n atleast_3d,\n dsplit,\n column_stack,\n row_stack,\n resize,\n append,\n delete_ as delete,\n insert,\n pad,\n // Advanced\n broadcast_to,\n broadcast_arrays,\n broadcast_shapes,\n take,\n put,\n choose,\n array_equal,\n array_equiv,\n // Indexing functions\n take_along_axis,\n put_along_axis,\n putmask,\n compress,\n select,\n place,\n diag_indices,\n diag_indices_from,\n tril_indices,\n tril_indices_from,\n triu_indices,\n triu_indices_from,\n mask_indices,\n indices,\n ix_,\n ravel_multi_index,\n unravel_index,\n // Reduction functions\n cumsum,\n cumprod,\n ptp,\n median,\n percentile,\n quantile,\n average,\n // NaN-aware reduction functions\n nansum,\n nanprod,\n nanmean,\n nanvar,\n nanstd,\n nanmin,\n nanmax,\n nanargmin,\n nanargmax,\n nancumsum,\n nancumprod,\n nanmedian,\n // Bitwise functions\n bitwise_and,\n bitwise_or,\n bitwise_xor,\n bitwise_not,\n invert,\n left_shift,\n right_shift,\n packbits,\n unpackbits,\n} from './core/ndarray';\n\n// IO functions (environment-agnostic parsing/serialization)\n// These work with bytes (ArrayBuffer/Uint8Array), not files\nexport {\n // NPY format\n parseNpy,\n serializeNpy,\n parseNpyHeader,\n parseNpyData,\n UnsupportedDTypeError,\n InvalidNpyError,\n SUPPORTED_DTYPES,\n DTYPE_TO_DESCR,\n type NpyHeader,\n type NpyMetadata,\n type NpyVersion,\n // NPZ format\n parseNpz,\n parseNpzSync,\n loadNpz,\n loadNpzSync,\n serializeNpz,\n serializeNpzSync,\n type NpzParseOptions,\n type NpzParseResult,\n type NpzSerializeOptions,\n} from './io';\n\n// Version (replaced at build time from package.json)\n// In development/tests, use package.json directly; in production, use the replaced value\ndeclare const __VERSION_PLACEHOLDER__: string;\nexport const __version__ =\n typeof __VERSION_PLACEHOLDER__ !== 'undefined' ? __VERSION_PLACEHOLDER__ : '0.7.0'; // Fallback for development/tests\n", "/**\n * Slicing utilities for NumPy-compatible array indexing\n *\n * Supports Python-style slice syntax via strings: \"0:5\", \":\", \"::2\", \"-1\"\n */\n\n/**\n * Represents a parsed slice specification\n */\nexport interface SliceSpec {\n start: number | null;\n stop: number | null;\n step: number;\n isIndex: boolean; // true if this is a single index, not a slice\n}\n\n/**\n * Parse a slice string into a SliceSpec\n *\n * Supports:\n * - Single index: \"5\", \"-1\"\n * - Full slice: \"0:5\", \"2:8\"\n * - With step: \"0:10:2\", \"::2\"\n * - Partial: \"5:\", \":10\", \":\"\n * - Negative: \"-5:\", \":-2\", \"::-1\"\n *\n * @param sliceStr - String representation of slice (e.g., \"0:5\", \":\", \"::2\")\n * @returns Parsed slice specification\n *\n * @example\n * ```typescript\n * parseSlice(\"0:5\") // {start: 0, stop: 5, step: 1, isIndex: false}\n * parseSlice(\":\") // {start: null, stop: null, step: 1, isIndex: false}\n * parseSlice(\"::2\") // {start: null, stop: null, step: 2, isIndex: false}\n * parseSlice(\"-1\") // {start: -1, stop: null, step: 1, isIndex: true}\n * parseSlice(\"5\") // {start: 5, stop: null, step: 1, isIndex: true}\n * ```\n */\nexport function parseSlice(sliceStr: string): SliceSpec {\n // Check if it's a single index (no colons)\n if (!sliceStr.includes(':')) {\n // Reject decimal points - indices must be integers\n if (sliceStr.includes('.')) {\n throw new Error(`Invalid slice index: \"${sliceStr}\" (must be integer)`);\n }\n const index = parseInt(sliceStr, 10);\n if (isNaN(index)) {\n throw new Error(`Invalid slice index: \"${sliceStr}\"`);\n }\n return {\n start: index,\n stop: null,\n step: 1,\n isIndex: true,\n };\n }\n\n // Parse slice notation: start:stop:step\n const parts = sliceStr.split(':');\n\n if (parts.length > 3) {\n throw new Error(`Invalid slice notation: \"${sliceStr}\" (too many colons)`);\n }\n\n const start = parts[0] === '' ? null : parseInt(parts[0]!, 10);\n const stop = parts[1] === '' || parts[1] === undefined ? null : parseInt(parts[1], 10);\n const step = parts[2] === '' || parts[2] === undefined ? 1 : parseInt(parts[2], 10);\n\n // Validate parsed values\n if (start !== null && isNaN(start)) {\n throw new Error(`Invalid start index in slice: \"${sliceStr}\"`);\n }\n if (stop !== null && isNaN(stop)) {\n throw new Error(`Invalid stop index in slice: \"${sliceStr}\"`);\n }\n if (isNaN(step)) {\n throw new Error(`Invalid step in slice: \"${sliceStr}\"`);\n }\n if (step === 0) {\n throw new Error(`Slice step cannot be zero`);\n }\n\n return {\n start,\n stop,\n step,\n isIndex: false,\n };\n}\n\n/**\n * Normalize a slice specification to absolute indices\n *\n * Handles negative indices and defaults:\n * - Negative indices count from the end\n * - null start becomes 0 (or size-1 for negative step)\n * - null stop becomes size (or -1 for negative step)\n *\n * @param spec - Parsed slice specification\n * @param size - Size of the dimension being sliced\n * @returns Normalized slice with absolute start, stop, step\n *\n * @example\n * ```typescript\n * normalizeSlice({start: -1, stop: null, step: 1, isIndex: true}, 10)\n * // {start: 9, stop: 10, step: 1, isIndex: true}\n *\n * normalizeSlice({start: null, stop: -2, step: 1, isIndex: false}, 10)\n * // {start: 0, stop: 8, step: 1, isIndex: false}\n * ```\n */\nexport function normalizeSlice(\n spec: SliceSpec,\n size: number\n): { start: number; stop: number; step: number; isIndex: boolean } {\n let { start, stop } = spec;\n const { step, isIndex } = spec;\n\n // For single index, normalize and return\n if (isIndex) {\n if (start === null) {\n throw new Error('Index cannot be null');\n }\n const normalizedStart = start < 0 ? size + start : start;\n if (normalizedStart < 0 || normalizedStart >= size) {\n throw new Error(`Index ${start} is out of bounds for size ${size}`);\n }\n return {\n start: normalizedStart,\n stop: normalizedStart + 1,\n step: 1,\n isIndex: true,\n };\n }\n\n // Handle slice defaults based on step direction\n if (step > 0) {\n // Forward slice\n if (start === null) start = 0;\n if (stop === null) stop = size;\n } else {\n // Backward slice\n if (start === null) start = size - 1;\n if (stop === null) stop = -size - 1; // Will be normalized to before start\n }\n\n // Normalize negative indices\n if (start < 0) start = size + start;\n if (stop < 0) stop = size + stop;\n\n // Clamp to valid range\n start = Math.max(0, Math.min(start, size));\n stop = Math.max(-1, Math.min(stop, size)); // -1 allowed for backward slices\n\n return {\n start,\n stop,\n step,\n isIndex: false,\n };\n}\n\n/**\n * Compute the length of a slice result\n *\n * @param start - Normalized start index\n * @param stop - Normalized stop index\n * @param step - Step value\n * @returns Number of elements in the slice\n */\nexport function computeSliceLength(start: number, stop: number, step: number): number {\n if (step > 0) {\n if (start >= stop) return 0;\n return Math.ceil((stop - start) / step);\n } else {\n if (start <= stop) return 0;\n return Math.ceil((start - stop) / -step);\n }\n}\n\n/**\n * Parse multiple slice specifications for multi-dimensional indexing\n *\n * @param sliceStrs - Array of slice strings, one per dimension\n * @returns Array of parsed slice specifications\n *\n * @example\n * ```typescript\n * parseSlices([\"0:5\", \":\", \"::2\"])\n * // [\n * // {start: 0, stop: 5, step: 1, isIndex: false},\n * // {start: null, stop: null, step: 1, isIndex: false},\n * // {start: null, stop: null, step: 2, isIndex: false}\n * // ]\n * ```\n */\nexport function parseSlices(sliceStrs: string[]): SliceSpec[] {\n return sliceStrs.map((s) => parseSlice(s));\n}\n", "/**\n * DType (Data Type) system for numpy-ts\n *\n * Supports NumPy numeric types:\n * - Floating point: float32, float64\n * - Signed integers: int8, int16, int32, int64\n * - Unsigned integers: uint8, uint16, uint32, uint64\n * - Boolean: bool\n */\n\n/**\n * All supported dtypes\n */\nexport type DType =\n | 'float64'\n | 'float32'\n | 'int64'\n | 'int32'\n | 'int16'\n | 'int8'\n | 'uint64'\n | 'uint32'\n | 'uint16'\n | 'uint8'\n | 'bool';\n\n/**\n * TypedArray types for each dtype\n */\nexport type TypedArray =\n | Float64Array\n | Float32Array\n | BigInt64Array\n | Int32Array\n | Int16Array\n | Int8Array\n | BigUint64Array\n | Uint32Array\n | Uint16Array\n | Uint8Array;\n\n/**\n * Default dtype (matches NumPy)\n */\nexport const DEFAULT_DTYPE: DType = 'float64';\n\n/**\n * Get the TypedArray constructor for a given dtype\n */\nexport function getTypedArrayConstructor(dtype: DType): TypedArrayConstructor | null {\n switch (dtype) {\n case 'float64':\n return Float64Array;\n case 'float32':\n return Float32Array;\n case 'int64':\n return BigInt64Array;\n case 'int32':\n return Int32Array;\n case 'int16':\n return Int16Array;\n case 'int8':\n return Int8Array;\n case 'uint64':\n return BigUint64Array;\n case 'uint32':\n return Uint32Array;\n case 'uint16':\n return Uint16Array;\n case 'uint8':\n return Uint8Array;\n case 'bool':\n return Uint8Array; // bool is stored as uint8\n default:\n throw new Error(`Unknown dtype: ${dtype}`);\n }\n}\n\ntype TypedArrayConstructor =\n | Float64ArrayConstructor\n | Float32ArrayConstructor\n | BigInt64ArrayConstructor\n | Int32ArrayConstructor\n | Int16ArrayConstructor\n | Int8ArrayConstructor\n | BigUint64ArrayConstructor\n | Uint32ArrayConstructor\n | Uint16ArrayConstructor\n | Uint8ArrayConstructor;\n\n/**\n * Get the element size in bytes for a given dtype\n */\nexport function getDTypeSize(dtype: DType): number {\n switch (dtype) {\n case 'float64':\n case 'int64':\n case 'uint64':\n return 8;\n case 'float32':\n case 'int32':\n case 'uint32':\n return 4;\n case 'int16':\n case 'uint16':\n return 2;\n case 'int8':\n case 'uint8':\n case 'bool':\n return 1;\n default:\n throw new Error(`Unknown dtype: ${dtype}`);\n }\n}\n\n/**\n * Check if dtype is integer\n */\nexport function isIntegerDType(dtype: DType): boolean {\n return (\n dtype === 'int64' ||\n dtype === 'int32' ||\n dtype === 'int16' ||\n dtype === 'int8' ||\n dtype === 'uint64' ||\n dtype === 'uint32' ||\n dtype === 'uint16' ||\n dtype === 'uint8'\n );\n}\n\n/**\n * Check if dtype is floating point\n */\nexport function isFloatDType(dtype: DType): boolean {\n return dtype === 'float64' || dtype === 'float32';\n}\n\n/**\n * Check if dtype uses BigInt\n */\nexport function isBigIntDType(dtype: DType): boolean {\n return dtype === 'int64' || dtype === 'uint64';\n}\n\n/**\n * Infer dtype from JavaScript value\n */\nexport function inferDType(value: unknown): DType {\n if (typeof value === 'bigint') {\n return 'int64';\n } else if (typeof value === 'number') {\n // Check if integer\n if (Number.isInteger(value)) {\n // Choose appropriate integer type based on range\n if (value >= 0 && value <= 255) return 'uint8';\n if (value >= -128 && value <= 127) return 'int8';\n if (value >= 0 && value <= 65535) return 'uint16';\n if (value >= -32768 && value <= 32767) return 'int16';\n if (value >= 0 && value <= 4294967295) return 'uint32';\n if (value >= -2147483648 && value <= 2147483647) return 'int32';\n return 'float64'; // Fallback for large integers\n }\n return 'float64';\n } else if (typeof value === 'boolean') {\n return 'bool';\n }\n return DEFAULT_DTYPE;\n}\n\n/**\n * Promote two dtypes to a common dtype\n * Follows NumPy's type promotion rules\n */\nexport function promoteDTypes(dtype1: DType, dtype2: DType): DType {\n // Same dtype\n if (dtype1 === dtype2) return dtype1;\n\n // Boolean - promote to the other type\n if (dtype1 === 'bool') return dtype2;\n if (dtype2 === 'bool') return dtype1;\n\n // Float types - integer + float always promotes to float\n if (isFloatDType(dtype1) || isFloatDType(dtype2)) {\n // NumPy behavior: Promote to the float type\n // float64 always wins\n if (dtype1 === 'float64' || dtype2 === 'float64') return 'float64';\n\n // float32 with small integers (8, 16 bit) \u2192 float32\n // float32 with large integers (32, 64 bit) \u2192 float64 (precision safety)\n // This is because float32 has 24-bit mantissa, can't hold all int32 values\n if (dtype1 === 'float32') {\n const intDtype = dtype2;\n if (\n intDtype === 'int32' ||\n intDtype === 'int64' ||\n intDtype === 'uint32' ||\n intDtype === 'uint64'\n ) {\n return 'float64';\n }\n return 'float32';\n }\n if (dtype2 === 'float32') {\n const intDtype = dtype1;\n if (\n intDtype === 'int32' ||\n intDtype === 'int64' ||\n intDtype === 'uint32' ||\n intDtype === 'uint64'\n ) {\n return 'float64';\n }\n return 'float32';\n }\n\n // Both are float32\n return 'float32';\n }\n\n // Integer types - complex promotion rules\n const isSigned1 = dtype1.startsWith('int');\n const isSigned2 = dtype2.startsWith('int');\n const isUnsigned1 = dtype1.startsWith('uint');\n const isUnsigned2 = dtype2.startsWith('uint');\n\n // Get bit sizes\n const getSize = (dtype: DType): number => {\n if (dtype.includes('64')) return 64;\n if (dtype.includes('32')) return 32;\n if (dtype.includes('16')) return 16;\n if (dtype.includes('8')) return 8;\n return 0;\n };\n\n const size1 = getSize(dtype1);\n const size2 = getSize(dtype2);\n\n // Special case: int64 + uint64 \u2192 float64 (no larger int type available)\n if ((dtype1 === 'int64' && dtype2 === 'uint64') || (dtype1 === 'uint64' && dtype2 === 'int64')) {\n return 'float64';\n }\n\n // Mixing signed and unsigned of the same size: promote to larger signed type\n if (isSigned1 && isUnsigned2 && size1 === size2) {\n if (size1 === 8) return 'int16';\n if (size1 === 16) return 'int32';\n if (size1 === 32) return 'int64';\n }\n if (isUnsigned1 && isSigned2 && size1 === size2) {\n if (size2 === 8) return 'int16';\n if (size2 === 16) return 'int32';\n if (size2 === 32) return 'int64';\n }\n\n // Same signedness: promote to larger size\n if ((isSigned1 && isSigned2) || (isUnsigned1 && isUnsigned2)) {\n const maxSize = Math.max(size1, size2);\n if (isSigned1) {\n if (maxSize === 64) return 'int64';\n if (maxSize === 32) return 'int32';\n if (maxSize === 16) return 'int16';\n return 'int8';\n } else {\n if (maxSize === 64) return 'uint64';\n if (maxSize === 32) return 'uint32';\n if (maxSize === 16) return 'uint16';\n return 'uint8';\n }\n }\n\n // Different signedness, different sizes: promote to type that can hold both\n // NumPy behavior: If signed type is larger, use it; otherwise promote conservatively\n\n // If signed int is larger than unsigned int, signed int can hold unsigned\n if (isSigned1 && isUnsigned2) {\n if (size1 > size2) {\n // e.g., int16 + uint8 \u2192 int16, int32 + uint16 \u2192 int32\n return dtype1;\n }\n // Otherwise need larger signed type\n // e.g., int8 + uint16 \u2192 int32\n if (size2 === 8) return 'int16';\n if (size2 === 16) return 'int32';\n if (size2 === 32) return 'int64';\n return 'float64'; // uint64 with smaller signed \u2192 float64\n }\n\n if (isUnsigned1 && isSigned2) {\n if (size2 > size1) {\n // e.g., uint8 + int16 \u2192 int16, uint16 + int32 \u2192 int32\n return dtype2;\n }\n // Otherwise need larger signed type\n // e.g., uint16 + int8 \u2192 int32\n if (size1 === 8) return 'int16';\n if (size1 === 16) return 'int32';\n if (size1 === 32) return 'int64';\n return 'float64'; // uint64 with smaller signed \u2192 float64\n }\n\n // Fallback (shouldn't reach here if logic above is complete)\n return 'float64';\n}\n\n/**\n * Validate dtype string\n */\nexport function isValidDType(dtype: string): dtype is DType {\n const validDTypes: DType[] = [\n 'float64',\n 'float32',\n 'int64',\n 'int32',\n 'int16',\n 'int8',\n 'uint64',\n 'uint32',\n 'uint16',\n 'uint8',\n 'bool',\n ];\n return validDTypes.includes(dtype as DType);\n}\n\n/**\n * Convert value to the appropriate type for the given dtype\n */\nexport function castValue(value: number | bigint | boolean, dtype: DType): number | bigint {\n if (isBigIntDType(dtype)) {\n return BigInt(value as number | bigint);\n }\n if (dtype === 'bool') {\n return value ? 1 : 0;\n }\n return Number(value);\n}\n\n/**\n * Map our dtype to @stdlib's supported dtype\n * @stdlib doesn't support int64, uint64 natively, but does support bool\n */\nexport function toStdlibDType(dtype: DType): string {\n // Map int64/uint64 to generic (we manage the BigInt arrays ourselves)\n if (dtype === 'int64' || dtype === 'uint64') {\n return 'generic';\n }\n // All other dtypes (including bool) are supported by stdlib\n return dtype;\n}\n", "/**\n * ArrayStorage - Internal storage abstraction\n *\n * Stores array data directly using TypedArrays without external dependencies.\n *\n * @internal - This is not part of the public API\n */\n\nimport {\n type DType,\n type TypedArray,\n DEFAULT_DTYPE,\n getTypedArrayConstructor,\n isBigIntDType,\n} from './dtype';\n\n/**\n * Internal storage for NDArray data\n * Manages the underlying TypedArray and metadata\n */\nexport class ArrayStorage {\n // Underlying TypedArray data buffer\n private _data: TypedArray;\n // Array shape\n private _shape: readonly number[];\n // Strides for each dimension\n private _strides: readonly number[];\n // Offset into the data buffer\n private _offset: number;\n // Data type\n private _dtype: DType;\n\n constructor(\n data: TypedArray,\n shape: readonly number[],\n strides: readonly number[],\n offset: number,\n dtype: DType\n ) {\n this._data = data;\n this._shape = shape;\n this._strides = strides;\n this._offset = offset;\n this._dtype = dtype;\n }\n\n /**\n * Shape of the array\n */\n get shape(): readonly number[] {\n return this._shape;\n }\n\n /**\n * Number of dimensions\n */\n get ndim(): number {\n return this._shape.length;\n }\n\n /**\n * Total number of elements\n */\n get size(): number {\n return this._shape.reduce((a, b) => a * b, 1);\n }\n\n /**\n * Data type\n */\n get dtype(): DType {\n return this._dtype;\n }\n\n /**\n * Underlying data buffer\n */\n get data(): TypedArray {\n return this._data;\n }\n\n /**\n * Strides (steps in each dimension)\n */\n get strides(): readonly number[] {\n return this._strides;\n }\n\n /**\n * Offset into the data buffer\n */\n get offset(): number {\n return this._offset;\n }\n\n /**\n * Check if array is C-contiguous (row-major, no gaps)\n */\n get isCContiguous(): boolean {\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) return true;\n if (ndim === 1) return strides[0] === 1;\n\n // Check if strides match row-major order\n let expectedStride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n if (strides[i] !== expectedStride) return false;\n expectedStride *= shape[i]!;\n }\n return true;\n }\n\n /**\n * Check if array is F-contiguous (column-major, no gaps)\n */\n get isFContiguous(): boolean {\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) return true;\n if (ndim === 1) return strides[0] === 1;\n\n // Check if strides match column-major order\n let expectedStride = 1;\n for (let i = 0; i < ndim; i++) {\n if (strides[i] !== expectedStride) return false;\n expectedStride *= shape[i]!;\n }\n return true;\n }\n\n /**\n * Get element at linear index (respects strides and offset)\n */\n iget(linearIndex: number): number | bigint {\n // Convert linear index to multi-index, then to actual buffer position\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) {\n return this._data[this._offset]!;\n }\n\n // Convert linear index to multi-index in row-major order\n let remaining = linearIndex;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < ndim; i++) {\n // Compute size of remaining dimensions\n let dimSize = 1;\n for (let j = i + 1; j < ndim; j++) {\n dimSize *= shape[j]!;\n }\n const idx = Math.floor(remaining / dimSize);\n remaining = remaining % dimSize;\n bufferIndex += idx * strides[i]!;\n }\n\n return this._data[bufferIndex]!;\n }\n\n /**\n * Set element at linear index (respects strides and offset)\n */\n iset(linearIndex: number, value: number | bigint): void {\n const shape = this._shape;\n const strides = this._strides;\n const ndim = shape.length;\n\n if (ndim === 0) {\n (this._data as unknown as (number | bigint)[])[this._offset] = value;\n return;\n }\n\n let remaining = linearIndex;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < ndim; i++) {\n let dimSize = 1;\n for (let j = i + 1; j < ndim; j++) {\n dimSize *= shape[j]!;\n }\n const idx = Math.floor(remaining / dimSize);\n remaining = remaining % dimSize;\n bufferIndex += idx * strides[i]!;\n }\n\n (this._data as unknown as (number | bigint)[])[bufferIndex] = value;\n }\n\n /**\n * Get element at multi-index position\n */\n get(...indices: number[]): number | bigint {\n const strides = this._strides;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < indices.length; i++) {\n bufferIndex += indices[i]! * strides[i]!;\n }\n\n return this._data[bufferIndex]!;\n }\n\n /**\n * Set element at multi-index position\n */\n set(indices: number[], value: number | bigint): void {\n const strides = this._strides;\n let bufferIndex = this._offset;\n\n for (let i = 0; i < indices.length; i++) {\n bufferIndex += indices[i]! * strides[i]!;\n }\n\n (this._data as unknown as (number | bigint)[])[bufferIndex] = value;\n }\n\n /**\n * Create a deep copy of this storage\n */\n copy(): ArrayStorage {\n const shape = Array.from(this._shape);\n const dtype = this._dtype;\n const size = this.size;\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot copy array with dtype ${dtype}`);\n }\n\n // Create new data buffer and copy\n const newData = new Constructor(size);\n\n if (this.isCContiguous && this._offset === 0) {\n // Fast path: direct copy\n if (isBigIntDType(dtype)) {\n const src = this._data as BigInt64Array | BigUint64Array;\n const dst = newData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n dst[i] = src[i]!;\n }\n } else {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>).set(\n this._data as Exclude<TypedArray, BigInt64Array | BigUint64Array>\n );\n }\n } else {\n // Slow path: respect strides\n if (isBigIntDType(dtype)) {\n const dst = newData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n dst[i] = this.iget(i) as bigint;\n }\n } else {\n for (let i = 0; i < size; i++) {\n newData[i] = this.iget(i) as number;\n }\n }\n }\n\n return new ArrayStorage(newData, shape, ArrayStorage._computeStrides(shape), 0, dtype);\n }\n\n /**\n * Create storage from TypedArray data\n */\n static fromData(\n data: TypedArray,\n shape: number[],\n dtype: DType,\n strides?: number[],\n offset?: number\n ): ArrayStorage {\n const finalStrides = strides ?? ArrayStorage._computeStrides(shape);\n const finalOffset = offset ?? 0;\n return new ArrayStorage(data, shape, finalStrides, finalOffset, dtype);\n }\n\n /**\n * Create storage with zeros\n */\n static zeros(shape: number[], dtype: DType = DEFAULT_DTYPE): ArrayStorage {\n const size = shape.reduce((a, b) => a * b, 1);\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${dtype}`);\n }\n\n const data = new Constructor(size);\n\n return new ArrayStorage(data, shape, ArrayStorage._computeStrides(shape), 0, dtype);\n }\n\n /**\n * Create storage with ones\n */\n static ones(shape: number[], dtype: DType = DEFAULT_DTYPE): ArrayStorage {\n const size = shape.reduce((a, b) => a * b, 1);\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${dtype}`);\n }\n\n const data = new Constructor(size);\n\n // Fill with ones using native fill (much faster than loop)\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array).fill(BigInt(1));\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>).fill(1);\n }\n\n return new ArrayStorage(data, shape, ArrayStorage._computeStrides(shape), 0, dtype);\n }\n\n /**\n * Compute strides for row-major (C-order) layout\n * @private\n */\n private static _computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n }\n}\n\n/**\n * Compute strides for a given shape (row-major order)\n * @internal\n */\nexport function computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n", "/**\n * Computation backend abstraction\n *\n * Internal module for element-wise and broadcast operations.\n * Provides a swappable backend for different computation strategies.\n *\n * @internal\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { promoteDTypes, isBigIntDType } from '../core/dtype';\n\n/**\n * Compute the broadcast shape of two arrays\n * Returns the shape that results from broadcasting a and b together\n * Throws if shapes are not compatible for broadcasting\n */\nexport function broadcastShapes(shapeA: readonly number[], shapeB: readonly number[]): number[] {\n const ndimA = shapeA.length;\n const ndimB = shapeB.length;\n const ndim = Math.max(ndimA, ndimB);\n const result = new Array(ndim);\n\n for (let i = 0; i < ndim; i++) {\n const dimA = i < ndim - ndimA ? 1 : shapeA[i - (ndim - ndimA)]!;\n const dimB = i < ndim - ndimB ? 1 : shapeB[i - (ndim - ndimB)]!;\n\n if (dimA === dimB) {\n result[i] = dimA;\n } else if (dimA === 1) {\n result[i] = dimB;\n } else if (dimB === 1) {\n result[i] = dimA;\n } else {\n throw new Error(\n `operands could not be broadcast together with shapes ${JSON.stringify(Array.from(shapeA))} ${JSON.stringify(Array.from(shapeB))}`\n );\n }\n }\n\n return result;\n}\n\n/**\n * Compute the strides for broadcasting an array to a target shape\n * Returns strides where dimensions that need broadcasting have stride 0\n */\nfunction broadcastStrides(\n shape: readonly number[],\n strides: readonly number[],\n targetShape: readonly number[]\n): number[] {\n const ndim = shape.length;\n const targetNdim = targetShape.length;\n const result = new Array(targetNdim).fill(0);\n\n // Align dimensions from the right\n for (let i = 0; i < ndim; i++) {\n const targetIdx = targetNdim - ndim + i;\n const dim = shape[i]!;\n const targetDim = targetShape[targetIdx]!;\n\n if (dim === targetDim) {\n // Same size, use original stride\n result[targetIdx] = strides[i]!;\n } else if (dim === 1) {\n // Broadcasting, stride is 0 (repeat along this dimension)\n result[targetIdx] = 0;\n } else {\n // This shouldn't happen if shapes were validated\n throw new Error('Invalid broadcast');\n }\n }\n\n return result;\n}\n\n/**\n * Create a broadcast view of an ArrayStorage\n * The returned storage shares data with the original but has different shape/strides\n */\nfunction broadcastTo(storage: ArrayStorage, targetShape: readonly number[]): ArrayStorage {\n const broadcastedStrides = broadcastStrides(storage.shape, storage.strides, targetShape);\n return ArrayStorage.fromData(\n storage.data,\n Array.from(targetShape),\n storage.dtype,\n broadcastedStrides,\n storage.offset\n );\n}\n\n/**\n * Perform element-wise operation with broadcasting\n *\n * NOTE: This is the slow path for broadcasting/non-contiguous arrays.\n * Fast paths for contiguous arrays are implemented directly in ops/arithmetic.ts\n *\n * @param a - First array storage\n * @param b - Second array storage\n * @param op - Operation to perform (a, b) => result\n * @param opName - Name of operation (for special handling)\n * @returns Result storage\n */\nexport function elementwiseBinaryOp(\n a: ArrayStorage,\n b: ArrayStorage,\n op: (a: number, b: number) => number,\n opName: string\n): ArrayStorage {\n // Compute broadcast shape\n const outputShape = broadcastShapes(a.shape, b.shape);\n\n // Create broadcast views\n const aBroadcast = broadcastTo(a, outputShape);\n const bBroadcast = broadcastTo(b, outputShape);\n\n // Determine output dtype using NumPy promotion rules\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, resultDtype);\n const resultData = result.data;\n const size = result.size;\n\n if (isBigIntDType(resultDtype)) {\n // BigInt arithmetic - no precision loss\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const aRaw = aBroadcast.iget(i);\n const bRaw = bBroadcast.iget(i);\n\n // Convert to BigInt - handle case where value is already BigInt\n const aVal = typeof aRaw === 'bigint' ? aRaw : BigInt(Math.round(aRaw));\n const bVal = typeof bRaw === 'bigint' ? bRaw : BigInt(Math.round(bRaw));\n\n // Use BigInt operations\n if (opName === 'add') {\n resultTyped[i] = aVal + bVal;\n } else if (opName === 'subtract') {\n resultTyped[i] = aVal - bVal;\n } else if (opName === 'multiply') {\n resultTyped[i] = aVal * bVal;\n } else if (opName === 'divide') {\n resultTyped[i] = aVal / bVal;\n } else {\n resultTyped[i] = BigInt(Math.round(op(Number(aVal), Number(bVal))));\n }\n }\n } else {\n // Regular numeric types (including float dtypes)\n // Need to convert BigInt values to Number if mixing dtypes\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n for (let i = 0; i < size; i++) {\n const aRaw = aBroadcast.iget(i);\n const bRaw = bBroadcast.iget(i);\n\n // Convert to Number if needed (handles BigInt \u2192 float promotion)\n const aVal = needsConversion && typeof aRaw === 'bigint' ? Number(aRaw) : Number(aRaw);\n const bVal = needsConversion && typeof bRaw === 'bigint' ? Number(bRaw) : Number(bRaw);\n\n resultData[i] = op(aVal, bVal);\n }\n }\n\n return result;\n}\n\n/**\n * Perform element-wise comparison with broadcasting\n * Returns boolean array (dtype: 'bool', stored as Uint8Array)\n */\nexport function elementwiseComparisonOp(\n a: ArrayStorage,\n b: ArrayStorage,\n op: (a: number, b: number) => boolean\n): ArrayStorage {\n // Compute broadcast shape\n const outputShape = broadcastShapes(a.shape, b.shape);\n\n // Create broadcast views\n const aBroadcast = broadcastTo(a, outputShape);\n const bBroadcast = broadcastTo(b, outputShape);\n\n // Get output shape\n const size = outputShape.reduce((a, b) => a * b, 1);\n\n // Create result array with bool dtype\n const resultData = new Uint8Array(size);\n\n // Check if we need to convert BigInt to Number for comparison\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n // Perform element-wise comparison\n for (let i = 0; i < size; i++) {\n const aRaw = aBroadcast.iget(i);\n const bRaw = bBroadcast.iget(i);\n\n // Convert BigInt to Number if needed\n const aVal = needsConversion && typeof aRaw === 'bigint' ? Number(aRaw) : Number(aRaw);\n const bVal = needsConversion && typeof bRaw === 'bigint' ? Number(bRaw) : Number(bRaw);\n\n resultData[i] = op(aVal, bVal) ? 1 : 0;\n }\n\n return ArrayStorage.fromData(resultData, outputShape, 'bool');\n}\n\n/**\n * Perform element-wise unary operation\n *\n * @param a - Input array storage\n * @param op - Operation to perform (x) => result\n * @param preserveDtype - If true, preserve input dtype; if false, promote to float64 (default: true)\n * @returns Result storage\n */\nexport function elementwiseUnaryOp(\n a: ArrayStorage,\n op: (x: number) => number,\n preserveDtype = true\n): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const size = a.size;\n\n // Determine output dtype\n // Math operations like sqrt may need float output even for integer input\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = preserveDtype ? dtype : isIntegerType ? 'float64' : dtype;\n\n // Create result storage\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n const inputData = a.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt input - convert to Number for operation, then convert back if preserving dtype\n if (isBigIntDType(resultDtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = Number(inputData[i]!);\n resultTyped[i] = BigInt(Math.round(op(val)));\n }\n } else {\n // BigInt input, float output\n for (let i = 0; i < size; i++) {\n resultData[i] = op(Number(inputData[i]!));\n }\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = op(Number(inputData[i]!));\n }\n }\n\n return result;\n}\n", "/**\n * Arithmetic operations\n *\n * Pure functions for element-wise arithmetic operations:\n * add, subtract, multiply, divide\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType, promoteDTypes } from '../core/dtype';\nimport { elementwiseBinaryOp } from '../internal/compute';\n\n/**\n * Helper: Check if two arrays can use the fast path\n * (both C-contiguous with same shape, no broadcasting needed)\n */\nfunction canUseFastPath(a: ArrayStorage, b: ArrayStorage): boolean {\n return (\n a.isCContiguous &&\n b.isCContiguous &&\n a.shape.length === b.shape.length &&\n a.shape.every((dim, i) => dim === b.shape[i])\n );\n}\n\n/**\n * Add two arrays or array and scalar\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage\n */\nexport function add(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return addScalar(a, b);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return addArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x + y, 'add');\n}\n\n/**\n * Fast path for adding two contiguous arrays\n * @private\n */\nfunction addArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) + (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! + bTyped[i]!;\n }\n }\n } else {\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? Number(aData[i]) : (aData[i] as number);\n const bVal = typeof bData[i] === 'bigint' ? Number(bData[i]) : (bData[i] as number);\n resultData[i] = aVal + bVal;\n }\n } else {\n // Pure numeric operations - fully optimizable\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) + (bData[i] as number);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Subtract two arrays or array and scalar\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage\n */\nexport function subtract(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return subtractScalar(a, b);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return subtractArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x - y, 'subtract');\n}\n\n/**\n * Fast path for subtracting two contiguous arrays\n * @private\n */\nfunction subtractArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) - (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! - bTyped[i]!;\n }\n }\n } else {\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? Number(aData[i]) : (aData[i] as number);\n const bVal = typeof bData[i] === 'bigint' ? Number(bData[i]) : (bData[i] as number);\n resultData[i] = aVal - bVal;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) - (bData[i] as number);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Multiply two arrays or array and scalar\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage\n */\nexport function multiply(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return multiplyScalar(a, b);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return multiplyArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x * y, 'multiply');\n}\n\n/**\n * Fast path for multiplying two contiguous arrays\n * @private\n */\nfunction multiplyArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) * (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! * bTyped[i]!;\n }\n }\n } else {\n const needsConversion = isBigIntDType(a.dtype) || isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? Number(aData[i]) : (aData[i] as number);\n const bVal = typeof bData[i] === 'bigint' ? Number(bData[i]) : (bData[i] as number);\n resultData[i] = aVal * bVal;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) * (bData[i] as number);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Divide two arrays or array and scalar\n *\n * NumPy behavior: Integer division always promotes to float\n * Type promotion rules:\n * - float64 + anything \u2192 float64\n * - float32 + integer \u2192 float32\n * - integer + integer \u2192 float64\n *\n * @param a - First array storage\n * @param b - Second array storage or scalar\n * @returns Result storage with promoted float dtype\n */\nexport function divide(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return divideScalar(a, b);\n }\n\n // Determine result dtype using NumPy promotion rules\n const aIsFloat64 = a.dtype === 'float64';\n const bIsFloat64 = b.dtype === 'float64';\n const aIsFloat32 = a.dtype === 'float32';\n const bIsFloat32 = b.dtype === 'float32';\n\n // If either is float64, result is float64\n if (aIsFloat64 || bIsFloat64) {\n const aFloat = aIsFloat64 ? a : convertToFloatDType(a, 'float64');\n const bFloat = bIsFloat64 ? b : convertToFloatDType(b, 'float64');\n return elementwiseBinaryOp(aFloat, bFloat, (x, y) => x / y, 'divide');\n }\n\n // If either is float32, result is float32\n if (aIsFloat32 || bIsFloat32) {\n const aFloat = aIsFloat32 ? a : convertToFloatDType(a, 'float32');\n const bFloat = bIsFloat32 ? b : convertToFloatDType(b, 'float32');\n return elementwiseBinaryOp(aFloat, bFloat, (x, y) => x / y, 'divide');\n }\n\n // Both are integers, promote to float64\n const aFloat = convertToFloatDType(a, 'float64');\n const bFloat = convertToFloatDType(b, 'float64');\n return elementwiseBinaryOp(aFloat, bFloat, (x, y) => x / y, 'divide');\n}\n\n/**\n * Convert ArrayStorage to float dtype\n * @private\n */\nfunction convertToFloatDType(\n storage: ArrayStorage,\n targetDtype: 'float32' | 'float64'\n): ArrayStorage {\n const result = ArrayStorage.zeros(Array.from(storage.shape), targetDtype);\n const size = storage.size;\n const srcData = storage.data;\n const dstData = result.data;\n\n for (let i = 0; i < size; i++) {\n dstData[i] = Number(srcData[i]!);\n }\n\n return result;\n}\n\n/**\n * Add scalar to array (optimized path)\n * @private\n */\nfunction addScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - no precision loss\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! + scalarBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) + scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Subtract scalar from array (optimized path)\n * @private\n */\nfunction subtractScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - no precision loss\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! - scalarBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) - scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Multiply array by scalar (optimized path)\n * @private\n */\nfunction multiplyScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - no precision loss\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! * scalarBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) * scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Divide array by scalar (optimized path)\n * NumPy behavior: Integer division promotes to float64\n * @private\n */\nfunction divideScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // NumPy behavior: Integer division always promotes to float64\n // This allows representing inf/nan for division by zero\n // Bool is also promoted to float64 (NumPy behavior)\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = isIntegerType ? 'float64' : dtype;\n\n // Create result with promoted dtype\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // Convert BigInt to Number for division (promotes to float64)\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) / scalar;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Number(data[i]!) / scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Absolute value of each element\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage with absolute values\n */\nexport function absolute(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = thisTyped[i]!;\n resultTyped[i] = val < 0n ? -val : val;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.abs(Number(data[i]!));\n }\n }\n\n return result;\n}\n\n/**\n * Numerical negative (element-wise negation)\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage with negated values\n */\nexport function negative(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = -thisTyped[i]!;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = -Number(data[i]!);\n }\n }\n\n return result;\n}\n\n/**\n * Sign of each element (-1, 0, or 1)\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage with signs\n */\nexport function sign(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = thisTyped[i]!;\n resultTyped[i] = val > 0n ? 1n : val < 0n ? -1n : 0n;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]!);\n resultData[i] = val > 0 ? 1 : val < 0 ? -1 : 0;\n }\n }\n\n return result;\n}\n\n/**\n * Modulo operation (remainder after division)\n * NumPy behavior: Uses floor modulo (sign follows divisor), not JavaScript's truncate modulo\n * Preserves dtype for integer types\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Result storage with modulo values\n */\nexport function mod(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return modScalar(a, b);\n }\n // NumPy uses floor modulo: ((x % y) + y) % y for proper sign handling\n return elementwiseBinaryOp(a, b, (x, y) => ((x % y) + y) % y, 'mod');\n}\n\n/**\n * Modulo with scalar divisor (optimized path)\n * NumPy uses floor modulo: result has same sign as divisor\n * @private\n */\nfunction modScalar(storage: ArrayStorage, divisor: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Create result with same dtype\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic - use floor modulo\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const divisorBig = BigInt(Math.round(divisor));\n for (let i = 0; i < size; i++) {\n const val = thisTyped[i]!;\n // Floor modulo for BigInt\n resultTyped[i] = ((val % divisorBig) + divisorBig) % divisorBig;\n }\n } else {\n // Regular numeric types - use floor modulo\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]!);\n // Floor modulo: ((x % y) + y) % y\n resultData[i] = ((val % divisor) + divisor) % divisor;\n }\n }\n\n return result;\n}\n\n/**\n * Floor division (division with result rounded down)\n * NumPy behavior: Preserves integer types\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Result storage with floor division values\n */\nexport function floorDivide(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return floorDivideScalar(a, b);\n }\n return elementwiseBinaryOp(a, b, (x, y) => Math.floor(x / y), 'floor_divide');\n}\n\n/**\n * Floor division with scalar divisor (optimized path)\n * @private\n */\nfunction floorDivideScalar(storage: ArrayStorage, divisor: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // NumPy behavior: floor_divide preserves integer types\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt floor division\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const divisorBig = BigInt(Math.round(divisor));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! / divisorBig;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.floor(Number(data[i]!) / divisor);\n }\n }\n\n return result;\n}\n\n/**\n * Unary positive (returns a copy of the array)\n * Preserves dtype\n *\n * @param a - Input array storage\n * @returns Result storage (copy of input)\n */\nexport function positive(a: ArrayStorage): ArrayStorage {\n // Positive is essentially a no-op that returns a copy\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n // Copy data\n for (let i = 0; i < size; i++) {\n resultData[i] = data[i]!;\n }\n\n return result;\n}\n\n/**\n * Reciprocal (1/x) of each element\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with reciprocal values\n */\nexport function reciprocal(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // NumPy behavior: reciprocal always promotes integers to float64\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = isIntegerType ? 'float64' : dtype;\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt input promotes to float64\n for (let i = 0; i < size; i++) {\n resultData[i] = 1.0 / Number(data[i]!);\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = 1.0 / Number(data[i]!);\n }\n }\n\n return result;\n}\n\n/**\n * Cube root of each element\n * NumPy behavior: Promotes integer types to float64\n *\n * @param a - Input array storage\n * @returns Result storage with cube root values\n */\nexport function cbrt(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // NumPy behavior: cbrt always promotes integers to float64\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const resultDtype = isIntegerType ? 'float64' : dtype;\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n // Handle all types uniformly - convert to number and apply Math.cbrt\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.cbrt(Number(data[i]!));\n }\n\n return result;\n}\n\n/**\n * Absolute value of each element, returning float\n * NumPy behavior: fabs always returns floating point\n *\n * @param a - Input array storage\n * @returns Result storage with absolute values as float\n */\nexport function fabs(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n // fabs always returns float64, except for float32 which stays float32\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n // Handle all types uniformly\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.abs(Number(data[i]!));\n }\n\n return result;\n}\n\n/**\n * Returns both quotient and remainder (floor divide and modulo)\n * NumPy behavior: divmod(a, b) = (floor_divide(a, b), mod(a, b))\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Tuple of [quotient, remainder] storages\n */\nexport function divmod(a: ArrayStorage, b: ArrayStorage | number): [ArrayStorage, ArrayStorage] {\n const quotient = floorDivide(a, b);\n const remainder = mod(a, b);\n return [quotient, remainder];\n}\n\n/**\n * Element-wise square of each element\n * NumPy behavior: x**2\n *\n * @param a - Input array storage\n * @returns Result storage with squared values\n */\nexport function square(a: ArrayStorage): ArrayStorage {\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const bigData = data as BigInt64Array | BigUint64Array;\n const bigResultData = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n bigResultData[i] = bigData[i]! * bigData[i]!;\n }\n } else {\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]!);\n resultData[i] = val * val;\n }\n }\n\n return result;\n}\n\n/**\n * Remainder of division (same as mod)\n * NumPy behavior: Same as mod, alias for compatibility\n *\n * @param a - Dividend array storage\n * @param b - Divisor (array storage or scalar)\n * @returns Result storage with remainder values\n */\nexport function remainder(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n return mod(a, b);\n}\n\n/**\n * Heaviside step function\n * NumPy behavior:\n * heaviside(x1, x2) = 0 if x1 < 0\n * = x2 if x1 == 0\n * = 1 if x1 > 0\n *\n * @param x1 - Input array storage\n * @param x2 - Value to use when x1 == 0 (array storage or scalar)\n * @returns Result storage with heaviside values\n */\nexport function heaviside(x1: ArrayStorage, x2: ArrayStorage | number): ArrayStorage {\n const dtype = x1.dtype;\n const shape = Array.from(x1.shape);\n const size = x1.size;\n\n // Result is always float64\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (typeof x2 === 'number') {\n // Scalar x2\n for (let i = 0; i < size; i++) {\n const val = Number(x1.data[i]!);\n if (val < 0) {\n resultData[i] = 0;\n } else if (val === 0) {\n resultData[i] = x2;\n } else {\n resultData[i] = 1;\n }\n }\n } else {\n // Array x2 - needs to broadcast\n const x2Data = x2.data;\n const x2Shape = x2.shape;\n\n // Simple case: same shape\n if (shape.every((d, i) => d === x2Shape[i])) {\n for (let i = 0; i < size; i++) {\n const val = Number(x1.data[i]!);\n if (val < 0) {\n resultData[i] = 0;\n } else if (val === 0) {\n resultData[i] = Number(x2Data[i]!);\n } else {\n resultData[i] = 1;\n }\n }\n } else {\n // Broadcasting case - use elementwiseBinaryOp approach\n for (let i = 0; i < size; i++) {\n const val = Number(x1.data[i]!);\n // Simple broadcast: assume x2 is broadcastable to x1\n const x2Idx = i % x2.size;\n if (val < 0) {\n resultData[i] = 0;\n } else if (val === 0) {\n resultData[i] = Number(x2Data[x2Idx]!);\n } else {\n resultData[i] = 1;\n }\n }\n }\n }\n\n return result;\n}\n", "/**\n * Broadcasting utilities for NumPy-compatible array operations\n *\n * Implements NumPy broadcasting rules without external dependencies\n */\n\nimport { ArrayStorage } from './storage';\n\n/**\n * Check if two or more shapes are broadcast-compatible\n * and compute the resulting output shape\n *\n * @param shapes - Array of shapes to broadcast\n * @returns The broadcast output shape, or null if incompatible\n *\n * @example\n * ```typescript\n * computeBroadcastShape([[3, 4], [4]]); // [3, 4]\n * computeBroadcastShape([[3, 4], [3, 1]]); // [3, 4]\n * computeBroadcastShape([[3, 4], [5]]); // null (incompatible)\n * ```\n */\nexport function computeBroadcastShape(shapes: readonly number[][]): number[] | null {\n if (shapes.length === 0) {\n return [];\n }\n\n if (shapes.length === 1) {\n return Array.from(shapes[0]!);\n }\n\n // Find max number of dimensions\n const maxNdim = Math.max(...shapes.map((s) => s.length));\n const result = new Array(maxNdim);\n\n for (let i = 0; i < maxNdim; i++) {\n let dim = 1;\n for (const shape of shapes) {\n const shapeIdx = shape.length - maxNdim + i;\n const shapeDim = shapeIdx < 0 ? 1 : shape[shapeIdx]!;\n\n if (shapeDim === 1) {\n // Can be broadcast\n continue;\n } else if (dim === 1) {\n // First non-1 dimension\n dim = shapeDim;\n } else if (dim !== shapeDim) {\n // Incompatible\n return null;\n }\n }\n result[i] = dim;\n }\n\n return result;\n}\n\n/**\n * Check if two shapes are broadcast-compatible\n *\n * @param shape1 - First shape\n * @param shape2 - Second shape\n * @returns true if shapes can be broadcast together, false otherwise\n *\n * @example\n * ```typescript\n * areBroadcastable([3, 4], [4]); // true\n * areBroadcastable([3, 4], [3, 1]); // true\n * areBroadcastable([3, 4], [5]); // false\n * ```\n */\nexport function areBroadcastable(shape1: readonly number[], shape2: readonly number[]): boolean {\n return computeBroadcastShape([Array.from(shape1), Array.from(shape2)]) !== null;\n}\n\n/**\n * Compute the strides for broadcasting an array to a target shape\n * Returns strides where dimensions that need broadcasting have stride 0\n */\nfunction broadcastStrides(\n shape: readonly number[],\n strides: readonly number[],\n targetShape: readonly number[]\n): number[] {\n const ndim = shape.length;\n const targetNdim = targetShape.length;\n const result = new Array(targetNdim).fill(0);\n\n // Align dimensions from the right\n for (let i = 0; i < ndim; i++) {\n const targetIdx = targetNdim - ndim + i;\n const dim = shape[i]!;\n const targetDim = targetShape[targetIdx]!;\n\n if (dim === targetDim) {\n // Same size, use original stride\n result[targetIdx] = strides[i]!;\n } else if (dim === 1) {\n // Broadcasting, stride is 0 (repeat along this dimension)\n result[targetIdx] = 0;\n } else {\n // This shouldn't happen if shapes were validated\n throw new Error('Invalid broadcast');\n }\n }\n\n return result;\n}\n\n/**\n * Broadcast an ArrayStorage to a target shape\n * Returns a view with modified strides for broadcasting\n *\n * @param storage - The storage to broadcast\n * @param targetShape - The target shape to broadcast to\n * @returns A new ArrayStorage view with broadcasting strides\n */\nexport function broadcastTo(storage: ArrayStorage, targetShape: readonly number[]): ArrayStorage {\n const broadcastedStrides = broadcastStrides(storage.shape, storage.strides, targetShape);\n return ArrayStorage.fromData(\n storage.data,\n Array.from(targetShape),\n storage.dtype,\n broadcastedStrides,\n storage.offset\n );\n}\n\n/**\n * Broadcast multiple ArrayStorage objects to a common shape\n *\n * Returns views of the input arrays broadcast to the same shape.\n * Views share memory with the original arrays.\n *\n * @param storages - ArrayStorage objects to broadcast\n * @returns Array of broadcast ArrayStorage views\n * @throws Error if arrays have incompatible shapes\n */\nexport function broadcastArrays(storages: ArrayStorage[]): ArrayStorage[] {\n if (storages.length === 0) {\n return [];\n }\n\n if (storages.length === 1) {\n return storages;\n }\n\n // Compute broadcast shape\n const shapes = storages.map((s) => Array.from(s.shape));\n const targetShape = computeBroadcastShape(shapes);\n\n if (targetShape === null) {\n throw new Error(\n `operands could not be broadcast together with shapes ${shapes.map((s) => JSON.stringify(s)).join(' ')}`\n );\n }\n\n // Broadcast each storage to the target shape\n return storages.map((s) => broadcastTo(s, targetShape));\n}\n\n/**\n * Compute the broadcast shape for multiple shapes without creating arrays.\n * Returns the resulting shape if all shapes are broadcast-compatible.\n *\n * This is the NumPy-compatible function for computing broadcast shape.\n *\n * @param shapes - Variable number of shapes to broadcast\n * @returns The broadcast output shape\n * @throws Error if shapes are not broadcast-compatible\n *\n * @example\n * ```typescript\n * broadcastShapes([3, 4], [4]); // [3, 4]\n * broadcastShapes([3, 4], [3, 1]); // [3, 4]\n * broadcastShapes([3, 4], [5]); // Error\n * ```\n */\nexport function broadcastShapes(...shapes: readonly number[][]): number[] {\n const result = computeBroadcastShape(shapes);\n\n if (result === null) {\n const shapeStrs = shapes.map((s) => `(${s.join(',')})`).join(' ');\n throw new Error(\n `shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between ${shapeStrs}`\n );\n }\n\n return result;\n}\n\n/**\n * Generate a descriptive error message for broadcasting failures\n *\n * @param shapes - The incompatible shapes\n * @param operation - The operation being attempted (e.g., 'add', 'multiply')\n * @returns Error message string\n */\nexport function broadcastErrorMessage(shapes: readonly number[][], operation?: string): string {\n const opStr = operation ? ` for ${operation}` : '';\n const shapeStrs = shapes.map((s) => `(${s.join(',')})`).join(' ');\n return `operands could not be broadcast together${opStr} with shapes ${shapeStrs}`;\n}\n", "/**\n * Comparison operations\n *\n * Element-wise comparison operations that return boolean arrays:\n * greater, greater_equal, less, less_equal, equal, not_equal,\n * isclose, allclose\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType } from '../core/dtype';\nimport { elementwiseComparisonOp } from '../internal/compute';\nimport { computeBroadcastShape, broadcastTo } from '../core/broadcasting';\n\n/**\n * Element-wise greater than comparison (a > b)\n */\nexport function greater(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return greaterScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x > y);\n}\n\n/**\n * Element-wise greater than or equal comparison (a >= b)\n */\nexport function greaterEqual(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return greaterEqualScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x >= y);\n}\n\n/**\n * Element-wise less than comparison (a < b)\n */\nexport function less(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return lessScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x < y);\n}\n\n/**\n * Element-wise less than or equal comparison (a <= b)\n */\nexport function lessEqual(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return lessEqualScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x <= y);\n}\n\n/**\n * Element-wise equality comparison (a == b)\n */\nexport function equal(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return equalScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x === y);\n}\n\n/**\n * Element-wise inequality comparison (a != b)\n */\nexport function notEqual(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return notEqualScalar(a, b);\n }\n return elementwiseComparisonOp(a, b, (x, y) => x !== y);\n}\n\n/**\n * Element-wise \"close\" comparison with tolerance\n * Returns true where |a - b| <= atol + rtol * |b|\n */\nexport function isclose(\n a: ArrayStorage,\n b: ArrayStorage | number,\n rtol: number = 1e-5,\n atol: number = 1e-8\n): ArrayStorage {\n if (typeof b === 'number') {\n return iscloseScalar(a, b, rtol, atol);\n }\n return elementwiseComparisonOp(a, b, (x, y) => {\n const diff = Math.abs(x - y);\n const threshold = atol + rtol * Math.abs(y);\n return diff <= threshold;\n });\n}\n\n/**\n * Check if all elements are close (scalar result)\n * Returns true if all elements satisfy isclose condition\n */\nexport function allclose(\n a: ArrayStorage,\n b: ArrayStorage | number,\n rtol: number = 1e-5,\n atol: number = 1e-8\n): boolean {\n const closeResult = isclose(a, b, rtol, atol);\n const data = closeResult.data as Uint8Array;\n\n // Check if all values are 1 (true)\n for (let i = 0; i < closeResult.size; i++) {\n if (data[i] === 0) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Returns True if two arrays are element-wise equal within a tolerance.\n * Unlike array_equal, this function broadcasts the arrays before comparison.\n *\n * NumPy behavior: Broadcasts arrays before comparing, returns True if shapes\n * are broadcast-compatible and all elements are equal.\n *\n * @param a1 - First input array\n * @param a2 - Second input array\n * @returns True if arrays are equivalent (after broadcasting), False otherwise\n */\nexport function arrayEquiv(a1: ArrayStorage, a2: ArrayStorage): boolean {\n // Check if arrays can be broadcast together\n const shapes = [Array.from(a1.shape), Array.from(a2.shape)];\n const broadcastShape = computeBroadcastShape(shapes);\n\n if (broadcastShape === null) {\n // If shapes are incompatible for broadcasting, arrays are not equivalent\n return false;\n }\n\n // Broadcast both arrays to the common shape\n const b1 = broadcastTo(a1, broadcastShape);\n const b2 = broadcastTo(a2, broadcastShape);\n\n // Compare element by element using proper multi-dimensional indexing\n const ndim = broadcastShape.length;\n const size = broadcastShape.reduce((acc, d) => acc * d, 1);\n\n // Handle different dtypes\n const isBigInt1 = isBigIntDType(b1.dtype);\n const isBigInt2 = isBigIntDType(b2.dtype);\n\n // Iterate over all elements using multi-dimensional indices\n for (let flatIdx = 0; flatIdx < size; flatIdx++) {\n // Convert flat index to multi-dimensional indices\n let temp = flatIdx;\n const indices: number[] = new Array(ndim);\n for (let i = ndim - 1; i >= 0; i--) {\n indices[i] = temp % broadcastShape[i]!;\n temp = Math.floor(temp / broadcastShape[i]!);\n }\n\n // Get values using proper indexing\n const val1 = b1.get(...indices);\n const val2 = b2.get(...indices);\n\n // Compare values\n if (isBigInt1 || isBigInt2) {\n const v1 = typeof val1 === 'bigint' ? val1 : BigInt(Number(val1));\n const v2 = typeof val2 === 'bigint' ? val2 : BigInt(Number(val2));\n if (v1 !== v2) {\n return false;\n }\n } else {\n if (val1 !== val2) {\n return false;\n }\n }\n }\n\n return true;\n}\n\n// Scalar comparison optimized paths\n\nfunction greaterScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! > scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction greaterEqualScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! >= scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction lessScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! < scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction lessEqualScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! <= scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction equalScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n const dtype = storage.dtype;\n\n if (isBigIntDType(dtype)) {\n // BigInt comparison: convert scalar to BigInt\n const scalarBig = BigInt(Math.round(scalar));\n const typedData = thisData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < storage.size; i++) {\n data[i] = typedData[i]! === scalarBig ? 1 : 0;\n }\n } else {\n // Regular comparison\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! === scalar ? 1 : 0;\n }\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction notEqualScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n\n for (let i = 0; i < storage.size; i++) {\n data[i] = thisData[i]! !== scalar ? 1 : 0;\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n\nfunction iscloseScalar(\n storage: ArrayStorage,\n scalar: number,\n rtol: number,\n atol: number\n): ArrayStorage {\n const data = new Uint8Array(storage.size);\n const thisData = storage.data;\n const dtype = storage.dtype;\n\n if (isBigIntDType(dtype)) {\n // For BigInt, convert to Number for comparison\n const thisTyped = thisData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < storage.size; i++) {\n const a = Number(thisTyped[i]!);\n const diff = Math.abs(a - scalar);\n const threshold = atol + rtol * Math.abs(scalar);\n data[i] = diff <= threshold ? 1 : 0;\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < storage.size; i++) {\n const a = Number(thisData[i]!);\n const diff = Math.abs(a - scalar);\n const threshold = atol + rtol * Math.abs(scalar);\n data[i] = diff <= threshold ? 1 : 0;\n }\n }\n\n return ArrayStorage.fromData(data, Array.from(storage.shape), 'bool');\n}\n", "/**\n * Indexing utilities for array operations\n * @internal\n */\n\n/**\n * Compute row-major strides for a given shape\n */\nexport function computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n\n/**\n * Convert multi-index to linear index in row-major order\n */\nexport function multiIndexToLinear(indices: number[], shape: readonly number[]): number {\n let linearIdx = 0;\n let stride = 1;\n for (let i = indices.length - 1; i >= 0; i--) {\n linearIdx += indices[i]! * stride;\n stride *= shape[i]!;\n }\n return linearIdx;\n}\n\n/**\n * Convert outer index and axis index to full multi-index\n * Used in reductions along a specific axis\n *\n * @param outerIdx - Linear index in the reduced (output) array\n * @param axis - The axis being reduced\n * @param axisIdx - Position along the reduction axis\n * @param shape - Original array shape\n * @returns Full multi-index in the original array\n */\nexport function outerIndexToMultiIndex(\n outerIdx: number,\n axis: number,\n axisIdx: number,\n shape: readonly number[]\n): number[] {\n const ndim = shape.length;\n const indices = new Array(ndim);\n const outputShape = Array.from(shape).filter((_, i) => i !== axis);\n\n // Convert outerIdx to multi-index in the output shape\n let remaining = outerIdx;\n for (let i = outputShape.length - 1; i >= 0; i--) {\n indices[i >= axis ? i + 1 : i] = remaining % outputShape[i]!;\n remaining = Math.floor(remaining / outputShape[i]!);\n }\n\n // Insert the axis index\n indices[axis] = axisIdx;\n return indices;\n}\n", "/**\n * Reduction operations (sum, mean, max, min)\n *\n * Pure functions for reducing arrays along axes.\n * @module ops/reduction\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType } from '../core/dtype';\nimport { outerIndexToMultiIndex, multiIndexToLinear } from '../internal/indexing';\n\n/**\n * Sum array elements over a given axis\n */\nexport function sum(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Sum all elements - return scalar\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n let total = BigInt(0);\n for (let i = 0; i < size; i++) {\n total += typedData[i]!;\n }\n return Number(total);\n } else {\n let total = 0;\n for (let i = 0; i < size; i++) {\n total += Number(data[i]!);\n }\n return total;\n }\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar - reuse scalar sum logic\n return sum(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumVal = BigInt(0);\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n sumVal += typedData[linearIdx]!;\n }\n resultTyped[outerIdx] = sumVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumVal = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n sumVal += Number(data[linearIdx]!);\n }\n resultData[outerIdx] = sumVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Compute the arithmetic mean along the specified axis\n * Note: mean() returns float64 for integer dtypes, matching NumPy behavior\n */\nexport function mean(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n\n if (axis === undefined) {\n return (sum(storage) as number) / storage.size;\n }\n\n // Normalize negative axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = shape.length + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= shape.length) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${shape.length}`);\n }\n\n const sumResult = sum(storage, axis, keepdims);\n if (typeof sumResult === 'number') {\n return sumResult / shape[normalizedAxis]!;\n }\n\n // Divide by the size of the reduced axis\n const divisor = shape[normalizedAxis]!;\n\n // For integer dtypes, mean returns float64 (matching NumPy behavior)\n let resultDtype = dtype;\n if (isBigIntDType(dtype) || dtype.startsWith('int') || dtype.startsWith('uint')) {\n resultDtype = 'float64';\n }\n\n const result = ArrayStorage.zeros(Array.from(sumResult.shape), resultDtype);\n const resultData = result.data;\n const sumData = sumResult.data;\n\n if (isBigIntDType(dtype)) {\n // Convert BigInt sum results to float for mean\n const sumTyped = sumData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < resultData.length; i++) {\n resultData[i] = Number(sumTyped[i]!) / divisor;\n }\n } else {\n for (let i = 0; i < resultData.length; i++) {\n resultData[i] = Number(sumData[i]!) / divisor;\n }\n }\n\n return result;\n}\n\n/**\n * Return the maximum along a given axis\n */\nexport function max(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Max of all elements - return scalar\n if (size === 0) {\n throw new Error('max of empty array');\n }\n\n let maxVal = data[0]!;\n for (let i = 1; i < size; i++) {\n if (data[i]! > maxVal) {\n maxVal = data[i]!;\n }\n }\n return Number(maxVal);\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return max(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let maxVal = typedData[firstIdx]!;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val > maxVal) {\n maxVal = val;\n }\n }\n resultTyped[outerIdx] = maxVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val > maxVal) {\n maxVal = val;\n }\n }\n resultData[outerIdx] = maxVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Product array elements over a given axis\n */\nexport function prod(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Product of all elements - return scalar\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n let product = BigInt(1);\n for (let i = 0; i < size; i++) {\n product *= typedData[i]!;\n }\n return Number(product);\n } else {\n let product = 1;\n for (let i = 0; i < size; i++) {\n product *= Number(data[i]!);\n }\n return product;\n }\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar - reuse scalar prod logic\n return prod(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let prodVal = BigInt(1);\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n prodVal *= typedData[linearIdx]!;\n }\n resultTyped[outerIdx] = prodVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let prodVal = 1;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n prodVal *= Number(data[linearIdx]!);\n }\n resultData[outerIdx] = prodVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Return the minimum along a given axis\n */\nexport function min(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Min of all elements - return scalar\n if (size === 0) {\n throw new Error('min of empty array');\n }\n\n let minVal = data[0]!;\n for (let i = 1; i < size; i++) {\n if (data[i]! < minVal) {\n minVal = data[i]!;\n }\n }\n return Number(minVal);\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return min(storage);\n }\n\n // Create result storage\n const result = ArrayStorage.zeros(outputShape, dtype);\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let minVal = typedData[firstIdx]!;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val < minVal) {\n minVal = val;\n }\n }\n resultTyped[outerIdx] = minVal;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val < minVal) {\n minVal = val;\n }\n }\n resultData[outerIdx] = minVal;\n }\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, dtype);\n }\n\n return result;\n}\n\n/**\n * Return the indices of the minimum values along a given axis\n */\nexport function argmin(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Argmin of all elements - return scalar index\n if (size === 0) {\n throw new Error('argmin of empty array');\n }\n\n let minVal = data[0]!;\n let minIdx = 0;\n for (let i = 1; i < size; i++) {\n if (data[i]! < minVal) {\n minVal = data[i]!;\n minIdx = i;\n }\n }\n return minIdx;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return argmin(storage);\n }\n\n // Create result storage with int32 dtype (indices are always integers)\n const result = ArrayStorage.zeros(outputShape, 'int32');\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let minVal = typedData[firstIdx]!;\n let minAxisIdx = 0;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val < minVal) {\n minVal = val;\n minAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = minAxisIdx;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n let minAxisIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val < minVal) {\n minVal = val;\n minAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = minAxisIdx;\n }\n }\n\n return result;\n}\n\n/**\n * Return the indices of the maximum values along a given axis\n */\nexport function argmax(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const dtype = storage.dtype;\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Argmax of all elements - return scalar index\n if (size === 0) {\n throw new Error('argmax of empty array');\n }\n\n let maxVal = data[0]!;\n let maxIdx = 0;\n for (let i = 1; i < size; i++) {\n if (data[i]! > maxVal) {\n maxVal = data[i]!;\n maxIdx = i;\n }\n }\n return maxIdx;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return argmax(storage);\n }\n\n // Create result storage with int32 dtype (indices are always integers)\n const result = ArrayStorage.zeros(outputShape, 'int32');\n const resultData = result.data;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n if (isBigIntDType(dtype)) {\n const typedData = data as BigInt64Array | BigUint64Array;\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Initialize with first value along axis\n const firstIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, 0, shape);\n const firstIdx = multiIndexToLinear(firstIndices, shape);\n let maxVal = typedData[firstIdx]!;\n let maxAxisIdx = 0;\n\n for (let axisIdx = 1; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = typedData[linearIdx]!;\n if (val > maxVal) {\n maxVal = val;\n maxAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = maxAxisIdx;\n }\n } else {\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n let maxAxisIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]!);\n if (val > maxVal) {\n maxVal = val;\n maxAxisIdx = axisIdx;\n }\n }\n resultData[outerIdx] = maxAxisIdx;\n }\n }\n\n return result;\n}\n\n/**\n * Compute the variance along the specified axis\n * @param storage - Input array storage\n * @param axis - Axis along which to compute variance\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - Keep dimensions (default: false)\n */\nexport function variance(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n // Compute mean\n const meanResult = mean(storage, axis, keepdims);\n\n if (axis === undefined) {\n // Variance of all elements - return scalar\n const meanVal = meanResult as number;\n let sumSqDiff = 0;\n\n for (let i = 0; i < size; i++) {\n const diff = Number(data[i]!) - meanVal;\n sumSqDiff += diff * diff;\n }\n\n return sumSqDiff / (size - ddof);\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const meanArray = meanResult as ArrayStorage;\n const meanData = meanArray.data;\n\n // Compute output shape (same as mean's output shape)\n const outputShape = keepdims\n ? meanArray.shape\n : Array.from(shape).filter((_, i) => i !== normalizedAxis);\n\n // Result is always float64 for variance\n const result = ArrayStorage.zeros(Array.from(outputShape), 'float64');\n const resultData = result.data;\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n // Compute variance for each position\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumSqDiff = 0;\n const meanVal = Number(meanData[outerIdx]!);\n\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const diff = Number(data[linearIdx]!) - meanVal;\n sumSqDiff += diff * diff;\n }\n\n resultData[outerIdx] = sumSqDiff / (axisSize - ddof);\n }\n\n return result;\n}\n\n/**\n * Compute the standard deviation along the specified axis\n * @param storage - Input array storage\n * @param axis - Axis along which to compute std\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - Keep dimensions (default: false)\n */\nexport function std(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const varResult = variance(storage, axis, ddof, keepdims);\n\n if (typeof varResult === 'number') {\n return Math.sqrt(varResult);\n }\n\n // Apply sqrt element-wise\n const result = ArrayStorage.zeros(Array.from(varResult.shape), 'float64');\n const varData = varResult.data;\n const resultData = result.data;\n\n for (let i = 0; i < varData.length; i++) {\n resultData[i] = Math.sqrt(Number(varData[i]!));\n }\n\n return result;\n}\n\n/**\n * Test whether all array elements along a given axis evaluate to True\n */\nexport function all(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | boolean {\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Test all elements\n for (let i = 0; i < size; i++) {\n if (!data[i]) {\n return false;\n }\n }\n return true;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return all(storage);\n }\n\n // Create result storage with bool dtype\n const result = ArrayStorage.zeros(outputShape, 'bool');\n const resultData = result.data as Uint8Array;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let allTrue = true;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n if (!data[linearIdx]) {\n allTrue = false;\n break;\n }\n }\n resultData[outerIdx] = allTrue ? 1 : 0;\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'bool');\n }\n\n return result;\n}\n\n/**\n * Test whether any array elements along a given axis evaluate to True\n */\nexport function any(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | boolean {\n const shape = storage.shape;\n const ndim = shape.length;\n const size = storage.size;\n const data = storage.data;\n\n if (axis === undefined) {\n // Test all elements\n for (let i = 0; i < size; i++) {\n if (data[i]) {\n return true;\n }\n }\n return false;\n }\n\n // Validate and normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n // Result is scalar\n return any(storage);\n }\n\n // Create result storage with bool dtype\n const result = ArrayStorage.zeros(outputShape, 'bool');\n const resultData = result.data as Uint8Array;\n\n // Perform reduction along axis\n const axisSize = shape[normalizedAxis]!;\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let anyTrue = false;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n if (data[linearIdx]) {\n anyTrue = true;\n break;\n }\n }\n resultData[outerIdx] = anyTrue ? 1 : 0;\n }\n\n // Handle keepdims\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'bool');\n }\n\n return result;\n}\n\n/**\n * Return cumulative sum of elements along a given axis\n */\nexport function cumsum(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumsum\n const size = storage.size;\n const resultData = new Float64Array(size);\n let sum = 0;\n for (let i = 0; i < size; i++) {\n sum += Number(data[i]);\n resultData[i] = sum;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumsum along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n // Determine position along axis\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = Number(data[i]);\n } else {\n // Add previous element along axis\n resultData[i] = resultData[i - axisStride]! + Number(data[i]);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Return cumulative product of elements along a given axis\n */\nexport function cumprod(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumprod\n const size = storage.size;\n const resultData = new Float64Array(size);\n let prod = 1;\n for (let i = 0; i < size; i++) {\n prod *= Number(data[i]);\n resultData[i] = prod;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumprod along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n // Determine position along axis\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = Number(data[i]);\n } else {\n // Multiply by previous element along axis\n resultData[i] = resultData[i - axisStride]! * Number(data[i]);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Peak to peak (maximum - minimum) value along a given axis\n */\nexport function ptp(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const maxResult = max(storage, axis, keepdims);\n const minResult = min(storage, axis, keepdims);\n\n if (typeof maxResult === 'number' && typeof minResult === 'number') {\n return maxResult - minResult;\n }\n\n // Both are arrays, subtract element-wise\n const maxStorage = maxResult as ArrayStorage;\n const minStorage = minResult as ArrayStorage;\n const maxData = maxStorage.data;\n const minData = minStorage.data;\n const resultData = new Float64Array(maxStorage.size);\n\n for (let i = 0; i < maxStorage.size; i++) {\n resultData[i] = Number(maxData[i]) - Number(minData[i]);\n }\n\n return ArrayStorage.fromData(resultData, [...maxStorage.shape], 'float64');\n}\n\n/**\n * Compute the median along the specified axis\n */\nexport function median(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n return quantile(storage, 0.5, axis, keepdims);\n}\n\n/**\n * Compute the q-th percentile of data along specified axis\n */\nexport function percentile(\n storage: ArrayStorage,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n return quantile(storage, q / 100, axis, keepdims);\n}\n\n/**\n * Compute the q-th quantile of data along specified axis\n */\nexport function quantile(\n storage: ArrayStorage,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n if (q < 0 || q > 1) {\n throw new Error('Quantile must be between 0 and 1');\n }\n\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Compute quantile over all elements\n const values: number[] = [];\n for (let i = 0; i < storage.size; i++) {\n values.push(Number(data[i]));\n }\n values.sort((a, b) => a - b);\n\n const n = values.length;\n const idx = q * (n - 1);\n const lower = Math.floor(idx);\n const upper = Math.ceil(idx);\n\n if (lower === upper) {\n return values[lower]!;\n }\n\n // Linear interpolation\n const frac = idx - lower;\n return values[lower]! * (1 - frac) + values[upper]! * frac;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return quantile(storage, q);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Collect values along axis\n const values: number[] = [];\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n values.push(Number(data[linearIdx]));\n }\n values.sort((a, b) => a - b);\n\n const n = values.length;\n const idx = q * (n - 1);\n const lower = Math.floor(idx);\n const upper = Math.ceil(idx);\n\n if (lower === upper) {\n resultData[outerIdx] = values[lower]!;\n } else {\n // Linear interpolation\n const frac = idx - lower;\n resultData[outerIdx] = values[lower]! * (1 - frac) + values[upper]! * frac;\n }\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute the weighted average along the specified axis\n */\nexport function average(\n storage: ArrayStorage,\n axis?: number,\n weights?: ArrayStorage,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (weights === undefined) {\n // Unweighted average is just mean\n return mean(storage, axis, keepdims);\n }\n\n if (axis === undefined) {\n // Compute weighted average over all elements\n let sumWeightedValues = 0;\n let sumWeights = 0;\n const weightData = weights.data;\n\n for (let i = 0; i < storage.size; i++) {\n const w = Number(weightData[i % weights.size]);\n sumWeightedValues += Number(data[i]) * w;\n sumWeights += w;\n }\n\n return sumWeights === 0 ? NaN : sumWeightedValues / sumWeights;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Compute output shape\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return average(storage, undefined, weights);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const weightData = weights.data;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let sumWeightedValues = 0;\n let sumWeights = 0;\n\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const w = Number(weightData[axisIdx % weights.size]);\n sumWeightedValues += Number(data[linearIdx]) * w;\n sumWeights += w;\n }\n\n resultData[outerIdx] = sumWeights === 0 ? NaN : sumWeightedValues / sumWeights;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n// ============================================================================\n// NaN-aware reduction functions\n// ============================================================================\n\n/**\n * Return sum of elements, treating NaNs as zero\n */\nexport function nansum(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let total = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total += val;\n }\n }\n return total;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nansum(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let total = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total += val;\n }\n }\n resultData[outerIdx] = total;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Return product of elements, treating NaNs as one\n */\nexport function nanprod(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let total = 1;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total *= val;\n }\n }\n return total;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanprod(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let total = 1;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total *= val;\n }\n }\n resultData[outerIdx] = total;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute mean ignoring NaN values\n */\nexport function nanmean(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let total = 0;\n let count = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n return count === 0 ? NaN : total / count;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmean(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let total = 0;\n let count = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n resultData[outerIdx] = count === 0 ? NaN : total / count;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute variance ignoring NaN values\n */\nexport function nanvar(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // First pass: compute mean\n let total = 0;\n let count = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n if (count - ddof <= 0) return NaN;\n const meanVal = total / count;\n\n // Second pass: compute sum of squared deviations\n let sumSq = 0;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n sumSq += (val - meanVal) ** 2;\n }\n }\n return sumSq / (count - ddof);\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanvar(storage, undefined, ddof);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // First pass: compute mean\n let total = 0;\n let count = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n total += val;\n count++;\n }\n }\n\n if (count - ddof <= 0) {\n resultData[outerIdx] = NaN;\n continue;\n }\n\n const meanVal = total / count;\n\n // Second pass: compute sum of squared deviations\n let sumSq = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n sumSq += (val - meanVal) ** 2;\n }\n }\n resultData[outerIdx] = sumSq / (count - ddof);\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Compute standard deviation ignoring NaN values\n */\nexport function nanstd(\n storage: ArrayStorage,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): ArrayStorage | number {\n const varResult = nanvar(storage, axis, ddof, keepdims);\n if (typeof varResult === 'number') {\n return Math.sqrt(varResult);\n }\n const varStorage = varResult as ArrayStorage;\n const resultData = new Float64Array(varStorage.size);\n for (let i = 0; i < varStorage.size; i++) {\n resultData[i] = Math.sqrt(Number(varStorage.data[i]));\n }\n return ArrayStorage.fromData(resultData, [...varStorage.shape], 'float64');\n}\n\n/**\n * Return minimum ignoring NaN values\n */\nexport function nanmin(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let minVal = Infinity;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n }\n }\n return minVal === Infinity ? NaN : minVal;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmin(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n }\n }\n resultData[outerIdx] = minVal === Infinity ? NaN : minVal;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Return maximum ignoring NaN values\n */\nexport function nanmax(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let maxVal = -Infinity;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n }\n }\n return maxVal === -Infinity ? NaN : maxVal;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmax(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n }\n }\n resultData[outerIdx] = maxVal === -Infinity ? NaN : maxVal;\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n\n/**\n * Return indices of minimum value, ignoring NaNs\n */\nexport function nanargmin(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let minVal = Infinity;\n let minIdx = -1;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n minIdx = i;\n }\n }\n return minIdx;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanargmin(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Int32Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let minVal = Infinity;\n let minIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val < minVal) {\n minVal = val;\n minIdx = axisIdx;\n }\n }\n resultData[outerIdx] = minIdx;\n }\n\n return ArrayStorage.fromData(resultData, outputShape, 'int32');\n}\n\n/**\n * Return indices of maximum value, ignoring NaNs\n */\nexport function nanargmax(storage: ArrayStorage, axis?: number): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n let maxVal = -Infinity;\n let maxIdx = -1;\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n maxIdx = i;\n }\n }\n return maxIdx;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanargmax(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Int32Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n let maxVal = -Infinity;\n let maxIdx = 0;\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val) && val > maxVal) {\n maxVal = val;\n maxIdx = axisIdx;\n }\n }\n resultData[outerIdx] = maxIdx;\n }\n\n return ArrayStorage.fromData(resultData, outputShape, 'int32');\n}\n\n/**\n * Return cumulative sum, treating NaNs as zero\n */\nexport function nancumsum(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumsum\n const size = storage.size;\n const resultData = new Float64Array(size);\n let sum = 0;\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n sum += val;\n }\n resultData[i] = sum;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumsum along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n const val = Number(data[i]);\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = isNaN(val) ? 0 : val;\n } else {\n resultData[i] = resultData[i - axisStride]! + (isNaN(val) ? 0 : val);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Return cumulative product, treating NaNs as one\n */\nexport function nancumprod(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Flatten and cumprod\n const size = storage.size;\n const resultData = new Float64Array(size);\n let prod = 1;\n for (let i = 0; i < size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n prod *= val;\n }\n resultData[i] = prod;\n }\n return ArrayStorage.fromData(resultData, [size], 'float64');\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Create result with same shape\n const resultData = new Float64Array(storage.size);\n const axisSize = shape[normalizedAxis]!;\n\n // Calculate strides\n const strides: number[] = [];\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides.unshift(stride);\n stride *= shape[i]!;\n }\n\n // Perform cumprod along axis\n const totalSize = storage.size;\n const axisStride = strides[normalizedAxis]!;\n\n for (let i = 0; i < totalSize; i++) {\n const val = Number(data[i]);\n const axisPos = Math.floor(i / axisStride) % axisSize;\n\n if (axisPos === 0) {\n resultData[i] = isNaN(val) ? 1 : val;\n } else {\n resultData[i] = resultData[i - axisStride]! * (isNaN(val) ? 1 : val);\n }\n }\n\n return ArrayStorage.fromData(resultData, [...shape], 'float64');\n}\n\n/**\n * Compute median ignoring NaN values\n */\nexport function nanmedian(\n storage: ArrayStorage,\n axis?: number,\n keepdims: boolean = false\n): ArrayStorage | number {\n const shape = storage.shape;\n const ndim = shape.length;\n const data = storage.data;\n\n if (axis === undefined) {\n // Collect non-NaN values\n const values: number[] = [];\n for (let i = 0; i < storage.size; i++) {\n const val = Number(data[i]);\n if (!isNaN(val)) {\n values.push(val);\n }\n }\n\n if (values.length === 0) return NaN;\n\n values.sort((a, b) => a - b);\n const n = values.length;\n const mid = Math.floor(n / 2);\n\n if (n % 2 === 0) {\n return (values[mid - 1]! + values[mid]!) / 2;\n }\n return values[mid]!;\n }\n\n // Normalize axis\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + normalizedAxis;\n }\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const outputShape = Array.from(shape).filter((_, i) => i !== normalizedAxis);\n if (outputShape.length === 0) {\n return nanmedian(storage);\n }\n\n const outerSize = outputShape.reduce((a, b) => a * b, 1);\n const axisSize = shape[normalizedAxis]!;\n const resultData = new Float64Array(outerSize);\n\n for (let outerIdx = 0; outerIdx < outerSize; outerIdx++) {\n // Collect non-NaN values along axis\n const values: number[] = [];\n for (let axisIdx = 0; axisIdx < axisSize; axisIdx++) {\n const inputIndices = outerIndexToMultiIndex(outerIdx, normalizedAxis, axisIdx, shape);\n const linearIdx = multiIndexToLinear(inputIndices, shape);\n const val = Number(data[linearIdx]);\n if (!isNaN(val)) {\n values.push(val);\n }\n }\n\n if (values.length === 0) {\n resultData[outerIdx] = NaN;\n continue;\n }\n\n values.sort((a, b) => a - b);\n const n = values.length;\n const mid = Math.floor(n / 2);\n\n if (n % 2 === 0) {\n resultData[outerIdx] = (values[mid - 1]! + values[mid]!) / 2;\n } else {\n resultData[outerIdx] = values[mid]!;\n }\n }\n\n const result = ArrayStorage.fromData(resultData, outputShape, 'float64');\n\n if (keepdims) {\n const keepdimsShape = [...shape];\n keepdimsShape[normalizedAxis] = 1;\n return ArrayStorage.fromData(resultData, keepdimsShape, 'float64');\n }\n\n return result;\n}\n", "/**\n * Shape manipulation operations\n *\n * Pure functions for reshaping, transposing, and manipulating array dimensions.\n * @module ops/shape\n */\n\nimport { ArrayStorage, computeStrides } from '../core/storage';\nimport { getTypedArrayConstructor, isBigIntDType, type TypedArray } from '../core/dtype';\n\n/**\n * Reshape array to a new shape\n * Returns a view if array is C-contiguous, otherwise copies data\n */\nexport function reshape(storage: ArrayStorage, newShape: number[]): ArrayStorage {\n const size = storage.size;\n const dtype = storage.dtype;\n\n // Check if -1 is in the shape (infer dimension)\n const negIndex = newShape.indexOf(-1);\n let finalShape: number[];\n\n if (negIndex !== -1) {\n // Infer the dimension at negIndex\n const knownSize = newShape.reduce((acc, dim, i) => (i === negIndex ? acc : acc * dim), 1);\n const inferredDim = size / knownSize;\n\n if (!Number.isInteger(inferredDim)) {\n throw new Error(\n `cannot reshape array of size ${size} into shape ${JSON.stringify(newShape)}`\n );\n }\n\n finalShape = newShape.map((dim, i) => (i === negIndex ? inferredDim : dim));\n } else {\n finalShape = newShape;\n }\n\n // Validate that the new shape has the same total size\n const newSize = finalShape.reduce((a, b) => a * b, 1);\n if (newSize !== size) {\n throw new Error(\n `cannot reshape array of size ${size} into shape ${JSON.stringify(finalShape)}`\n );\n }\n\n // Fast path: if array is C-contiguous, create a view (no copy)\n if (storage.isCContiguous) {\n const data = storage.data;\n return ArrayStorage.fromData(data, finalShape, dtype, computeStrides(finalShape), 0);\n }\n\n // Slow path: array is not contiguous, must copy data first\n // Create contiguous copy, then reshape\n const contiguousCopy = storage.copy(); // copy() creates C-contiguous array\n const data = contiguousCopy.data;\n return ArrayStorage.fromData(data, finalShape, dtype, computeStrides(finalShape), 0);\n}\n\n/**\n * Return a flattened copy of the array\n * Creates 1D array containing all elements in row-major order\n * Always returns a copy (matching NumPy behavior)\n */\nexport function flatten(storage: ArrayStorage): ArrayStorage {\n const size = storage.size;\n const dtype = storage.dtype;\n const Constructor = getTypedArrayConstructor(dtype);\n\n if (!Constructor) {\n throw new Error(`Cannot flatten array with dtype ${dtype}`);\n }\n\n // Fast path: if array is C-contiguous, just copy the underlying data\n if (storage.isCContiguous) {\n const data = storage.data;\n const newData = data.slice(storage.offset, storage.offset + size);\n return ArrayStorage.fromData(newData as TypedArray, [size], dtype, [1], 0);\n }\n\n // Slow path: non-contiguous array, copy using iget (flat index)\n // This is much faster than recursive get(...indices) calls\n const newData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n for (let i = 0; i < size; i++) {\n const value = storage.iget(i);\n if (isBigInt) {\n (newData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(newData, [size], dtype, [1], 0);\n}\n\n/**\n * Return a flattened array (view when possible, otherwise copy)\n * Returns a view if array is C-contiguous, otherwise copies data\n */\nexport function ravel(storage: ArrayStorage): ArrayStorage {\n const size = storage.size;\n const dtype = storage.dtype;\n\n // Fast path: if array is C-contiguous, create a view (no copy needed)\n if (storage.isCContiguous) {\n const data = storage.data;\n return ArrayStorage.fromData(data, [size], dtype, [1], 0);\n }\n\n // Slow path: array is not contiguous, must copy like flatten()\n return flatten(storage);\n}\n\n/**\n * Transpose array (permute dimensions)\n * Returns a view with transposed dimensions\n */\nexport function transpose(storage: ArrayStorage, axes?: number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n let permutation: number[];\n\n if (axes === undefined) {\n // Default: reverse all dimensions\n permutation = Array.from({ length: ndim }, (_, i) => ndim - 1 - i);\n } else {\n // Validate axes\n if (axes.length !== ndim) {\n throw new Error(`axes must have length ${ndim}, got ${axes.length}`);\n }\n\n // Check that axes is a valid permutation\n const seen = new Set<number>();\n for (const axis of axes) {\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n if (seen.has(normalizedAxis)) {\n throw new Error(`repeated axis in transpose`);\n }\n seen.add(normalizedAxis);\n }\n\n permutation = axes.map((ax) => (ax < 0 ? ndim + ax : ax));\n }\n\n // Compute new shape and strides\n const newShape = permutation.map((i) => shape[i]!);\n const oldStrides = Array.from(strides);\n const newStrides = permutation.map((i) => oldStrides[i]!);\n\n // Create transposed view\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n}\n\n/**\n * Remove axes of length 1\n * Returns a view with specified dimensions removed\n */\nexport function squeeze(storage: ArrayStorage, axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n if (axis === undefined) {\n // Remove all axes with size 1\n const newShape: number[] = [];\n const newStrides: number[] = [];\n\n for (let i = 0; i < ndim; i++) {\n if (shape[i] !== 1) {\n newShape.push(shape[i]!);\n newStrides.push(strides[i]!);\n }\n }\n\n // If all dimensions were 1, result would be a scalar (0-d array)\n // For now, keep at least one dimension\n if (newShape.length === 0) {\n newShape.push(1);\n newStrides.push(1);\n }\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n } else {\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Check that the axis has size 1\n if (shape[normalizedAxis] !== 1) {\n throw new Error(\n `cannot select an axis which has size not equal to one (axis ${axis} has size ${shape[normalizedAxis]})`\n );\n }\n\n // Remove the specified axis\n const newShape: number[] = [];\n const newStrides: number[] = [];\n\n for (let i = 0; i < ndim; i++) {\n if (i !== normalizedAxis) {\n newShape.push(shape[i]!);\n newStrides.push(strides[i]!);\n }\n }\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n }\n}\n\n/**\n * Expand the shape by inserting a new axis of length 1\n * Returns a view with additional dimension\n */\nexport function expandDims(storage: ArrayStorage, axis: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n // Normalize axis (can be from -ndim-1 to ndim)\n let normalizedAxis = axis;\n if (normalizedAxis < 0) {\n normalizedAxis = ndim + axis + 1;\n }\n\n if (normalizedAxis < 0 || normalizedAxis > ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim + 1}`);\n }\n\n // Insert 1 at the specified position\n const newShape = [...Array.from(shape)];\n newShape.splice(normalizedAxis, 0, 1);\n\n // Insert a stride at the new axis position\n // The stride for a dimension of size 1 doesn't matter, but conventionally\n // it should be the product of all dimensions to its right\n const newStrides = [...Array.from(strides)];\n const insertedStride =\n normalizedAxis < ndim ? strides[normalizedAxis]! * (shape[normalizedAxis] || 1) : 1;\n newStrides.splice(normalizedAxis, 0, insertedStride);\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n}\n\n/**\n * Swap two axes of an array\n * Returns a view with axes swapped\n */\nexport function swapaxes(storage: ArrayStorage, axis1: number, axis2: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const strides = storage.strides;\n const data = storage.data;\n const dtype = storage.dtype;\n\n // Normalize axes\n let normalizedAxis1 = axis1 < 0 ? ndim + axis1 : axis1;\n let normalizedAxis2 = axis2 < 0 ? ndim + axis2 : axis2;\n\n if (normalizedAxis1 < 0 || normalizedAxis1 >= ndim) {\n throw new Error(`axis1 ${axis1} is out of bounds for array of dimension ${ndim}`);\n }\n if (normalizedAxis2 < 0 || normalizedAxis2 >= ndim) {\n throw new Error(`axis2 ${axis2} is out of bounds for array of dimension ${ndim}`);\n }\n\n // If same axis, return a view without change\n if (normalizedAxis1 === normalizedAxis2) {\n return ArrayStorage.fromData(\n data,\n Array.from(shape),\n dtype,\n Array.from(strides),\n storage.offset\n );\n }\n\n // Swap shape and strides\n const newShape = Array.from(shape);\n const newStrides = Array.from(strides);\n\n [newShape[normalizedAxis1], newShape[normalizedAxis2]] = [\n newShape[normalizedAxis2]!,\n newShape[normalizedAxis1]!,\n ];\n [newStrides[normalizedAxis1], newStrides[normalizedAxis2]] = [\n newStrides[normalizedAxis2]!,\n newStrides[normalizedAxis1]!,\n ];\n\n return ArrayStorage.fromData(data, newShape, dtype, newStrides, storage.offset);\n}\n\n/**\n * Move axes to new positions\n * Returns a view with axes moved\n */\nexport function moveaxis(\n storage: ArrayStorage,\n source: number | number[],\n destination: number | number[]\n): ArrayStorage {\n const ndim = storage.ndim;\n\n // Convert to arrays\n const sourceArr = Array.isArray(source) ? source : [source];\n const destArr = Array.isArray(destination) ? destination : [destination];\n\n if (sourceArr.length !== destArr.length) {\n throw new Error('source and destination must have the same number of elements');\n }\n\n // Normalize axes\n const normalizedSource = sourceArr.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`source axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n });\n\n const normalizedDest = destArr.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`destination axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n });\n\n // Check for duplicate source/dest axes\n if (new Set(normalizedSource).size !== normalizedSource.length) {\n throw new Error('repeated axis in source');\n }\n if (new Set(normalizedDest).size !== normalizedDest.length) {\n throw new Error('repeated axis in destination');\n }\n\n // Build permutation\n // Start with axes not in source\n const order: number[] = [];\n for (let i = 0; i < ndim; i++) {\n if (!normalizedSource.includes(i)) {\n order.push(i);\n }\n }\n\n // Insert source axes at destination positions\n for (let i = 0; i < normalizedSource.length; i++) {\n const dst = normalizedDest[i]!;\n order.splice(dst, 0, normalizedSource[i]!);\n }\n\n return transpose(storage, order);\n}\n\n/**\n * Concatenate arrays along an axis\n */\nexport function concatenate(storages: ArrayStorage[], axis: number = 0): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to concatenate');\n }\n\n if (storages.length === 1) {\n return storages[0]!.copy();\n }\n\n const first = storages[0]!;\n const ndim = first.ndim;\n const dtype = first.dtype;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Validate shapes: all arrays must have same shape except along axis\n for (let i = 1; i < storages.length; i++) {\n const s = storages[i]!;\n if (s.ndim !== ndim) {\n throw new Error('all the input arrays must have same number of dimensions');\n }\n for (let d = 0; d < ndim; d++) {\n if (d !== normalizedAxis && s.shape[d] !== first.shape[d]) {\n throw new Error(\n `all the input array dimensions except for the concatenation axis must match exactly`\n );\n }\n }\n }\n\n // Calculate output shape\n const outputShape = Array.from(first.shape);\n let totalAlongAxis = first.shape[normalizedAxis]!;\n for (let i = 1; i < storages.length; i++) {\n totalAlongAxis += storages[i]!.shape[normalizedAxis]!;\n }\n outputShape[normalizedAxis] = totalAlongAxis;\n\n // Create output array\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot concatenate arrays with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // Copy data from each input array\n let offset = 0;\n for (const storage of storages) {\n const axisSize = storage.shape[normalizedAxis]!;\n copyToOutput(storage, outputData, outputShape, outputStrides, normalizedAxis, offset, dtype);\n offset += axisSize;\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Helper to copy data into concatenated output\n */\nfunction copyToOutput(\n source: ArrayStorage,\n outputData: TypedArray,\n _outputShape: number[],\n outputStrides: number[],\n axis: number,\n axisOffset: number,\n dtype: string\n): void {\n const sourceShape = source.shape;\n const ndim = sourceShape.length;\n const sourceSize = source.size;\n const isBigInt = dtype === 'int64' || dtype === 'uint64';\n\n // Fast path: if concatenating along axis 0 and both are C-contiguous,\n // we can do bulk copy\n if (axis === 0 && source.isCContiguous && ndim > 0) {\n // Calculate the starting position in output array\n const outputOffset = axisOffset * outputStrides[0]!;\n const sourceData = source.data;\n const start = source.offset;\n const end = start + sourceSize;\n\n // Bulk copy the entire source array\n // @ts-expect-error - TypedArray.set() works with any typed array subarray\n outputData.set(sourceData.subarray(start, end), outputOffset);\n return;\n }\n\n // Optimized path for axis=1 (common for hstack): copy row by row\n if (axis === 1 && ndim === 2 && source.isCContiguous) {\n const rows = sourceShape[0]!;\n const cols = sourceShape[1]!;\n const outputCols = _outputShape[1]!;\n const sourceData = source.data;\n const sourceStart = source.offset;\n\n for (let row = 0; row < rows; row++) {\n const sourceRowStart = sourceStart + row * cols;\n const outputRowStart = row * outputCols + axisOffset;\n // @ts-expect-error - TypedArray.set() works with any typed array subarray\n outputData.set(sourceData.subarray(sourceRowStart, sourceRowStart + cols), outputRowStart);\n }\n return;\n }\n\n // Slow path: element-by-element copy using flat indices (iget)\n // Optimized to avoid array spread and pre-compute base offset\n const indices = new Array(ndim).fill(0);\n const baseOutputOffset = axisOffset * outputStrides[axis]!;\n\n for (let i = 0; i < sourceSize; i++) {\n // Get value from source using flat index\n const value = source.iget(i);\n\n // Compute output index more efficiently\n let outputIdx = baseOutputOffset;\n for (let d = 0; d < ndim; d++) {\n outputIdx += indices[d]! * outputStrides[d]!;\n }\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outputIdx] =\n value as number;\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n indices[d]++;\n if (indices[d]! < sourceShape[d]!) {\n break;\n }\n indices[d] = 0;\n }\n }\n}\n\n/**\n * Stack arrays along a new axis\n */\nexport function stack(storages: ArrayStorage[], axis: number = 0): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n const first = storages[0]!;\n const shape = first.shape;\n const ndim = first.ndim;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + 1 + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis > ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim + 1}`);\n }\n\n // Validate shapes: all arrays must have exact same shape\n for (let i = 1; i < storages.length; i++) {\n const s = storages[i]!;\n if (s.ndim !== ndim) {\n throw new Error('all input arrays must have the same shape');\n }\n for (let d = 0; d < ndim; d++) {\n if (s.shape[d] !== shape[d]) {\n throw new Error('all input arrays must have the same shape');\n }\n }\n }\n\n // Expand dims on each array, then concatenate\n const expanded = storages.map((s) => expandDims(s, normalizedAxis));\n return concatenate(expanded, normalizedAxis);\n}\n\n/**\n * Stack arrays vertically (row-wise)\n * vstack is equivalent to concatenation along the first axis after\n * 1-D arrays of shape (N,) have been reshaped to (1,N)\n */\nexport function vstack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // For 1D arrays, reshape to (1, N) first\n const prepared = storages.map((s) => {\n if (s.ndim === 1) {\n return reshape(s, [1, s.shape[0]!]);\n }\n return s;\n });\n\n return concatenate(prepared, 0);\n}\n\n/**\n * Stack arrays horizontally (column-wise)\n * hstack is equivalent to concatenation along the second axis,\n * except for 1-D arrays where it concatenates along the first axis\n */\nexport function hstack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // Check if all arrays are 1D\n const allOneDim = storages.every((s) => s.ndim === 1);\n\n if (allOneDim) {\n // For 1D arrays, concatenate along axis 0\n return concatenate(storages, 0);\n }\n\n // For higher-dimensional arrays, concatenate along axis 1\n return concatenate(storages, 1);\n}\n\n/**\n * Stack arrays depth-wise (along third axis)\n * dstack is equivalent to concatenation along the third axis after\n * 2-D arrays of shape (M,N) have been reshaped to (M,N,1) and\n * 1-D arrays of shape (N,) have been reshaped to (1,N,1)\n */\nexport function dstack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // Prepare arrays\n const prepared = storages.map((s) => {\n if (s.ndim === 1) {\n // Reshape (N,) to (1, N, 1)\n return reshape(expandDims(reshape(s, [1, s.shape[0]!]), 2), [1, s.shape[0]!, 1]);\n } else if (s.ndim === 2) {\n // Reshape (M, N) to (M, N, 1)\n return expandDims(s, 2);\n }\n return s;\n });\n\n return concatenate(prepared, 2);\n}\n\n/**\n * Split array into sub-arrays\n */\nexport function split(\n storage: ArrayStorage,\n indicesOrSections: number | number[],\n axis: number = 0\n): ArrayStorage[] {\n const shape = storage.shape;\n const ndim = shape.length;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n\n let splitIndices: number[];\n\n if (typeof indicesOrSections === 'number') {\n // Split into N equal sections\n if (axisSize % indicesOrSections !== 0) {\n throw new Error(`array split does not result in an equal division`);\n }\n const sectionSize = axisSize / indicesOrSections;\n splitIndices = [];\n for (let i = 1; i < indicesOrSections; i++) {\n splitIndices.push(i * sectionSize);\n }\n } else {\n // Split at specified indices\n splitIndices = indicesOrSections;\n }\n\n return splitAtIndices(storage, splitIndices, normalizedAxis);\n}\n\n/**\n * Split array into sub-arrays (allows unequal splits)\n */\nexport function arraySplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[],\n axis: number = 0\n): ArrayStorage[] {\n const shape = storage.shape;\n const ndim = shape.length;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n\n let splitIndices: number[];\n\n if (typeof indicesOrSections === 'number') {\n // Split into N sections (may be unequal)\n const numSections = indicesOrSections;\n const sectionSize = Math.floor(axisSize / numSections);\n const remainder = axisSize % numSections;\n\n splitIndices = [];\n let offset = 0;\n for (let i = 0; i < numSections - 1; i++) {\n offset += sectionSize + (i < remainder ? 1 : 0);\n splitIndices.push(offset);\n }\n } else {\n // Split at specified indices\n splitIndices = indicesOrSections;\n }\n\n return splitAtIndices(storage, splitIndices, normalizedAxis);\n}\n\n/**\n * Helper to split array at specified indices\n */\nfunction splitAtIndices(storage: ArrayStorage, indices: number[], axis: number): ArrayStorage[] {\n const shape = storage.shape;\n const axisSize = shape[axis]!;\n\n // Add boundaries\n const boundaries = [0, ...indices, axisSize];\n const result: ArrayStorage[] = [];\n\n for (let i = 0; i < boundaries.length - 1; i++) {\n const start = boundaries[i]!;\n const end = boundaries[i + 1]!;\n\n if (start > end) {\n throw new Error('split indices must be in ascending order');\n }\n\n // Create slice\n const sliceShape = Array.from(shape);\n sliceShape[axis] = end - start;\n\n // Calculate new offset and strides\n const newOffset = storage.offset + start * storage.strides[axis]!;\n\n result.push(\n ArrayStorage.fromData(\n storage.data,\n sliceShape,\n storage.dtype,\n Array.from(storage.strides),\n newOffset\n )\n );\n }\n\n return result;\n}\n\n/**\n * Split array vertically (row-wise)\n */\nexport function vsplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[]\n): ArrayStorage[] {\n if (storage.ndim < 2) {\n throw new Error('vsplit only works on arrays of 2 or more dimensions');\n }\n return arraySplit(storage, indicesOrSections, 0);\n}\n\n/**\n * Split array horizontally (column-wise)\n */\nexport function hsplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[]\n): ArrayStorage[] {\n if (storage.ndim < 1) {\n throw new Error('hsplit only works on arrays of 1 or more dimensions');\n }\n // For 1D arrays, split along axis 0; for higher dims, split along axis 1\n const axis = storage.ndim === 1 ? 0 : 1;\n return arraySplit(storage, indicesOrSections, axis);\n}\n\n/**\n * Tile array by repeating along each axis\n */\nexport function tile(storage: ArrayStorage, reps: number | number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n // Normalize reps to array\n const repsArr = Array.isArray(reps) ? reps : [reps];\n\n // Pad reps or shape to match dimensions\n const maxDim = Math.max(ndim, repsArr.length);\n const paddedShape = new Array(maxDim).fill(1);\n const paddedReps = new Array(maxDim).fill(1);\n\n // Fill from the right\n for (let i = 0; i < ndim; i++) {\n paddedShape[maxDim - ndim + i] = shape[i]!;\n }\n for (let i = 0; i < repsArr.length; i++) {\n paddedReps[maxDim - repsArr.length + i] = repsArr[i]!;\n }\n\n // Calculate output shape\n const outputShape = paddedShape.map((s, i) => s * paddedReps[i]!);\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot tile array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // If we need to expand dimensions of input, reshape it\n let expandedStorage = storage;\n if (ndim < maxDim) {\n expandedStorage = reshape(storage, paddedShape);\n }\n\n const isBigInt = dtype === 'int64' || dtype === 'uint64';\n const expandedStrides = expandedStorage.strides;\n\n // Fill output by iterating through all output positions\n const outputIndices = new Array(maxDim).fill(0);\n\n for (let i = 0; i < outputSize; i++) {\n // Compute source flat index directly (wrap around for tiling)\n let sourceFlatIdx = expandedStorage.offset;\n for (let d = 0; d < maxDim; d++) {\n const sourceIdx = outputIndices[d]! % paddedShape[d]!;\n sourceFlatIdx += sourceIdx * expandedStrides[d]!;\n }\n\n // Read value directly from flat index\n const value = expandedStorage.data[sourceFlatIdx];\n\n // Write to output using direct index calculation\n let outputIdx = 0;\n for (let d = 0; d < maxDim; d++) {\n outputIdx += outputIndices[d]! * outputStrides[d]!;\n }\n\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outputIdx] =\n value as number;\n }\n\n // Increment indices\n for (let d = maxDim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < outputShape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Repeat elements of an array\n */\nexport function repeat(\n storage: ArrayStorage,\n repeats: number | number[],\n axis?: number\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n const size = storage.size;\n\n if (axis === undefined) {\n // Flatten and repeat each element\n const flatSize = size;\n const repeatsArr = Array.isArray(repeats) ? repeats : new Array(flatSize).fill(repeats);\n\n if (repeatsArr.length !== flatSize) {\n throw new Error(\n `operands could not be broadcast together with shape (${flatSize},) (${repeatsArr.length},)`\n );\n }\n\n const outputSize = repeatsArr.reduce((a, b) => a + b, 0);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot repeat array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n let outIdx = 0;\n for (let i = 0; i < flatSize; i++) {\n const value = storage.iget(i);\n const rep = repeatsArr[i]!;\n for (let r = 0; r < rep; r++) {\n if (dtype === 'int64' || dtype === 'uint64') {\n (outputData as BigInt64Array | BigUint64Array)[outIdx++] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx++] =\n value as number;\n }\n }\n }\n\n return ArrayStorage.fromData(outputData, [outputSize], dtype);\n }\n\n // Repeat along specified axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const repeatsArr = Array.isArray(repeats) ? repeats : new Array(axisSize).fill(repeats);\n\n if (repeatsArr.length !== axisSize) {\n throw new Error(\n `operands could not be broadcast together with shape (${axisSize},) (${repeatsArr.length},)`\n );\n }\n\n // Calculate output shape\n const outputShape = Array.from(shape);\n outputShape[normalizedAxis] = repeatsArr.reduce((a, b) => a + b, 0);\n\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot repeat array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // Iterate through source and write repeated values\n const sourceIndices = new Array(ndim).fill(0);\n const isBigInt = dtype === 'int64' || dtype === 'uint64';\n\n // Track cumulative positions along axis\n const axisPositions: number[] = [0];\n for (let i = 0; i < axisSize; i++) {\n axisPositions.push(axisPositions[i]! + repeatsArr[i]!);\n }\n\n for (let i = 0; i < size; i++) {\n // Use iget for flat index access instead of get(...indices)\n const value = storage.iget(i);\n const axisIdx = sourceIndices[normalizedAxis]!;\n const rep = repeatsArr[axisIdx]!;\n\n // Calculate base output index (without axis component)\n let baseOutIdx = 0;\n for (let d = 0; d < ndim; d++) {\n if (d !== normalizedAxis) {\n baseOutIdx += sourceIndices[d]! * outputStrides[d]!;\n }\n }\n\n // Write repeated values\n const axisStride = outputStrides[normalizedAxis]!;\n const axisStart = axisPositions[axisIdx]!;\n for (let r = 0; r < rep; r++) {\n const outIdx = baseOutIdx + (axisStart + r) * axisStride;\n\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx] =\n value as number;\n }\n }\n\n // Increment source indices\n for (let d = ndim - 1; d >= 0; d--) {\n sourceIndices[d]++;\n if (sourceIndices[d]! < shape[d]!) {\n break;\n }\n sourceIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Reverse the order of elements in an array along given axis\n */\nexport function flip(storage: ArrayStorage, axis?: number | number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n const size = storage.size;\n\n // Determine which axes to flip\n let axesToFlip: Set<number>;\n if (axis === undefined) {\n // Flip all axes\n axesToFlip = new Set(Array.from({ length: ndim }, (_, i) => i));\n } else if (typeof axis === 'number') {\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n axesToFlip = new Set([normalizedAxis]);\n } else {\n axesToFlip = new Set(\n axis.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n })\n );\n }\n\n // Create output array\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot flip array with dtype ${dtype}`);\n }\n const outputData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n // Fast path for 1D arrays\n if (ndim === 1 && storage.isCContiguous) {\n const sourceData = storage.data;\n const start = storage.offset;\n for (let i = 0; i < size; i++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = sourceData[\n start + size - 1 - i\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = sourceData[\n start + size - 1 - i\n ] as number;\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n\n // Fast path for 2D arrays\n if (ndim === 2 && storage.isCContiguous) {\n const rows = shape[0]!;\n const cols = shape[1]!;\n const sourceData = storage.data;\n const start = storage.offset;\n\n // Flipping both axes - reverse entire array\n if (axesToFlip.size === 2) {\n for (let i = 0; i < size; i++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = sourceData[\n start + size - 1 - i\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = sourceData[\n start + size - 1 - i\n ] as number;\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n\n if (axesToFlip.size === 1) {\n if (axesToFlip.has(0)) {\n // Flip rows: copy rows in reverse order\n for (let r = 0; r < rows; r++) {\n const sourceRowStart = start + (rows - 1 - r) * cols;\n const outputRowStart = r * cols;\n for (let c = 0; c < cols; c++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputRowStart + c] = sourceData[\n sourceRowStart + c\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[\n outputRowStart + c\n ] = sourceData[sourceRowStart + c] as number;\n }\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n } else if (axesToFlip.has(1)) {\n // Flip columns: reverse each row\n for (let r = 0; r < rows; r++) {\n const sourceRowStart = start + r * cols;\n const outputRowStart = r * cols;\n for (let c = 0; c < cols; c++) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputRowStart + c] = sourceData[\n sourceRowStart + cols - 1 - c\n ] as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[\n outputRowStart + c\n ] = sourceData[sourceRowStart + cols - 1 - c] as number;\n }\n }\n }\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n }\n }\n\n // General path: element-by-element copy\n const sourceIndices = new Array(ndim);\n const outputIndices = new Array(ndim).fill(0);\n\n for (let i = 0; i < size; i++) {\n // Compute source indices by flipping the specified axes\n for (let d = 0; d < ndim; d++) {\n sourceIndices[d] = axesToFlip.has(d) ? shape[d]! - 1 - outputIndices[d]! : outputIndices[d];\n }\n\n // Get value from source\n let sourceOffset = storage.offset;\n for (let d = 0; d < ndim; d++) {\n sourceOffset += sourceIndices[d]! * storage.strides[d]!;\n }\n const value = storage.data[sourceOffset];\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n\n // Increment output indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < shape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n}\n\n/**\n * Rotate array by 90 degrees in the plane specified by axes\n */\nexport function rot90(\n storage: ArrayStorage,\n k: number = 1,\n axes: [number, number] = [0, 1]\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n if (ndim < 2) {\n throw new Error('Input must be at least 2-D');\n }\n\n // Normalize axes\n const axis0 = axes[0] < 0 ? ndim + axes[0] : axes[0];\n const axis1 = axes[1] < 0 ? ndim + axes[1] : axes[1];\n\n if (axis0 < 0 || axis0 >= ndim || axis1 < 0 || axis1 >= ndim) {\n throw new Error(`Axes are out of bounds for array of dimension ${ndim}`);\n }\n\n if (axis0 === axis1) {\n throw new Error('Axes must be different');\n }\n\n // Normalize k to 0-3\n k = ((k % 4) + 4) % 4;\n\n if (k === 0) {\n return storage.copy();\n }\n\n // Optimized: do the rotation in one pass instead of k iterations\n // k=1: flip axis1, transpose\n // k=2: flip both axes\n // k=3: flip axis0, transpose\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot rotate array with dtype ${dtype}`);\n }\n\n const outputShape = [...shape];\n if (k === 1 || k === 3) {\n // Swap dimensions for axis0 and axis1\n [outputShape[axis0], outputShape[axis1]] = [outputShape[axis1]!, outputShape[axis0]!];\n }\n\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n const isBigInt = isBigIntDType(dtype);\n\n const indices = new Array(ndim).fill(0);\n const sourceIndices = new Array(ndim);\n\n for (let i = 0; i < storage.size; i++) {\n // Transform indices based on k\n for (let d = 0; d < ndim; d++) {\n sourceIndices[d] = indices[d];\n }\n\n let outIdx0, outIdx1;\n if (k === 1) {\n // 90 degrees: flip axis1, then transpose\n outIdx0 = shape[axis1]! - 1 - indices[axis1]!;\n outIdx1 = indices[axis0];\n } else if (k === 2) {\n // 180 degrees: flip both axes\n outIdx0 = shape[axis0]! - 1 - indices[axis0]!;\n outIdx1 = shape[axis1]! - 1 - indices[axis1]!;\n sourceIndices[axis0] = outIdx0;\n sourceIndices[axis1] = outIdx1;\n } else {\n // k === 3, 270 degrees: flip axis0, then transpose\n outIdx0 = indices[axis1];\n outIdx1 = shape[axis0]! - 1 - indices[axis0]!;\n }\n\n if (k !== 2) {\n sourceIndices[axis0] = outIdx0;\n sourceIndices[axis1] = outIdx1;\n }\n\n // Compute output offset\n let outputOffset = 0;\n for (let d = 0; d < ndim; d++) {\n outputOffset += sourceIndices[d]! * outputStrides[d]!;\n }\n\n // Get source value\n const value = storage.iget(i);\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outputOffset] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outputOffset] =\n value as number;\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n indices[d]++;\n if (indices[d]! < shape[d]!) {\n break;\n }\n indices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Roll array elements along a given axis\n */\nexport function roll(\n storage: ArrayStorage,\n shift: number | number[],\n axis?: number | number[]\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n const size = storage.size;\n\n // Handle no axis case - roll as flattened array\n if (axis === undefined) {\n const flatShift = Array.isArray(shift) ? shift.reduce((a, b) => a + b, 0) : shift;\n const flatStorage = flatten(storage);\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot roll array with dtype ${dtype}`);\n }\n const outputData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n for (let i = 0; i < size; i++) {\n const sourceIdx = (((i - flatShift) % size) + size) % size;\n const value = flatStorage.iget(sourceIdx);\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n // Reshape back to original shape\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n }\n\n // Handle axis specified case\n const shifts = Array.isArray(shift) ? shift : [shift];\n const axes = Array.isArray(axis) ? axis : [axis];\n\n if (shifts.length !== axes.length) {\n throw new Error('shift and axis must have the same length');\n }\n\n // Normalize axes\n const normalizedAxes = axes.map((ax) => {\n const normalized = ax < 0 ? ndim + ax : ax;\n if (normalized < 0 || normalized >= ndim) {\n throw new Error(`axis ${ax} is out of bounds for array of dimension ${ndim}`);\n }\n return normalized;\n });\n\n // Create output array\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot roll array with dtype ${dtype}`);\n }\n const outputData = new Constructor(size);\n const isBigInt = isBigIntDType(dtype);\n\n // Iterate through all output positions\n const outputIndices = new Array(ndim).fill(0);\n\n for (let i = 0; i < size; i++) {\n // Compute source indices by rolling back\n const sourceIndices = [...outputIndices];\n for (let j = 0; j < normalizedAxes.length; j++) {\n const ax = normalizedAxes[j]!;\n const axisSize = shape[ax]!;\n const sh = shifts[j]!;\n sourceIndices[ax] = (((sourceIndices[ax]! - sh) % axisSize) + axisSize) % axisSize;\n }\n\n // Get value from source\n let sourceOffset = storage.offset;\n for (let d = 0; d < ndim; d++) {\n sourceOffset += sourceIndices[d]! * storage.strides[d]!;\n }\n const value = storage.data[sourceOffset];\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n\n // Increment output indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < shape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, [...shape], dtype);\n}\n\n/**\n * Roll the specified axis backwards until it lies in a given position\n */\nexport function rollaxis(storage: ArrayStorage, axis: number, start: number = 0): ArrayStorage {\n const ndim = storage.ndim;\n\n // Normalize axis\n let normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Normalize start\n let normalizedStart = start < 0 ? ndim + start : start;\n if (normalizedStart < 0 || normalizedStart > ndim) {\n throw new Error(`start ${start} is out of bounds`);\n }\n\n if (normalizedAxis < normalizedStart) {\n normalizedStart--;\n }\n\n if (normalizedAxis === normalizedStart) {\n return ArrayStorage.fromData(\n storage.data,\n Array.from(storage.shape),\n storage.dtype,\n Array.from(storage.strides),\n storage.offset\n );\n }\n\n return moveaxis(storage, normalizedAxis, normalizedStart);\n}\n\n/**\n * Split array along third axis (depth)\n */\nexport function dsplit(\n storage: ArrayStorage,\n indicesOrSections: number | number[]\n): ArrayStorage[] {\n if (storage.ndim < 3) {\n throw new Error('dsplit only works on arrays of 3 or more dimensions');\n }\n return arraySplit(storage, indicesOrSections, 2);\n}\n\n/**\n * Stack 1-D arrays as columns into a 2-D array\n */\nexport function columnStack(storages: ArrayStorage[]): ArrayStorage {\n if (storages.length === 0) {\n throw new Error('need at least one array to stack');\n }\n\n // If all arrays are 1D, reshape them to column vectors\n const prepared = storages.map((s) => {\n if (s.ndim === 1) {\n return reshape(s, [s.shape[0]!, 1]);\n }\n return s;\n });\n\n return hstack(prepared);\n}\n\n/**\n * Stack arrays in sequence vertically (row_stack is an alias for vstack)\n */\nexport const rowStack = vstack;\n\n/**\n * Resize array to new shape (returns new array, may repeat or truncate)\n */\nexport function resize(storage: ArrayStorage, newShape: number[]): ArrayStorage {\n const dtype = storage.dtype;\n const newSize = newShape.reduce((a, b) => a * b, 1);\n const oldSize = storage.size;\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot resize array with dtype ${dtype}`);\n }\n const outputData = new Constructor(newSize);\n const isBigInt = isBigIntDType(dtype);\n\n // Fill output by cycling through source data\n for (let i = 0; i < newSize; i++) {\n const sourceIdx = i % oldSize;\n const value = storage.iget(sourceIdx);\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, newShape, dtype);\n}\n\n/**\n * Convert arrays to at least 1D\n */\nexport function atleast1d(storages: ArrayStorage[]): ArrayStorage[] {\n return storages.map((s) => {\n if (s.ndim === 0) {\n // 0-D array -> 1-D with one element\n return reshape(s, [1]);\n }\n return s;\n });\n}\n\n/**\n * Convert arrays to at least 2D\n */\nexport function atleast2d(storages: ArrayStorage[]): ArrayStorage[] {\n return storages.map((s) => {\n if (s.ndim === 0) {\n return reshape(s, [1, 1]);\n } else if (s.ndim === 1) {\n return reshape(s, [1, s.shape[0]!]);\n }\n return s;\n });\n}\n\n/**\n * Convert arrays to at least 3D\n */\nexport function atleast3d(storages: ArrayStorage[]): ArrayStorage[] {\n return storages.map((s) => {\n if (s.ndim === 0) {\n return reshape(s, [1, 1, 1]);\n } else if (s.ndim === 1) {\n return reshape(s, [1, s.shape[0]!, 1]);\n } else if (s.ndim === 2) {\n return reshape(s, [s.shape[0]!, s.shape[1]!, 1]);\n }\n return s;\n });\n}\n", "/**\n * Linear algebra operations\n *\n * Pure functions for matrix operations (matmul, etc.).\n * @module ops/linalg\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { promoteDTypes } from '../core/dtype';\nimport * as shapeOps from './shape';\n\n/**\n * BLAS-like types for matrix operations\n */\ntype Layout = 'row-major' | 'column-major';\ntype Transpose = 'no-transpose' | 'transpose';\n\n/**\n * Double-precision general matrix multiply (DGEMM)\n *\n * Full BLAS-compatible implementation without external dependencies.\n * Performs: C = alpha * op(A) * op(B) + beta * C\n *\n * Supports all combinations of:\n * - Row-major and column-major layouts\n * - Transpose and no-transpose operations\n * - Arbitrary alpha and beta scalars\n *\n * Uses specialized loops for each case to avoid function call overhead.\n *\n * @internal\n */\nfunction dgemm(\n layout: Layout,\n transA: Transpose,\n transB: Transpose,\n M: number, // rows of op(A) and C\n N: number, // cols of op(B) and C\n K: number, // cols of op(A) and rows of op(B)\n alpha: number, // scalar alpha\n A: Float64Array, // matrix A\n lda: number, // leading dimension of A\n B: Float64Array, // matrix B\n ldb: number, // leading dimension of B\n beta: number, // scalar beta\n C: Float64Array, // matrix C (output)\n ldc: number // leading dimension of C\n): void {\n // Apply beta scaling to C first\n if (beta === 0) {\n for (let i = 0; i < M * N; i++) {\n C[i] = 0;\n }\n } else if (beta !== 1) {\n for (let i = 0; i < M * N; i++) {\n C[i] = (C[i] ?? 0) * beta;\n }\n }\n\n // Select specialized loop based on layout and transpose modes\n // This avoids function call overhead in the hot loop\n const isRowMajor = layout === 'row-major';\n const transposeA = transA === 'transpose';\n const transposeB = transB === 'transpose';\n\n if (isRowMajor && !transposeA && !transposeB) {\n // Row-major, no transpose (most common case)\n // C[i,j] = sum_k A[i,k] * B[k,j]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (isRowMajor && transposeA && !transposeB) {\n // Row-major, A transposed\n // C[i,j] = sum_k A[k,i] * B[k,j]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (isRowMajor && !transposeA && transposeB) {\n // Row-major, B transposed\n // C[i,j] = sum_k A[i,k] * B[j,k]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (isRowMajor && transposeA && transposeB) {\n // Row-major, both transposed\n // C[i,j] = sum_k A[k,i] * B[j,k]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[i * ldc + j] = (C[i * ldc + j] ?? 0) + alpha * sum;\n }\n }\n } else if (!isRowMajor && !transposeA && !transposeB) {\n // Column-major, no transpose\n // C[i,j] = sum_k A[i,k] * B[k,j]\n // Column-major: A[i,k] = A[k*lda + i], C[i,j] = C[j*ldc + i]\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n } else if (!isRowMajor && transposeA && !transposeB) {\n // Column-major, A transposed\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[j * ldb + k] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n } else if (!isRowMajor && !transposeA && transposeB) {\n // Column-major, B transposed\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[k * lda + i] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n } else {\n // Column-major, both transposed\n for (let i = 0; i < M; i++) {\n for (let j = 0; j < N; j++) {\n let sum = 0;\n for (let k = 0; k < K; k++) {\n sum += (A[i * lda + k] ?? 0) * (B[k * ldb + j] ?? 0);\n }\n C[j * ldc + i] = (C[j * ldc + i] ?? 0) + alpha * sum;\n }\n }\n }\n}\n\n/**\n * Dot product of two arrays (fully NumPy-compatible)\n *\n * Behavior depends on input dimensions:\n * - 0D \u00B7 0D: Multiply scalars \u2192 scalar\n * - 0D \u00B7 ND or ND \u00B7 0D: Element-wise multiply \u2192 ND\n * - 1D \u00B7 1D: Inner product \u2192 scalar\n * - 2D \u00B7 2D: Matrix multiplication \u2192 2D\n * - 2D \u00B7 1D: Matrix-vector product \u2192 1D\n * - 1D \u00B7 2D: Vector-matrix product \u2192 1D\n * - ND \u00B7 1D (N\u22652): Sum product over last axis of a \u2192 (N-1)D\n * - 1D \u00B7 ND (N\u22652): Sum product over first axis of b \u2192 (N-1)D\n * - ND \u00B7 MD (N,M\u22652): Sum product over last axis of a and second-to-last of b \u2192 (N+M-2)D\n *\n * For 2D\u00B72D, prefer using matmul() instead.\n */\nexport function dot(a: ArrayStorage, b: ArrayStorage): ArrayStorage | number | bigint {\n const aDim = a.ndim;\n const bDim = b.ndim;\n\n // Case 0: Scalar (0D) cases - treat as multiplication\n if (aDim === 0 || bDim === 0) {\n // Get scalar values\n const aVal = aDim === 0 ? a.get() : null;\n const bVal = bDim === 0 ? b.get() : null;\n\n if (aDim === 0 && bDim === 0) {\n // Both scalars: multiply them\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n return aVal * bVal;\n }\n return Number(aVal) * Number(bVal);\n } else if (aDim === 0) {\n // a is scalar, b is array: scalar * array (element-wise)\n // Equivalent to multiply(a, b)\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([...b.shape], resultDtype);\n for (let i = 0; i < b.size; i++) {\n const bData = b.data[i + b.offset];\n if (typeof aVal === 'bigint' && typeof bData === 'bigint') {\n result.data[i] = aVal * bData;\n } else {\n result.data[i] = Number(aVal) * Number(bData);\n }\n }\n return result;\n } else {\n // b is scalar, a is array: array * scalar (element-wise)\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([...a.shape], resultDtype);\n for (let i = 0; i < a.size; i++) {\n const aData = a.data[i + a.offset];\n if (typeof aData === 'bigint' && typeof bVal === 'bigint') {\n result.data[i] = aData * bVal;\n } else {\n result.data[i] = Number(aData) * Number(bVal);\n }\n }\n return result;\n }\n }\n\n // Case 1: Both 1D -> scalar (inner product)\n if (aDim === 1 && bDim === 1) {\n if (a.shape[0] !== b.shape[0]) {\n throw new Error(`dot: incompatible shapes (${a.shape[0]},) and (${b.shape[0]},)`);\n }\n const n = a.shape[0]!;\n let sum = 0;\n for (let i = 0; i < n; i++) {\n const aVal = a.get(i);\n const bVal = b.get(i);\n // Handle BigInt\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n return sum;\n }\n\n // Case 2: Both 2D -> matrix multiplication (delegate to matmul)\n if (aDim === 2 && bDim === 2) {\n return matmul(a, b);\n }\n\n // Case 3: 2D \u00B7 1D -> matrix-vector product (returns 1D)\n if (aDim === 2 && bDim === 1) {\n const [m, k] = a.shape;\n const n = b.shape[0]!;\n if (k !== n) {\n throw new Error(`dot: incompatible shapes (${m},${k}) and (${n},)`);\n }\n\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([m!], resultDtype);\n\n for (let i = 0; i < m!; i++) {\n let sum = 0;\n for (let j = 0; j < k!; j++) {\n const aVal = a.get(i, j);\n const bVal = b.get(j);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set([i], sum);\n }\n\n return result;\n }\n\n // Case 4: 1D \u00B7 2D -> vector-matrix product (returns 1D)\n if (aDim === 1 && bDim === 2) {\n const m = a.shape[0]!;\n const [k, n] = b.shape;\n if (m !== k) {\n throw new Error(`dot: incompatible shapes (${m},) and (${k},${n})`);\n }\n\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([n!], resultDtype);\n\n for (let j = 0; j < n!; j++) {\n let sum = 0;\n for (let i = 0; i < m; i++) {\n const aVal = a.get(i);\n const bVal = b.get(i, j);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set([j], sum);\n }\n\n return result;\n }\n\n // Case 5: ND \u00B7 1D (N > 2) -> sum product over last axis, result is (N-1)D\n if (aDim > 2 && bDim === 1) {\n const lastDimA = a.shape[aDim - 1]!;\n const bSize = b.shape[0]!;\n if (lastDimA !== bSize) {\n throw new Error(`dot: incompatible shapes ${JSON.stringify(a.shape)} and (${bSize},)`);\n }\n\n // Result shape is a.shape[:-1]\n const resultShape = [...a.shape.slice(0, -1)];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n // Iterate over all positions in result\n const resultSize = resultShape.reduce((acc, dim) => acc * dim, 1);\n for (let i = 0; i < resultSize; i++) {\n let sum = 0;\n // Compute multi-dimensional index for result\n let temp = i;\n const resultIdx: number[] = [];\n for (let d = resultShape.length - 1; d >= 0; d--) {\n resultIdx[d] = temp % resultShape[d]!;\n temp = Math.floor(temp / resultShape[d]!);\n }\n\n // Sum over the last dimension of a\n for (let k = 0; k < lastDimA; k++) {\n const aIdx = [...resultIdx, k];\n const aVal = a.get(...aIdx);\n const bVal = b.get(k);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set(resultIdx, sum);\n }\n\n return result;\n }\n\n // Case 6: 1D \u00B7 ND (N > 2) -> sum product over SECOND axis of b, result is (b.shape[0], b.shape[2:])\n // Actually for 1D\u00B73D: sum over axis 1 of b\n // For general case: need to handle this more carefully\n if (aDim === 1 && bDim > 2) {\n const aSize = a.shape[0]!;\n // For 1D (size K) \u00B7 ND, we contract over axis 1 of b (which should have size K)\n const contractAxisB = 1;\n const contractDimB = b.shape[contractAxisB]!;\n\n if (aSize !== contractDimB) {\n throw new Error(`dot: incompatible shapes (${aSize},) and ${JSON.stringify(b.shape)}`);\n }\n\n // Result shape: b.shape[0:1] + b.shape[2:]\n // For (K,) \u00B7 (L, K, M, N, ...) -> (L, M, N, ...)\n const resultShape = [...b.shape.slice(0, contractAxisB), ...b.shape.slice(contractAxisB + 1)];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n // Compute using multi-dimensional indices\n const resultSize = resultShape.reduce((acc, dim) => acc * dim, 1);\n for (let i = 0; i < resultSize; i++) {\n // Convert flat index to multi-dim result index\n let temp = i;\n const resultIdx: number[] = [];\n for (let d = resultShape.length - 1; d >= 0; d--) {\n resultIdx[d] = temp % resultShape[d]!;\n temp = Math.floor(temp / resultShape[d]!);\n }\n\n // Build b index by inserting the contract dimension\n // result[i,j,...] corresponds to b[i, :, j, ...]\n const bIdxBefore = resultIdx.slice(0, contractAxisB);\n const bIdxAfter = resultIdx.slice(contractAxisB);\n\n let sum = 0;\n for (let k = 0; k < aSize; k++) {\n const aVal = a.get(k);\n const bIdx = [...bIdxBefore, k, ...bIdxAfter];\n const bVal = b.get(...bIdx);\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n result.set(resultIdx, sum);\n }\n\n return result;\n }\n\n // Case 7: ND \u00B7 MD (N,M \u2265 2, not both 2) -> general tensor contraction\n // Result shape: a.shape[:-1] + b.shape[:-2] + b.shape[-1:]\n if (aDim >= 2 && bDim >= 2 && !(aDim === 2 && bDim === 2)) {\n const lastDimA = a.shape[aDim - 1]!;\n const secondLastDimB = b.shape[bDim - 2]!;\n\n if (lastDimA !== secondLastDimB) {\n throw new Error(\n `dot: incompatible shapes ${JSON.stringify(a.shape)} and ${JSON.stringify(b.shape)}`\n );\n }\n\n // Build result shape\n const resultShape = [...a.shape.slice(0, -1), ...b.shape.slice(0, -2), b.shape[bDim - 1]!];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n const aOuterSize = a.shape.slice(0, -1).reduce((acc, dim) => acc * dim, 1);\n const bOuterSize = b.shape.slice(0, -2).reduce((acc, dim) => acc * dim, 1);\n const bLastDim = b.shape[bDim - 1]!;\n const contractionDim = lastDimA;\n\n // Iterate: result[i, j, k] = sum_m a[i, m] * b[j, m, k]\n for (let i = 0; i < aOuterSize; i++) {\n for (let j = 0; j < bOuterSize; j++) {\n for (let k = 0; k < bLastDim; k++) {\n let sum = 0;\n for (let m = 0; m < contractionDim; m++) {\n // Get a[i, m] - need to convert flat index i to multi-dim\n const aIdx = i * contractionDim + m;\n const aVal = a.data[aIdx + a.offset];\n\n // Get b[j, m, k] - need multi-dim indexing\n const bIdx = j * contractionDim * bLastDim + m * bLastDim + k;\n const bVal = b.data[bIdx + b.offset];\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n\n // Set result at the appropriate position\n const resultIdx = i * bOuterSize * bLastDim + j * bLastDim + k;\n result.data[resultIdx] = sum;\n }\n }\n }\n\n return result;\n }\n\n // Should never reach here - all cases covered\n throw new Error(`dot: unexpected combination of dimensions ${aDim}D \u00B7 ${bDim}D`);\n}\n\n/**\n * Matrix multiplication\n * Requires 2D arrays with compatible shapes\n *\n * Automatically detects transposed/non-contiguous arrays via strides\n * and uses appropriate DGEMM transpose parameters.\n *\n * Note: Currently uses float64 precision for all operations.\n * Integer inputs are promoted to float64 (matching NumPy behavior).\n */\nexport function matmul(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n if (a.ndim !== 2 || b.ndim !== 2) {\n throw new Error('matmul requires 2D arrays');\n }\n\n const [m = 0, k = 0] = a.shape;\n const [k2 = 0, n = 0] = b.shape;\n\n if (k !== k2) {\n throw new Error(`matmul shape mismatch: (${m},${k}) @ (${k2},${n})`);\n }\n\n // Determine result dtype (promote inputs, but use float64 for integer types)\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const computeDtype =\n resultDtype.startsWith('int') || resultDtype.startsWith('uint') || resultDtype === 'bool'\n ? 'float64'\n : resultDtype;\n\n // For now, we only support float64 matmul (using dgemm)\n // TODO: Add float32 support using sgemm\n if (computeDtype !== 'float64') {\n throw new Error(`matmul currently only supports float64, got ${computeDtype}`);\n }\n\n // Convert inputs to Float64Array if needed\n let aData =\n a.dtype === 'float64'\n ? (a.data as Float64Array)\n : Float64Array.from(Array.from(a.data as ArrayLike<number>).map(Number));\n let bData =\n b.dtype === 'float64'\n ? (b.data as Float64Array)\n : Float64Array.from(Array.from(b.data as ArrayLike<number>).map(Number));\n\n // Handle offset for sliced arrays (views)\n // If the array has an offset, we need to pass the subarray starting from that offset\n if (a.offset > 0) {\n aData = aData.subarray(a.offset) as Float64Array;\n }\n if (b.offset > 0) {\n bData = bData.subarray(b.offset) as Float64Array;\n }\n\n // Detect array layout from strides\n // Row-major (C-contiguous): row stride > col stride\n // Transposed (F-contiguous or transposed view): col stride > row stride\n const [aStrideRow = 0, aStrideCol = 0] = a.strides;\n const [bStrideRow = 0, bStrideCol = 0] = b.strides;\n\n // Determine if arrays are effectively transposed\n // For a normal MxK array: strides are [K, 1] (row stride = K cols)\n // For a transposed KxM array (viewed as MxK): strides are [1, M] (col stride > row stride)\n const aIsTransposed = aStrideCol > aStrideRow;\n const bIsTransposed = bStrideCol > bStrideRow;\n\n const transA: Transpose = aIsTransposed ? 'transpose' : 'no-transpose';\n const transB: Transpose = bIsTransposed ? 'transpose' : 'no-transpose';\n\n // Determine leading dimensions based on memory layout\n // Leading dimension is the stride of the major dimension in memory\n let lda: number;\n let ldb: number;\n\n if (aIsTransposed) {\n // Array is stored with columns contiguous (F-order or transposed)\n // The leading dimension is how many elements to skip between columns\n lda = aStrideCol;\n } else {\n // Array is row-major (C-order)\n // The leading dimension is the row stride (number of elements per row)\n lda = aStrideRow;\n }\n\n if (bIsTransposed) {\n ldb = bStrideCol;\n } else {\n ldb = bStrideRow;\n }\n\n // Create result array (always row-major)\n const result = ArrayStorage.zeros([m, n], 'float64');\n\n // Call dgemm with detected transpose flags and leading dimensions\n dgemm(\n 'row-major',\n transA,\n transB,\n m,\n n,\n k,\n 1.0, // alpha\n aData,\n lda, // leading dimension of a (accounts for actual memory layout)\n bData,\n ldb, // leading dimension of b (accounts for actual memory layout)\n 0.0, // beta\n result.data as Float64Array,\n n // ldc (result is always row-major with n cols)\n );\n\n return result;\n}\n\n/**\n * Sum along the diagonal of a 2D array\n *\n * Computes the trace (sum of diagonal elements) of a matrix.\n * For non-square matrices, sums along the diagonal up to min(rows, cols).\n *\n * @param a - Input 2D array\n * @returns Sum of diagonal elements\n */\nexport function trace(a: ArrayStorage): number | bigint {\n if (a.ndim !== 2) {\n throw new Error(`trace requires 2D array, got ${a.ndim}D`);\n }\n\n const [rows = 0, cols = 0] = a.shape;\n const diagLen = Math.min(rows, cols);\n\n let sum: number | bigint = 0;\n\n for (let i = 0; i < diagLen; i++) {\n const val = a.get(i, i);\n if (typeof val === 'bigint') {\n sum = (typeof sum === 'bigint' ? sum : BigInt(sum)) + val;\n } else {\n sum = (typeof sum === 'bigint' ? Number(sum) : sum) + val;\n }\n }\n\n return sum;\n}\n\n/**\n * Permute the dimensions of an array\n *\n * Standalone version of NDArray.transpose() method.\n * Returns a view with axes permuted.\n *\n * @param a - Input array\n * @param axes - Optional permutation of axes (defaults to reverse order)\n * @returns Transposed view\n */\nexport function transpose(a: ArrayStorage, axes?: number[]): ArrayStorage {\n return shapeOps.transpose(a, axes);\n}\n\n/**\n * Inner product of two arrays\n *\n * Computes sum product over the LAST axes of both a and b.\n * - 1D \u00B7 1D: Same as dot (ordinary inner product) \u2192 scalar\n * - ND \u00B7 MD: Contracts last dimension of each \u2192 (*a.shape[:-1], *b.shape[:-1])\n *\n * Different from dot: always uses last axis of BOTH arrays.\n *\n * @param a - First array\n * @param b - Second array\n * @returns Inner product result\n */\nexport function inner(a: ArrayStorage, b: ArrayStorage): ArrayStorage | number | bigint {\n const aDim = a.ndim;\n const bDim = b.ndim;\n\n // Last dimensions must match\n const aLastDim = a.shape[aDim - 1]!;\n const bLastDim = b.shape[bDim - 1]!;\n\n if (aLastDim !== bLastDim) {\n throw new Error(\n `inner: incompatible shapes - last dimensions ${aLastDim} and ${bLastDim} don't match`\n );\n }\n\n // Special case: both 1D -> scalar\n if (aDim === 1 && bDim === 1) {\n return dot(a, b) as number;\n }\n\n // General case: result shape is a.shape[:-1] + b.shape[:-1]\n const resultShape = [...a.shape.slice(0, -1), ...b.shape.slice(0, -1)];\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n const aOuterSize = aDim === 1 ? 1 : a.shape.slice(0, -1).reduce((acc, dim) => acc * dim, 1);\n const bOuterSize = bDim === 1 ? 1 : b.shape.slice(0, -1).reduce((acc, dim) => acc * dim, 1);\n const contractionDim = aLastDim;\n\n // Compute: result[i, j] = sum_k a[i, k] * b[j, k]\n for (let i = 0; i < aOuterSize; i++) {\n for (let j = 0; j < bOuterSize; j++) {\n let sum = 0;\n for (let k = 0; k < contractionDim; k++) {\n // Get a[i, k] and b[j, k]\n const aIdx = aDim === 1 ? k : i * contractionDim + k;\n const bIdx = bDim === 1 ? k : j * contractionDim + k;\n const aVal = a.data[aIdx + a.offset];\n const bVal = b.data[bIdx + b.offset];\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n\n // Set result\n if (resultShape.length === 0) {\n // Scalar result\n return sum;\n }\n const resultIdx = aOuterSize === 1 ? j : i * bOuterSize + j;\n result.data[resultIdx] = sum;\n }\n }\n\n return result;\n}\n\n/**\n * Outer product of two vectors\n *\n * Computes out[i, j] = a[i] * b[j]\n * Input arrays are flattened if not 1D.\n *\n * @param a - First input (flattened to 1D)\n * @param b - Second input (flattened to 1D)\n * @returns 2D array of shape (a.size, b.size)\n */\nexport function outer(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n // Flatten inputs to 1D\n const aFlat = a.ndim === 1 ? a : shapeOps.ravel(a);\n const bFlat = b.ndim === 1 ? b : shapeOps.ravel(b);\n\n const m = aFlat.size;\n const n = bFlat.size;\n\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros([m, n], resultDtype);\n\n // Compute outer product: result[i,j] = a[i] * b[j]\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n const aVal = aFlat.get(i);\n const bVal = bFlat.get(j);\n\n let product;\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n product = aVal * bVal;\n } else {\n product = Number(aVal) * Number(bVal);\n }\n\n result.set([i, j], product);\n }\n }\n\n return result;\n}\n\n/**\n * Tensor dot product along specified axes\n *\n * Computes sum product over specified axes.\n *\n * @param a - First array\n * @param b - Second array\n * @param axes - Axes to contract:\n * - Integer N: Contract last N axes of a with first N of b\n * - [a_axes, b_axes]: Contract specified axes\n * @returns Tensor dot product\n */\nexport function tensordot(\n a: ArrayStorage,\n b: ArrayStorage,\n axes: number | [number[], number[]]\n): ArrayStorage | number | bigint {\n let aAxes: number[];\n let bAxes: number[];\n\n if (typeof axes === 'number') {\n // Contract last N axes of a with first N of b\n const N = axes;\n if (N < 0) {\n throw new Error('tensordot: axes must be non-negative');\n }\n if (N > a.ndim || N > b.ndim) {\n throw new Error('tensordot: axes exceeds array dimensions');\n }\n\n // Last N axes of a\n aAxes = Array.from({ length: N }, (_, i) => a.ndim - N + i);\n // First N axes of b\n bAxes = Array.from({ length: N }, (_, i) => i);\n } else {\n [aAxes, bAxes] = axes;\n if (aAxes.length !== bAxes.length) {\n throw new Error('tensordot: axes lists must have same length');\n }\n }\n\n // Validate axes and check dimension compatibility\n for (let i = 0; i < aAxes.length; i++) {\n const aAxis = aAxes[i]!;\n const bAxis = bAxes[i]!;\n if (aAxis < 0 || aAxis >= a.ndim || bAxis < 0 || bAxis >= b.ndim) {\n throw new Error('tensordot: axis out of bounds');\n }\n if (a.shape[aAxis] !== b.shape[bAxis]) {\n throw new Error(\n `tensordot: shape mismatch on axes ${aAxis} and ${bAxis}: ${a.shape[aAxis]} != ${b.shape[bAxis]}`\n );\n }\n }\n\n // Separate axes into contracted and free axes\n const aFreeAxes: number[] = [];\n const bFreeAxes: number[] = [];\n\n for (let i = 0; i < a.ndim; i++) {\n if (!aAxes.includes(i)) {\n aFreeAxes.push(i);\n }\n }\n for (let i = 0; i < b.ndim; i++) {\n if (!bAxes.includes(i)) {\n bFreeAxes.push(i);\n }\n }\n\n // Build result shape: free axes of a + free axes of b\n const resultShape = [\n ...aFreeAxes.map((ax) => a.shape[ax]!),\n ...bFreeAxes.map((ax) => b.shape[ax]!),\n ];\n\n // Special case: no free axes (full contraction) -> scalar result\n if (resultShape.length === 0) {\n let sum = 0;\n // Iterate over all combinations of contracted axes\n const contractSize = aAxes.map((ax) => a.shape[ax]!).reduce((acc, dim) => acc * dim, 1);\n\n for (let i = 0; i < contractSize; i++) {\n // Convert flat index to contracted indices\n let temp = i;\n const contractedIdx: number[] = new Array(aAxes.length);\n for (let j = aAxes.length - 1; j >= 0; j--) {\n const ax = aAxes[j]!;\n contractedIdx[j] = temp % a.shape[ax]!;\n temp = Math.floor(temp / a.shape[ax]!);\n }\n\n // Build full indices for a and b\n const aIdx: number[] = new Array(a.ndim);\n const bIdx: number[] = new Array(b.ndim);\n\n for (let j = 0; j < aAxes.length; j++) {\n aIdx[aAxes[j]!] = contractedIdx[j]!;\n }\n for (let j = 0; j < bAxes.length; j++) {\n bIdx[bAxes[j]!] = contractedIdx[j]!;\n }\n\n const aVal = a.get(...aIdx);\n const bVal = b.get(...bIdx);\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n return sum;\n }\n\n // General case: with free axes\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(resultShape, resultDtype);\n\n const resultSize = resultShape.reduce((acc, dim) => acc * dim, 1);\n const contractSize = aAxes.map((ax) => a.shape[ax]!).reduce((acc, dim) => acc * dim, 1);\n\n // Iterate over all result positions\n for (let resIdx = 0; resIdx < resultSize; resIdx++) {\n // Convert flat result index to multi-dimensional\n let temp = resIdx;\n const resultIndices: number[] = [];\n for (let i = resultShape.length - 1; i >= 0; i--) {\n resultIndices[i] = temp % resultShape[i]!;\n temp = Math.floor(temp / resultShape[i]!);\n }\n\n // Extract indices for a's free axes and b's free axes\n const aFreeIndices = resultIndices.slice(0, aFreeAxes.length);\n const bFreeIndices = resultIndices.slice(aFreeAxes.length);\n\n let sum = 0;\n\n // Sum over all contracted axes\n for (let c = 0; c < contractSize; c++) {\n // Convert flat contracted index to multi-dimensional\n temp = c;\n const contractedIndices: number[] = [];\n for (let i = aAxes.length - 1; i >= 0; i--) {\n const ax = aAxes[i]!;\n contractedIndices[i] = temp % a.shape[ax]!;\n temp = Math.floor(temp / a.shape[ax]!);\n }\n\n // Build full indices for a and b\n const aFullIdx: number[] = new Array(a.ndim);\n const bFullIdx: number[] = new Array(b.ndim);\n\n // Fill in free axes\n for (let i = 0; i < aFreeAxes.length; i++) {\n aFullIdx[aFreeAxes[i]!] = aFreeIndices[i]!;\n }\n for (let i = 0; i < bFreeAxes.length; i++) {\n bFullIdx[bFreeAxes[i]!] = bFreeIndices[i]!;\n }\n\n // Fill in contracted axes\n for (let i = 0; i < aAxes.length; i++) {\n aFullIdx[aAxes[i]!] = contractedIndices[i]!;\n bFullIdx[bAxes[i]!] = contractedIndices[i]!;\n }\n\n const aVal = a.get(...aFullIdx);\n const bVal = b.get(...bFullIdx);\n\n if (typeof aVal === 'bigint' && typeof bVal === 'bigint') {\n sum = Number(sum) + Number(aVal * bVal);\n } else {\n sum += Number(aVal) * Number(bVal);\n }\n }\n\n result.set(resultIndices, sum);\n }\n\n return result;\n}\n\n/**\n * Extract a diagonal or construct a diagonal array.\n *\n * NumPy behavior:\n * - For 2D arrays: extract the k-th diagonal\n * - For ND arrays (N >= 2): extract diagonal from the axes specified\n * - Returns a view when possible, copy otherwise\n *\n * @param a - Input array (must be at least 2D)\n * @param offset - Offset of the diagonal from the main diagonal (default: 0)\n * - offset > 0: diagonal above main diagonal\n * - offset < 0: diagonal below main diagonal\n * @param axis1 - First axis for ND arrays (default: 0)\n * @param axis2 - Second axis for ND arrays (default: 1)\n * @returns Array containing the diagonal elements\n */\nexport function diagonal(\n a: ArrayStorage,\n offset: number = 0,\n axis1: number = 0,\n axis2: number = 1\n): ArrayStorage {\n const shape = a.shape;\n const ndim = shape.length;\n\n if (ndim < 2) {\n throw new Error('diagonal requires an array of at least two dimensions');\n }\n\n // Normalize negative axes\n const ax1 = axis1 < 0 ? ndim + axis1 : axis1;\n const ax2 = axis2 < 0 ? ndim + axis2 : axis2;\n\n if (ax1 < 0 || ax1 >= ndim || ax2 < 0 || ax2 >= ndim) {\n throw new Error('axis out of bounds');\n }\n\n if (ax1 === ax2) {\n throw new Error('axis1 and axis2 cannot be the same');\n }\n\n // Get dimensions of the two axes\n const dim1 = shape[ax1]!;\n const dim2 = shape[ax2]!;\n\n // Calculate diagonal length\n let diagLen: number;\n if (offset >= 0) {\n diagLen = Math.max(0, Math.min(dim1, dim2 - offset));\n } else {\n diagLen = Math.max(0, Math.min(dim1 + offset, dim2));\n }\n\n // Build output shape: remove axis1 and axis2, append diagLen\n const outShape: number[] = [];\n for (let i = 0; i < ndim; i++) {\n if (i !== ax1 && i !== ax2) {\n outShape.push(shape[i]!);\n }\n }\n outShape.push(diagLen);\n\n // Create output array\n const result = ArrayStorage.zeros(outShape, a.dtype);\n\n // Extract diagonal elements\n // We need to iterate over all combinations of indices for other dimensions\n const otherDims = shape.filter((_, i) => i !== ax1 && i !== ax2);\n const otherSize = otherDims.reduce((acc, d) => acc * d, 1);\n\n for (let otherIdx = 0; otherIdx < otherSize; otherIdx++) {\n // Convert flat index to multi-dimensional indices for \"other\" dimensions\n let temp = otherIdx;\n const otherIndices: number[] = [];\n for (let i = otherDims.length - 1; i >= 0; i--) {\n otherIndices.unshift(temp % otherDims[i]!);\n temp = Math.floor(temp / otherDims[i]!);\n }\n\n // Extract diagonal for this slice\n for (let d = 0; d < diagLen; d++) {\n // Build source indices\n const srcIndices: number[] = new Array(ndim);\n let otherIdx2 = 0;\n for (let i = 0; i < ndim; i++) {\n if (i === ax1) {\n srcIndices[i] = offset >= 0 ? d : d - offset;\n } else if (i === ax2) {\n srcIndices[i] = offset >= 0 ? d + offset : d;\n } else {\n srcIndices[i] = otherIndices[otherIdx2++]!;\n }\n }\n\n // Build destination indices\n const dstIndices = [...otherIndices, d];\n\n // Copy element\n const value = a.get(...srcIndices);\n result.set(dstIndices, value);\n }\n }\n\n return result;\n}\n\n/**\n * Einstein summation convention\n *\n * Performs tensor contractions and reductions using Einstein summation notation.\n *\n * Examples:\n * - 'ij,jk->ik': matrix multiplication\n * - 'i,i->': dot product (inner product)\n * - 'ij->ji': transpose\n * - 'ii->': trace\n * - 'ij->j': sum over first axis\n * - 'ijk,ikl->ijl': batched matrix multiplication\n *\n * @param subscripts - Einstein summation subscripts (e.g., 'ij,jk->ik')\n * @param operands - Input arrays\n * @returns Result of the Einstein summation\n */\nexport function einsum(\n subscripts: string,\n ...operands: ArrayStorage[]\n): ArrayStorage | number | bigint {\n // Parse the subscripts\n const arrowMatch = subscripts.indexOf('->');\n\n let inputSubscripts: string;\n let outputSubscript: string;\n\n if (arrowMatch === -1) {\n // Implicit output: collect unique indices not repeated\n inputSubscripts = subscripts;\n outputSubscript = inferOutputSubscript(inputSubscripts);\n } else {\n inputSubscripts = subscripts.slice(0, arrowMatch);\n outputSubscript = subscripts.slice(arrowMatch + 2);\n }\n\n // Parse input subscripts into individual operand subscripts\n const operandSubscripts = inputSubscripts.split(',').map((s) => s.trim());\n\n if (operandSubscripts.length !== operands.length) {\n throw new Error(\n `einsum: expected ${operandSubscripts.length} operands, got ${operands.length}`\n );\n }\n\n // Validate subscripts and build index dimension map\n const indexDims = new Map<string, number>();\n\n for (let i = 0; i < operands.length; i++) {\n const sub = operandSubscripts[i]!;\n const op = operands[i]!;\n\n if (sub.length !== op.ndim) {\n throw new Error(\n `einsum: operand ${i} has ${op.ndim} dimensions but subscript '${sub}' has ${sub.length} indices`\n );\n }\n\n for (let j = 0; j < sub.length; j++) {\n const idx = sub[j]!;\n const dim = op.shape[j]!;\n\n if (indexDims.has(idx)) {\n if (indexDims.get(idx) !== dim) {\n throw new Error(\n `einsum: size mismatch for index '${idx}': ${indexDims.get(idx)} vs ${dim}`\n );\n }\n } else {\n indexDims.set(idx, dim);\n }\n }\n }\n\n // Validate output subscript\n for (const idx of outputSubscript) {\n if (!indexDims.has(idx)) {\n throw new Error(`einsum: output subscript contains unknown index '${idx}'`);\n }\n }\n\n // Identify summation indices (in inputs but not in output)\n const outputIndices = new Set(outputSubscript);\n const allInputIndices = new Set<string>();\n for (const sub of operandSubscripts) {\n for (const idx of sub) {\n allInputIndices.add(idx);\n }\n }\n\n const sumIndices: string[] = [];\n for (const idx of allInputIndices) {\n if (!outputIndices.has(idx)) {\n sumIndices.push(idx);\n }\n }\n\n // ========================================\n // FAST PATHS: Detect common patterns and delegate to optimized implementations\n // ========================================\n\n // Pattern: Matrix multiplication \"ij,jk->ik\" or similar\n if (operands.length === 2 && operandSubscripts.length === 2) {\n const [sub1, sub2] = operandSubscripts;\n const [op1, op2] = operands;\n\n // Check for matmul pattern: two 2D arrays, one shared index\n if (\n sub1!.length === 2 &&\n sub2!.length === 2 &&\n outputSubscript.length === 2 &&\n op1!.ndim === 2 &&\n op2!.ndim === 2\n ) {\n const [i1, j1] = [sub1![0]!, sub1![1]!];\n const [i2, j2] = [sub2![0]!, sub2![1]!];\n const [o1, o2] = [outputSubscript[0]!, outputSubscript[1]!];\n\n // Pattern: \"ij,jk->ik\" (standard matmul)\n if (i1 === o1 && j2 === o2 && j1 === i2 && sumIndices.length === 1 && sumIndices[0] === j1) {\n return matmul(op1!, op2!);\n }\n\n // Pattern: \"ik,kj->ij\" (matmul with different index names)\n if (i1 === o1 && j2 === o2 && j1 === i2 && sumIndices.length === 1 && sumIndices[0] === j1) {\n return matmul(op1!, op2!);\n }\n\n // Pattern: \"ji,jk->ik\" (transpose A then multiply)\n if (j1 === o1 && j2 === o2 && i1 === i2 && sumIndices.length === 1 && sumIndices[0] === i1) {\n const op1T = transpose(op1!);\n return matmul(op1T, op2!);\n }\n\n // Pattern: \"ij,kj->ik\" (transpose B then multiply)\n if (i1 === o1 && i2 === o2 && j1 === j2 && sumIndices.length === 1 && sumIndices[0] === j1) {\n const op2T = transpose(op2!);\n return matmul(op1!, op2T);\n }\n }\n\n // Check for dot product pattern: two 1D arrays \"i,i->\" or \"i,i->scalar\"\n if (\n sub1!.length === 1 &&\n sub2!.length === 1 &&\n sub1 === sub2 &&\n outputSubscript.length === 0 &&\n op1!.ndim === 1 &&\n op2!.ndim === 1\n ) {\n return computeEinsumScalar(operands, operandSubscripts, sumIndices, indexDims);\n }\n\n // Check for outer product pattern: \"i,j->ij\"\n if (\n sub1 &&\n sub2 &&\n sub1.length === 1 &&\n sub2.length === 1 &&\n outputSubscript.length === 2 &&\n outputSubscript === sub1 + sub2 &&\n sumIndices.length === 0 &&\n op1!.ndim === 1 &&\n op2!.ndim === 1\n ) {\n return outer(op1!, op2!);\n }\n }\n\n // Pattern: Single operand trace \"ii->\"\n if (operands.length === 1 && operandSubscripts[0]!.length === 2 && outputSubscript.length === 0) {\n const sub = operandSubscripts[0]!;\n if (sub[0] === sub[1]) {\n // This is a trace operation\n const op = operands[0]!;\n if (op.ndim === 2) {\n return computeEinsumScalar(operands, operandSubscripts, sumIndices, indexDims);\n }\n }\n }\n\n // ========================================\n // END FAST PATHS - Fall through to generic implementation\n // ========================================\n\n // Build output shape\n const outputShape = Array.from(outputSubscript).map((idx) => indexDims.get(idx)!);\n\n // Special case: scalar output\n if (outputShape.length === 0) {\n return computeEinsumScalar(operands, operandSubscripts, sumIndices, indexDims);\n }\n\n // Determine result dtype\n let resultDtype = operands[0]!.dtype;\n for (let i = 1; i < operands.length; i++) {\n resultDtype = promoteDTypes(resultDtype, operands[i]!.dtype);\n }\n\n // Create output array\n const result = ArrayStorage.zeros(outputShape, resultDtype);\n\n // Compute output size\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n\n // Compute sum range\n let sumSize = 1;\n for (const idx of sumIndices) {\n sumSize *= indexDims.get(idx)!;\n }\n\n // Iterate over all output positions\n for (let outIdx = 0; outIdx < outputSize; outIdx++) {\n // Convert flat index to multi-dimensional output index\n const outMultiIdx = flatToMulti(outIdx, outputShape);\n\n // Build index assignment for output indices\n const indexValues = new Map<string, number>();\n for (let i = 0; i < outputSubscript.length; i++) {\n indexValues.set(outputSubscript[i]!, outMultiIdx[i]!);\n }\n\n // Sum over summation indices\n let sum = 0;\n for (let sumIdx = 0; sumIdx < sumSize; sumIdx++) {\n // Assign values to summation indices\n let temp = sumIdx;\n for (let i = sumIndices.length - 1; i >= 0; i--) {\n const idx = sumIndices[i]!;\n const dim = indexDims.get(idx)!;\n indexValues.set(idx, temp % dim);\n temp = Math.floor(temp / dim);\n }\n\n // Compute product of all operand values\n let product = 1;\n for (let i = 0; i < operands.length; i++) {\n const op = operands[i]!;\n const sub = operandSubscripts[i]!;\n\n // Build operand index\n const opIdx: number[] = [];\n for (const idx of sub) {\n opIdx.push(indexValues.get(idx)!);\n }\n\n const val = op.get(...opIdx);\n product *= Number(val);\n }\n\n sum += product;\n }\n\n result.set(outMultiIdx, sum);\n }\n\n return result;\n}\n\n/**\n * Infer output subscript for implicit einsum notation\n * @private\n */\nfunction inferOutputSubscript(inputSubscripts: string): string {\n // Count occurrences of each index\n const counts = new Map<string, number>();\n const operandSubscripts = inputSubscripts.split(',');\n\n for (const sub of operandSubscripts) {\n for (const idx of sub.trim()) {\n counts.set(idx, (counts.get(idx) || 0) + 1);\n }\n }\n\n // Output contains indices that appear exactly once, sorted alphabetically\n const outputIndices: string[] = [];\n for (const [idx, count] of counts) {\n if (count === 1) {\n outputIndices.push(idx);\n }\n }\n\n return outputIndices.sort().join('');\n}\n\n/**\n * Compute einsum result when output is a scalar\n * @private\n */\nfunction computeEinsumScalar(\n operands: ArrayStorage[],\n operandSubscripts: string[],\n sumIndices: string[],\n indexDims: Map<string, number>\n): number {\n // All indices are summation indices\n let sumSize = 1;\n for (const idx of sumIndices) {\n sumSize *= indexDims.get(idx)!;\n }\n\n let sum = 0;\n\n for (let sumIdx = 0; sumIdx < sumSize; sumIdx++) {\n // Assign values to summation indices\n const indexValues = new Map<string, number>();\n let temp = sumIdx;\n for (let i = sumIndices.length - 1; i >= 0; i--) {\n const idx = sumIndices[i]!;\n const dim = indexDims.get(idx)!;\n indexValues.set(idx, temp % dim);\n temp = Math.floor(temp / dim);\n }\n\n // Compute product of all operand values\n let product = 1;\n for (let i = 0; i < operands.length; i++) {\n const op = operands[i]!;\n const sub = operandSubscripts[i]!;\n\n // Build operand index\n const opIdx: number[] = [];\n for (const idx of sub) {\n opIdx.push(indexValues.get(idx)!);\n }\n\n const val = op.get(...opIdx);\n product *= Number(val);\n }\n\n sum += product;\n }\n\n return sum;\n}\n\n/**\n * Convert flat index to multi-dimensional index\n * @private\n */\nfunction flatToMulti(flatIdx: number, shape: number[]): number[] {\n const result: number[] = new Array(shape.length);\n let temp = flatIdx;\n\n for (let i = shape.length - 1; i >= 0; i--) {\n result[i] = temp % shape[i]!;\n temp = Math.floor(temp / shape[i]!);\n }\n\n return result;\n}\n\n/**\n * Kronecker product of two arrays.\n *\n * Computes the Kronecker product, a composite array made of blocks of the\n * second array scaled by the elements of the first.\n *\n * NumPy behavior:\n * - If both inputs are vectors (1D), output is also a vector\n * - If both inputs are 2D matrices, output shape is (m1*m2, n1*n2)\n * - General case: broadcasts shapes then computes block product\n *\n * @param a - First input array\n * @param b - Second input array\n * @returns Kronecker product of a and b\n */\nexport function kron(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const aShape = a.shape;\n const bShape = b.shape;\n const aNdim = aShape.length;\n const bNdim = bShape.length;\n\n // Promote dtypes\n const resultDtype = promoteDTypes(a.dtype, b.dtype);\n\n // Determine output shape\n const ndim = Math.max(aNdim, bNdim);\n const outShape: number[] = new Array(ndim);\n\n // Pad shapes with ones on the left if needed\n const aPadded: number[] = new Array(ndim).fill(1);\n const bPadded: number[] = new Array(ndim).fill(1);\n\n for (let i = 0; i < aNdim; i++) {\n aPadded[ndim - aNdim + i] = aShape[i]!;\n }\n for (let i = 0; i < bNdim; i++) {\n bPadded[ndim - bNdim + i] = bShape[i]!;\n }\n\n // Output shape is element-wise product\n for (let i = 0; i < ndim; i++) {\n outShape[i] = aPadded[i]! * bPadded[i]!;\n }\n\n // Create result array\n const result = ArrayStorage.zeros(outShape, resultDtype);\n\n // Compute total number of elements in each array\n const aSize = aShape.reduce((acc, d) => acc * d, 1);\n const bSize = bShape.reduce((acc, d) => acc * d, 1);\n\n // Nested loop approach: for each element in a, scale all of b\n for (let aIdx = 0; aIdx < aSize; aIdx++) {\n // Convert flat index to multi-dimensional index for a\n let temp = aIdx;\n const aIndices: number[] = new Array(aNdim);\n for (let i = aNdim - 1; i >= 0; i--) {\n aIndices[i] = temp % aShape[i]!;\n temp = Math.floor(temp / aShape[i]!);\n }\n\n // Pad aIndices to match ndim\n const aIndicesPadded: number[] = new Array(ndim).fill(0);\n for (let i = 0; i < aNdim; i++) {\n aIndicesPadded[ndim - aNdim + i] = aIndices[i]!;\n }\n\n const aVal = a.get(...aIndices);\n\n // For each element in b\n for (let bIdx = 0; bIdx < bSize; bIdx++) {\n // Convert flat index to multi-dimensional index for b\n let temp2 = bIdx;\n const bIndices: number[] = new Array(bNdim);\n for (let i = bNdim - 1; i >= 0; i--) {\n bIndices[i] = temp2 % bShape[i]!;\n temp2 = Math.floor(temp2 / bShape[i]!);\n }\n\n // Pad bIndices to match ndim\n const bIndicesPadded: number[] = new Array(ndim).fill(0);\n for (let i = 0; i < bNdim; i++) {\n bIndicesPadded[ndim - bNdim + i] = bIndices[i]!;\n }\n\n const bVal = b.get(...bIndices);\n\n // Compute output index: each dimension is aIdx*bDim + bIdx\n const outIndices: number[] = new Array(ndim);\n for (let i = 0; i < ndim; i++) {\n outIndices[i] = aIndicesPadded[i]! * bPadded[i]! + bIndicesPadded[i]!;\n }\n\n // Compute product and store\n const product =\n typeof aVal === 'bigint' || typeof bVal === 'bigint'\n ? BigInt(Number(aVal)) * BigInt(Number(bVal))\n : Number(aVal) * Number(bVal);\n\n result.set(outIndices, product);\n }\n }\n\n return result;\n}\n", "/**\n * Exponential, logarithmic, and power operations\n *\n * Pure functions for element-wise exponential operations:\n * exp, log, sqrt, power, etc.\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { elementwiseUnaryOp, elementwiseBinaryOp } from '../internal/compute';\nimport { isBigIntDType } from '../core/dtype';\n\n/**\n * Square root of each element\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with sqrt applied\n */\nexport function sqrt(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.sqrt, false); // false = promote integers to float64\n}\n\n/**\n * Raise elements to power\n * NumPy behavior: Promotes to float64 for integer types with non-integer exponents\n *\n * @param a - Base array storage\n * @param b - Exponent (array storage or scalar)\n * @returns Result storage with power applied\n */\nexport function power(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n if (typeof b === 'number') {\n return powerScalar(a, b);\n }\n return elementwiseBinaryOp(a, b, Math.pow, 'power');\n}\n\n/**\n * Power with scalar exponent (optimized path)\n * @private\n */\nfunction powerScalar(storage: ArrayStorage, exponent: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // NumPy behavior: integer ** integer stays integer if exponent >= 0\n // integer ** negative or float exponent promotes to float64\n const isIntegerType = dtype !== 'float32' && dtype !== 'float64';\n const needsFloatPromotion = isIntegerType && (exponent < 0 || !Number.isInteger(exponent));\n const resultDtype = needsFloatPromotion ? 'float64' : dtype;\n\n // Create result with appropriate dtype\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n // BigInt arithmetic\n if (isBigIntDType(resultDtype) && Number.isInteger(exponent) && exponent >= 0) {\n // BigInt ** positive integer stays BigInt\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! ** BigInt(exponent);\n }\n } else {\n // BigInt ** negative or float promotes to float64\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.pow(Number(data[i]!), exponent);\n }\n }\n } else {\n // Regular numeric types\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.pow(Number(data[i]!), exponent);\n }\n }\n\n return result;\n}\n", "/**\n * Trigonometric operations\n *\n * Pure functions for element-wise trigonometric operations:\n * sin, cos, tan, arcsin, arccos, arctan, arctan2, hypot, degrees, radians\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { elementwiseUnaryOp } from '../internal/compute';\nimport { isBigIntDType } from '../core/dtype';\n\n/**\n * Sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Result storage with sin applied\n */\nexport function sin(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.sin, false);\n}\n\n/**\n * Cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Result storage with cos applied\n */\nexport function cos(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.cos, false);\n}\n\n/**\n * Tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Result storage with tan applied\n */\nexport function tan(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.tan, false);\n}\n\n/**\n * Inverse sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values in range [-1, 1])\n * @returns Result storage with arcsin applied (radians)\n */\nexport function arcsin(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.asin, false);\n}\n\n/**\n * Inverse cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values in range [-1, 1])\n * @returns Result storage with arccos applied (radians)\n */\nexport function arccos(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.acos, false);\n}\n\n/**\n * Inverse tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with arctan applied (radians)\n */\nexport function arctan(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.atan, false);\n}\n\n/**\n * Element-wise arc tangent of x1/x2 choosing the quadrant correctly.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param x1 - y-coordinates\n * @param x2 - x-coordinates (array storage or scalar)\n * @returns Angle in radians between -\u03C0 and \u03C0\n */\nexport function arctan2(x1: ArrayStorage, x2: ArrayStorage | number): ArrayStorage {\n if (typeof x2 === 'number') {\n return arctan2Scalar(x1, x2);\n }\n return arctan2Array(x1, x2);\n}\n\n/**\n * arctan2 with array x2 (always returns float64 for non-float32 inputs)\n * @private\n */\nfunction arctan2Array(x1: ArrayStorage, x2: ArrayStorage): ArrayStorage {\n const shape = Array.from(x1.shape);\n const size = x1.size;\n const dtype1 = x1.dtype;\n const dtype2 = x2.dtype;\n\n // Always promote to float64 for arctan2 (matching NumPy behavior)\n // Only preserve float32 if both inputs are float32\n const resultDtype = dtype1 === 'float32' && dtype2 === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n for (let i = 0; i < size; i++) {\n const val1 = isBigIntDType(dtype1) ? Number(x1.data[i]!) : Number(x1.data[i]!);\n const val2 = isBigIntDType(dtype2) ? Number(x2.data[i]!) : Number(x2.data[i]!);\n resultData[i] = Math.atan2(val1, val2);\n }\n\n return result;\n}\n\n/**\n * arctan2 with scalar x2 (optimized path)\n * @private\n */\nfunction arctan2Scalar(storage: ArrayStorage, x2: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Always promote to float64 for trig operations\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.atan2(Number(data[i]!), x2);\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.atan2(Number(data[i]!), x2);\n }\n }\n\n return result;\n}\n\n/**\n * Given the \"legs\" of a right triangle, return its hypotenuse.\n * Equivalent to sqrt(x1**2 + x2**2), element-wise.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param x1 - First leg\n * @param x2 - Second leg (array storage or scalar)\n * @returns Hypotenuse\n */\nexport function hypot(x1: ArrayStorage, x2: ArrayStorage | number): ArrayStorage {\n if (typeof x2 === 'number') {\n return hypotScalar(x1, x2);\n }\n return hypotArray(x1, x2);\n}\n\n/**\n * hypot with array x2 (always returns float64 for non-float32 inputs)\n * @private\n */\nfunction hypotArray(x1: ArrayStorage, x2: ArrayStorage): ArrayStorage {\n const shape = Array.from(x1.shape);\n const size = x1.size;\n const dtype1 = x1.dtype;\n const dtype2 = x2.dtype;\n\n // Always promote to float64 for hypot (matching NumPy behavior)\n // Only preserve float32 if both inputs are float32\n const resultDtype = dtype1 === 'float32' && dtype2 === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n for (let i = 0; i < size; i++) {\n const val1 = isBigIntDType(dtype1) ? Number(x1.data[i]!) : Number(x1.data[i]!);\n const val2 = isBigIntDType(dtype2) ? Number(x2.data[i]!) : Number(x2.data[i]!);\n resultData[i] = Math.hypot(val1, val2);\n }\n\n return result;\n}\n\n/**\n * hypot with scalar x2 (optimized path)\n * @private\n */\nfunction hypotScalar(storage: ArrayStorage, x2: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n // Always promote to float64 for trig operations\n const resultDtype = dtype === 'float32' ? 'float32' : 'float64';\n\n const result = ArrayStorage.zeros(shape, resultDtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.hypot(Number(data[i]!), x2);\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = Math.hypot(Number(data[i]!), x2);\n }\n }\n\n return result;\n}\n\n/**\n * Convert angles from radians to degrees.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Angles in degrees\n */\nexport function degrees(a: ArrayStorage): ArrayStorage {\n const factor = 180 / Math.PI;\n return elementwiseUnaryOp(a, (x) => x * factor, false);\n}\n\n/**\n * Convert angles from degrees to radians.\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in degrees)\n * @returns Angles in radians\n */\nexport function radians(a: ArrayStorage): ArrayStorage {\n const factor = Math.PI / 180;\n return elementwiseUnaryOp(a, (x) => x * factor, false);\n}\n\n/**\n * Convert angles from degrees to radians (alias for radians).\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in degrees)\n * @returns Angles in radians\n */\nexport function deg2rad(a: ArrayStorage): ArrayStorage {\n return radians(a);\n}\n\n/**\n * Convert angles from radians to degrees (alias for degrees).\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (angles in radians)\n * @returns Angles in degrees\n */\nexport function rad2deg(a: ArrayStorage): ArrayStorage {\n return degrees(a);\n}\n", "/**\n * Hyperbolic operations\n *\n * Pure functions for element-wise hyperbolic operations:\n * sinh, cosh, tanh, arcsinh, arccosh, arctanh\n *\n * These functions are used by NDArray methods but are separated\n * to keep the codebase modular and testable.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { elementwiseUnaryOp } from '../internal/compute';\n\n/**\n * Hyperbolic sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with sinh applied\n */\nexport function sinh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.sinh, false);\n}\n\n/**\n * Hyperbolic cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with cosh applied\n */\nexport function cosh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.cosh, false);\n}\n\n/**\n * Hyperbolic tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with tanh applied\n */\nexport function tanh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.tanh, false);\n}\n\n/**\n * Inverse hyperbolic sine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage\n * @returns Result storage with arcsinh applied\n */\nexport function arcsinh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.asinh, false);\n}\n\n/**\n * Inverse hyperbolic cosine of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values >= 1)\n * @returns Result storage with arccosh applied\n */\nexport function arccosh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.acosh, false);\n}\n\n/**\n * Inverse hyperbolic tangent of each element (element-wise)\n * NumPy behavior: Always promotes to float64 for integer types\n *\n * @param a - Input array storage (values in range (-1, 1))\n * @returns Result storage with arctanh applied\n */\nexport function arctanh(a: ArrayStorage): ArrayStorage {\n return elementwiseUnaryOp(a, Math.atanh, false);\n}\n", "/**\n * Advanced array operations\n *\n * Broadcasting, indexing, and comparison functions.\n * @module ops/advanced\n */\n\nimport { ArrayStorage, computeStrides } from '../core/storage';\nimport { getTypedArrayConstructor, isBigIntDType, type TypedArray } from '../core/dtype';\nimport { computeBroadcastShape, broadcastTo, broadcastShapes } from '../core/broadcasting';\n\n/**\n * Broadcast an array to a given shape\n * Returns a read-only view on the original array\n */\nexport function broadcast_to(storage: ArrayStorage, targetShape: number[]): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const targetNdim = targetShape.length;\n\n if (targetNdim < ndim) {\n throw new Error(`input operand has more dimensions than allowed by the axis remapping`);\n }\n\n // Validate that broadcasting is possible\n const broadcastedShape = computeBroadcastShape([Array.from(shape), targetShape]);\n if (broadcastedShape === null) {\n throw new Error(\n `operands could not be broadcast together with shape (${shape.join(',')}) (${targetShape.join(',')})`\n );\n }\n\n // Check result matches target\n for (let i = 0; i < targetNdim; i++) {\n if (broadcastedShape[i] !== targetShape[i]) {\n throw new Error(\n `operands could not be broadcast together with shape (${shape.join(',')}) (${targetShape.join(',')})`\n );\n }\n }\n\n return broadcastTo(storage, targetShape);\n}\n\n/**\n * Broadcast multiple arrays to a common shape\n * Returns views on the original arrays\n */\nexport function broadcast_arrays(storages: ArrayStorage[]): ArrayStorage[] {\n if (storages.length === 0) {\n return [];\n }\n\n if (storages.length === 1) {\n return [storages[0]!];\n }\n\n // Compute broadcast shape\n const shapes = storages.map((s) => Array.from(s.shape));\n const targetShape = computeBroadcastShape(shapes);\n\n if (targetShape === null) {\n throw new Error(\n `operands could not be broadcast together with shapes ${shapes.map((s) => `(${s.join(',')})`).join(' ')}`\n );\n }\n\n // Broadcast each array to the target shape\n return storages.map((s) => broadcastTo(s, targetShape));\n}\n\n/**\n * Compute the broadcast shape for multiple shapes\n * Re-export from core/broadcasting for convenience\n */\nexport { broadcastShapes as broadcast_shapes };\n\n/**\n * Take elements from an array along an axis\n */\nexport function take(storage: ArrayStorage, indices: number[], axis?: number): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n if (axis === undefined) {\n // Flatten and take\n const flatSize = storage.size;\n\n // Validate indices\n for (const idx of indices) {\n const normalizedIdx = idx < 0 ? flatSize + idx : idx;\n if (normalizedIdx < 0 || normalizedIdx >= flatSize) {\n throw new Error(`index ${idx} is out of bounds for axis 0 with size ${flatSize}`);\n }\n }\n\n // Create output array\n const outputSize = indices.length;\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot take from array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n for (let i = 0; i < outputSize; i++) {\n let idx = indices[i]!;\n if (idx < 0) idx = flatSize + idx;\n const value = storage.iget(idx);\n\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, [outputSize], dtype);\n }\n\n // Take along specified axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n\n // Validate indices\n for (const idx of indices) {\n const normalizedIdx = idx < 0 ? axisSize + idx : idx;\n if (normalizedIdx < 0 || normalizedIdx >= axisSize) {\n throw new Error(\n `index ${idx} is out of bounds for axis ${normalizedAxis} with size ${axisSize}`\n );\n }\n }\n\n // Calculate output shape\n const outputShape = Array.from(shape);\n outputShape[normalizedAxis] = indices.length;\n\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot take from array with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const outputStrides = computeStrides(outputShape);\n\n // Iterate through output positions\n const outputIndices = new Array(ndim).fill(0);\n for (let i = 0; i < outputSize; i++) {\n // Compute source index\n const sourceIndices = [...outputIndices];\n let targetIdx = outputIndices[normalizedAxis]!;\n let sourceAxisIdx = indices[targetIdx]!;\n if (sourceAxisIdx < 0) sourceAxisIdx = axisSize + sourceAxisIdx;\n sourceIndices[normalizedAxis] = sourceAxisIdx;\n\n const value = storage.get(...sourceIndices);\n\n // Write to output\n let outIdx = 0;\n for (let d = 0; d < ndim; d++) {\n outIdx += outputIndices[d]! * outputStrides[d]!;\n }\n\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[outIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx] = value as number;\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < outputShape[d]!) {\n break;\n }\n outputIndices[d] = 0;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Put values at specified indices (modifies array in-place)\n */\nexport function put(\n storage: ArrayStorage,\n indices: number[],\n values: ArrayStorage | number | bigint\n): void {\n const flatSize = storage.size;\n const dtype = storage.dtype;\n\n // Get values to put\n let valueArray: (number | bigint)[];\n if (typeof values === 'number' || typeof values === 'bigint') {\n valueArray = new Array(indices.length).fill(values);\n } else {\n // Extract values from storage\n valueArray = [];\n for (let i = 0; i < values.size; i++) {\n valueArray.push(values.iget(i));\n }\n // Broadcast values if needed\n if (valueArray.length === 1) {\n valueArray = new Array(indices.length).fill(valueArray[0]);\n } else if (valueArray.length !== indices.length) {\n // Tile values to match indices length\n const original = [...valueArray];\n valueArray = [];\n for (let i = 0; i < indices.length; i++) {\n valueArray.push(original[i % original.length]!);\n }\n }\n }\n\n // Put values at indices\n for (let i = 0; i < indices.length; i++) {\n let idx = indices[i]!;\n if (idx < 0) idx = flatSize + idx;\n\n if (idx < 0 || idx >= flatSize) {\n throw new Error(`index ${indices[i]} is out of bounds for axis 0 with size ${flatSize}`);\n }\n\n let value = valueArray[i]!;\n\n // Convert value to appropriate type\n if (isBigIntDType(dtype)) {\n if (typeof value !== 'bigint') {\n value = BigInt(Math.round(Number(value)));\n }\n } else {\n if (typeof value === 'bigint') {\n value = Number(value);\n }\n }\n\n storage.iset(idx, value);\n }\n}\n\n/**\n * Construct array from index array and choices\n */\nexport function choose(indexStorage: ArrayStorage, choices: ArrayStorage[]): ArrayStorage {\n if (choices.length === 0) {\n throw new Error('choices cannot be empty');\n }\n\n const indexShape = indexStorage.shape;\n const numChoices = choices.length;\n const dtype = choices[0]!.dtype;\n\n // Validate that all choices have compatible shapes\n const shapes = choices.map((c) => Array.from(c.shape));\n shapes.unshift(Array.from(indexShape));\n const broadcastedShape = computeBroadcastShape(shapes);\n\n if (broadcastedShape === null) {\n throw new Error('operands could not be broadcast together');\n }\n\n // Broadcast index array and choices to common shape\n const broadcastedIndex = broadcastTo(indexStorage, broadcastedShape);\n const broadcastedChoices = choices.map((c) => broadcastTo(c, broadcastedShape));\n\n // Create output array\n const outputSize = broadcastedShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot choose with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n // Fill output\n for (let i = 0; i < outputSize; i++) {\n const choiceIdx = Number(broadcastedIndex.iget(i));\n\n if (choiceIdx < 0 || choiceIdx >= numChoices) {\n throw new Error(`index ${choiceIdx} is out of bounds for axis 0 with size ${numChoices}`);\n }\n\n const value = broadcastedChoices[choiceIdx]!.iget(i);\n\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, broadcastedShape, dtype);\n}\n\n/**\n * Check if two arrays are element-wise equal\n */\nexport function array_equal(a: ArrayStorage, b: ArrayStorage, equal_nan: boolean = false): boolean {\n // Check shapes match\n if (a.ndim !== b.ndim) {\n return false;\n }\n\n for (let i = 0; i < a.ndim; i++) {\n if (a.shape[i] !== b.shape[i]) {\n return false;\n }\n }\n\n // Check all elements\n const size = a.size;\n for (let i = 0; i < size; i++) {\n const aVal = a.iget(i);\n const bVal = b.iget(i);\n\n // Handle NaN comparison\n if (equal_nan) {\n const aIsNaN = typeof aVal === 'number' && Number.isNaN(aVal);\n const bIsNaN = typeof bVal === 'number' && Number.isNaN(bVal);\n if (aIsNaN && bIsNaN) {\n continue;\n }\n }\n\n if (aVal !== bVal) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Take values along an axis using 1D index array\n */\nexport function take_along_axis(\n storage: ArrayStorage,\n indices: ArrayStorage,\n axis: number\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // indices must have same ndim as storage\n const indicesShape = indices.shape;\n if (indicesShape.length !== ndim) {\n throw new Error(\n `indices and arr must have the same number of dimensions, got ${indicesShape.length} vs ${ndim}`\n );\n }\n\n // Check that non-axis dimensions match (or are broadcastable with 1)\n for (let i = 0; i < ndim; i++) {\n if (i !== normalizedAxis) {\n if (indicesShape[i] !== shape[i] && indicesShape[i] !== 1 && shape[i] !== 1) {\n throw new Error(\n `index ${indicesShape[i]} is out of bounds for size ${shape[i]} in dimension ${i}`\n );\n }\n }\n }\n\n // Output shape matches indices shape\n const outputShape = Array.from(indicesShape);\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot take_along_axis with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n const inputStrides = computeStrides(shape);\n const indicesStrides = computeStrides(indicesShape);\n\n const axisSize = shape[normalizedAxis]!;\n\n // Iterate through output positions\n for (let outIdx = 0; outIdx < outputSize; outIdx++) {\n // Convert outIdx to multi-index in output shape\n const multiIdx = new Array(ndim);\n let remaining = outIdx;\n for (let d = ndim - 1; d >= 0; d--) {\n multiIdx[d] = remaining % outputShape[d]!;\n remaining = Math.floor(remaining / outputShape[d]!);\n }\n\n // Get the index value from indices array\n let indicesLinearIdx = 0;\n for (let d = 0; d < ndim; d++) {\n const idx = indicesShape[d] === 1 ? 0 : multiIdx[d]!;\n indicesLinearIdx += idx * indicesStrides[d]!;\n }\n let indexValue = Number(indices.iget(indicesLinearIdx));\n if (indexValue < 0) indexValue = axisSize + indexValue;\n if (indexValue < 0 || indexValue >= axisSize) {\n throw new Error(\n `index ${indexValue} is out of bounds for axis ${normalizedAxis} with size ${axisSize}`\n );\n }\n\n // Compute source index\n const sourceMultiIdx = [...multiIdx];\n sourceMultiIdx[normalizedAxis] = indexValue;\n let srcLinearIdx = 0;\n for (let d = 0; d < ndim; d++) {\n const idx = shape[d] === 1 ? 0 : sourceMultiIdx[d]!;\n srcLinearIdx += idx * inputStrides[d]!;\n }\n\n const value = storage.iget(srcLinearIdx);\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[outIdx] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx] = value as number;\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Put values into array along an axis using 1D index array\n */\nexport function put_along_axis(\n storage: ArrayStorage,\n indices: ArrayStorage,\n values: ArrayStorage,\n axis: number\n): void {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n // Normalize axis\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const indicesShape = indices.shape;\n const valuesShape = values.shape;\n\n if (indicesShape.length !== ndim || valuesShape.length !== ndim) {\n throw new Error('indices, arr, and values must have same ndim');\n }\n\n const axisSize = shape[normalizedAxis]!;\n const inputStrides = computeStrides(shape);\n const indicesStrides = computeStrides(indicesShape);\n const valuesStrides = computeStrides(valuesShape);\n\n // Iterate through indices positions\n const indicesSize = indicesShape.reduce((a, b) => a * b, 1);\n for (let idx = 0; idx < indicesSize; idx++) {\n // Convert idx to multi-index\n const multiIdx = new Array(ndim);\n let remaining = idx;\n for (let d = ndim - 1; d >= 0; d--) {\n multiIdx[d] = remaining % indicesShape[d]!;\n remaining = Math.floor(remaining / indicesShape[d]!);\n }\n\n // Get the index value\n let indicesLinearIdx = 0;\n for (let d = 0; d < ndim; d++) {\n indicesLinearIdx += multiIdx[d]! * indicesStrides[d]!;\n }\n let indexValue = Number(indices.iget(indicesLinearIdx));\n if (indexValue < 0) indexValue = axisSize + indexValue;\n if (indexValue < 0 || indexValue >= axisSize) {\n throw new Error(\n `index ${indexValue} is out of bounds for axis ${normalizedAxis} with size ${axisSize}`\n );\n }\n\n // Get value from values array (broadcast if needed)\n let valuesLinearIdx = 0;\n for (let d = 0; d < ndim; d++) {\n const vidx = valuesShape[d] === 1 ? 0 : multiIdx[d]!;\n valuesLinearIdx += vidx * valuesStrides[d]!;\n }\n let value = values.iget(valuesLinearIdx);\n\n // Compute destination index\n const destMultiIdx = [...multiIdx];\n destMultiIdx[normalizedAxis] = indexValue;\n let destLinearIdx = 0;\n for (let d = 0; d < ndim; d++) {\n destLinearIdx += destMultiIdx[d]! * inputStrides[d]!;\n }\n\n // Convert type if needed\n if (isBigIntDType(dtype)) {\n if (typeof value !== 'bigint') {\n value = BigInt(Math.round(Number(value)));\n }\n } else {\n if (typeof value === 'bigint') {\n value = Number(value);\n }\n }\n\n storage.iset(destLinearIdx, value);\n }\n}\n\n/**\n * Change elements of array based on conditional mask\n */\nexport function putmask(\n storage: ArrayStorage,\n mask: ArrayStorage,\n values: ArrayStorage | number | bigint\n): void {\n const size = storage.size;\n const dtype = storage.dtype;\n\n // Get values array\n let valueArray: (number | bigint)[];\n if (typeof values === 'number' || typeof values === 'bigint') {\n valueArray = [values];\n } else {\n valueArray = [];\n for (let i = 0; i < values.size; i++) {\n valueArray.push(values.iget(i));\n }\n }\n\n // Put values where mask is true\n let valueIdx = 0;\n for (let i = 0; i < size; i++) {\n const maskVal = mask.iget(i);\n if (maskVal) {\n let value = valueArray[valueIdx % valueArray.length]!;\n\n // Convert type if needed\n if (isBigIntDType(dtype)) {\n if (typeof value !== 'bigint') {\n value = BigInt(Math.round(Number(value)));\n }\n } else {\n if (typeof value === 'bigint') {\n value = Number(value);\n }\n }\n\n storage.iset(i, value);\n valueIdx++;\n }\n }\n}\n\n/**\n * Return selected slices along given axis based on condition\n */\nexport function compress(\n condition: ArrayStorage,\n storage: ArrayStorage,\n axis?: number\n): ArrayStorage {\n const shape = storage.shape;\n const ndim = shape.length;\n const dtype = storage.dtype;\n\n // Get direct access to underlying data for fast reading\n const inputData = storage.data;\n const isBigInt = isBigIntDType(dtype);\n\n if (axis === undefined) {\n // Flatten and select - optimized path\n // First pass: count true values\n let trueCount = 0;\n const maxLen = Math.min(condition.size, storage.size);\n for (let i = 0; i < maxLen; i++) {\n if (condition.iget(i)) trueCount++;\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot compress with dtype ${dtype}`);\n }\n const outputData = new Constructor(trueCount);\n\n // Second pass: copy values\n let outIdx = 0;\n for (let i = 0; i < maxLen; i++) {\n if (condition.iget(i)) {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[outIdx] = (\n inputData as BigInt64Array | BigUint64Array\n )[i]!;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[outIdx] = (\n inputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>\n )[i]!;\n }\n outIdx++;\n }\n }\n\n return ArrayStorage.fromData(outputData, [trueCount], dtype);\n }\n\n // Compress along axis - optimized version\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Build boolean array and axis mapping in one pass\n const axisSize = shape[normalizedAxis]!;\n const maxLen = Math.min(condition.size, axisSize);\n const axisMap: number[] = [];\n\n for (let i = 0; i < maxLen; i++) {\n if (condition.iget(i)) {\n axisMap.push(i);\n }\n }\n\n const trueCount = axisMap.length;\n\n // Output shape\n const outputShape = [...shape];\n outputShape[normalizedAxis] = trueCount;\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot compress with dtype ${dtype}`);\n }\n const outputData = new Constructor(outputSize);\n\n // Compute strides for efficient indexing\n const inputStrides = computeStrides(shape);\n\n // Special case: axis = 0 (most common, optimize heavily)\n if (normalizedAxis === 0) {\n const strideAlongAxis = inputStrides[0]!;\n const elementsPerSlice = shape.slice(1).reduce((a, b) => a * b, 1);\n\n let outIdx = 0;\n for (let i = 0; i < trueCount; i++) {\n const inputAxisIdx = axisMap[i]!;\n const srcOffset = inputAxisIdx * strideAlongAxis;\n\n // Copy entire slice at once\n if (isBigInt) {\n const src = inputData as BigInt64Array | BigUint64Array;\n const dst = outputData as BigInt64Array | BigUint64Array;\n for (let j = 0; j < elementsPerSlice; j++) {\n dst[outIdx++] = src[srcOffset + j]!;\n }\n } else {\n const src = inputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n const dst = outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let j = 0; j < elementsPerSlice; j++) {\n dst[outIdx++] = src[srcOffset + j]!;\n }\n }\n }\n } else {\n // General case for other axes\n // Pre-compute outer and inner iteration counts\n const outerSize = shape.slice(0, normalizedAxis).reduce((a, b) => a * b, 1);\n const innerSize = shape.slice(normalizedAxis + 1).reduce((a, b) => a * b, 1);\n\n let outIdx = 0;\n for (let outer = 0; outer < outerSize; outer++) {\n for (let axisIdx = 0; axisIdx < trueCount; axisIdx++) {\n const inputAxisIdx = axisMap[axisIdx]!;\n\n // Compute base offset for this outer/axis combination\n let baseOffset = 0;\n let rem = outer;\n for (let d = normalizedAxis - 1; d >= 0; d--) {\n const idx = rem % shape[d]!;\n rem = Math.floor(rem / shape[d]!);\n baseOffset += idx * inputStrides[d]!;\n }\n baseOffset += inputAxisIdx * inputStrides[normalizedAxis]!;\n\n // Copy inner elements\n if (isBigInt) {\n const src = inputData as BigInt64Array | BigUint64Array;\n const dst = outputData as BigInt64Array | BigUint64Array;\n for (let inner = 0; inner < innerSize; inner++) {\n dst[outIdx++] = src[baseOffset + inner]!;\n }\n } else {\n const src = inputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n const dst = outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let inner = 0; inner < innerSize; inner++) {\n dst[outIdx++] = src[baseOffset + inner]!;\n }\n }\n }\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Return array drawn from elements in choicelist, depending on conditions\n */\nexport function select(\n condlist: ArrayStorage[],\n choicelist: ArrayStorage[],\n defaultValue: number | bigint = 0\n): ArrayStorage {\n if (condlist.length !== choicelist.length) {\n throw new Error('condlist and choicelist must have same length');\n }\n\n if (condlist.length === 0) {\n throw new Error('condlist and choicelist cannot be empty');\n }\n\n // Compute broadcast shape from all conditions and choices\n const allShapes = [\n ...condlist.map((c) => Array.from(c.shape)),\n ...choicelist.map((c) => Array.from(c.shape)),\n ];\n const outputShape = computeBroadcastShape(allShapes);\n if (outputShape === null) {\n throw new Error('condlist and choicelist arrays could not be broadcast together');\n }\n\n const dtype = choicelist[0]!.dtype;\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot select with dtype ${dtype}`);\n }\n\n // Initialize with default value\n let defaultVal: number | bigint = defaultValue;\n if (isBigIntDType(dtype)) {\n defaultVal = typeof defaultValue === 'bigint' ? defaultValue : BigInt(defaultValue);\n } else {\n defaultVal = typeof defaultValue === 'bigint' ? Number(defaultValue) : defaultValue;\n }\n\n const outputData = new Constructor(outputSize);\n for (let i = 0; i < outputSize; i++) {\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[i] = defaultVal as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = defaultVal as number;\n }\n }\n\n // Broadcast all arrays\n const broadcastedConds = condlist.map((c) => broadcastTo(c, outputShape));\n const broadcastedChoices = choicelist.map((c) => broadcastTo(c, outputShape));\n\n // Process conditions in order (first match wins)\n for (let i = 0; i < outputSize; i++) {\n for (let j = 0; j < condlist.length; j++) {\n if (broadcastedConds[j]!.iget(i)) {\n const value = broadcastedChoices[j]!.iget(i);\n if (isBigIntDType(dtype)) {\n (outputData as BigInt64Array | BigUint64Array)[i] = value as bigint;\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value as number;\n }\n break;\n }\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Change elements of array based on conditional and input values\n */\nexport function place(storage: ArrayStorage, mask: ArrayStorage, vals: ArrayStorage): void {\n const size = storage.size;\n const dtype = storage.dtype;\n\n // Get values array\n const valueArray: (number | bigint)[] = [];\n for (let i = 0; i < vals.size; i++) {\n valueArray.push(vals.iget(i));\n }\n\n if (valueArray.length === 0) {\n return;\n }\n\n // Place values where mask is true\n let valueIdx = 0;\n for (let i = 0; i < size; i++) {\n const maskVal = mask.iget(i);\n if (maskVal) {\n let value = valueArray[valueIdx % valueArray.length]!;\n\n // Convert type if needed\n if (isBigIntDType(dtype)) {\n if (typeof value !== 'bigint') {\n value = BigInt(Math.round(Number(value)));\n }\n } else {\n if (typeof value === 'bigint') {\n value = Number(value);\n }\n }\n\n storage.iset(i, value);\n valueIdx++;\n }\n }\n}\n\n/**\n * Return indices to access main diagonal of array\n */\nexport function diag_indices(n: number, ndim: number = 2): ArrayStorage[] {\n if (ndim < 1) {\n throw new Error('ndim must be at least 1');\n }\n\n const indices = new Int32Array(n);\n for (let i = 0; i < n; i++) {\n indices[i] = i;\n }\n\n const result: ArrayStorage[] = [];\n for (let d = 0; d < ndim; d++) {\n result.push(ArrayStorage.fromData(new Int32Array(indices), [n], 'int32'));\n }\n\n return result;\n}\n\n/**\n * Return indices to access main diagonal of array from given array\n */\nexport function diag_indices_from(storage: ArrayStorage): ArrayStorage[] {\n const shape = storage.shape;\n const ndim = shape.length;\n\n if (ndim < 2) {\n throw new Error('array must be at least 2-D');\n }\n\n // Check that all dimensions are equal\n const n = shape[0]!;\n for (let i = 1; i < ndim; i++) {\n if (shape[i] !== n) {\n throw new Error('All dimensions of input must be equal');\n }\n }\n\n return diag_indices(n, ndim);\n}\n\n/**\n * Return indices for lower-triangle of an (n, m) array\n */\nexport function tril_indices(n: number, k: number = 0, m?: number): ArrayStorage[] {\n const cols = m ?? n;\n\n const rows: number[] = [];\n const colIndices: number[] = [];\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j <= Math.min(i + k, cols - 1); j++) {\n if (j >= 0) {\n rows.push(i);\n colIndices.push(j);\n }\n }\n }\n\n return [\n ArrayStorage.fromData(new Int32Array(rows), [rows.length], 'int32'),\n ArrayStorage.fromData(new Int32Array(colIndices), [colIndices.length], 'int32'),\n ];\n}\n\n/**\n * Return indices for lower-triangle of given array\n */\nexport function tril_indices_from(storage: ArrayStorage, k: number = 0): ArrayStorage[] {\n const shape = storage.shape;\n\n if (shape.length !== 2) {\n throw new Error('array must be 2-D');\n }\n\n return tril_indices(shape[0]!, k, shape[1]);\n}\n\n/**\n * Return indices for upper-triangle of an (n, m) array\n */\nexport function triu_indices(n: number, k: number = 0, m?: number): ArrayStorage[] {\n const cols = m ?? n;\n\n const rows: number[] = [];\n const colIndices: number[] = [];\n\n for (let i = 0; i < n; i++) {\n for (let j = Math.max(i + k, 0); j < cols; j++) {\n rows.push(i);\n colIndices.push(j);\n }\n }\n\n return [\n ArrayStorage.fromData(new Int32Array(rows), [rows.length], 'int32'),\n ArrayStorage.fromData(new Int32Array(colIndices), [colIndices.length], 'int32'),\n ];\n}\n\n/**\n * Return indices for upper-triangle of given array\n */\nexport function triu_indices_from(storage: ArrayStorage, k: number = 0): ArrayStorage[] {\n const shape = storage.shape;\n\n if (shape.length !== 2) {\n throw new Error('array must be 2-D');\n }\n\n return triu_indices(shape[0]!, k, shape[1]);\n}\n\n/**\n * Return indices to access elements using mask function\n */\nexport function mask_indices(\n n: number,\n mask_func: (n: number, k: number) => ArrayStorage,\n k: number = 0\n): ArrayStorage[] {\n // Generate the mask using the mask function\n const mask = mask_func(n, k);\n const maskShape = mask.shape;\n\n if (maskShape.length !== 2 || maskShape[0] !== n || maskShape[1] !== n) {\n throw new Error('mask_func must return n x n array');\n }\n\n const rows: number[] = [];\n const cols: number[] = [];\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (mask.get(i, j)) {\n rows.push(i);\n cols.push(j);\n }\n }\n }\n\n return [\n ArrayStorage.fromData(new Int32Array(rows), [rows.length], 'int32'),\n ArrayStorage.fromData(new Int32Array(cols), [cols.length], 'int32'),\n ];\n}\n\n/**\n * Return array representing indices of a grid\n */\nexport function indices(\n dimensions: number[],\n dtype: 'int32' | 'int64' | 'float64' = 'int32'\n): ArrayStorage {\n const ndim = dimensions.length;\n const outputShape = [ndim, ...dimensions];\n const outputSize = outputShape.reduce((a, b) => a * b, 1);\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create indices with dtype ${dtype}`);\n }\n\n const outputData = new Constructor(outputSize);\n const gridSize = dimensions.reduce((a, b) => a * b, 1);\n\n // For each dimension, fill the corresponding slice\n for (let d = 0; d < ndim; d++) {\n const sliceOffset = d * gridSize;\n\n // Iterate through grid positions\n for (let gridIdx = 0; gridIdx < gridSize; gridIdx++) {\n // Convert gridIdx to multi-index\n const multiIdx = new Array(ndim);\n let remaining = gridIdx;\n for (let i = ndim - 1; i >= 0; i--) {\n multiIdx[i] = remaining % dimensions[i]!;\n remaining = Math.floor(remaining / dimensions[i]!);\n }\n\n const value = multiIdx[d]!;\n if (dtype === 'int64') {\n (outputData as BigInt64Array)[sliceOffset + gridIdx] = BigInt(value);\n } else {\n (outputData as Float64Array | Int32Array)[sliceOffset + gridIdx] = value;\n }\n }\n }\n\n return ArrayStorage.fromData(outputData, outputShape, dtype);\n}\n\n/**\n * Construct open mesh from multiple sequences\n */\nexport function ix_(...args: ArrayStorage[]): ArrayStorage[] {\n const ndim = args.length;\n const result: ArrayStorage[] = [];\n\n for (let i = 0; i < ndim; i++) {\n const arr = args[i]!;\n const arrSize = arr.size;\n const dtype = arr.dtype;\n\n // Create shape with 1s except at position i\n const shape = new Array(ndim).fill(1);\n shape[i] = arrSize;\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create ix_ with dtype ${dtype}`);\n }\n\n const data = new Constructor(arrSize);\n for (let j = 0; j < arrSize; j++) {\n const value = arr.iget(j);\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array)[j] = value as bigint;\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[j] = value as number;\n }\n }\n\n result.push(ArrayStorage.fromData(data, shape, dtype));\n }\n\n return result;\n}\n\n/**\n * Convert multi-dimensional index arrays to flat index array\n */\nexport function ravel_multi_index(\n multi_index: ArrayStorage[],\n dims: number[],\n mode: 'raise' | 'wrap' | 'clip' = 'raise'\n): ArrayStorage {\n if (multi_index.length !== dims.length) {\n throw new Error('multi_index length must equal dims length');\n }\n\n if (multi_index.length === 0) {\n throw new Error('multi_index cannot be empty');\n }\n\n const size = multi_index[0]!.size;\n const ndim = dims.length;\n const outputData = new Int32Array(size);\n\n // Compute strides for row-major (C) order\n const strides = new Array(ndim);\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= dims[i]!;\n }\n\n for (let i = 0; i < size; i++) {\n let flatIdx = 0;\n for (let d = 0; d < ndim; d++) {\n let idx = Number(multi_index[d]!.iget(i));\n const dimSize = dims[d]!;\n\n // Handle mode\n if (mode === 'wrap') {\n idx = ((idx % dimSize) + dimSize) % dimSize;\n } else if (mode === 'clip') {\n idx = Math.max(0, Math.min(idx, dimSize - 1));\n } else if (idx < 0 || idx >= dimSize) {\n throw new Error(`index ${idx} is out of bounds for axis ${d} with size ${dimSize}`);\n }\n\n flatIdx += idx * strides[d]!;\n }\n outputData[i] = flatIdx;\n }\n\n return ArrayStorage.fromData(outputData, [size], 'int32');\n}\n\n/**\n * Convert flat index array to tuple of coordinate arrays\n */\nexport function unravel_index(\n indices: ArrayStorage | number,\n shape: number[],\n order: 'C' | 'F' = 'C'\n): ArrayStorage[] {\n const ndim = shape.length;\n\n // Handle scalar input\n let indicesArray: number[];\n let outputShape: number[];\n if (typeof indices === 'number') {\n indicesArray = [indices];\n outputShape = [];\n } else {\n indicesArray = [];\n for (let i = 0; i < indices.size; i++) {\n indicesArray.push(Number(indices.iget(i)));\n }\n outputShape = Array.from(indices.shape);\n }\n\n const size = indicesArray.length;\n const totalSize = shape.reduce((a, b) => a * b, 1);\n\n // Compute strides\n const strides = new Array(ndim);\n if (order === 'C') {\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n } else {\n let stride = 1;\n for (let i = 0; i < ndim; i++) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n }\n\n // Create output arrays\n const result: ArrayStorage[] = [];\n for (let d = 0; d < ndim; d++) {\n const data = new Int32Array(size);\n result.push(ArrayStorage.fromData(data, outputShape.length ? outputShape : [1], 'int32'));\n }\n\n // Convert each flat index\n for (let i = 0; i < size; i++) {\n let flatIdx = indicesArray[i]!;\n if (flatIdx < 0 || flatIdx >= totalSize) {\n throw new Error(`index ${flatIdx} is out of bounds for array with size ${totalSize}`);\n }\n\n if (order === 'C') {\n for (let d = 0; d < ndim; d++) {\n const coord = Math.floor(flatIdx / strides[d]!);\n flatIdx = flatIdx % strides[d]!;\n (result[d]!.data as Int32Array)[i] = coord % shape[d]!;\n }\n } else {\n for (let d = ndim - 1; d >= 0; d--) {\n const coord = Math.floor(flatIdx / strides[d]!);\n flatIdx = flatIdx % strides[d]!;\n (result[d]!.data as Int32Array)[i] = coord % shape[d]!;\n }\n }\n }\n\n // For scalar input, return scalar-shaped results\n if (typeof indices === 'number') {\n return result.map((arr) => {\n const value = arr.iget(0);\n return ArrayStorage.fromData(new Int32Array([Number(value)]), [], 'int32');\n });\n }\n\n return result;\n}\n", "/**\n * Bitwise operations\n *\n * Pure functions for element-wise bitwise operations:\n * bitwise_and, bitwise_or, bitwise_xor, bitwise_not, invert,\n * left_shift, right_shift, packbits, unpackbits\n *\n * These operations only work on integer types.\n */\n\nimport { ArrayStorage } from '../core/storage';\nimport { isBigIntDType, isIntegerDType, promoteDTypes, DType } from '../core/dtype';\nimport { elementwiseBinaryOp } from '../internal/compute';\n\n/**\n * Helper: Validate that dtype is an integer type for bitwise operations\n */\nfunction validateIntegerDType(dtype: DType, opName: string): void {\n if (!isIntegerDType(dtype) && dtype !== 'bool') {\n throw new TypeError(\n `ufunc '${opName}' not supported for the input types, and the inputs could not be safely coerced to any supported types`\n );\n }\n}\n\n/**\n * Helper: Check if two arrays can use the fast path\n * (both C-contiguous with same shape, no broadcasting needed)\n */\nfunction canUseFastPath(a: ArrayStorage, b: ArrayStorage): boolean {\n return (\n a.isCContiguous &&\n b.isCContiguous &&\n a.shape.length === b.shape.length &&\n a.shape.every((dim, i) => dim === b.shape[i])\n );\n}\n\n/**\n * Bitwise AND of two arrays or array and scalar\n *\n * @param a - First array storage (must be integer type)\n * @param b - Second array storage or scalar (must be integer type)\n * @returns Result storage\n */\nexport function bitwise_and(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n validateIntegerDType(a.dtype, 'bitwise_and');\n\n if (typeof b === 'number') {\n return bitwiseAndScalar(a, b);\n }\n\n validateIntegerDType(b.dtype, 'bitwise_and');\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return bitwiseAndArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x & y, 'bitwise_and');\n}\n\n/**\n * Fast path for bitwise AND of two contiguous arrays\n * @private\n */\nfunction bitwiseAndArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) & (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! & bTyped[i]!;\n }\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) & (bData[i] as number);\n }\n }\n\n return result;\n}\n\n/**\n * Bitwise AND with scalar (optimized path)\n * @private\n */\nfunction bitwiseAndScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! & scalarBig;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (data[i] as number) & scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Bitwise OR of two arrays or array and scalar\n *\n * @param a - First array storage (must be integer type)\n * @param b - Second array storage or scalar (must be integer type)\n * @returns Result storage\n */\nexport function bitwise_or(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n validateIntegerDType(a.dtype, 'bitwise_or');\n\n if (typeof b === 'number') {\n return bitwiseOrScalar(a, b);\n }\n\n validateIntegerDType(b.dtype, 'bitwise_or');\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return bitwiseOrArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x | y, 'bitwise_or');\n}\n\n/**\n * Fast path for bitwise OR of two contiguous arrays\n * @private\n */\nfunction bitwiseOrArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) | (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! | bTyped[i]!;\n }\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) | (bData[i] as number);\n }\n }\n\n return result;\n}\n\n/**\n * Bitwise OR with scalar (optimized path)\n * @private\n */\nfunction bitwiseOrScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! | scalarBig;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (data[i] as number) | scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Bitwise XOR of two arrays or array and scalar\n *\n * @param a - First array storage (must be integer type)\n * @param b - Second array storage or scalar (must be integer type)\n * @returns Result storage\n */\nexport function bitwise_xor(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n validateIntegerDType(a.dtype, 'bitwise_xor');\n\n if (typeof b === 'number') {\n return bitwiseXorScalar(a, b);\n }\n\n validateIntegerDType(b.dtype, 'bitwise_xor');\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return bitwiseXorArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x ^ y, 'bitwise_xor');\n}\n\n/**\n * Fast path for bitwise XOR of two contiguous arrays\n * @private\n */\nfunction bitwiseXorArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const needsConversion = !isBigIntDType(a.dtype) || !isBigIntDType(b.dtype);\n\n if (needsConversion) {\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) ^ (bVal as bigint);\n }\n } else {\n const aTyped = aData as BigInt64Array | BigUint64Array;\n const bTyped = bData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = aTyped[i]! ^ bTyped[i]!;\n }\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) ^ (bData[i] as number);\n }\n }\n\n return result;\n}\n\n/**\n * Bitwise XOR with scalar (optimized path)\n * @private\n */\nfunction bitwiseXorScalar(storage: ArrayStorage, scalar: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const scalarBig = BigInt(Math.round(scalar));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! ^ scalarBig;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (data[i] as number) ^ scalar;\n }\n }\n\n return result;\n}\n\n/**\n * Bitwise NOT (invert) of each element\n *\n * @param a - Input array storage (must be integer type)\n * @returns Result storage with bitwise NOT values\n */\nexport function bitwise_not(a: ArrayStorage): ArrayStorage {\n validateIntegerDType(a.dtype, 'bitwise_not');\n\n const dtype = a.dtype;\n const shape = Array.from(a.shape);\n const data = a.data;\n const size = a.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n resultTyped[i] = ~thisTyped[i]!;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = ~(data[i] as number);\n }\n }\n\n return result;\n}\n\n/**\n * Invert (bitwise NOT) - alias for bitwise_not\n *\n * @param a - Input array storage (must be integer type)\n * @returns Result storage with inverted values\n */\nexport function invert(a: ArrayStorage): ArrayStorage {\n return bitwise_not(a);\n}\n\n/**\n * Left shift of array elements\n *\n * @param a - Input array storage (must be integer type)\n * @param b - Shift amount (array storage or scalar)\n * @returns Result storage with left-shifted values\n */\nexport function left_shift(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n validateIntegerDType(a.dtype, 'left_shift');\n\n if (typeof b === 'number') {\n return leftShiftScalar(a, b);\n }\n\n validateIntegerDType(b.dtype, 'left_shift');\n\n // Fast path: single-element array or broadcastable scalar shape treated as scalar\n if (b.size === 1 || (b.ndim === 1 && b.shape[0] === 1)) {\n const shiftVal = isBigIntDType(b.dtype) ? Number(b.data[0] as bigint) : (b.data[0] as number);\n return leftShiftScalar(a, shiftVal);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return leftShiftArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x << y, 'left_shift');\n}\n\n/**\n * Fast path for left shift of two contiguous arrays\n * @private\n */\nfunction leftShiftArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) << (bVal as bigint);\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) << (bData[i] as number);\n }\n }\n\n return result;\n}\n\n/**\n * Left shift with scalar (optimized path)\n * @private\n */\nfunction leftShiftScalar(storage: ArrayStorage, shift: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const shiftBig = BigInt(Math.round(shift));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! << shiftBig;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (data[i] as number) << shift;\n }\n }\n\n return result;\n}\n\n/**\n * Right shift of array elements\n *\n * @param a - Input array storage (must be integer type)\n * @param b - Shift amount (array storage or scalar)\n * @returns Result storage with right-shifted values\n */\nexport function right_shift(a: ArrayStorage, b: ArrayStorage | number): ArrayStorage {\n validateIntegerDType(a.dtype, 'right_shift');\n\n if (typeof b === 'number') {\n return rightShiftScalar(a, b);\n }\n\n validateIntegerDType(b.dtype, 'right_shift');\n\n // Fast path: single-element array or broadcastable scalar shape treated as scalar\n if (b.size === 1 || (b.ndim === 1 && b.shape[0] === 1)) {\n const shiftVal = isBigIntDType(b.dtype) ? Number(b.data[0] as bigint) : (b.data[0] as number);\n return rightShiftScalar(a, shiftVal);\n }\n\n // Fast path: both contiguous, same shape\n if (canUseFastPath(a, b)) {\n return rightShiftArraysFast(a, b);\n }\n\n // Slow path: broadcasting or non-contiguous\n return elementwiseBinaryOp(a, b, (x, y) => x >> y, 'right_shift');\n}\n\n/**\n * Fast path for right shift of two contiguous arrays\n * @private\n */\nfunction rightShiftArraysFast(a: ArrayStorage, b: ArrayStorage): ArrayStorage {\n const dtype = promoteDTypes(a.dtype, b.dtype);\n const result = ArrayStorage.zeros(Array.from(a.shape), dtype);\n const size = a.size;\n const aData = a.data;\n const bData = b.data;\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const aVal = typeof aData[i] === 'bigint' ? aData[i] : BigInt(Math.round(Number(aData[i])));\n const bVal = typeof bData[i] === 'bigint' ? bData[i] : BigInt(Math.round(Number(bData[i])));\n resultTyped[i] = (aVal as bigint) >> (bVal as bigint);\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (aData[i] as number) >> (bData[i] as number);\n }\n }\n\n return result;\n}\n\n/**\n * Right shift with scalar (optimized path)\n * @private\n */\nfunction rightShiftScalar(storage: ArrayStorage, shift: number): ArrayStorage {\n const dtype = storage.dtype;\n const shape = Array.from(storage.shape);\n const data = storage.data;\n const size = storage.size;\n\n const result = ArrayStorage.zeros(shape, dtype);\n const resultData = result.data;\n\n if (isBigIntDType(dtype)) {\n const thisTyped = data as BigInt64Array | BigUint64Array;\n const resultTyped = resultData as BigInt64Array | BigUint64Array;\n const shiftBig = BigInt(Math.round(shift));\n for (let i = 0; i < size; i++) {\n resultTyped[i] = thisTyped[i]! >> shiftBig;\n }\n } else {\n for (let i = 0; i < size; i++) {\n resultData[i] = (data[i] as number) >> shift;\n }\n }\n\n return result;\n}\n\n/**\n * Pack binary values into uint8 array\n *\n * Packs the elements of a binary-valued array into bits in a uint8 array.\n * The result has the same shape as the input, except for the specified axis\n * which is divided by 8 (rounded up).\n *\n * @param a - Input array (values are interpreted as binary: 0 or non-zero)\n * @param axis - The dimension over which bit-packing is done (default: -1, meaning the last axis)\n * @param bitorder - The order of bits within each packed byte. 'big' means the most significant bit is first. (default: 'big')\n * @returns Packed uint8 array\n */\nexport function packbits(\n a: ArrayStorage,\n axis: number = -1,\n bitorder: 'big' | 'little' = 'big'\n): ArrayStorage {\n const shape = Array.from(a.shape);\n const ndim = shape.length;\n\n // Handle negative axis\n if (axis < 0) {\n axis = ndim + axis;\n }\n\n if (axis < 0 || axis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Calculate output shape\n const axisSize = shape[axis]!;\n const packedAxisSize = Math.ceil(axisSize / 8);\n const outShape = [...shape];\n outShape[axis] = packedAxisSize;\n\n const result = ArrayStorage.zeros(outShape, 'uint8');\n const resultData = result.data as Uint8Array;\n\n // For 1D arrays, simple case\n if (ndim === 1) {\n for (let i = 0; i < packedAxisSize; i++) {\n let byte = 0;\n for (let bit = 0; bit < 8; bit++) {\n const srcIdx = i * 8 + bit;\n if (srcIdx < axisSize) {\n const val = Number(a.data[srcIdx]!) !== 0 ? 1 : 0;\n if (bitorder === 'big') {\n byte |= val << (7 - bit);\n } else {\n byte |= val << bit;\n }\n }\n }\n resultData[i] = byte;\n }\n return result;\n }\n\n // For N-D arrays, iterate over all combinations except the packed axis\n const preAxisShape = shape.slice(0, axis);\n const postAxisShape = shape.slice(axis + 1);\n\n const preAxisSize = preAxisShape.reduce((acc, dim) => acc * dim, 1);\n const postAxisSize = postAxisShape.reduce((acc, dim) => acc * dim, 1);\n\n // Calculate strides for input and output\n const inputStrides = computeStrides(shape);\n const outputStrides = computeStrides(outShape);\n\n for (let pre = 0; pre < preAxisSize; pre++) {\n for (let post = 0; post < postAxisSize; post++) {\n for (let packedIdx = 0; packedIdx < packedAxisSize; packedIdx++) {\n let byte = 0;\n for (let bit = 0; bit < 8; bit++) {\n const axisIdx = packedIdx * 8 + bit;\n if (axisIdx < axisSize) {\n // Calculate input linear index\n let inputIdx = 0;\n let preRemaining = pre;\n for (let d = 0; d < axis; d++) {\n const dimSize =\n d < axis - 1 ? preAxisShape.slice(d + 1).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(preRemaining / dimSize);\n preRemaining %= dimSize;\n inputIdx += coord * inputStrides[d]!;\n }\n inputIdx += axisIdx * inputStrides[axis]!;\n let postRemaining = post;\n for (let d = axis + 1; d < ndim; d++) {\n const dimSize =\n d < ndim - 1 ? postAxisShape.slice(d - axis).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(postRemaining / dimSize);\n postRemaining %= dimSize;\n inputIdx += coord * inputStrides[d]!;\n }\n\n const val = Number(a.data[inputIdx]!) !== 0 ? 1 : 0;\n if (bitorder === 'big') {\n byte |= val << (7 - bit);\n } else {\n byte |= val << bit;\n }\n }\n }\n\n // Calculate output linear index\n let outputIdx = 0;\n let preRemaining = pre;\n for (let d = 0; d < axis; d++) {\n const dimSize =\n d < axis - 1 ? preAxisShape.slice(d + 1).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(preRemaining / dimSize);\n preRemaining %= dimSize;\n outputIdx += coord * outputStrides[d]!;\n }\n outputIdx += packedIdx * outputStrides[axis]!;\n let postRemaining = post;\n for (let d = axis + 1; d < ndim; d++) {\n const dimSize =\n d < ndim - 1 ? postAxisShape.slice(d - axis).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(postRemaining / dimSize);\n postRemaining %= dimSize;\n outputIdx += coord * outputStrides[d]!;\n }\n\n resultData[outputIdx] = byte;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Unpack uint8 array into binary values\n *\n * Unpacks elements of a uint8 array into a binary-valued output array.\n * Each element of the input array is unpacked into 8 binary values.\n *\n * @param a - Input uint8 array\n * @param axis - The dimension over which bit-unpacking is done (default: -1, meaning the last axis)\n * @param count - The number of elements to unpack along axis, or -1 for all (default: -1)\n * @param bitorder - The order of bits within each packed byte. 'big' means the most significant bit is first. (default: 'big')\n * @returns Unpacked uint8 array of 0s and 1s\n */\nexport function unpackbits(\n a: ArrayStorage,\n axis: number = -1,\n count: number = -1,\n bitorder: 'big' | 'little' = 'big'\n): ArrayStorage {\n if (a.dtype !== 'uint8') {\n throw new TypeError('Expected an input array of unsigned byte data type');\n }\n\n const shape = Array.from(a.shape);\n const ndim = shape.length;\n\n // Handle negative axis\n if (axis < 0) {\n axis = ndim + axis;\n }\n\n if (axis < 0 || axis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n // Calculate output shape\n const packedAxisSize = shape[axis]!;\n let unpackedAxisSize = packedAxisSize * 8;\n\n // Apply count if specified\n if (count >= 0) {\n unpackedAxisSize = count;\n }\n\n const outShape = [...shape];\n outShape[axis] = unpackedAxisSize;\n\n const result = ArrayStorage.zeros(outShape, 'uint8');\n const resultData = result.data as Uint8Array;\n\n // For 1D arrays, simple case\n if (ndim === 1) {\n for (let i = 0; i < packedAxisSize; i++) {\n const byte = Number(a.data[i]!);\n for (let bit = 0; bit < 8; bit++) {\n const outIdx = i * 8 + bit;\n if (outIdx >= unpackedAxisSize) break;\n if (bitorder === 'big') {\n resultData[outIdx] = (byte >> (7 - bit)) & 1;\n } else {\n resultData[outIdx] = (byte >> bit) & 1;\n }\n }\n }\n return result;\n }\n\n // For N-D arrays\n const preAxisShape = shape.slice(0, axis);\n const postAxisShape = shape.slice(axis + 1);\n\n const preAxisSize = preAxisShape.reduce((acc, dim) => acc * dim, 1);\n const postAxisSize = postAxisShape.reduce((acc, dim) => acc * dim, 1);\n\n const inputStrides = computeStrides(shape);\n const outputStrides = computeStrides(outShape);\n\n for (let pre = 0; pre < preAxisSize; pre++) {\n for (let post = 0; post < postAxisSize; post++) {\n for (let packedIdx = 0; packedIdx < packedAxisSize; packedIdx++) {\n // Calculate input linear index\n let inputIdx = 0;\n let preRemaining = pre;\n for (let d = 0; d < axis; d++) {\n const dimSize =\n d < axis - 1 ? preAxisShape.slice(d + 1).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(preRemaining / dimSize);\n preRemaining %= dimSize;\n inputIdx += coord * inputStrides[d]!;\n }\n inputIdx += packedIdx * inputStrides[axis]!;\n let postRemaining = post;\n for (let d = axis + 1; d < ndim; d++) {\n const dimSize =\n d < ndim - 1 ? postAxisShape.slice(d - axis).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(postRemaining / dimSize);\n postRemaining %= dimSize;\n inputIdx += coord * inputStrides[d]!;\n }\n\n const byte = Number(a.data[inputIdx]!);\n\n for (let bit = 0; bit < 8; bit++) {\n const axisIdx = packedIdx * 8 + bit;\n if (axisIdx >= unpackedAxisSize) break;\n\n // Calculate output linear index\n let outputIdx = 0;\n preRemaining = pre;\n for (let d = 0; d < axis; d++) {\n const dimSize =\n d < axis - 1 ? preAxisShape.slice(d + 1).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(preRemaining / dimSize);\n preRemaining %= dimSize;\n outputIdx += coord * outputStrides[d]!;\n }\n outputIdx += axisIdx * outputStrides[axis]!;\n postRemaining = post;\n for (let d = axis + 1; d < ndim; d++) {\n const dimSize =\n d < ndim - 1 ? postAxisShape.slice(d - axis).reduce((acc, b) => acc * b, 1) : 1;\n const coord = Math.floor(postRemaining / dimSize);\n postRemaining %= dimSize;\n outputIdx += coord * outputStrides[d]!;\n }\n\n if (bitorder === 'big') {\n resultData[outputIdx] = (byte >> (7 - bit)) & 1;\n } else {\n resultData[outputIdx] = (byte >> bit) & 1;\n }\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Compute C-contiguous strides for a shape\n * @private\n */\nfunction computeStrides(shape: number[]): number[] {\n const ndim = shape.length;\n const strides = new Array(ndim);\n let stride = 1;\n for (let i = ndim - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n", "/**\n * NDArray - NumPy-compatible multidimensional array\n *\n * Core array class providing NumPy-like API\n */\n\nimport { parseSlice, normalizeSlice } from './slicing';\nimport {\n type DType,\n type TypedArray,\n DEFAULT_DTYPE,\n getTypedArrayConstructor,\n isBigIntDType,\n} from './dtype';\nimport { ArrayStorage } from './storage';\nimport * as arithmeticOps from '../ops/arithmetic';\nimport * as comparisonOps from '../ops/comparison';\nimport * as reductionOps from '../ops/reduction';\nimport * as shapeOps from '../ops/shape';\nimport * as linalgOps from '../ops/linalg';\nimport * as exponentialOps from '../ops/exponential';\nimport * as trigOps from '../ops/trig';\nimport * as hyperbolicOps from '../ops/hyperbolic';\nimport * as advancedOps from '../ops/advanced';\nimport * as bitwiseOps from '../ops/bitwise';\n\nexport class NDArray {\n // Internal storage\n private _storage: ArrayStorage;\n // Track if this array is a view of another array\n private _base?: NDArray;\n\n constructor(storage: ArrayStorage, base?: NDArray) {\n this._storage = storage;\n this._base = base;\n }\n\n /**\n * Get internal storage (for ops modules)\n * @internal\n */\n get storage(): ArrayStorage {\n return this._storage;\n }\n\n /**\n * Create NDArray from storage (for ops modules)\n * @internal\n */\n static _fromStorage(storage: ArrayStorage, base?: NDArray): NDArray {\n return new NDArray(storage, base);\n }\n\n // NumPy properties\n get shape(): readonly number[] {\n return this._storage.shape;\n }\n\n get ndim(): number {\n return this._storage.ndim;\n }\n\n get size(): number {\n return this._storage.size;\n }\n\n get dtype(): string {\n return this._storage.dtype;\n }\n\n get data(): TypedArray {\n return this._storage.data;\n }\n\n get strides(): readonly number[] {\n return this._storage.strides;\n }\n\n /**\n * Array flags (similar to NumPy's flags)\n * Provides information about memory layout\n */\n get flags(): {\n C_CONTIGUOUS: boolean;\n F_CONTIGUOUS: boolean;\n OWNDATA: boolean;\n } {\n return {\n C_CONTIGUOUS: this._storage.isCContiguous,\n F_CONTIGUOUS: this._storage.isFContiguous,\n OWNDATA: this._base === undefined, // True if we own data, false if we're a view\n };\n }\n\n /**\n * Base array if this is a view, null if this array owns its data\n * Similar to NumPy's base attribute\n */\n get base(): NDArray | null {\n return this._base ?? null;\n }\n\n /**\n * Get a single element from the array\n * @param indices - Array of indices, one per dimension (e.g., [0, 1] for 2D array)\n * @returns The element value (BigInt for int64/uint64, number otherwise)\n */\n get(indices: number[]): number | bigint {\n // Validate number of indices\n if (indices.length !== this.ndim) {\n throw new Error(\n `Index has ${indices.length} dimensions, but array has ${this.ndim} dimensions`\n );\n }\n\n // Normalize negative indices\n const normalizedIndices = indices.map((idx, dim) => {\n let normalized = idx;\n if (normalized < 0) {\n normalized = this.shape[dim]! + normalized;\n }\n // Validate bounds\n if (normalized < 0 || normalized >= this.shape[dim]!) {\n throw new Error(\n `Index ${idx} is out of bounds for axis ${dim} with size ${this.shape[dim]}`\n );\n }\n return normalized;\n });\n\n return this._storage.get(...normalizedIndices);\n }\n\n /**\n * Set a single element in the array\n * @param indices - Array of indices, one per dimension (e.g., [0, 1] for 2D array)\n * @param value - Value to set (will be converted to array's dtype)\n */\n set(indices: number[], value: number | bigint): void {\n // Validate number of indices\n if (indices.length !== this.ndim) {\n throw new Error(\n `Index has ${indices.length} dimensions, but array has ${this.ndim} dimensions`\n );\n }\n\n // Normalize negative indices\n const normalizedIndices = indices.map((idx, dim) => {\n let normalized = idx;\n if (normalized < 0) {\n normalized = this.shape[dim]! + normalized;\n }\n // Validate bounds\n if (normalized < 0 || normalized >= this.shape[dim]!) {\n throw new Error(\n `Index ${idx} is out of bounds for axis ${dim} with size ${this.shape[dim]}`\n );\n }\n return normalized;\n });\n\n // Convert value to appropriate type based on dtype\n const currentDtype = this.dtype as DType;\n let convertedValue: number | bigint;\n\n if (isBigIntDType(currentDtype)) {\n // Convert to BigInt for BigInt dtypes\n convertedValue = typeof value === 'bigint' ? value : BigInt(Math.round(value));\n } else if (currentDtype === 'bool') {\n // Convert to 0 or 1 for bool dtype\n convertedValue = value ? 1 : 0;\n } else {\n // Convert to number for all other dtypes\n convertedValue = Number(value);\n }\n\n this._storage.set(normalizedIndices, convertedValue);\n }\n\n /**\n * Return a deep copy of the array\n */\n copy(): NDArray {\n return new NDArray(this._storage.copy());\n }\n\n /**\n * Cast array to a different dtype\n * @param dtype - Target dtype\n * @param copy - If false and dtype matches, return self; otherwise create copy (default: true)\n * @returns Array with specified dtype\n */\n astype(dtype: DType, copy: boolean = true): NDArray {\n const currentDtype = this.dtype as DType;\n\n // If dtype matches and copy=false, return self\n if (currentDtype === dtype && !copy) {\n return this;\n }\n\n // If dtype matches and copy=true, create a copy\n if (currentDtype === dtype && copy) {\n return this.copy();\n }\n\n // Need to convert dtype\n const shape = Array.from(this.shape);\n const size = this.size;\n\n // Get TypedArray constructor for conversion\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot convert to dtype ${dtype}`);\n }\n const newData = new Constructor(size);\n const oldData = this.data;\n\n // Handle BigInt to other types\n if (isBigIntDType(currentDtype) && !isBigIntDType(dtype)) {\n const typedOldData = oldData as BigInt64Array | BigUint64Array;\n if (dtype === 'bool') {\n for (let i = 0; i < size; i++) {\n (newData as Uint8Array)[i] = typedOldData[i] !== BigInt(0) ? 1 : 0;\n }\n } else {\n for (let i = 0; i < size; i++) {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Number(\n typedOldData[i]\n );\n }\n }\n }\n // Handle other types to BigInt\n else if (!isBigIntDType(currentDtype) && isBigIntDType(dtype)) {\n const typedOldData = oldData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n (newData as BigInt64Array | BigUint64Array)[i] = BigInt(\n Math.round(Number(typedOldData[i]))\n );\n }\n }\n // Handle other types to bool\n else if (dtype === 'bool') {\n const typedOldData = oldData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n (newData as Uint8Array)[i] = typedOldData[i] !== 0 ? 1 : 0;\n }\n }\n // Handle bool to other types\n else if (currentDtype === 'bool' && !isBigIntDType(dtype)) {\n const typedOldData = oldData as Uint8Array;\n for (let i = 0; i < size; i++) {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = typedOldData[i]!;\n }\n }\n // Handle regular numeric conversions\n else if (!isBigIntDType(currentDtype) && !isBigIntDType(dtype)) {\n const typedOldData = oldData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n (newData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = typedOldData[i]!;\n }\n }\n // Handle BigInt to BigInt conversions (int64 <-> uint64)\n else {\n const typedOldData = oldData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n (newData as BigInt64Array | BigUint64Array)[i] = typedOldData[i]!;\n }\n }\n\n const storage = ArrayStorage.fromData(newData, shape, dtype);\n return new NDArray(storage);\n }\n\n // Arithmetic operations\n /**\n * Element-wise addition\n * @param other - Array or scalar to add\n * @returns Result of addition with broadcasting\n */\n add(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.add(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise subtraction\n * @param other - Array or scalar to subtract\n * @returns Result of subtraction with broadcasting\n */\n subtract(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.subtract(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise multiplication\n * @param other - Array or scalar to multiply\n * @returns Result of multiplication with broadcasting\n */\n multiply(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.multiply(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise division\n * @param other - Array or scalar to divide by\n * @returns Result of division with broadcasting\n */\n divide(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.divide(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise modulo operation\n * @param other - Array or scalar divisor\n * @returns Remainder after division\n */\n mod(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.mod(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise floor division\n * @param other - Array or scalar to divide by\n * @returns Floor of the quotient\n */\n floor_divide(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = arithmeticOps.floorDivide(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Numerical positive (element-wise +x)\n * @returns Copy of the array\n */\n positive(): NDArray {\n const resultStorage = arithmeticOps.positive(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise reciprocal (1/x)\n * @returns New array with reciprocals\n */\n reciprocal(): NDArray {\n const resultStorage = arithmeticOps.reciprocal(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Mathematical operations\n /**\n * Square root of each element\n * Promotes integer types to float64\n * @returns New array with square roots\n */\n sqrt(): NDArray {\n const resultStorage = exponentialOps.sqrt(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Raise elements to power\n * @param exponent - Power to raise to (array or scalar)\n * @returns New array with powered values\n */\n power(exponent: NDArray | number): NDArray {\n const exponentStorage = typeof exponent === 'number' ? exponent : exponent._storage;\n const resultStorage = exponentialOps.power(this._storage, exponentStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Absolute value of each element\n * @returns New array with absolute values\n */\n absolute(): NDArray {\n const resultStorage = arithmeticOps.absolute(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Numerical negative (element-wise negation)\n * @returns New array with negated values\n */\n negative(): NDArray {\n const resultStorage = arithmeticOps.negative(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Sign of each element (-1, 0, or 1)\n * @returns New array with signs\n */\n sign(): NDArray {\n const resultStorage = arithmeticOps.sign(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Trigonometric operations\n /**\n * Sine of each element (in radians)\n * Promotes integer types to float64\n * @returns New array with sine values\n */\n sin(): NDArray {\n const resultStorage = trigOps.sin(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Cosine of each element (in radians)\n * Promotes integer types to float64\n * @returns New array with cosine values\n */\n cos(): NDArray {\n const resultStorage = trigOps.cos(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Tangent of each element (in radians)\n * Promotes integer types to float64\n * @returns New array with tangent values\n */\n tan(): NDArray {\n const resultStorage = trigOps.tan(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse sine of each element\n * Promotes integer types to float64\n * @returns New array with arcsin values (radians)\n */\n arcsin(): NDArray {\n const resultStorage = trigOps.arcsin(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse cosine of each element\n * Promotes integer types to float64\n * @returns New array with arccos values (radians)\n */\n arccos(): NDArray {\n const resultStorage = trigOps.arccos(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse tangent of each element\n * Promotes integer types to float64\n * @returns New array with arctan values (radians)\n */\n arctan(): NDArray {\n const resultStorage = trigOps.arctan(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise arc tangent of this/other choosing the quadrant correctly\n * @param other - x-coordinates (array or scalar)\n * @returns Angle in radians between -\u03C0 and \u03C0\n */\n arctan2(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = trigOps.arctan2(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Given the \"legs\" of a right triangle, return its hypotenuse\n * Equivalent to sqrt(this**2 + other**2), element-wise\n * @param other - Second leg (array or scalar)\n * @returns Hypotenuse values\n */\n hypot(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = trigOps.hypot(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Convert angles from radians to degrees\n * @returns New array with angles in degrees\n */\n degrees(): NDArray {\n const resultStorage = trigOps.degrees(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Convert angles from degrees to radians\n * @returns New array with angles in radians\n */\n radians(): NDArray {\n const resultStorage = trigOps.radians(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Hyperbolic operations\n /**\n * Hyperbolic sine of each element\n * Promotes integer types to float64\n * @returns New array with sinh values\n */\n sinh(): NDArray {\n const resultStorage = hyperbolicOps.sinh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Hyperbolic cosine of each element\n * Promotes integer types to float64\n * @returns New array with cosh values\n */\n cosh(): NDArray {\n const resultStorage = hyperbolicOps.cosh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Hyperbolic tangent of each element\n * Promotes integer types to float64\n * @returns New array with tanh values\n */\n tanh(): NDArray {\n const resultStorage = hyperbolicOps.tanh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse hyperbolic sine of each element\n * Promotes integer types to float64\n * @returns New array with arcsinh values\n */\n arcsinh(): NDArray {\n const resultStorage = hyperbolicOps.arcsinh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse hyperbolic cosine of each element\n * Promotes integer types to float64\n * @returns New array with arccosh values\n */\n arccosh(): NDArray {\n const resultStorage = hyperbolicOps.arccosh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Inverse hyperbolic tangent of each element\n * Promotes integer types to float64\n * @returns New array with arctanh values\n */\n arctanh(): NDArray {\n const resultStorage = hyperbolicOps.arctanh(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Comparison operations\n /**\n * Element-wise greater than comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n greater(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.greater(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise greater than or equal comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n greater_equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.greaterEqual(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise less than comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n less(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.less(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise less than or equal comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n less_equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.lessEqual(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise equality comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.equal(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise not equal comparison\n * @param other - Value or array to compare with\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n not_equal(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.notEqual(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise comparison with tolerance\n * Returns True where |a - b| <= (atol + rtol * |b|)\n * @param other - Value or array to compare with\n * @param rtol - Relative tolerance (default: 1e-5)\n * @param atol - Absolute tolerance (default: 1e-8)\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n isclose(other: NDArray | number, rtol: number = 1e-5, atol: number = 1e-8): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = comparisonOps.isclose(this._storage, otherStorage, rtol, atol);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise comparison with tolerance\n * Returns True where |a - b| <= (atol + rtol * |b|)\n * @param other - Value or array to compare with\n * @param rtol - Relative tolerance (default: 1e-5)\n * @param atol - Absolute tolerance (default: 1e-8)\n * @returns Boolean array (represented as uint8: 1=true, 0=false)\n */\n allclose(other: NDArray | number, rtol: number = 1e-5, atol: number = 1e-8): boolean {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n return comparisonOps.allclose(this._storage, otherStorage, rtol, atol);\n }\n\n // Bitwise operations\n /**\n * Bitwise AND element-wise\n * @param other - Array or scalar for AND operation (must be integer type)\n * @returns Result of bitwise AND\n */\n bitwise_and(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = bitwiseOps.bitwise_and(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Bitwise OR element-wise\n * @param other - Array or scalar for OR operation (must be integer type)\n * @returns Result of bitwise OR\n */\n bitwise_or(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = bitwiseOps.bitwise_or(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Bitwise XOR element-wise\n * @param other - Array or scalar for XOR operation (must be integer type)\n * @returns Result of bitwise XOR\n */\n bitwise_xor(other: NDArray | number): NDArray {\n const otherStorage = typeof other === 'number' ? other : other._storage;\n const resultStorage = bitwiseOps.bitwise_xor(this._storage, otherStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Bitwise NOT (inversion) element-wise\n * @returns Result of bitwise NOT\n */\n bitwise_not(): NDArray {\n const resultStorage = bitwiseOps.bitwise_not(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Invert (bitwise NOT) element-wise - alias for bitwise_not\n * @returns Result of bitwise inversion\n */\n invert(): NDArray {\n const resultStorage = bitwiseOps.invert(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Left shift elements by positions\n * @param shift - Shift amount (array or scalar)\n * @returns Result of left shift\n */\n left_shift(shift: NDArray | number): NDArray {\n const shiftStorage = typeof shift === 'number' ? shift : shift._storage;\n const resultStorage = bitwiseOps.left_shift(this._storage, shiftStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Right shift elements by positions\n * @param shift - Shift amount (array or scalar)\n * @returns Result of right shift\n */\n right_shift(shift: NDArray | number): NDArray {\n const shiftStorage = typeof shift === 'number' ? shift : shift._storage;\n const resultStorage = bitwiseOps.right_shift(this._storage, shiftStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Reductions\n /**\n * Sum array elements over a given axis\n * @param axis - Axis along which to sum. If undefined, sum all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Sum of array elements, or array of sums along axis\n */\n sum(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.sum(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the arithmetic mean along the specified axis\n * @param axis - Axis along which to compute mean. If undefined, compute mean of all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Mean of array elements, or array of means along axis\n *\n * Note: mean() returns float64 for integer dtypes, matching NumPy behavior\n */\n mean(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.mean(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the maximum along a given axis\n * @param axis - Axis along which to compute maximum. If undefined, compute maximum of all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Maximum of array elements, or array of maximums along axis\n */\n max(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.max(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the minimum along a given axis\n * @param axis - Axis along which to compute minimum. If undefined, compute minimum of all elements\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Minimum of array elements, or array of minimums along axis\n */\n min(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.min(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Product of array elements over a given axis\n * @param axis - Axis along which to compute the product. If undefined, product of all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Product of array elements, or array of products along axis\n */\n prod(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.prod(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Indices of the minimum values along an axis\n * @param axis - Axis along which to find minimum indices. If undefined, index of global minimum.\n * @returns Indices of minimum values\n */\n argmin(axis?: number): NDArray | number {\n const result = reductionOps.argmin(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Indices of the maximum values along an axis\n * @param axis - Axis along which to find maximum indices. If undefined, index of global maximum.\n * @returns Indices of maximum values\n */\n argmax(axis?: number): NDArray | number {\n const result = reductionOps.argmax(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute variance along the specified axis\n * @param axis - Axis along which to compute variance. If undefined, variance of all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Variance of array elements\n */\n var(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.variance(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute standard deviation along the specified axis\n * @param axis - Axis along which to compute std. If undefined, std of all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Standard deviation of array elements\n */\n std(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.std(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Test whether all array elements along a given axis evaluate to True\n * @param axis - Axis along which to perform logical AND. If undefined, test all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Boolean or array of booleans\n */\n all(axis?: number, keepdims: boolean = false): NDArray | boolean {\n const result = reductionOps.all(this._storage, axis, keepdims);\n return typeof result === 'boolean' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Test whether any array elements along a given axis evaluate to True\n * @param axis - Axis along which to perform logical OR. If undefined, test all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Boolean or array of booleans\n */\n any(axis?: number, keepdims: boolean = false): NDArray | boolean {\n const result = reductionOps.any(this._storage, axis, keepdims);\n return typeof result === 'boolean' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the cumulative sum of elements along a given axis\n * @param axis - Axis along which to compute cumsum. If undefined, compute over flattened array.\n * @returns Array with cumulative sums\n */\n cumsum(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumsum(this._storage, axis));\n }\n\n /**\n * Return the cumulative product of elements along a given axis\n * @param axis - Axis along which to compute cumprod. If undefined, compute over flattened array.\n * @returns Array with cumulative products\n */\n cumprod(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumprod(this._storage, axis));\n }\n\n /**\n * Peak to peak (maximum - minimum) value along a given axis\n * @param axis - Axis along which to compute ptp. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Range of values\n */\n ptp(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.ptp(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the median along the specified axis\n * @param axis - Axis along which to compute median. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median of array elements\n */\n median(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.median(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the q-th percentile of the data along the specified axis\n * @param q - Percentile to compute (0-100)\n * @param axis - Axis along which to compute percentile. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Percentile of array elements\n */\n percentile(q: number, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.percentile(this._storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the q-th quantile of the data along the specified axis\n * @param q - Quantile to compute (0-1)\n * @param axis - Axis along which to compute quantile. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Quantile of array elements\n */\n quantile(q: number, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.quantile(this._storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the weighted average along the specified axis\n * @param weights - Array of weights (optional)\n * @param axis - Axis along which to compute average. If undefined, compute over all elements.\n * @returns Weighted average of array elements\n */\n average(weights?: NDArray, axis?: number): NDArray | number {\n const result = reductionOps.average(this._storage, axis, weights?.storage);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the sum of array elements, treating NaNs as zero\n * @param axis - Axis along which to compute sum. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Sum of array elements ignoring NaNs\n */\n nansum(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nansum(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the product of array elements, treating NaNs as ones\n * @param axis - Axis along which to compute product. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Product of array elements ignoring NaNs\n */\n nanprod(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanprod(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the arithmetic mean, ignoring NaNs\n * @param axis - Axis along which to compute mean. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Mean of array elements ignoring NaNs\n */\n nanmean(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmean(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the variance, ignoring NaNs\n * @param axis - Axis along which to compute variance. If undefined, compute over all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Variance of array elements ignoring NaNs\n */\n nanvar(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanvar(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Compute the standard deviation, ignoring NaNs\n * @param axis - Axis along which to compute std. If undefined, compute over all elements.\n * @param ddof - Delta degrees of freedom (default: 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Standard deviation of array elements ignoring NaNs\n */\n nanstd(axis?: number, ddof: number = 0, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanstd(this._storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return minimum of an array or minimum along an axis, ignoring NaNs\n * @param axis - Axis along which to compute minimum. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Minimum of array elements ignoring NaNs\n */\n nanmin(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmin(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return maximum of an array or maximum along an axis, ignoring NaNs\n * @param axis - Axis along which to compute maximum. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Maximum of array elements ignoring NaNs\n */\n nanmax(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmax(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the indices of the minimum values, ignoring NaNs\n * @param axis - Axis along which to find minimum indices. If undefined, index of global minimum.\n * @returns Indices of minimum values ignoring NaNs\n */\n nanargmin(axis?: number): NDArray | number {\n const result = reductionOps.nanargmin(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the indices of the maximum values, ignoring NaNs\n * @param axis - Axis along which to find maximum indices. If undefined, index of global maximum.\n * @returns Indices of maximum values ignoring NaNs\n */\n nanargmax(axis?: number): NDArray | number {\n const result = reductionOps.nanargmax(this._storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n /**\n * Return the cumulative sum of elements, treating NaNs as zero\n * @param axis - Axis along which to compute cumsum. If undefined, compute over flattened array.\n * @returns Array with cumulative sums ignoring NaNs\n */\n nancumsum(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumsum(this._storage, axis));\n }\n\n /**\n * Return the cumulative product of elements, treating NaNs as one\n * @param axis - Axis along which to compute cumprod. If undefined, compute over flattened array.\n * @returns Array with cumulative products ignoring NaNs\n */\n nancumprod(axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumprod(this._storage, axis));\n }\n\n /**\n * Compute the median, ignoring NaNs\n * @param axis - Axis along which to compute median. If undefined, compute over all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median of array elements ignoring NaNs\n */\n nanmedian(axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmedian(this._storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n }\n\n // Shape manipulation\n /**\n * Reshape array to a new shape\n * Returns a new array with the specified shape\n * @param shape - New shape (must be compatible with current size)\n * @returns Reshaped array\n */\n reshape(...shape: number[]): NDArray {\n const newShape = shape.length === 1 && Array.isArray(shape[0]) ? shape[0] : shape;\n const resultStorage = shapeOps.reshape(this._storage, newShape);\n const isView = resultStorage.data === this.data;\n const base = isView ? (this._base ?? this) : undefined;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Return a flattened copy of the array\n * @returns 1D array containing all elements\n */\n flatten(): NDArray {\n const resultStorage = shapeOps.flatten(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Return a flattened array (view when possible, otherwise copy)\n * @returns 1D array containing all elements\n */\n ravel(): NDArray {\n const resultStorage = shapeOps.ravel(this._storage);\n const isView = resultStorage.data === this.data;\n const base = isView ? (this._base ?? this) : undefined;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Transpose array (permute dimensions)\n * @param axes - Permutation of axes. If undefined, reverse the dimensions\n * @returns Transposed array (always a view)\n */\n transpose(axes?: number[]): NDArray {\n const resultStorage = shapeOps.transpose(this._storage, axes);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Remove axes of length 1\n * @param axis - Axis to squeeze. If undefined, squeeze all axes of length 1\n * @returns Array with specified dimensions removed (always a view)\n */\n squeeze(axis?: number): NDArray {\n const resultStorage = shapeOps.squeeze(this._storage, axis);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Expand the shape by inserting a new axis of length 1\n * @param axis - Position where new axis is placed\n * @returns Array with additional dimension (always a view)\n */\n expand_dims(axis: number): NDArray {\n const resultStorage = shapeOps.expandDims(this._storage, axis);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Swap two axes of an array\n * @param axis1 - First axis\n * @param axis2 - Second axis\n * @returns Array with swapped axes (always a view)\n */\n swapaxes(axis1: number, axis2: number): NDArray {\n const resultStorage = shapeOps.swapaxes(this._storage, axis1, axis2);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Move axes to new positions\n * @param source - Original positions of axes to move\n * @param destination - New positions for axes\n * @returns Array with moved axes (always a view)\n */\n moveaxis(source: number | number[], destination: number | number[]): NDArray {\n const resultStorage = shapeOps.moveaxis(this._storage, source, destination);\n const base = this._base ?? this;\n return NDArray._fromStorage(resultStorage, base);\n }\n\n /**\n * Repeat elements of an array\n * @param repeats - Number of repetitions for each element\n * @param axis - Axis along which to repeat (if undefined, flattens first)\n * @returns New array with repeated elements\n */\n repeat(repeats: number | number[], axis?: number): NDArray {\n const resultStorage = shapeOps.repeat(this._storage, repeats, axis);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Take elements from array along an axis\n * @param indices - Indices of elements to take\n * @param axis - Axis along which to take (if undefined, flattens first)\n * @returns New array with selected elements\n */\n take(indices: number[], axis?: number): NDArray {\n const resultStorage = advancedOps.take(this._storage, indices, axis);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Put values at specified indices (modifies array in-place)\n * @param indices - Indices at which to place values\n * @param values - Values to put\n */\n put(indices: number[], values: NDArray | number | bigint): void {\n const valuesStorage = values instanceof NDArray ? values._storage : values;\n advancedOps.put(this._storage, indices, valuesStorage);\n }\n\n // Linear algebra operations\n /**\n * Matrix multiplication\n * @param other - Array to multiply with\n * @returns Result of matrix multiplication\n */\n matmul(other: NDArray): NDArray {\n const resultStorage = linalgOps.matmul(this._storage, other._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Dot product (matching NumPy behavior)\n * @param other - Array to dot with\n * @returns Result of dot product (scalar or array depending on dimensions)\n */\n dot(other: NDArray): NDArray | number | bigint {\n const result = linalgOps.dot(this._storage, other._storage);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n }\n\n /**\n * Sum of diagonal elements (trace)\n * @returns Sum of diagonal elements\n */\n trace(): number | bigint {\n return linalgOps.trace(this._storage);\n }\n\n /**\n * Inner product (contracts over last axes of both arrays)\n * @param other - Array to compute inner product with\n * @returns Inner product result\n */\n inner(other: NDArray): NDArray | number | bigint {\n const result = linalgOps.inner(this._storage, other._storage);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n }\n\n /**\n * Outer product (flattens inputs then computes a[i]*b[j])\n * @param other - Array to compute outer product with\n * @returns 2D outer product matrix\n */\n outer(other: NDArray): NDArray {\n const result = linalgOps.outer(this._storage, other._storage);\n return NDArray._fromStorage(result);\n }\n\n /**\n * Tensor dot product along specified axes\n * @param other - Array to contract with\n * @param axes - Axes to contract (integer or [a_axes, b_axes])\n * @returns Tensor dot product result\n */\n tensordot(other: NDArray, axes: number | [number[], number[]] = 2): NDArray | number | bigint {\n const result = linalgOps.tensordot(this._storage, other._storage, axes);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n }\n\n // Additional arithmetic operations\n\n /**\n * Element-wise cube root\n * Promotes integer types to float64\n * @returns New array with cube root values\n */\n cbrt(): NDArray {\n const resultStorage = arithmeticOps.cbrt(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise absolute value (always returns float)\n * @returns New array with absolute values as float\n */\n fabs(): NDArray {\n const resultStorage = arithmeticOps.fabs(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Returns both quotient and remainder (floor divide and modulo)\n * @param divisor - Array or scalar divisor\n * @returns Tuple of [quotient, remainder] arrays\n */\n divmod(divisor: NDArray | number): [NDArray, NDArray] {\n const divisorStorage = typeof divisor === 'number' ? divisor : divisor._storage;\n const [quotientStorage, remainderStorage] = arithmeticOps.divmod(this._storage, divisorStorage);\n return [NDArray._fromStorage(quotientStorage), NDArray._fromStorage(remainderStorage)];\n }\n\n /**\n * Element-wise square (x**2)\n * @returns New array with squared values\n */\n square(): NDArray {\n const resultStorage = arithmeticOps.square(this._storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Element-wise remainder (same as mod)\n * @param divisor - Array or scalar divisor\n * @returns New array with remainder values\n */\n remainder(divisor: NDArray | number): NDArray {\n const divisorStorage = typeof divisor === 'number' ? divisor : divisor._storage;\n const resultStorage = arithmeticOps.remainder(this._storage, divisorStorage);\n return NDArray._fromStorage(resultStorage);\n }\n\n /**\n * Heaviside step function\n * @param x2 - Value to use when this array element is 0\n * @returns New array with heaviside values\n */\n heaviside(x2: NDArray | number): NDArray {\n const x2Storage = typeof x2 === 'number' ? x2 : x2._storage;\n const resultStorage = arithmeticOps.heaviside(this._storage, x2Storage);\n return NDArray._fromStorage(resultStorage);\n }\n\n // Slicing\n /**\n * Slice the array using NumPy-style string syntax\n *\n * @param sliceStrs - Slice specifications, one per dimension\n * @returns Sliced view of the array\n */\n slice(...sliceStrs: string[]): NDArray {\n if (sliceStrs.length === 0) {\n return this;\n }\n\n if (sliceStrs.length > this.ndim) {\n throw new Error(\n `Too many indices for array: array is ${this.ndim}-dimensional, but ${sliceStrs.length} were indexed`\n );\n }\n\n // Parse slice strings and normalize them\n const sliceSpecs = sliceStrs.map((str, i) => {\n const spec = parseSlice(str);\n const normalized = normalizeSlice(spec, this.shape[i]!);\n return normalized;\n });\n\n // Pad with full slices for remaining dimensions\n while (sliceSpecs.length < this.ndim) {\n sliceSpecs.push({\n start: 0,\n stop: this.shape[sliceSpecs.length]!,\n step: 1,\n isIndex: false,\n });\n }\n\n // Calculate new shape and strides\n const newShape: number[] = [];\n const newStrides: number[] = [];\n let newOffset = this._storage.offset;\n\n for (let i = 0; i < sliceSpecs.length; i++) {\n const spec = sliceSpecs[i]!;\n const stride = this._storage.strides[i]!;\n\n // Update offset based on start position\n newOffset += spec.start * stride;\n\n if (!spec.isIndex) {\n // Calculate size of this dimension\n // For positive step: (stop - start) / step\n // For negative step: (start - stop) / |step| (since we go from high to low)\n let dimSize: number;\n if (spec.step > 0) {\n dimSize = Math.max(0, Math.ceil((spec.stop - spec.start) / spec.step));\n } else {\n // Negative step: iterate from start down to (but not including) stop\n dimSize = Math.max(0, Math.ceil((spec.start - spec.stop) / Math.abs(spec.step)));\n }\n newShape.push(dimSize);\n newStrides.push(stride * spec.step);\n }\n // If isIndex is true, this dimension is removed (scalar indexing)\n }\n\n // Create sliced view\n const slicedStorage = ArrayStorage.fromData(\n this._storage.data,\n newShape,\n this._storage.dtype,\n newStrides,\n newOffset\n );\n\n const base = this._base ?? this;\n return new NDArray(slicedStorage, base);\n }\n\n // Convenience methods\n /**\n * Get a single row (convenience method)\n * @param i - Row index\n * @returns Row as 1D or (n-1)D array\n */\n\n row(i: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('row() requires at least 2 dimensions');\n }\n return this.slice(String(i), ':');\n }\n\n /**\n * Get a single column (convenience method)\n * @param j - Column index\n * @returns Column as 1D or (n-1)D array\n */\n col(j: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('col() requires at least 2 dimensions');\n }\n return this.slice(':', String(j));\n }\n\n /**\n * Get a range of rows (convenience method)\n * @param start - Start row index\n * @param stop - Stop row index (exclusive)\n * @returns Rows as array\n */\n rows(start: number, stop: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('rows() requires at least 2 dimensions');\n }\n return this.slice(`${start}:${stop}`, ':');\n }\n\n /**\n * Get a range of columns (convenience method)\n * @param start - Start column index\n * @param stop - Stop column index (exclusive)\n * @returns Columns as array\n */\n cols(start: number, stop: number): NDArray {\n if (this.ndim < 2) {\n throw new Error('cols() requires at least 2 dimensions');\n }\n return this.slice(':', `${start}:${stop}`);\n }\n\n // String representation\n /**\n * String representation of the array\n * @returns String describing the array shape and dtype\n */\n toString(): string {\n return `NDArray(shape=${JSON.stringify(this.shape)}, dtype=${this.dtype})`;\n }\n\n /**\n * Convert to nested JavaScript array\n * @returns Nested JavaScript array representation\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n toArray(): any {\n // Handle 0-dimensional arrays (scalars)\n if (this.ndim === 0) {\n return this._storage.iget(0);\n }\n\n const shape = this.shape;\n const ndim = shape.length;\n\n // Recursive function to build nested array\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const buildNestedArray = (indices: number[], dim: number): any => {\n if (dim === ndim) {\n return this._storage.get(...indices);\n }\n\n const arr = [];\n for (let i = 0; i < shape[dim]!; i++) {\n indices[dim] = i;\n arr.push(buildNestedArray(indices, dim + 1));\n }\n return arr;\n };\n\n return buildNestedArray(new Array(ndim), 0);\n }\n}\n\n// Creation functions\n\n/**\n * Create array of zeros\n * @param shape - Shape of the array\n * @param dtype - Data type (default: float64)\n * @returns Array filled with zeros\n */\nexport function zeros(shape: number[], dtype: DType = DEFAULT_DTYPE): NDArray {\n const storage = ArrayStorage.zeros(shape, dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array of ones\n * @param shape - Shape of the array\n * @param dtype - Data type (default: float64)\n * @returns Array filled with ones\n */\nexport function ones(shape: number[], dtype: DType = DEFAULT_DTYPE): NDArray {\n const storage = ArrayStorage.ones(shape, dtype);\n return new NDArray(storage);\n}\n\n/**\n * Helper to infer shape from nested arrays\n */\nfunction inferShape(data: unknown): number[] {\n const shape: number[] = [];\n let current = data;\n while (Array.isArray(current)) {\n shape.push(current.length);\n current = current[0];\n }\n return shape;\n}\n\n/**\n * Helper to check if data contains BigInt values\n */\nfunction containsBigInt(data: unknown): boolean {\n if (typeof data === 'bigint') return true;\n if (Array.isArray(data)) {\n return data.some((item) => containsBigInt(item));\n }\n return false;\n}\n\n/**\n * Helper to flatten nested arrays keeping BigInt values\n */\nfunction flattenKeepBigInt(data: unknown): unknown[] {\n const result: unknown[] = [];\n function flatten(arr: unknown): void {\n if (Array.isArray(arr)) {\n arr.forEach((item) => flatten(item));\n } else {\n result.push(arr);\n }\n }\n flatten(data);\n return result;\n}\n\n/**\n * Create array from nested JavaScript arrays\n * @param data - Nested arrays or existing NDArray\n * @param dtype - Data type (optional, will be inferred if not provided)\n * @returns New NDArray\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function array(data: any, dtype?: DType): NDArray {\n // If data is already an NDArray, optionally convert dtype\n if (data instanceof NDArray) {\n if (!dtype || data.dtype === dtype) {\n return data.copy();\n }\n return data.astype(dtype);\n }\n\n const hasBigInt = containsBigInt(data);\n\n // Infer shape from nested arrays\n const shape = inferShape(data);\n const size = shape.reduce((a: number, b: number) => a * b, 1);\n\n // Determine dtype\n let actualDtype = dtype;\n if (!actualDtype) {\n if (hasBigInt) {\n actualDtype = 'int64';\n } else {\n actualDtype = DEFAULT_DTYPE;\n }\n }\n\n // Get TypedArray constructor\n const Constructor = getTypedArrayConstructor(actualDtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${actualDtype}`);\n }\n\n const typedData = new Constructor(size);\n const flatData = flattenKeepBigInt(data);\n\n // Fill the typed array\n if (isBigIntDType(actualDtype)) {\n const bigintData = typedData as BigInt64Array | BigUint64Array;\n for (let i = 0; i < size; i++) {\n const val = flatData[i];\n bigintData[i] = typeof val === 'bigint' ? val : BigInt(Math.round(Number(val)));\n }\n } else if (actualDtype === 'bool') {\n const boolData = typedData as Uint8Array;\n for (let i = 0; i < size; i++) {\n boolData[i] = flatData[i] ? 1 : 0;\n }\n } else {\n const numData = typedData as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < size; i++) {\n const val = flatData[i];\n numData[i] = typeof val === 'bigint' ? Number(val) : Number(val);\n }\n }\n\n const storage = ArrayStorage.fromData(typedData, shape, actualDtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with evenly spaced values within a given interval\n * Similar to Python's range() but returns array\n * @param start - Start value (or stop if only one argument)\n * @param stop - Stop value (exclusive)\n * @param step - Step between values (default: 1)\n * @param dtype - Data type (default: float64)\n * @returns Array of evenly spaced values\n */\nexport function arange(\n start: number,\n stop?: number,\n step: number = 1,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n let actualStart = start;\n let actualStop = stop;\n\n if (stop === undefined) {\n actualStart = 0;\n actualStop = start;\n }\n\n if (actualStop === undefined) {\n throw new Error('stop is required');\n }\n\n const length = Math.max(0, Math.ceil((actualStop - actualStart) / step));\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create arange array with dtype ${dtype}`);\n }\n\n const data = new Constructor(length);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < length; i++) {\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(actualStart + i * step));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < length; i++) {\n (data as Uint8Array)[i] = actualStart + i * step !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < length; i++) {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = actualStart + i * step;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [length], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with evenly spaced values over a specified interval\n * @param start - Starting value\n * @param stop - Ending value (inclusive)\n * @param num - Number of samples (default: 50)\n * @param dtype - Data type (default: float64)\n * @returns Array of evenly spaced values\n */\nexport function linspace(\n start: number,\n stop: number,\n num: number = 50,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n if (num < 0) {\n throw new Error('num must be non-negative');\n }\n\n if (num === 0) {\n return array([], dtype);\n }\n\n if (num === 1) {\n return array([start], dtype);\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create linspace array with dtype ${dtype}`);\n }\n\n const data = new Constructor(num);\n const step = (stop - start) / (num - 1);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < num; i++) {\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(start + i * step));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < num; i++) {\n (data as Uint8Array)[i] = start + i * step !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < num; i++) {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = start + i * step;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [num], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with logarithmically spaced values\n * Returns num samples, equally spaced on a log scale from base^start to base^stop\n * @param start - base^start is the starting value\n * @param stop - base^stop is the ending value\n * @param num - Number of samples (default: 50)\n * @param base - Base of the log space (default: 10.0)\n * @param dtype - Data type (default: float64)\n * @returns Array of logarithmically spaced values\n */\nexport function logspace(\n start: number,\n stop: number,\n num: number = 50,\n base: number = 10.0,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n if (num < 0) {\n throw new Error('num must be non-negative');\n }\n\n if (num === 0) {\n return array([], dtype);\n }\n\n if (num === 1) {\n return array([Math.pow(base, start)], dtype);\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create logspace array with dtype ${dtype}`);\n }\n\n const data = new Constructor(num);\n const step = (stop - start) / (num - 1);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < num; i++) {\n const exponent = start + i * step;\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(Math.pow(base, exponent)));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < num; i++) {\n const exponent = start + i * step;\n (data as Uint8Array)[i] = Math.pow(base, exponent) !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < num; i++) {\n const exponent = start + i * step;\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Math.pow(base, exponent);\n }\n }\n\n const storage = ArrayStorage.fromData(data, [num], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create array with geometrically spaced values\n * Returns num samples, equally spaced on a log scale (geometric progression)\n * @param start - Starting value\n * @param stop - Ending value\n * @param num - Number of samples (default: 50)\n * @param dtype - Data type (default: float64)\n * @returns Array of geometrically spaced values\n */\nexport function geomspace(\n start: number,\n stop: number,\n num: number = 50,\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n if (num < 0) {\n throw new Error('num must be non-negative');\n }\n\n if (start === 0 || stop === 0) {\n throw new Error('Geometric sequence cannot include zero');\n }\n\n if (num === 0) {\n return array([], dtype);\n }\n\n if (num === 1) {\n return array([start], dtype);\n }\n\n const signStart = Math.sign(start);\n const signStop = Math.sign(stop);\n\n if (signStart !== signStop) {\n throw new Error('Geometric sequence cannot contain both positive and negative values');\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create geomspace array with dtype ${dtype}`);\n }\n\n const data = new Constructor(num);\n const logStart = Math.log(Math.abs(start));\n const logStop = Math.log(Math.abs(stop));\n const step = (logStop - logStart) / (num - 1);\n\n if (isBigIntDType(dtype)) {\n for (let i = 0; i < num; i++) {\n const value = signStart * Math.exp(logStart + i * step);\n (data as BigInt64Array | BigUint64Array)[i] = BigInt(Math.round(value));\n }\n } else if (dtype === 'bool') {\n for (let i = 0; i < num; i++) {\n const value = signStart * Math.exp(logStart + i * step);\n (data as Uint8Array)[i] = value !== 0 ? 1 : 0;\n }\n } else {\n for (let i = 0; i < num; i++) {\n const value = signStart * Math.exp(logStart + i * step);\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = value;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [num], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Create identity matrix\n * @param n - Number of rows\n * @param m - Number of columns (default: n)\n * @param k - Index of diagonal (0 for main diagonal, positive for upper, negative for lower)\n * @param dtype - Data type (default: float64)\n * @returns Identity matrix\n */\nexport function eye(n: number, m?: number, k: number = 0, dtype: DType = DEFAULT_DTYPE): NDArray {\n const cols = m ?? n;\n const result = zeros([n, cols], dtype);\n const data = result.data;\n\n if (isBigIntDType(dtype)) {\n const typedData = data as unknown as BigInt64Array | BigUint64Array;\n for (let i = 0; i < n; i++) {\n const j = i + k;\n if (j >= 0 && j < cols) {\n typedData[i * cols + j] = BigInt(1);\n }\n }\n } else {\n const typedData = data as unknown as Exclude<TypedArray, BigInt64Array | BigUint64Array>;\n for (let i = 0; i < n; i++) {\n const j = i + k;\n if (j >= 0 && j < cols) {\n typedData[i * cols + j] = 1;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Create an uninitialized array\n * Note: TypedArrays are zero-initialized by default in JavaScript\n * @param shape - Shape of the array\n * @param dtype - Data type (default: float64)\n * @returns Uninitialized array\n */\nexport function empty(shape: number[], dtype: DType = DEFAULT_DTYPE): NDArray {\n return zeros(shape, dtype);\n}\n\n/**\n * Create array filled with a constant value\n * @param shape - Shape of the array\n * @param fill_value - Value to fill the array with\n * @param dtype - Data type (optional, inferred from fill_value if not provided)\n * @returns Array filled with the constant value\n */\nexport function full(\n shape: number[],\n fill_value: number | bigint | boolean,\n dtype?: DType\n): NDArray {\n let actualDtype = dtype;\n if (!actualDtype) {\n if (typeof fill_value === 'bigint') {\n actualDtype = 'int64';\n } else if (typeof fill_value === 'boolean') {\n actualDtype = 'bool';\n } else if (Number.isInteger(fill_value)) {\n actualDtype = 'int32';\n } else {\n actualDtype = DEFAULT_DTYPE;\n }\n }\n\n const Constructor = getTypedArrayConstructor(actualDtype);\n if (!Constructor) {\n throw new Error(`Cannot create full array with dtype ${actualDtype}`);\n }\n const size = shape.reduce((a, b) => a * b, 1);\n const data = new Constructor(size);\n\n if (isBigIntDType(actualDtype)) {\n const bigintValue =\n typeof fill_value === 'bigint' ? fill_value : BigInt(Math.round(Number(fill_value)));\n (data as BigInt64Array | BigUint64Array).fill(bigintValue);\n } else if (actualDtype === 'bool') {\n (data as Uint8Array).fill(fill_value ? 1 : 0);\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>).fill(Number(fill_value));\n }\n\n const storage = ArrayStorage.fromData(data, shape, actualDtype);\n return new NDArray(storage);\n}\n\n/**\n * Create a square identity matrix\n * @param n - Size of the square matrix\n * @param dtype - Data type (default: float64)\n * @returns n\u00D7n identity matrix\n */\nexport function identity(n: number, dtype: DType = DEFAULT_DTYPE): NDArray {\n return eye(n, n, 0, dtype);\n}\n\n/**\n * Convert input to an ndarray\n * @param a - Input data (array-like or NDArray)\n * @param dtype - Data type (optional)\n * @returns NDArray representation of the input\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function asarray(a: NDArray | any, dtype?: DType): NDArray {\n if (a instanceof NDArray) {\n if (!dtype || a.dtype === dtype) {\n return a;\n }\n return a.astype(dtype);\n }\n return array(a, dtype);\n}\n\n/**\n * Create a deep copy of an array\n * @param a - Array to copy\n * @returns Deep copy of the array\n */\nexport function copy(a: NDArray): NDArray {\n return a.copy();\n}\n\n/**\n * Create array of zeros with the same shape as another array\n * @param a - Array to match shape from\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Array of zeros\n */\nexport function zeros_like(a: NDArray, dtype?: DType): NDArray {\n return zeros(Array.from(a.shape), dtype ?? (a.dtype as DType));\n}\n\n/**\n * Create array of ones with the same shape as another array\n * @param a - Array to match shape from\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Array of ones\n */\nexport function ones_like(a: NDArray, dtype?: DType): NDArray {\n return ones(Array.from(a.shape), dtype ?? (a.dtype as DType));\n}\n\n/**\n * Create uninitialized array with the same shape as another array\n * @param a - Array to match shape from\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Uninitialized array\n */\nexport function empty_like(a: NDArray, dtype?: DType): NDArray {\n return empty(Array.from(a.shape), dtype ?? (a.dtype as DType));\n}\n\n/**\n * Create array filled with a constant value, same shape as another array\n * @param a - Array to match shape from\n * @param fill_value - Value to fill with\n * @param dtype - Data type (optional, uses a's dtype if not provided)\n * @returns Filled array\n */\nexport function full_like(\n a: NDArray,\n fill_value: number | bigint | boolean,\n dtype?: DType\n): NDArray {\n return full(Array.from(a.shape), fill_value, dtype ?? (a.dtype as DType));\n}\n\n/**\n * Convert input to an ndarray (alias for asarray for compatibility)\n * In numpy-ts, this behaves the same as asarray since we don't have subclasses\n * @param a - Input data\n * @param dtype - Data type (optional)\n * @returns NDArray\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function asanyarray(a: NDArray | any, dtype?: DType): NDArray {\n return asarray(a, dtype);\n}\n\n/**\n * Return a contiguous array (ndim >= 1) in memory (C order)\n * Since our arrays are already C-contiguous in memory, this either\n * returns the input unchanged or creates a contiguous copy\n * @param a - Input data\n * @param dtype - Data type (optional)\n * @returns Contiguous array in C order\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function ascontiguousarray(a: NDArray | any, dtype?: DType): NDArray {\n const arr = asarray(a, dtype);\n if (arr.flags.C_CONTIGUOUS) {\n return arr;\n }\n return arr.copy();\n}\n\n/**\n * Return an array laid out in Fortran order in memory\n * Note: numpy-ts uses C-order internally, so this creates a copy\n * that is equivalent to the Fortran-ordered layout\n * @param a - Input data\n * @param dtype - Data type (optional)\n * @returns Array (copy in C order, as Fortran order is not supported)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function asfortranarray(a: NDArray | any, dtype?: DType): NDArray {\n const arr = asarray(a, dtype);\n // We always return C-contiguous arrays, so just return a copy\n return arr.copy();\n}\n\n/**\n * Extract a diagonal or construct a diagonal array\n * @param v - Input array (if 2D, extract diagonal; if 1D, construct diagonal matrix)\n * @param k - Diagonal offset (default 0 is main diagonal, positive above, negative below)\n * @returns Diagonal elements as 1D array, or 2D diagonal matrix\n */\nexport function diag(v: NDArray, k: number = 0): NDArray {\n if (v.ndim === 1) {\n // Construct diagonal matrix from 1D array\n const n = v.size;\n const size = n + Math.abs(k);\n const result = zeros([size, size], v.dtype as DType);\n\n for (let i = 0; i < n; i++) {\n const row = k >= 0 ? i : i - k;\n const col = k >= 0 ? i + k : i;\n result.set([row, col], v.get([i]) as number);\n }\n return result;\n } else if (v.ndim === 2) {\n // Extract diagonal from 2D array\n const [rows, cols] = v.shape;\n let startRow: number, startCol: number, diagLength: number;\n\n if (k >= 0) {\n startRow = 0;\n startCol = k;\n diagLength = Math.min(rows!, cols! - k);\n } else {\n startRow = -k;\n startCol = 0;\n diagLength = Math.min(rows! + k, cols!);\n }\n\n if (diagLength <= 0) {\n return zeros([0], v.dtype as DType);\n }\n\n const Constructor = getTypedArrayConstructor(v.dtype as DType);\n const data = new Constructor!(diagLength);\n\n for (let i = 0; i < diagLength; i++) {\n const val = v.get([startRow + i, startCol + i]);\n if (isBigIntDType(v.dtype as DType)) {\n (data as BigInt64Array | BigUint64Array)[i] =\n typeof val === 'bigint' ? val : BigInt(val as number);\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = val as number;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [diagLength], v.dtype as DType);\n return new NDArray(storage);\n } else {\n throw new Error('Input must be 1-D or 2-D');\n }\n}\n\n/**\n * Create a 2-D array with the flattened input as a diagonal\n * @param v - Input array (will be flattened)\n * @param k - Diagonal offset (default 0)\n * @returns 2D diagonal matrix\n */\nexport function diagflat(v: NDArray, k: number = 0): NDArray {\n const flat = v.flatten();\n return diag(flat, k);\n}\n\n/**\n * Construct an array by executing a function over each coordinate\n * @param fn - Function that takes coordinate indices and returns value\n * @param shape - Shape of output array\n * @param dtype - Data type (default: float64)\n * @returns Array with values computed from function\n */\nexport function fromfunction(\n fn: (...indices: number[]) => number | bigint | boolean,\n shape: number[],\n dtype: DType = DEFAULT_DTYPE\n): NDArray {\n const size = shape.reduce((a, b) => a * b, 1);\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Cannot create array with dtype ${dtype}`);\n }\n const data = new Constructor(size);\n const ndim = shape.length;\n const indices = new Array(ndim).fill(0);\n\n for (let i = 0; i < size; i++) {\n const value = fn(...indices);\n\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array)[i] =\n typeof value === 'bigint' ? value : BigInt(Number(value));\n } else if (dtype === 'bool') {\n (data as Uint8Array)[i] = value ? 1 : 0;\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Number(value);\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n indices[d]++;\n if (indices[d]! < shape[d]!) {\n break;\n }\n indices[d] = 0;\n }\n }\n\n const storage = ArrayStorage.fromData(data, shape, dtype);\n return new NDArray(storage);\n}\n\n/**\n * Return coordinate matrices from coordinate vectors\n * @param arrays - 1D coordinate arrays\n * @param indexing - 'xy' (Cartesian, default) or 'ij' (matrix indexing)\n * @returns Array of coordinate grids\n */\nexport function meshgrid(...args: (NDArray | { indexing?: 'xy' | 'ij' })[]): NDArray[] {\n // Parse arguments - last arg might be options\n let arrays: NDArray[] = [];\n let indexing: 'xy' | 'ij' = 'xy';\n\n for (const arg of args) {\n if (arg instanceof NDArray) {\n arrays.push(arg);\n } else if (typeof arg === 'object' && 'indexing' in arg) {\n indexing = arg.indexing || 'xy';\n }\n }\n\n if (arrays.length === 0) {\n return [];\n }\n\n if (arrays.length === 1) {\n return [arrays[0]!.copy()];\n }\n\n // Get sizes\n const sizes = arrays.map((a) => a.size);\n\n // For 'xy' indexing, swap first two dimensions\n if (indexing === 'xy' && arrays.length >= 2) {\n arrays = [arrays[1]!, arrays[0]!, ...arrays.slice(2)];\n [sizes[0], sizes[1]] = [sizes[1]!, sizes[0]!];\n }\n\n // Output shape is the combination of all input sizes\n const outputShape = sizes;\n const ndim = outputShape.length;\n\n const results: NDArray[] = [];\n\n for (let i = 0; i < arrays.length; i++) {\n const inputArr = arrays[i]!;\n const inputSize = inputArr.size;\n\n // Build the shape for broadcasting this array\n const broadcastShape: number[] = new Array(ndim).fill(1);\n broadcastShape[i] = inputSize;\n\n // Reshape and broadcast\n const reshaped = inputArr.reshape(...broadcastShape);\n const resultStorage = advancedOps.broadcast_to(reshaped.storage, outputShape);\n const result = NDArray._fromStorage(resultStorage.copy()); // copy to make contiguous\n results.push(result);\n }\n\n // For 'xy' indexing, swap back the first two results\n if (indexing === 'xy' && results.length >= 2) {\n [results[0], results[1]] = [results[1]!, results[0]!];\n }\n\n return results;\n}\n\n/**\n * An array with ones at and below the given diagonal and zeros elsewhere\n * @param N - Number of rows\n * @param M - Number of columns (default: N)\n * @param k - Diagonal offset (default 0)\n * @param dtype - Data type (default: float64)\n * @returns Triangular array\n */\nexport function tri(N: number, M?: number, k: number = 0, dtype: DType = DEFAULT_DTYPE): NDArray {\n const cols = M ?? N;\n const result = zeros([N, cols], dtype);\n\n for (let i = 0; i < N; i++) {\n for (let j = 0; j <= i + k && j < cols; j++) {\n if (j >= 0) {\n result.set([i, j], 1);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Lower triangle of an array\n * @param m - Input array\n * @param k - Diagonal above which to zero elements (default 0)\n * @returns Copy with upper triangle zeroed\n */\nexport function tril(m: NDArray, k: number = 0): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must have at least 2 dimensions');\n }\n\n const result = m.copy();\n const shape = result.shape;\n const rows = shape[shape.length - 2]!;\n const cols = shape[shape.length - 1]!;\n\n // Handle multi-dimensional arrays\n const outerSize = shape.slice(0, -2).reduce((a, b) => a * b, 1);\n\n for (let outer = 0; outer < outerSize; outer++) {\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n if (j > i + k) {\n // Build the indices array\n const indices: number[] = [];\n let temp = outer;\n for (let d = shape.length - 3; d >= 0; d--) {\n indices.unshift(temp % shape[d]!);\n temp = Math.floor(temp / shape[d]!);\n }\n indices.push(i, j);\n result.set(indices, 0);\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Upper triangle of an array\n * @param m - Input array\n * @param k - Diagonal below which to zero elements (default 0)\n * @returns Copy with lower triangle zeroed\n */\nexport function triu(m: NDArray, k: number = 0): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must have at least 2 dimensions');\n }\n\n const result = m.copy();\n const shape = result.shape;\n const rows = shape[shape.length - 2]!;\n const cols = shape[shape.length - 1]!;\n\n // Handle multi-dimensional arrays\n const outerSize = shape.slice(0, -2).reduce((a, b) => a * b, 1);\n\n for (let outer = 0; outer < outerSize; outer++) {\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n if (j < i + k) {\n // Build the indices array\n const indices: number[] = [];\n let temp = outer;\n for (let d = shape.length - 3; d >= 0; d--) {\n indices.unshift(temp % shape[d]!);\n temp = Math.floor(temp / shape[d]!);\n }\n indices.push(i, j);\n result.set(indices, 0);\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Generate a Vandermonde matrix\n * @param x - Input 1D array\n * @param N - Number of columns (default: length of x)\n * @param increasing - Order of powers (default: false, highest powers first)\n * @returns Vandermonde matrix\n */\nexport function vander(x: NDArray, N?: number, increasing: boolean = false): NDArray {\n if (x.ndim !== 1) {\n throw new Error('Input must be 1-D');\n }\n\n const len = x.size;\n const cols = N ?? len;\n\n if (cols < 0) {\n throw new Error('N must be non-negative');\n }\n\n const result = zeros([len, cols], x.dtype as DType);\n\n for (let i = 0; i < len; i++) {\n const val = x.get([i]) as number;\n for (let j = 0; j < cols; j++) {\n const power = increasing ? j : cols - 1 - j;\n result.set([i, j], Math.pow(val, power));\n }\n }\n\n return result;\n}\n\n/**\n * Interpret a buffer as a 1-dimensional array\n * @param buffer - Buffer-like object (ArrayBuffer, TypedArray, or DataView)\n * @param dtype - Data type (default: float64)\n * @param count - Number of items to read (-1 means all)\n * @param offset - Start reading from this byte offset\n * @returns NDArray from buffer data\n */\nexport function frombuffer(\n buffer: ArrayBuffer | ArrayBufferView,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1,\n offset: number = 0\n): NDArray {\n let arrayBuffer: ArrayBufferLike;\n let byteOffset = offset;\n\n if (buffer instanceof ArrayBuffer) {\n arrayBuffer = buffer;\n } else {\n // It's a TypedArray or DataView\n arrayBuffer = buffer.buffer;\n byteOffset += buffer.byteOffset;\n }\n\n const bytesPerElement = getBytesPerElement(dtype);\n const availableBytes = arrayBuffer.byteLength - byteOffset;\n const maxElements = Math.floor(availableBytes / bytesPerElement);\n const numElements = count < 0 ? maxElements : Math.min(count, maxElements);\n\n if (numElements <= 0) {\n return array([], dtype);\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new Error(`Unsupported dtype: ${dtype}`);\n }\n\n // Create a view into the buffer\n const data = new Constructor(arrayBuffer as ArrayBuffer, byteOffset, numElements);\n const storage = ArrayStorage.fromData(data as TypedArray, [numElements], dtype);\n return new NDArray(storage);\n}\n\n/**\n * Construct an array by executing a function over each coordinate.\n * Note: This is a JS implementation - fromfile for actual files isn't directly applicable in browser JS.\n * This function creates an array from an iterable or callable.\n * @param file - In JS context, this is an iterable yielding values\n * @param dtype - Data type\n * @param count - Number of items to read (-1 means all)\n * @returns NDArray from the iterable\n */\nexport function fromfile(\n file: Iterable<number | bigint>,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1\n): NDArray {\n // In JavaScript, we interpret this as reading from an iterable\n const values: Array<number | bigint> = [];\n let i = 0;\n\n for (const val of file) {\n if (count >= 0 && i >= count) break;\n values.push(val);\n i++;\n }\n\n return array(values, dtype);\n}\n\n/**\n * Create a new 1-dimensional array from an iterable object\n * @param iter - Iterable object\n * @param dtype - Data type\n * @param count - Number of items to read (-1 means all)\n * @returns NDArray from the iterable\n */\nexport function fromiter(\n iter: Iterable<number | bigint>,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1\n): NDArray {\n const values: Array<number | bigint> = [];\n let i = 0;\n\n for (const val of iter) {\n if (count >= 0 && i >= count) break;\n values.push(val);\n i++;\n }\n\n return array(values, dtype);\n}\n\n/**\n * Create a new 1-dimensional array from text string\n * @param string - Input string containing numbers separated by whitespace or separator\n * @param dtype - Data type (default: float64)\n * @param count - Number of items to read (-1 means all)\n * @param sep - Separator between values (default: any whitespace)\n * @returns NDArray from parsed string\n */\nexport function fromstring(\n string: string,\n dtype: DType = DEFAULT_DTYPE,\n count: number = -1,\n sep: string = ''\n): NDArray {\n // Split the string by separator (or whitespace if sep is empty)\n let parts: string[];\n if (sep === '') {\n parts = string.trim().split(/\\s+/);\n } else {\n parts = string.split(sep);\n }\n\n // Parse values\n const values: Array<number | bigint> = [];\n let i = 0;\n for (const part of parts) {\n if (count >= 0 && i >= count) break;\n const trimmed = part.trim();\n if (trimmed === '') continue;\n\n if (isBigIntDType(dtype)) {\n values.push(BigInt(trimmed));\n } else {\n values.push(parseFloat(trimmed));\n }\n i++;\n }\n\n return array(values, dtype);\n}\n\n/**\n * Helper to get bytes per element for a dtype\n */\nfunction getBytesPerElement(dtype: DType): number {\n switch (dtype) {\n case 'int8':\n case 'uint8':\n case 'bool':\n return 1;\n case 'int16':\n case 'uint16':\n return 2;\n case 'int32':\n case 'uint32':\n case 'float32':\n return 4;\n case 'int64':\n case 'uint64':\n case 'float64':\n return 8;\n default:\n return 8;\n }\n}\n\n// Mathematical functions (standalone)\n\n/**\n * Element-wise square root\n * @param x - Input array\n * @returns Array of square roots\n */\nexport function sqrt(x: NDArray): NDArray {\n return x.sqrt();\n}\n\n/**\n * Element-wise power\n * @param x - Base array\n * @param exponent - Exponent (array or scalar)\n * @returns Array of x raised to exponent\n */\nexport function power(x: NDArray, exponent: NDArray | number): NDArray {\n return x.power(exponent);\n}\n\n/**\n * Element-wise absolute value\n * @param x - Input array\n * @returns Array of absolute values\n */\nexport function absolute(x: NDArray): NDArray {\n return x.absolute();\n}\n\n/**\n * Element-wise negation\n * @param x - Input array\n * @returns Array of negated values\n */\nexport function negative(x: NDArray): NDArray {\n return x.negative();\n}\n\n/**\n * Element-wise sign (-1, 0, or 1)\n * @param x - Input array\n * @returns Array of signs\n */\nexport function sign(x: NDArray): NDArray {\n return x.sign();\n}\n\n/**\n * Element-wise modulo\n * @param x - Dividend array\n * @param divisor - Divisor (array or scalar)\n * @returns Remainder after division\n */\nexport function mod(x: NDArray, divisor: NDArray | number): NDArray {\n return x.mod(divisor);\n}\n\n/**\n * Element-wise floor division\n * @param x - Dividend array\n * @param divisor - Divisor (array or scalar)\n * @returns Floor of the quotient\n */\nexport function floor_divide(x: NDArray, divisor: NDArray | number): NDArray {\n return x.floor_divide(divisor);\n}\n\n/**\n * Element-wise positive (unary +)\n * @param x - Input array\n * @returns Copy of the array\n */\nexport function positive(x: NDArray): NDArray {\n return x.positive();\n}\n\n/**\n * Element-wise reciprocal (1/x)\n * @param x - Input array\n * @returns Array of reciprocals\n */\nexport function reciprocal(x: NDArray): NDArray {\n return x.reciprocal();\n}\n\n/**\n * Dot product of two arrays\n *\n * Fully NumPy-compatible. Behavior depends on input dimensions:\n * - 0D \u00B7 0D: Multiply scalars \u2192 scalar\n * - 0D \u00B7 ND or ND \u00B7 0D: Element-wise multiply \u2192 ND\n * - 1D \u00B7 1D: Inner product \u2192 scalar\n * - 2D \u00B7 2D: Matrix multiplication \u2192 2D\n * - 2D \u00B7 1D: Matrix-vector product \u2192 1D\n * - 1D \u00B7 2D: Vector-matrix product \u2192 1D\n * - ND \u00B7 1D (N>2): Sum over last axis \u2192 (N-1)D\n * - 1D \u00B7 ND (N>2): Sum over first axis \u2192 (N-1)D\n * - ND \u00B7 MD (N,M\u22652): Tensor contraction \u2192 (N+M-2)D\n *\n * @param a - First array\n * @param b - Second array\n * @returns Result of dot product\n */\nexport function dot(a: NDArray, b: NDArray): NDArray | number | bigint {\n return a.dot(b);\n}\n\n/**\n * Sum of diagonal elements\n *\n * @param a - Input 2D array\n * @returns Sum of diagonal elements\n */\nexport function trace(a: NDArray): number | bigint {\n return a.trace();\n}\n\n/**\n * Extract a diagonal from a matrix or N-D array\n *\n * @param a - Input array (must be at least 2D)\n * @param offset - Offset of the diagonal from the main diagonal (default: 0)\n * @param axis1 - First axis (default: 0)\n * @param axis2 - Second axis (default: 1)\n * @returns Array containing the diagonal elements\n */\nexport function diagonal(\n a: NDArray,\n offset: number = 0,\n axis1: number = 0,\n axis2: number = 1\n): NDArray {\n const resultStorage = linalgOps.diagonal(a.storage, offset, axis1, axis2);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Kronecker product of two arrays\n *\n * @param a - First input array\n * @param b - Second input array\n * @returns Kronecker product of a and b\n */\nexport function kron(a: NDArray, b: NDArray): NDArray {\n const resultStorage = linalgOps.kron(a.storage, b.storage);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Permute array dimensions\n *\n * @param a - Input array\n * @param axes - Optional permutation of axes (defaults to reverse order)\n * @returns Transposed view\n */\nexport function transpose(a: NDArray, axes?: number[]): NDArray {\n return a.transpose(axes);\n}\n\n/**\n * Inner product of two arrays\n *\n * Contracts over last axes of both arrays.\n * Result shape: (*a.shape[:-1], *b.shape[:-1])\n *\n * @param a - First array\n * @param b - Second array\n * @returns Inner product result\n */\nexport function inner(a: NDArray, b: NDArray): NDArray | number | bigint {\n return a.inner(b);\n}\n\n/**\n * Outer product of two arrays\n *\n * Flattens inputs then computes result[i,j] = a[i] * b[j]\n *\n * @param a - First array\n * @param b - Second array\n * @returns 2D outer product matrix\n */\nexport function outer(a: NDArray, b: NDArray): NDArray {\n return a.outer(b);\n}\n\n/**\n * Tensor dot product along specified axes\n *\n * @param a - First array\n * @param b - Second array\n * @param axes - Axes to contract (integer or [a_axes, b_axes])\n * @returns Tensor dot product\n */\nexport function tensordot(\n a: NDArray,\n b: NDArray,\n axes: number | [number[], number[]] = 2\n): NDArray | number | bigint {\n return a.tensordot(b, axes);\n}\n\n// Trigonometric functions (standalone)\n\n/**\n * Element-wise sine\n * @param x - Input array (angles in radians)\n * @returns Array of sine values\n */\nexport function sin(x: NDArray): NDArray {\n return x.sin();\n}\n\n/**\n * Element-wise cosine\n * @param x - Input array (angles in radians)\n * @returns Array of cosine values\n */\nexport function cos(x: NDArray): NDArray {\n return x.cos();\n}\n\n/**\n * Element-wise tangent\n * @param x - Input array (angles in radians)\n * @returns Array of tangent values\n */\nexport function tan(x: NDArray): NDArray {\n return x.tan();\n}\n\n/**\n * Element-wise inverse sine\n * @param x - Input array (values in range [-1, 1])\n * @returns Array of angles in radians\n */\nexport function arcsin(x: NDArray): NDArray {\n return x.arcsin();\n}\n\n/**\n * Element-wise inverse cosine\n * @param x - Input array (values in range [-1, 1])\n * @returns Array of angles in radians\n */\nexport function arccos(x: NDArray): NDArray {\n return x.arccos();\n}\n\n/**\n * Element-wise inverse tangent\n * @param x - Input array\n * @returns Array of angles in radians\n */\nexport function arctan(x: NDArray): NDArray {\n return x.arctan();\n}\n\n/**\n * Element-wise arc tangent of x1/x2 choosing the quadrant correctly\n * @param x1 - y-coordinates\n * @param x2 - x-coordinates (array or scalar)\n * @returns Angles in radians between -\u03C0 and \u03C0\n */\nexport function arctan2(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.arctan2(x2);\n}\n\n/**\n * Given the \"legs\" of a right triangle, return its hypotenuse\n * Equivalent to sqrt(x1**2 + x2**2), element-wise\n * @param x1 - First leg\n * @param x2 - Second leg (array or scalar)\n * @returns Hypotenuse values\n */\nexport function hypot(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.hypot(x2);\n}\n\n/**\n * Convert angles from radians to degrees\n * @param x - Input array (angles in radians)\n * @returns Angles in degrees\n */\nexport function degrees(x: NDArray): NDArray {\n return x.degrees();\n}\n\n/**\n * Convert angles from degrees to radians\n * @param x - Input array (angles in degrees)\n * @returns Angles in radians\n */\nexport function radians(x: NDArray): NDArray {\n return x.radians();\n}\n\n/**\n * Convert angles from degrees to radians (alias for radians)\n * @param x - Input array (angles in degrees)\n * @returns Angles in radians\n */\nexport function deg2rad(x: NDArray): NDArray {\n return x.radians();\n}\n\n/**\n * Convert angles from radians to degrees (alias for degrees)\n * @param x - Input array (angles in radians)\n * @returns Angles in degrees\n */\nexport function rad2deg(x: NDArray): NDArray {\n return x.degrees();\n}\n\n// Hyperbolic functions (standalone)\n\n/**\n * Element-wise hyperbolic sine\n * @param x - Input array\n * @returns Array of sinh values\n */\nexport function sinh(x: NDArray): NDArray {\n return x.sinh();\n}\n\n/**\n * Element-wise hyperbolic cosine\n * @param x - Input array\n * @returns Array of cosh values\n */\nexport function cosh(x: NDArray): NDArray {\n return x.cosh();\n}\n\n/**\n * Element-wise hyperbolic tangent\n * @param x - Input array\n * @returns Array of tanh values\n */\nexport function tanh(x: NDArray): NDArray {\n return x.tanh();\n}\n\n/**\n * Element-wise inverse hyperbolic sine\n * @param x - Input array\n * @returns Array of arcsinh values\n */\nexport function arcsinh(x: NDArray): NDArray {\n return x.arcsinh();\n}\n\n/**\n * Element-wise inverse hyperbolic cosine\n * @param x - Input array (values >= 1)\n * @returns Array of arccosh values\n */\nexport function arccosh(x: NDArray): NDArray {\n return x.arccosh();\n}\n\n/**\n * Element-wise inverse hyperbolic tangent\n * @param x - Input array (values in range (-1, 1))\n * @returns Array of arctanh values\n */\nexport function arctanh(x: NDArray): NDArray {\n return x.arctanh();\n}\n\n// ========================================\n// Array Manipulation Functions\n// ========================================\n\n/**\n * Swap two axes of an array\n *\n * @param a - Input array\n * @param axis1 - First axis\n * @param axis2 - Second axis\n * @returns View with axes swapped\n */\nexport function swapaxes(a: NDArray, axis1: number, axis2: number): NDArray {\n return a.swapaxes(axis1, axis2);\n}\n\n/**\n * Move axes to new positions\n *\n * @param a - Input array\n * @param source - Original positions of axes to move\n * @param destination - New positions for axes\n * @returns View with axes moved\n */\nexport function moveaxis(\n a: NDArray,\n source: number | number[],\n destination: number | number[]\n): NDArray {\n return a.moveaxis(source, destination);\n}\n\n/**\n * Concatenate arrays along an existing axis\n *\n * @param arrays - Arrays to concatenate\n * @param axis - Axis along which to concatenate (default: 0)\n * @returns Concatenated array\n */\nexport function concatenate(arrays: NDArray[], axis: number = 0): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to concatenate');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.concatenate(storages, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays along a new axis\n *\n * @param arrays - Arrays to stack (must have same shape)\n * @param axis - Axis in the result array along which to stack (default: 0)\n * @returns Stacked array\n */\nexport function stack(arrays: NDArray[], axis: number = 0): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.stack(storages, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays vertically (row-wise)\n *\n * @param arrays - Arrays to stack\n * @returns Vertically stacked array\n */\nexport function vstack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.vstack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays horizontally (column-wise)\n *\n * @param arrays - Arrays to stack\n * @returns Horizontally stacked array\n */\nexport function hstack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.hstack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays depth-wise (along third axis)\n *\n * @param arrays - Arrays to stack\n * @returns Depth-stacked array\n */\nexport function dstack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.dstack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Split array into multiple sub-arrays\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of equal sections or indices where to split\n * @param axis - Axis along which to split (default: 0)\n * @returns List of sub-arrays\n */\nexport function split(\n a: NDArray,\n indicesOrSections: number | number[],\n axis: number = 0\n): NDArray[] {\n const storages = shapeOps.split(a.storage, indicesOrSections, axis);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Split array into multiple sub-arrays (allows unequal splits)\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of sections or indices where to split\n * @param axis - Axis along which to split (default: 0)\n * @returns List of sub-arrays\n */\nexport function array_split(\n a: NDArray,\n indicesOrSections: number | number[],\n axis: number = 0\n): NDArray[] {\n const storages = shapeOps.arraySplit(a.storage, indicesOrSections, axis);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Split array vertically (row-wise)\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of sections or indices where to split\n * @returns List of sub-arrays\n */\nexport function vsplit(a: NDArray, indicesOrSections: number | number[]): NDArray[] {\n const storages = shapeOps.vsplit(a.storage, indicesOrSections);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Split array horizontally (column-wise)\n *\n * @param a - Array to split\n * @param indicesOrSections - Number of sections or indices where to split\n * @returns List of sub-arrays\n */\nexport function hsplit(a: NDArray, indicesOrSections: number | number[]): NDArray[] {\n const storages = shapeOps.hsplit(a.storage, indicesOrSections);\n return storages.map((s) => NDArray._fromStorage(s, a.base ?? a));\n}\n\n/**\n * Tile array by repeating along each axis\n *\n * @param a - Input array\n * @param reps - Number of repetitions along each axis\n * @returns Tiled array\n */\nexport function tile(a: NDArray, reps: number | number[]): NDArray {\n const resultStorage = shapeOps.tile(a.storage, reps);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Repeat elements of an array\n *\n * @param a - Input array\n * @param repeats - Number of repetitions for each element\n * @param axis - Axis along which to repeat (if undefined, flattens first)\n * @returns Array with repeated elements\n */\nexport function repeat(a: NDArray, repeats: number | number[], axis?: number): NDArray {\n return a.repeat(repeats, axis);\n}\n\n/**\n * Return a contiguous flattened array\n *\n * @param a - Input array\n * @returns Flattened 1-D array (view if possible)\n */\nexport function ravel(a: NDArray): NDArray {\n return a.ravel();\n}\n\n/**\n * Reshape array to new shape\n *\n * @param a - Input array\n * @param newShape - New shape\n * @returns Reshaped array (view if possible)\n */\nexport function reshape(a: NDArray, newShape: number[]): NDArray {\n return a.reshape(...newShape);\n}\n\n/**\n * Remove axes of length 1\n *\n * @param a - Input array\n * @param axis - Axis to squeeze (optional, squeezes all if not specified)\n * @returns Squeezed array (view)\n */\nexport function squeeze(a: NDArray, axis?: number): NDArray {\n return a.squeeze(axis);\n}\n\n/**\n * Expand the shape of an array by inserting a new axis\n *\n * @param a - Input array\n * @param axis - Position where new axis should be inserted\n * @returns Array with expanded shape (view)\n */\nexport function expand_dims(a: NDArray, axis: number): NDArray {\n return a.expand_dims(axis);\n}\n\n/**\n * Reverse the order of elements along the given axis\n *\n * @param m - Input array\n * @param axis - Axis or axes to flip (flips all if undefined)\n * @returns Flipped array\n */\nexport function flip(m: NDArray, axis?: number | number[]): NDArray {\n const resultStorage = shapeOps.flip(m.storage, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Flip array in the left/right direction (reverse along axis 1)\n *\n * @param m - Input array (must be at least 2-D)\n * @returns Flipped array\n */\nexport function fliplr(m: NDArray): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must be at least 2-D');\n }\n return flip(m, 1);\n}\n\n/**\n * Flip array in the up/down direction (reverse along axis 0)\n *\n * @param m - Input array (must be at least 2-D)\n * @returns Flipped array\n */\nexport function flipud(m: NDArray): NDArray {\n if (m.ndim < 2) {\n throw new Error('Input must be at least 2-D');\n }\n return flip(m, 0);\n}\n\n/**\n * Rotate array by 90 degrees\n *\n * @param m - Input array\n * @param k - Number of times to rotate (default 1)\n * @param axes - The axes to rotate in (default [0, 1])\n * @returns Rotated array\n */\nexport function rot90(m: NDArray, k: number = 1, axes: [number, number] = [0, 1]): NDArray {\n const resultStorage = shapeOps.rot90(m.storage, k, axes);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Roll array elements along a given axis\n *\n * @param a - Input array\n * @param shift - Number of positions to shift\n * @param axis - Axis along which to roll (rolls flattened array if undefined)\n * @returns Rolled array\n */\nexport function roll(a: NDArray, shift: number | number[], axis?: number | number[]): NDArray {\n const resultStorage = shapeOps.roll(a.storage, shift, axis);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Roll the specified axis backwards until it lies in a given position\n *\n * @param a - Input array\n * @param axis - The axis to roll backwards\n * @param start - Position to roll to (default 0)\n * @returns Array with rolled axis (view)\n */\nexport function rollaxis(a: NDArray, axis: number, start: number = 0): NDArray {\n const resultStorage = shapeOps.rollaxis(a.storage, axis, start);\n return NDArray._fromStorage(resultStorage, a.base ?? a);\n}\n\n/**\n * Convert inputs to arrays with at least 1 dimension\n *\n * @param arrays - Input arrays\n * @returns Arrays with at least 1 dimension\n */\nexport function atleast_1d(...arrays: NDArray[]): NDArray | NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = shapeOps.atleast1d(storages);\n const results = resultStorages.map((s, i) => {\n if (s === storages[i]) {\n return arrays[i]!;\n }\n return NDArray._fromStorage(s);\n });\n return results.length === 1 ? results[0]! : results;\n}\n\n/**\n * Convert inputs to arrays with at least 2 dimensions\n *\n * @param arrays - Input arrays\n * @returns Arrays with at least 2 dimensions\n */\nexport function atleast_2d(...arrays: NDArray[]): NDArray | NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = shapeOps.atleast2d(storages);\n const results = resultStorages.map((s, i) => {\n if (s === storages[i]) {\n return arrays[i]!;\n }\n return NDArray._fromStorage(s);\n });\n return results.length === 1 ? results[0]! : results;\n}\n\n/**\n * Convert inputs to arrays with at least 3 dimensions\n *\n * @param arrays - Input arrays\n * @returns Arrays with at least 3 dimensions\n */\nexport function atleast_3d(...arrays: NDArray[]): NDArray | NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = shapeOps.atleast3d(storages);\n const results = resultStorages.map((s, i) => {\n if (s === storages[i]) {\n return arrays[i]!;\n }\n return NDArray._fromStorage(s);\n });\n return results.length === 1 ? results[0]! : results;\n}\n\n/**\n * Split array along third axis (depth)\n *\n * @param ary - Input array (must be at least 3-D)\n * @param indices_or_sections - Number of sections or indices where to split\n * @returns List of sub-arrays\n */\nexport function dsplit(ary: NDArray, indices_or_sections: number | number[]): NDArray[] {\n const storages = shapeOps.dsplit(ary.storage, indices_or_sections);\n return storages.map((s) => NDArray._fromStorage(s, ary.base ?? ary));\n}\n\n/**\n * Stack 1-D arrays as columns into a 2-D array\n *\n * @param arrays - 1-D arrays to stack\n * @returns 2-D array with inputs as columns\n */\nexport function column_stack(arrays: NDArray[]): NDArray {\n if (arrays.length === 0) {\n throw new Error('need at least one array to stack');\n }\n const storages = arrays.map((a) => a.storage);\n const resultStorage = shapeOps.columnStack(storages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Stack arrays in sequence vertically (alias for vstack)\n *\n * @param arrays - Arrays to stack\n * @returns Vertically stacked array\n */\nexport function row_stack(arrays: NDArray[]): NDArray {\n return vstack(arrays);\n}\n\n/**\n * Return a new array with the given shape (repeating data if needed)\n *\n * @param a - Input array\n * @param new_shape - New shape\n * @returns Resized array\n */\nexport function resize(a: NDArray, new_shape: number[]): NDArray {\n const resultStorage = shapeOps.resize(a.storage, new_shape);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Append values to the end of an array\n *\n * @param arr - Input array\n * @param values - Values to append\n * @param axis - Axis along which to append (flattens if undefined)\n * @returns Array with values appended\n */\nexport function append(\n arr: NDArray,\n values: NDArray | ArrayLike<number | bigint> | number,\n axis?: number\n): NDArray {\n // Convert values to NDArray if needed\n const valArray =\n values instanceof NDArray\n ? values\n : array(values as ArrayLike<number | bigint> | number, arr.dtype as DType);\n\n if (axis === undefined) {\n // Flatten both and concatenate\n const flatArr = arr.flatten();\n const flatValues = valArray.flatten();\n return concatenate([flatArr, flatValues]);\n }\n\n // Concatenate along specified axis\n return concatenate([arr, valArray], axis);\n}\n\n/**\n * Return a new array with sub-arrays along an axis deleted\n *\n * @param arr - Input array\n * @param obj - Indices to delete\n * @param axis - Axis along which to delete (flattens if undefined)\n * @returns Array with elements deleted\n */\n\nexport function delete_(arr: NDArray, obj: number | number[], axis?: number): NDArray {\n const dtype = arr.dtype as DType;\n\n if (axis === undefined) {\n // Delete from flattened array\n const flat = arr.flatten();\n const indices = Array.isArray(obj) ? obj : [obj];\n const normalizedIndices = indices.map((i) => (i < 0 ? flat.size + i : i));\n const keepIndices: number[] = [];\n\n for (let i = 0; i < flat.size; i++) {\n if (!normalizedIndices.includes(i)) {\n keepIndices.push(i);\n }\n }\n\n const Constructor = getTypedArrayConstructor(dtype);\n const data = new Constructor!(keepIndices.length);\n\n for (let i = 0; i < keepIndices.length; i++) {\n const val = flat.get([keepIndices[i]!]);\n if (isBigIntDType(dtype)) {\n (data as BigInt64Array | BigUint64Array)[i] =\n typeof val === 'bigint' ? val : BigInt(val as number);\n } else {\n (data as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = val as number;\n }\n }\n\n const storage = ArrayStorage.fromData(data, [keepIndices.length], dtype);\n return new NDArray(storage);\n }\n\n // Delete along specified axis\n const shape = arr.shape;\n const ndim = shape.length;\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const indices = Array.isArray(obj) ? obj : [obj];\n const normalizedIndices = new Set(indices.map((i) => (i < 0 ? axisSize + i : i)));\n\n // Build slices to keep\n const keepRanges: [number, number][] = [];\n let start = 0;\n\n for (let i = 0; i <= axisSize; i++) {\n if (normalizedIndices.has(i) || i === axisSize) {\n if (i > start) {\n keepRanges.push([start, i]);\n }\n start = i + 1;\n }\n }\n\n if (keepRanges.length === 0) {\n // Delete all elements along this axis\n const newShape = [...shape];\n newShape[normalizedAxis] = 0;\n return zeros(newShape, dtype);\n }\n\n // Split and concatenate the kept parts\n const parts: NDArray[] = [];\n for (const [rangeStart, rangeEnd] of keepRanges) {\n // Create a slice for this range\n const slices: string[] = shape.map(() => ':');\n slices[normalizedAxis] = `${rangeStart}:${rangeEnd}`;\n parts.push(arr.slice(...slices));\n }\n\n return concatenate(parts, normalizedAxis);\n}\n\n/**\n * Insert values along the given axis before the given indices\n *\n * @param arr - Input array\n * @param obj - Index before which to insert\n * @param values - Values to insert\n * @param axis - Axis along which to insert (flattens if undefined)\n * @returns Array with values inserted\n */\nexport function insert(\n arr: NDArray,\n obj: number,\n values: NDArray | ArrayLike<number | bigint> | number,\n axis?: number\n): NDArray {\n // Convert values to NDArray if needed\n const valArray =\n values instanceof NDArray\n ? values\n : array(values as ArrayLike<number | bigint> | number, arr.dtype as DType);\n\n if (axis === undefined) {\n // Insert into flattened array\n const flat = arr.flatten();\n const flatValues = valArray.flatten();\n const idx = obj < 0 ? flat.size + obj : obj;\n\n if (idx < 0 || idx > flat.size) {\n throw new Error(`index ${obj} is out of bounds for array of size ${flat.size}`);\n }\n\n const before = idx > 0 ? flat.slice(`0:${idx}`) : null;\n const after = idx < flat.size ? flat.slice(`${idx}:`) : null;\n\n const parts: NDArray[] = [];\n if (before) parts.push(before);\n parts.push(flatValues);\n if (after) parts.push(after);\n\n return concatenate(parts);\n }\n\n // Insert along specified axis\n const shape = arr.shape;\n const ndim = shape.length;\n const normalizedAxis = axis < 0 ? ndim + axis : axis;\n\n if (normalizedAxis < 0 || normalizedAxis >= ndim) {\n throw new Error(`axis ${axis} is out of bounds for array of dimension ${ndim}`);\n }\n\n const axisSize = shape[normalizedAxis]!;\n const idx = obj < 0 ? axisSize + obj : obj;\n\n if (idx < 0 || idx > axisSize) {\n throw new Error(`index ${obj} is out of bounds for axis ${axis} with size ${axisSize}`);\n }\n\n const parts: NDArray[] = [];\n\n if (idx > 0) {\n const slices: string[] = shape.map(() => ':');\n slices[normalizedAxis] = `0:${idx}`;\n parts.push(arr.slice(...slices));\n }\n\n parts.push(valArray);\n\n if (idx < axisSize) {\n const slices: string[] = shape.map(() => ':');\n slices[normalizedAxis] = `${idx}:`;\n parts.push(arr.slice(...slices));\n }\n\n return concatenate(parts, normalizedAxis);\n}\n\n/**\n * Pad an array\n *\n * @param array - Input array\n * @param pad_width - Number of values padded to edges of each axis\n * @param mode - Padding mode ('constant', 'edge', 'reflect', 'symmetric', 'wrap')\n * @param constant_values - Value for constant padding (default 0)\n * @returns Padded array\n */\nexport function pad(\n arr: NDArray,\n pad_width: number | [number, number] | Array<[number, number]>,\n mode: 'constant' | 'edge' | 'reflect' | 'symmetric' | 'wrap' = 'constant',\n constant_values: number = 0\n): NDArray {\n const shape = arr.shape;\n const ndim = shape.length;\n const dtype = arr.dtype as DType;\n\n // Normalize pad_width to [[before, after], ...] for each axis\n let padWidths: Array<[number, number]>;\n if (typeof pad_width === 'number') {\n padWidths = shape.map(() => [pad_width, pad_width] as [number, number]);\n } else if (Array.isArray(pad_width) && typeof pad_width[0] === 'number') {\n // Single [before, after] pair for all axes\n padWidths = shape.map(() => pad_width as [number, number]);\n } else {\n padWidths = pad_width as Array<[number, number]>;\n }\n\n if (padWidths.length !== ndim) {\n throw new Error(`pad_width must have ${ndim} elements`);\n }\n\n // Calculate new shape\n const newShape = shape.map((s, i) => s + padWidths[i]![0] + padWidths[i]![1]);\n const newSize = newShape.reduce((a, b) => a * b, 1);\n\n const Constructor = getTypedArrayConstructor(dtype);\n const outputData = new Constructor!(newSize);\n const isBigInt = isBigIntDType(dtype);\n\n // Initialize with constant value for constant mode\n if (mode === 'constant') {\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array).fill(BigInt(constant_values));\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>).fill(constant_values);\n }\n }\n\n // Copy original data to center\n const outputIndices = new Array(ndim).fill(0);\n\n for (let i = 0; i < newSize; i++) {\n // Check if this position is in the original data region\n let inOriginal = true;\n const sourceIndices: number[] = [];\n\n for (let d = 0; d < ndim; d++) {\n const [padBefore] = padWidths[d]!;\n const srcIdx = outputIndices[d]! - padBefore;\n if (srcIdx < 0 || srcIdx >= shape[d]!) {\n inOriginal = false;\n break;\n }\n sourceIndices.push(srcIdx);\n }\n\n let value: number | bigint;\n\n if (inOriginal) {\n // Get from original array\n value = arr.get(sourceIndices) as number | bigint;\n } else if (mode === 'constant') {\n // Already filled with constant\n // Increment indices and continue\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < newShape[d]!) break;\n outputIndices[d] = 0;\n }\n continue;\n } else {\n // Calculate source index based on mode\n const mappedIndices: number[] = [];\n for (let d = 0; d < ndim; d++) {\n const [padBefore] = padWidths[d]!;\n let srcIdx = outputIndices[d]! - padBefore;\n const axisSize = shape[d]!;\n\n if (srcIdx < 0) {\n if (mode === 'edge') {\n srcIdx = 0;\n } else if (mode === 'reflect') {\n srcIdx = -srcIdx;\n if (srcIdx >= axisSize) srcIdx = axisSize - 1;\n } else if (mode === 'symmetric') {\n srcIdx = -srcIdx - 1;\n if (srcIdx >= axisSize) srcIdx = axisSize - 1;\n if (srcIdx < 0) srcIdx = 0;\n } else if (mode === 'wrap') {\n srcIdx = ((srcIdx % axisSize) + axisSize) % axisSize;\n }\n } else if (srcIdx >= axisSize) {\n if (mode === 'edge') {\n srcIdx = axisSize - 1;\n } else if (mode === 'reflect') {\n srcIdx = 2 * axisSize - srcIdx - 2;\n if (srcIdx < 0) srcIdx = 0;\n } else if (mode === 'symmetric') {\n srcIdx = 2 * axisSize - srcIdx - 1;\n if (srcIdx < 0) srcIdx = 0;\n } else if (mode === 'wrap') {\n srcIdx = srcIdx % axisSize;\n }\n }\n\n mappedIndices.push(Math.max(0, Math.min(axisSize - 1, srcIdx)));\n }\n value = arr.get(mappedIndices) as number | bigint;\n }\n\n // Write to output\n if (isBigInt) {\n (outputData as BigInt64Array | BigUint64Array)[i] =\n typeof value === 'bigint' ? value : BigInt(Number(value));\n } else {\n (outputData as Exclude<TypedArray, BigInt64Array | BigUint64Array>)[i] = Number(value);\n }\n\n // Increment indices\n for (let d = ndim - 1; d >= 0; d--) {\n outputIndices[d]++;\n if (outputIndices[d]! < newShape[d]!) break;\n outputIndices[d] = 0;\n }\n }\n\n const storage = ArrayStorage.fromData(outputData, newShape, dtype);\n return new NDArray(storage);\n}\n\n// ========================================\n// Advanced Functions\n// ========================================\n\n/**\n * Broadcast an array to a given shape\n *\n * @param a - Input array\n * @param shape - Target shape\n * @returns View broadcast to target shape\n */\nexport function broadcast_to(a: NDArray, shape: number[]): NDArray {\n const resultStorage = advancedOps.broadcast_to(a.storage, shape);\n return NDArray._fromStorage(resultStorage, a.base ?? a);\n}\n\n/**\n * Broadcast arrays to a common shape\n *\n * @param arrays - Arrays to broadcast\n * @returns Arrays broadcast to common shape\n */\nexport function broadcast_arrays(...arrays: NDArray[]): NDArray[] {\n const storages = arrays.map((a) => a.storage);\n const resultStorages = advancedOps.broadcast_arrays(storages);\n return resultStorages.map((s, i) => NDArray._fromStorage(s, arrays[i]!.base ?? arrays[i]!));\n}\n\n/**\n * Compute the broadcast shape for multiple shapes\n *\n * Returns the resulting shape if all shapes are broadcast-compatible.\n * Throws an error if shapes are not broadcast-compatible.\n *\n * @param shapes - Variable number of shapes to broadcast\n * @returns The broadcast output shape\n * @throws Error if shapes are not broadcast-compatible\n */\nexport function broadcast_shapes(...shapes: number[][]): number[] {\n return advancedOps.broadcast_shapes(...shapes);\n}\n\n/**\n * Take elements from an array along an axis\n *\n * @param a - Input array\n * @param indices - Indices of elements to take\n * @param axis - Axis along which to take (if undefined, flattens first)\n * @returns Array with selected elements\n */\nexport function take(a: NDArray, indices: number[], axis?: number): NDArray {\n return a.take(indices, axis);\n}\n\n/**\n * Put values at specified indices (modifies array in-place)\n *\n * @param a - Target array\n * @param indices - Indices at which to place values\n * @param values - Values to put\n */\nexport function put(a: NDArray, indices: number[], values: NDArray | number | bigint): void {\n a.put(indices, values);\n}\n\n/**\n * Construct array from index array and choices\n *\n * @param a - Index array (integer indices into choices)\n * @param choices - Arrays to choose from\n * @returns Array constructed from choices\n */\nexport function choose(a: NDArray, choices: NDArray[]): NDArray {\n const choiceStorages = choices.map((c) => c.storage);\n const resultStorage = advancedOps.choose(a.storage, choiceStorages);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Check if two arrays are element-wise equal\n *\n * @param a - First array\n * @param b - Second array\n * @param equal_nan - Whether to consider NaN equal to NaN (default: false)\n * @returns True if arrays are equal element-wise\n */\nexport function array_equal(a: NDArray, b: NDArray, equal_nan: boolean = false): boolean {\n return advancedOps.array_equal(a.storage, b.storage, equal_nan);\n}\n\n/**\n * Returns True if two arrays are element-wise equal within a tolerance.\n * Unlike array_equal, this function broadcasts the arrays before comparison.\n *\n * @param a1 - First input array\n * @param a2 - Second input array\n * @returns True if arrays are equivalent (after broadcasting)\n */\nexport function array_equiv(a1: NDArray, a2: NDArray): boolean {\n return comparisonOps.arrayEquiv(a1.storage, a2.storage);\n}\n\n// ============================================================================\n// Top-level Reduction Functions\n// ============================================================================\n\n/**\n * Return the cumulative sum of the elements along a given axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, flattened array is used.\n * @returns Array with cumulative sums\n */\nexport function cumsum(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumsum(a.storage, axis));\n}\n\n/**\n * Return the cumulative product of the elements along a given axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, flattened array is used.\n * @returns Array with cumulative products\n */\nexport function cumprod(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.cumprod(a.storage, axis));\n}\n\n/**\n * Peak to peak (maximum - minimum) value along a given axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Peak to peak value(s)\n */\nexport function ptp(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.ptp(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the median along the specified axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median value(s)\n */\nexport function median(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.median(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the q-th percentile of the data along the specified axis.\n * @param a - Input array\n * @param q - Percentile (0-100)\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Percentile value(s)\n */\nexport function percentile(\n a: NDArray,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.percentile(a.storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the q-th quantile of the data along the specified axis.\n * @param a - Input array\n * @param q - Quantile (0-1)\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Quantile value(s)\n */\nexport function quantile(\n a: NDArray,\n q: number,\n axis?: number,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.quantile(a.storage, q, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the weighted average along the specified axis.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param weights - Array of weights (must be same shape as array along specified axis)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Weighted average value(s)\n */\nexport function average(\n a: NDArray,\n axis?: number,\n weights?: NDArray,\n keepdims: boolean = false\n): NDArray | number {\n const weightsStorage = weights ? weights.storage : undefined;\n const result = reductionOps.average(a.storage, axis, weightsStorage, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n// ============================================================================\n// NaN-aware Reduction Functions\n// ============================================================================\n\n/**\n * Return the sum of array elements over a given axis, treating NaNs as zero.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Sum value(s)\n */\nexport function nansum(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nansum(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return the product of array elements over a given axis, treating NaNs as one.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Product value(s)\n */\nexport function nanprod(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanprod(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the arithmetic mean along the specified axis, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Mean value(s)\n */\nexport function nanmean(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmean(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the variance along the specified axis, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param ddof - Delta degrees of freedom (default 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Variance value(s)\n */\nexport function nanvar(\n a: NDArray,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.nanvar(a.storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Compute the standard deviation along the specified axis, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param ddof - Delta degrees of freedom (default 0)\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Standard deviation value(s)\n */\nexport function nanstd(\n a: NDArray,\n axis?: number,\n ddof: number = 0,\n keepdims: boolean = false\n): NDArray | number {\n const result = reductionOps.nanstd(a.storage, axis, ddof, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return minimum of an array, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Minimum value(s)\n */\nexport function nanmin(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmin(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return maximum of an array, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Maximum value(s)\n */\nexport function nanmax(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmax(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return indices of the minimum value, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Index/indices of minimum value(s)\n */\nexport function nanargmin(a: NDArray, axis?: number): NDArray | number {\n const result = reductionOps.nanargmin(a.storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return indices of the maximum value, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Index/indices of maximum value(s)\n */\nexport function nanargmax(a: NDArray, axis?: number): NDArray | number {\n const result = reductionOps.nanargmax(a.storage, axis);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n/**\n * Return cumulative sum of elements, treating NaNs as zero.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Array with cumulative sums\n */\nexport function nancumsum(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumsum(a.storage, axis));\n}\n\n/**\n * Return cumulative product of elements, treating NaNs as one.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use flattened array.\n * @returns Array with cumulative products\n */\nexport function nancumprod(a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(reductionOps.nancumprod(a.storage, axis));\n}\n\n/**\n * Compute the median, ignoring NaNs.\n * @param a - Input array\n * @param axis - Axis along which to compute. If undefined, use all elements.\n * @param keepdims - If true, reduced axes are left as dimensions with size 1\n * @returns Median value(s)\n */\nexport function nanmedian(a: NDArray, axis?: number, keepdims: boolean = false): NDArray | number {\n const result = reductionOps.nanmedian(a.storage, axis, keepdims);\n return typeof result === 'number' ? result : NDArray._fromStorage(result);\n}\n\n// ========================================\n// Arithmetic Functions (Additional)\n// ========================================\n\n/**\n * Element-wise cube root\n *\n * @param x - Input array\n * @returns Array with cube root of each element\n */\nexport function cbrt(x: NDArray): NDArray {\n return x.cbrt();\n}\n\n/**\n * Element-wise absolute value (always returns float)\n *\n * @param x - Input array\n * @returns Array with absolute values as float\n */\nexport function fabs(x: NDArray): NDArray {\n return x.fabs();\n}\n\n/**\n * Returns both quotient and remainder (floor divide and modulo)\n *\n * @param x - Dividend array\n * @param y - Divisor (array or scalar)\n * @returns Tuple of [quotient, remainder] arrays\n */\nexport function divmod(x: NDArray, y: NDArray | number): [NDArray, NDArray] {\n return x.divmod(y);\n}\n\n/**\n * Element-wise square (x**2)\n *\n * @param x - Input array\n * @returns Array with squared values\n */\nexport function square(x: NDArray): NDArray {\n return x.square();\n}\n\n/**\n * Element-wise remainder (same as mod)\n *\n * @param x - Dividend array\n * @param y - Divisor (array or scalar)\n * @returns Array with remainder values\n */\nexport function remainder(x: NDArray, y: NDArray | number): NDArray {\n return x.remainder(y);\n}\n\n/**\n * Heaviside step function\n *\n * @param x1 - Input array\n * @param x2 - Value to use when x1 is 0\n * @returns Array with heaviside values (0 if x1 < 0, x2 if x1 == 0, 1 if x1 > 0)\n */\nexport function heaviside(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.heaviside(x2);\n}\n\n// ========================================\n// Bitwise Functions\n// ========================================\n\n/**\n * Bitwise AND element-wise\n *\n * @param x1 - First input array (must be integer type)\n * @param x2 - Second input array or scalar (must be integer type)\n * @returns Result of bitwise AND\n */\nexport function bitwise_and(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.bitwise_and(x2);\n}\n\n/**\n * Bitwise OR element-wise\n *\n * @param x1 - First input array (must be integer type)\n * @param x2 - Second input array or scalar (must be integer type)\n * @returns Result of bitwise OR\n */\nexport function bitwise_or(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.bitwise_or(x2);\n}\n\n/**\n * Bitwise XOR element-wise\n *\n * @param x1 - First input array (must be integer type)\n * @param x2 - Second input array or scalar (must be integer type)\n * @returns Result of bitwise XOR\n */\nexport function bitwise_xor(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.bitwise_xor(x2);\n}\n\n/**\n * Bitwise NOT (inversion) element-wise\n *\n * @param x - Input array (must be integer type)\n * @returns Result of bitwise NOT\n */\nexport function bitwise_not(x: NDArray): NDArray {\n return x.bitwise_not();\n}\n\n/**\n * Invert (bitwise NOT) element-wise\n * Alias for bitwise_not\n *\n * @param x - Input array (must be integer type)\n * @returns Result of bitwise inversion\n */\nexport function invert(x: NDArray): NDArray {\n return x.invert();\n}\n\n/**\n * Left shift elements by positions\n *\n * @param x1 - Input array (must be integer type)\n * @param x2 - Shift amount (array or scalar)\n * @returns Result of left shift\n */\nexport function left_shift(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.left_shift(x2);\n}\n\n/**\n * Right shift elements by positions\n *\n * @param x1 - Input array (must be integer type)\n * @param x2 - Shift amount (array or scalar)\n * @returns Result of right shift\n */\nexport function right_shift(x1: NDArray, x2: NDArray | number): NDArray {\n return x1.right_shift(x2);\n}\n\n/**\n * Pack binary values into uint8 array\n *\n * Packs the elements of a binary-valued array into bits in a uint8 array.\n *\n * @param a - Input array (values are interpreted as binary: 0 or non-zero)\n * @param axis - The dimension over which bit-packing is done (default: -1)\n * @param bitorder - Order of bits: 'big' or 'little' (default: 'big')\n * @returns Packed uint8 array\n */\nexport function packbits(\n a: NDArray,\n axis: number = -1,\n bitorder: 'big' | 'little' = 'big'\n): NDArray {\n const resultStorage = bitwiseOps.packbits(a.storage, axis, bitorder);\n return NDArray._fromStorage(resultStorage);\n}\n\n/**\n * Unpack uint8 array into binary values\n *\n * Unpacks elements of a uint8 array into a binary-valued output array.\n *\n * @param a - Input uint8 array\n * @param axis - The dimension over which bit-unpacking is done (default: -1)\n * @param count - Number of elements to unpack, or -1 for all (default: -1)\n * @param bitorder - Order of bits: 'big' or 'little' (default: 'big')\n * @returns Unpacked uint8 array of 0s and 1s\n */\nexport function unpackbits(\n a: NDArray,\n axis: number = -1,\n count: number = -1,\n bitorder: 'big' | 'little' = 'big'\n): NDArray {\n const resultStorage = bitwiseOps.unpackbits(a.storage, axis, count, bitorder);\n return NDArray._fromStorage(resultStorage);\n}\n\n// ========================================\n// Linear Algebra Functions (Additional)\n// ========================================\n\n/**\n * Einstein summation convention\n *\n * Performs tensor contractions and reductions using Einstein notation.\n *\n * @param subscripts - Einstein summation subscripts (e.g., 'ij,jk->ik')\n * @param operands - Input arrays\n * @returns Result of the Einstein summation\n *\n * @example\n * // Matrix multiplication\n * einsum('ij,jk->ik', a, b)\n *\n * @example\n * // Inner product\n * einsum('i,i->', a, b)\n *\n * @example\n * // Trace\n * einsum('ii->', a)\n */\nexport function einsum(subscripts: string, ...operands: NDArray[]): NDArray | number | bigint {\n const storages = operands.map((op) => op.storage);\n const result = linalgOps.einsum(subscripts, ...storages);\n if (typeof result === 'number' || typeof result === 'bigint') {\n return result;\n }\n return NDArray._fromStorage(result);\n}\n\n// ============================================================================\n// Indexing Functions\n// ============================================================================\n\n/**\n * Take values from the input array by matching 1d index and data slices along axis.\n *\n * @param arr - Input array\n * @param indices - Index array with same ndim as arr\n * @param axis - The axis along which to select values\n * @returns Array of values taken along the axis\n */\nexport function take_along_axis(arr: NDArray, indices: NDArray, axis: number): NDArray {\n return NDArray._fromStorage(advancedOps.take_along_axis(arr.storage, indices.storage, axis));\n}\n\n/**\n * Put values into the destination array using 1d index and data slices along axis.\n *\n * @param arr - Destination array (modified in-place)\n * @param indices - Index array with same ndim as arr\n * @param values - Values to put\n * @param axis - The axis along which to put values\n */\nexport function put_along_axis(\n arr: NDArray,\n indices: NDArray,\n values: NDArray,\n axis: number\n): void {\n advancedOps.put_along_axis(arr.storage, indices.storage, values.storage, axis);\n}\n\n/**\n * Change elements of array based on conditional mask.\n *\n * @param a - Array to modify (in-place)\n * @param mask - Boolean mask array\n * @param values - Values to put where mask is True\n */\nexport function putmask(a: NDArray, mask: NDArray, values: NDArray | number | bigint): void {\n const valuesArg = values instanceof NDArray ? values.storage : values;\n advancedOps.putmask(a.storage, mask.storage, valuesArg);\n}\n\n/**\n * Return selected slices of array along given axis.\n *\n * @param condition - Boolean array for selecting\n * @param a - Array from which to select\n * @param axis - Axis along which to select (if undefined, works on flattened array)\n * @returns Compressed array\n */\nexport function compress(condition: NDArray, a: NDArray, axis?: number): NDArray {\n return NDArray._fromStorage(advancedOps.compress(condition.storage, a.storage, axis));\n}\n\n/**\n * Return an array drawn from elements in choicelist, depending on conditions.\n *\n * @param condlist - List of boolean arrays (conditions)\n * @param choicelist - List of arrays to choose from\n * @param defaultVal - Default value when no condition is met (default 0)\n * @returns Array with selected values\n */\nexport function select(\n condlist: NDArray[],\n choicelist: NDArray[],\n defaultVal: number | bigint = 0\n): NDArray {\n const condStorages = condlist.map((c) => c.storage);\n const choiceStorages = choicelist.map((c) => c.storage);\n return NDArray._fromStorage(advancedOps.select(condStorages, choiceStorages, defaultVal));\n}\n\n/**\n * Change elements of an array based on conditional and input values.\n *\n * @param arr - Array to modify (in-place)\n * @param mask - Boolean mask array\n * @param vals - Values to place where mask is True (cycles if shorter)\n */\nexport function place(arr: NDArray, mask: NDArray, vals: NDArray): void {\n advancedOps.place(arr.storage, mask.storage, vals.storage);\n}\n\n/**\n * Return the indices to access the main diagonal of an array.\n *\n * @param n - Size of arrays for which indices are returned\n * @param ndim - Number of dimensions (default 2)\n * @returns Tuple of index arrays\n */\nexport function diag_indices(n: number, ndim: number = 2): NDArray[] {\n const storages = advancedOps.diag_indices(n, ndim);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return the indices to access the main diagonal of an n-dimensional array.\n *\n * @param arr - Input array (must have all equal dimensions)\n * @returns Tuple of index arrays\n */\nexport function diag_indices_from(arr: NDArray): NDArray[] {\n const storages = advancedOps.diag_indices_from(arr.storage);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return the indices for the lower-triangle of an (n, m) array.\n *\n * @param n - Number of rows\n * @param k - Diagonal offset (0 = main, positive = above, negative = below)\n * @param m - Number of columns (default n)\n * @returns Tuple of row and column index arrays\n */\nexport function tril_indices(n: number, k: number = 0, m?: number): NDArray[] {\n const storages = advancedOps.tril_indices(n, k, m);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return the indices for the lower-triangle of arr.\n *\n * @param arr - Input 2-D array\n * @param k - Diagonal offset (0 = main, positive = above, negative = below)\n * @returns Tuple of row and column index arrays\n */\nexport function tril_indices_from(arr: NDArray, k: number = 0): NDArray[] {\n const storages = advancedOps.tril_indices_from(arr.storage, k);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return the indices for the upper-triangle of an (n, m) array.\n *\n * @param n - Number of rows\n * @param k - Diagonal offset (0 = main, positive = above, negative = below)\n * @param m - Number of columns (default n)\n * @returns Tuple of row and column index arrays\n */\nexport function triu_indices(n: number, k: number = 0, m?: number): NDArray[] {\n const storages = advancedOps.triu_indices(n, k, m);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return the indices for the upper-triangle of arr.\n *\n * @param arr - Input 2-D array\n * @param k - Diagonal offset (0 = main, positive = above, negative = below)\n * @returns Tuple of row and column index arrays\n */\nexport function triu_indices_from(arr: NDArray, k: number = 0): NDArray[] {\n const storages = advancedOps.triu_indices_from(arr.storage, k);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return the indices to access (n, n) arrays, given a masking function.\n *\n * @param n - The returned indices will be valid to access arrays of shape (n, n)\n * @param mask_func - A function that generates an (n, n) boolean mask\n * @param k - Optional diagonal offset passed to mask_func\n * @returns Tuple of row and column index arrays\n */\nexport function mask_indices(\n n: number,\n mask_func: (n: number, k: number) => NDArray,\n k: number = 0\n): NDArray[] {\n // Wrap the function to work with storage\n const storageMaskFunc = (n: number, k: number) => mask_func(n, k).storage;\n const storages = advancedOps.mask_indices(n, storageMaskFunc, k);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Return an array representing the indices of a grid.\n *\n * @param dimensions - The shape of the grid\n * @param dtype - Data type of result (default 'int32')\n * @returns Array of shape (len(dimensions), *dimensions)\n */\nexport function indices(\n dimensions: number[],\n dtype: 'int32' | 'int64' | 'float64' = 'int32'\n): NDArray {\n return NDArray._fromStorage(advancedOps.indices(dimensions, dtype));\n}\n\n/**\n * Construct an open mesh from multiple sequences.\n *\n * This function returns a list of arrays with shapes suitable for broadcasting.\n *\n * @param args - 1-D sequences\n * @returns Tuple of arrays for open mesh\n */\nexport function ix_(...args: NDArray[]): NDArray[] {\n const storages = advancedOps.ix_(...args.map((a) => a.storage));\n return storages.map((s) => NDArray._fromStorage(s));\n}\n\n/**\n * Convert a tuple of index arrays into an array of flat indices.\n *\n * @param multi_index - Tuple of index arrays\n * @param dims - Shape of array into which indices apply\n * @param mode - How to handle out-of-bounds indices ('raise', 'wrap', 'clip')\n * @returns Flattened indices\n */\nexport function ravel_multi_index(\n multi_index: NDArray[],\n dims: number[],\n mode: 'raise' | 'wrap' | 'clip' = 'raise'\n): NDArray {\n const storages = multi_index.map((a) => a.storage);\n return NDArray._fromStorage(advancedOps.ravel_multi_index(storages, dims, mode));\n}\n\n/**\n * Convert a flat index or array of flat indices into a tuple of coordinate arrays.\n *\n * @param indices - Array of indices or single index\n * @param shape - Shape of the array to index into\n * @param order - Row-major ('C') or column-major ('F') order\n * @returns Tuple of coordinate arrays\n */\nexport function unravel_index(\n indices: NDArray | number,\n shape: number[],\n order: 'C' | 'F' = 'C'\n): NDArray[] {\n const indicesArg = indices instanceof NDArray ? indices.storage : indices;\n const storages = advancedOps.unravel_index(indicesArg, shape, order);\n return storages.map((s) => NDArray._fromStorage(s));\n}\n", "/**\n * NPY file format constants and type definitions\n *\n * NPY is NumPy's native binary format for storing arrays.\n * Spec: https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html\n */\n\nimport type { DType } from '../../core/dtype';\n\n/**\n * NPY magic number: \\x93NUMPY (6 bytes)\n */\nexport const NPY_MAGIC = new Uint8Array([0x93, 0x4e, 0x55, 0x4d, 0x50, 0x59]);\n\n/**\n * Supported NPY format versions\n * - v1.0: 2-byte header length (max 65535 bytes)\n * - v2.0: 4-byte header length (max 4GB)\n * - v3.0: allows UTF-8 in description (same as v2 otherwise)\n *\n * We read v1, v2, and v3; we write v2 only\n */\nexport interface NpyVersion {\n major: number;\n minor: number;\n}\n\n/**\n * NPY header information\n */\nexport interface NpyHeader {\n /** Data type descriptor (e.g., '<f8', '>i4') */\n descr: string;\n /** Whether array is Fortran-contiguous (column-major) */\n fortran_order: boolean;\n /** Array shape */\n shape: number[];\n}\n\n/**\n * Parsed NPY metadata including version\n */\nexport interface NpyMetadata {\n version: NpyVersion;\n header: NpyHeader;\n /** Byte offset where data starts */\n dataOffset: number;\n}\n\n/**\n * Result of parsing an NPY header descriptor to our DType\n */\nexport interface DTypeParseResult {\n dtype: DType;\n /** Whether the data needs byte swapping (big-endian on little-endian or vice versa) */\n needsByteSwap: boolean;\n /** Element size in bytes */\n itemsize: number;\n}\n\n/**\n * All dtypes we support\n */\nexport const SUPPORTED_DTYPES: DType[] = [\n 'float64',\n 'float32',\n 'int64',\n 'int32',\n 'int16',\n 'int8',\n 'uint64',\n 'uint32',\n 'uint16',\n 'uint8',\n 'bool',\n];\n\n/**\n * Detect system endianness\n */\nexport function isSystemLittleEndian(): boolean {\n const buffer = new ArrayBuffer(2);\n new DataView(buffer).setInt16(0, 256, true);\n return new Int16Array(buffer)[0] === 256;\n}\n\n/**\n * NPY descriptor to DType mapping\n *\n * NumPy descriptors follow the format: <endian><type><size>\n * - Endian: '<' little, '>' big, '=' native, '|' not applicable (1-byte types)\n * - Type: 'f' float, 'i' signed int, 'u' unsigned int, 'b' bool, 'c' complex, etc.\n * - Size: byte size (1, 2, 4, 8)\n */\nconst DESCR_TO_DTYPE: Record<string, DType> = {\n // Float types\n f8: 'float64',\n f4: 'float32',\n // Signed integer types\n i8: 'int64',\n i4: 'int32',\n i2: 'int16',\n i1: 'int8',\n // Unsigned integer types\n u8: 'uint64',\n u4: 'uint32',\n u2: 'uint16',\n u1: 'uint8',\n // Boolean\n b1: 'bool',\n};\n\n/**\n * DType to NPY descriptor mapping (for serialization)\n * We always write little-endian\n */\nexport const DTYPE_TO_DESCR: Record<DType, string> = {\n float64: '<f8',\n float32: '<f4',\n int64: '<i8',\n int32: '<i4',\n int16: '<i2',\n int8: '|i1',\n uint64: '<u8',\n uint32: '<u4',\n uint16: '<u2',\n uint8: '|u1',\n bool: '|b1',\n};\n\n/**\n * Unsupported dtype types (for error messages)\n */\nexport const UNSUPPORTED_DTYPE_PATTERNS: Record<string, string> = {\n c: 'complex numbers',\n S: 'byte strings',\n U: 'Unicode strings',\n O: 'Python objects',\n V: 'structured arrays (void)',\n M: 'datetime64',\n m: 'timedelta64',\n};\n\n/**\n * Parse a NumPy dtype descriptor string to our DType\n *\n * @param descr - NumPy descriptor like '<f8', '>i4', '|b1'\n * @returns Parsed result with dtype and byte order info\n * @throws Error if dtype is not supported\n */\nexport function parseDescriptor(descr: string): DTypeParseResult {\n // Handle structured dtypes (tuples/lists) - not supported\n if (descr.startsWith('[') || descr.startsWith('(')) {\n throw new UnsupportedDTypeError(`Structured/compound dtypes are not supported: ${descr}`);\n }\n\n // Extract endianness, type, and size\n let endian = '';\n let typeAndSize = descr;\n\n // Check for endian prefix\n if (descr[0] === '<' || descr[0] === '>' || descr[0] === '=' || descr[0] === '|') {\n endian = descr[0];\n typeAndSize = descr.slice(1);\n }\n\n // Check for unsupported types\n const typeChar = typeAndSize[0];\n if (typeChar && typeChar in UNSUPPORTED_DTYPE_PATTERNS) {\n throw new UnsupportedDTypeError(\n `Unsupported dtype: ${UNSUPPORTED_DTYPE_PATTERNS[typeChar]} (${descr}). ` +\n `Use the 'force' parameter to skip arrays with unsupported dtypes.`\n );\n }\n\n // Look up in our mapping\n const dtype = DESCR_TO_DTYPE[typeAndSize];\n if (!dtype) {\n throw new UnsupportedDTypeError(\n `Unknown or unsupported dtype descriptor: ${descr}. ` +\n `Supported types: ${SUPPORTED_DTYPES.join(', ')}. ` +\n `Use the 'force' parameter to skip arrays with unsupported dtypes.`\n );\n }\n\n // Determine if byte swapping is needed\n const isLittleEndian = isSystemLittleEndian();\n const dataIsLittleEndian = endian === '<' || endian === '|' || (endian === '=' && isLittleEndian);\n const dataIsBigEndian = endian === '>' || (endian === '=' && !isLittleEndian);\n\n // We need to byte swap if:\n // - Data is big-endian and system is little-endian\n // - Data is little-endian and system is big-endian\n // But only for multi-byte types\n const itemsize = parseInt(typeAndSize.slice(1), 10);\n const needsByteSwap =\n itemsize > 1 &&\n ((dataIsBigEndian && isLittleEndian) || (dataIsLittleEndian && !isLittleEndian));\n\n return {\n dtype,\n needsByteSwap,\n itemsize,\n };\n}\n\n/**\n * Custom error for unsupported dtypes\n */\nexport class UnsupportedDTypeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UnsupportedDTypeError';\n }\n}\n\n/**\n * Custom error for invalid NPY format\n */\nexport class InvalidNpyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidNpyError';\n }\n}\n", "/**\n * NPY file parser\n *\n * Parses NumPy .npy files (both v1 and v2/v3 formats) into NDArray objects.\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { ArrayStorage } from '../../core/storage';\nimport { getTypedArrayConstructor, isBigIntDType, type DType } from '../../core/dtype';\nimport {\n NPY_MAGIC,\n parseDescriptor,\n InvalidNpyError,\n type NpyHeader,\n type NpyMetadata,\n} from './format';\n\n/**\n * Parse an NPY file from a Uint8Array or ArrayBuffer\n *\n * @param buffer - The NPY file contents\n * @returns An NDArray containing the parsed data\n * @throws InvalidNpyError if the file format is invalid\n * @throws UnsupportedDTypeError if the dtype is not supported\n */\nexport function parseNpy(buffer: ArrayBuffer | Uint8Array): NDArray {\n const bytes = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n const metadata = parseNpyHeader(bytes);\n return parseNpyData(bytes, metadata);\n}\n\n/**\n * Parse just the NPY header without reading the data\n *\n * @param bytes - The NPY file bytes\n * @returns Parsed metadata including version, header, and data offset\n */\nexport function parseNpyHeader(bytes: Uint8Array): NpyMetadata {\n // Check minimum size\n if (bytes.length < 10) {\n throw new InvalidNpyError('File too small to be a valid NPY file');\n }\n\n // Verify magic number\n for (let i = 0; i < NPY_MAGIC.length; i++) {\n if (bytes[i] !== NPY_MAGIC[i]) {\n throw new InvalidNpyError('Invalid NPY magic number');\n }\n }\n\n // Read version\n const major = bytes[6]!;\n const minor = bytes[7]!;\n\n if (major !== 1 && major !== 2 && major !== 3) {\n throw new InvalidNpyError(`Unsupported NPY version: ${major}.${minor}`);\n }\n\n // Read header length\n let headerLen: number;\n let headerStart: number;\n\n if (major === 1) {\n // v1.0: 2-byte little-endian header length\n headerLen = bytes[8]! | (bytes[9]! << 8);\n headerStart = 10;\n } else {\n // v2.0 and v3.0: 4-byte little-endian header length\n headerLen = bytes[8]! | (bytes[9]! << 8) | (bytes[10]! << 16) | (bytes[11]! << 24);\n headerStart = 12;\n }\n\n // Read header string\n const headerEnd = headerStart + headerLen;\n if (bytes.length < headerEnd) {\n throw new InvalidNpyError('File truncated: header extends beyond file');\n }\n\n const headerBytes = bytes.slice(headerStart, headerEnd);\n const headerStr = new TextDecoder('utf-8').decode(headerBytes).trim();\n\n // Parse header dictionary\n const header = parseHeaderDict(headerStr);\n\n return {\n version: { major, minor },\n header,\n dataOffset: headerEnd,\n };\n}\n\n/**\n * Parse the data section of an NPY file given parsed metadata\n */\nexport function parseNpyData(bytes: Uint8Array, metadata: NpyMetadata): NDArray {\n const { header, dataOffset } = metadata;\n\n // Parse dtype descriptor\n const { dtype, needsByteSwap, itemsize } = parseDescriptor(header.descr);\n\n // Calculate expected data size\n const numElements = header.shape.reduce((a, b) => a * b, 1);\n const expectedBytes = numElements * itemsize;\n const actualBytes = bytes.length - dataOffset;\n\n if (actualBytes < expectedBytes) {\n throw new InvalidNpyError(\n `File truncated: expected ${expectedBytes} bytes of data, got ${actualBytes}`\n );\n }\n\n // Extract data buffer - create a copy to ensure we have a plain ArrayBuffer\n const dataBuffer = new ArrayBuffer(expectedBytes);\n const dataView = new Uint8Array(dataBuffer);\n dataView.set(bytes.subarray(dataOffset, dataOffset + expectedBytes));\n\n // Create typed array from data\n const typedData = createTypedArray(dataBuffer, dtype, numElements, needsByteSwap, itemsize);\n\n // Handle Fortran order (column-major)\n // NumPy stores data in row-major (C order) by default\n // If fortran_order is true, we need to adjust\n let shape = header.shape;\n let storage: ArrayStorage;\n\n if (header.fortran_order && shape.length > 1) {\n // For Fortran order, we can either:\n // 1. Transpose the shape and data (requires copy)\n // 2. Use column-major strides (creates a view)\n // We'll transpose to convert to C-order for consistency\n const reversedShape = [...shape].reverse();\n const tempStorage = ArrayStorage.fromData(typedData, reversedShape, dtype);\n\n // Transpose to get correct C-order layout\n storage = transposeStorage(tempStorage, reversedShape);\n shape = header.shape; // Use original shape after transpose\n } else {\n storage = ArrayStorage.fromData(typedData, [...shape], dtype);\n }\n\n return new NDArray(storage);\n}\n\n/**\n * Parse the Python dictionary header string\n */\nfunction parseHeaderDict(headerStr: string): NpyHeader {\n // Header is a Python dict literal like:\n // {'descr': '<f8', 'fortran_order': False, 'shape': (3, 4), }\n\n // Simple regex-based parser for the specific format\n const descrMatch = headerStr.match(/'descr'\\s*:\\s*'([^']+)'/);\n const fortranMatch = headerStr.match(/'fortran_order'\\s*:\\s*(True|False)/);\n const shapeMatch = headerStr.match(/'shape'\\s*:\\s*\\(([^)]*)\\)/);\n\n if (!descrMatch || !fortranMatch || !shapeMatch) {\n throw new InvalidNpyError(`Failed to parse NPY header: ${headerStr}`);\n }\n\n const descr = descrMatch[1]!;\n const fortran_order = fortranMatch[1] === 'True';\n\n // Parse shape tuple\n const shapeStr = shapeMatch[1]!.trim();\n let shape: number[];\n\n if (shapeStr === '') {\n // Scalar: shape is ()\n shape = [];\n } else {\n // Parse comma-separated integers\n shape = shapeStr\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s !== '')\n .map((s) => {\n const n = parseInt(s, 10);\n if (isNaN(n)) {\n throw new InvalidNpyError(`Invalid shape value: ${s}`);\n }\n return n;\n });\n }\n\n return { descr, fortran_order, shape };\n}\n\n/**\n * Create a typed array from raw bytes with optional byte swapping\n */\nfunction createTypedArray(\n buffer: ArrayBuffer,\n dtype: DType,\n numElements: number,\n needsByteSwap: boolean,\n itemsize: number\n):\n | Float64Array\n | Float32Array\n | BigInt64Array\n | Int32Array\n | Int16Array\n | Int8Array\n | BigUint64Array\n | Uint32Array\n | Uint16Array\n | Uint8Array {\n const Constructor = getTypedArrayConstructor(dtype);\n if (!Constructor) {\n throw new InvalidNpyError(`Cannot create array for dtype: ${dtype}`);\n }\n\n if (!needsByteSwap) {\n // Fast path: no byte swapping needed\n return new Constructor(buffer, 0, numElements);\n }\n\n // Slow path: need to byte swap\n const bytes = new Uint8Array(buffer);\n const swapped = new Uint8Array(buffer.byteLength);\n\n for (let i = 0; i < numElements; i++) {\n const start = i * itemsize;\n // Reverse bytes for this element\n for (let j = 0; j < itemsize; j++) {\n swapped[start + j] = bytes[start + itemsize - 1 - j]!;\n }\n }\n\n return new Constructor(swapped.buffer, 0, numElements);\n}\n\n/**\n * Transpose storage to convert from Fortran to C order\n */\nfunction transposeStorage(storage: ArrayStorage, shape: readonly number[]): ArrayStorage {\n const ndim = shape.length;\n const size = storage.size;\n const dtype = storage.dtype;\n const Constructor = getTypedArrayConstructor(dtype);\n\n if (!Constructor) {\n throw new InvalidNpyError(`Cannot create array for dtype: ${dtype}`);\n }\n\n const newData = new Constructor(size);\n const newShape = [...shape].reverse();\n\n // Compute strides for both orderings\n const oldStrides = computeStrides(shape);\n const newStrides = computeStrides(newShape);\n\n // Copy data with transposition\n const indices = new Array(ndim).fill(0);\n\n for (let linearIdx = 0; linearIdx < size; linearIdx++) {\n // Get multi-index in old layout\n let remaining = linearIdx;\n for (let i = 0; i < ndim; i++) {\n const dimSize = oldStrides[i]!;\n indices[i] = Math.floor(remaining / dimSize);\n remaining = remaining % dimSize;\n }\n\n // Compute new linear index (reverse indices for transpose)\n let newLinearIdx = 0;\n for (let i = 0; i < ndim; i++) {\n newLinearIdx += indices[ndim - 1 - i]! * newStrides[i]!;\n }\n\n // Copy value\n if (isBigIntDType(dtype)) {\n (newData as BigInt64Array | BigUint64Array)[newLinearIdx] = storage.iget(linearIdx) as bigint;\n } else {\n (newData as Exclude<typeof newData, BigInt64Array | BigUint64Array>)[newLinearIdx] =\n storage.iget(linearIdx) as number;\n }\n }\n\n return ArrayStorage.fromData(newData, newShape, dtype);\n}\n\n/**\n * Compute C-order strides for a shape\n */\nfunction computeStrides(shape: readonly number[]): number[] {\n const strides = new Array(shape.length);\n let stride = 1;\n for (let i = shape.length - 1; i >= 0; i--) {\n strides[i] = stride;\n stride *= shape[i]!;\n }\n return strides;\n}\n", "/**\n * NPY file serializer\n *\n * Serializes NDArray objects to NumPy .npy format (v3.0).\n * Always writes in little-endian, C-contiguous order.\n *\n * v3.0 is identical to v2.0 but allows UTF-8 in dtype descriptions.\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { getDTypeSize, isBigIntDType, type DType } from '../../core/dtype';\nimport { NPY_MAGIC, DTYPE_TO_DESCR, isSystemLittleEndian } from './format';\n\n/**\n * Serialize an NDArray to NPY format (v3.0)\n *\n * @param arr - The NDArray to serialize\n * @returns A Uint8Array containing the NPY file data\n */\nexport function serializeNpy(arr: NDArray): Uint8Array {\n const shape = arr.shape;\n const dtype = arr.dtype as DType;\n\n // Build header dictionary string\n const descr = DTYPE_TO_DESCR[dtype];\n const shapeStr =\n shape.length === 0 ? '()' : shape.length === 1 ? `(${shape[0]},)` : `(${shape.join(', ')})`;\n\n // Python dict format: {'descr': '<f8', 'fortran_order': False, 'shape': (3, 4), }\n let headerDict = `{'descr': '${descr}', 'fortran_order': False, 'shape': ${shapeStr}, }`;\n\n // Header must be padded to 64-byte alignment (including magic, version, header_len)\n // v3.0 uses 4 bytes for header length (same as v2.0)\n // Total prefix is 6 (magic) + 2 (version) + 4 (header_len) = 12 bytes\n // Header string + newline should make total divisible by 64\n const PREFIX_LEN = 12;\n const totalBeforeData = PREFIX_LEN + headerDict.length + 1; // +1 for trailing newline\n const padding = (64 - (totalBeforeData % 64)) % 64;\n headerDict = headerDict + ' '.repeat(padding) + '\\n';\n\n const headerBytes = new TextEncoder().encode(headerDict);\n const headerLen = headerBytes.length;\n\n // Calculate data size\n const numElements = arr.size;\n const itemsize = getDTypeSize(dtype);\n const dataSize = numElements * itemsize;\n\n // Allocate output buffer\n const totalSize = PREFIX_LEN + headerLen + dataSize;\n const output = new Uint8Array(totalSize);\n\n // Write magic number\n output.set(NPY_MAGIC, 0);\n\n // Write version (3.0)\n output[6] = 3;\n output[7] = 0;\n\n // Write header length (4-byte little-endian)\n output[8] = headerLen & 0xff;\n output[9] = (headerLen >> 8) & 0xff;\n output[10] = (headerLen >> 16) & 0xff;\n output[11] = (headerLen >> 24) & 0xff;\n\n // Write header string\n output.set(headerBytes, PREFIX_LEN);\n\n // Write data\n const dataOffset = PREFIX_LEN + headerLen;\n writeArrayData(arr, output.subarray(dataOffset), itemsize);\n\n return output;\n}\n\n/**\n * Write array data to the output buffer\n */\nfunction writeArrayData(arr: NDArray, output: Uint8Array, itemsize: number): void {\n const dtype = arr.dtype as DType;\n const size = arr.size;\n const isLittleEndian = isSystemLittleEndian();\n const isBigInt = isBigIntDType(dtype);\n\n // Get raw data - need to handle non-contiguous arrays\n const storage = arr['_storage']; // Access private member\n const isCContiguous = storage.isCContiguous && storage.offset === 0;\n\n if (isCContiguous && isLittleEndian) {\n // Fast path: just copy the underlying buffer\n const srcData = storage.data;\n const srcBytes = new Uint8Array(srcData.buffer, srcData.byteOffset, size * itemsize);\n output.set(srcBytes);\n } else {\n // Slow path: element by element copy with potential byte swapping\n const dataView = new DataView(output.buffer, output.byteOffset, output.byteLength);\n\n for (let i = 0; i < size; i++) {\n const value = storage.iget(i);\n const offset = i * itemsize;\n\n if (isBigInt) {\n // Write BigInt as little-endian\n writeBigInt64LE(dataView, offset, value as bigint, dtype === 'uint64');\n } else {\n // Write number as little-endian\n writeNumberLE(dataView, offset, value as number, dtype);\n }\n }\n }\n}\n\n/**\n * Write a BigInt as little-endian\n */\nfunction writeBigInt64LE(view: DataView, offset: number, value: bigint, unsigned: boolean): void {\n if (unsigned) {\n view.setBigUint64(offset, value, true);\n } else {\n view.setBigInt64(offset, value, true);\n }\n}\n\n/**\n * Write a number as little-endian\n */\nfunction writeNumberLE(view: DataView, offset: number, value: number, dtype: DType): void {\n switch (dtype) {\n case 'float64':\n view.setFloat64(offset, value, true);\n break;\n case 'float32':\n view.setFloat32(offset, value, true);\n break;\n case 'int32':\n view.setInt32(offset, value, true);\n break;\n case 'int16':\n view.setInt16(offset, value, true);\n break;\n case 'int8':\n view.setInt8(offset, value);\n break;\n case 'uint32':\n view.setUint32(offset, value, true);\n break;\n case 'uint16':\n view.setUint16(offset, value, true);\n break;\n case 'uint8':\n case 'bool':\n view.setUint8(offset, value);\n break;\n default:\n throw new Error(`Unsupported dtype for serialization: ${dtype}`);\n }\n}\n", "/**\n * ZIP file format types and constants\n */\n\n/**\n * ZIP local file header signature\n */\nexport const ZIP_LOCAL_SIGNATURE = 0x04034b50;\n\n/**\n * ZIP central directory header signature\n */\nexport const ZIP_CENTRAL_SIGNATURE = 0x02014b50;\n\n/**\n * ZIP end of central directory signature\n */\nexport const ZIP_END_SIGNATURE = 0x06054b50;\n\n/**\n * Compression methods\n */\nexport const ZIP_STORED = 0; // No compression\nexport const ZIP_DEFLATED = 8; // DEFLATE compression\n\n/**\n * Entry in a ZIP file\n */\nexport interface ZipEntry {\n /** File name */\n name: string;\n /** Uncompressed data */\n data: Uint8Array;\n /** Compression method used */\n compressionMethod: number;\n /** CRC-32 checksum */\n crc32: number;\n /** Compressed size */\n compressedSize: number;\n /** Uncompressed size */\n uncompressedSize: number;\n}\n\n/**\n * Raw entry as read from ZIP (before decompression)\n */\nexport interface RawZipEntry {\n /** File name */\n name: string;\n /** Compressed data */\n compressedData: Uint8Array;\n /** Compression method */\n compressionMethod: number;\n /** CRC-32 checksum */\n crc32: number;\n /** Compressed size */\n compressedSize: number;\n /** Uncompressed size */\n uncompressedSize: number;\n}\n\n/**\n * CRC-32 lookup table\n */\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[i] = c;\n }\n return table;\n})();\n\n/**\n * Calculate CRC-32 checksum\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i++) {\n crc = CRC32_TABLE[(crc ^ data[i]!) & 0xff]! ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n", "/**\n * Minimal ZIP file reader\n *\n * Reads ZIP files with STORED or DEFLATE compression.\n * Uses the Compression Streams API (built into modern browsers and Node.js 18+).\n */\n\nimport {\n ZIP_LOCAL_SIGNATURE,\n ZIP_END_SIGNATURE,\n ZIP_STORED,\n ZIP_DEFLATED,\n type RawZipEntry,\n} from './types';\n\n/**\n * Read a ZIP file and return its entries\n *\n * @param buffer - ZIP file contents\n * @returns Map of file names to their uncompressed data\n */\nexport async function readZip(buffer: ArrayBuffer | Uint8Array): Promise<Map<string, Uint8Array>> {\n const entries = parseZipEntries(buffer);\n const result = new Map<string, Uint8Array>();\n\n for (const entry of entries) {\n const data = await decompressEntry(entry);\n result.set(entry.name, data);\n }\n\n return result;\n}\n\n/**\n * Synchronously read a ZIP file (only works for STORED entries)\n *\n * @param buffer - ZIP file contents\n * @returns Map of file names to their uncompressed data\n * @throws Error if any entry uses compression\n */\nexport function readZipSync(buffer: ArrayBuffer | Uint8Array): Map<string, Uint8Array> {\n const entries = parseZipEntries(buffer);\n const result = new Map<string, Uint8Array>();\n\n for (const entry of entries) {\n if (entry.compressionMethod !== ZIP_STORED) {\n throw new Error(\n `Cannot read compressed entry synchronously: ${entry.name}. ` +\n `Use readZip() (async) for DEFLATE-compressed files.`\n );\n }\n result.set(entry.name, entry.compressedData);\n }\n\n return result;\n}\n\n/**\n * Central directory entry info\n */\ninterface CentralDirEntry {\n name: string;\n compressionMethod: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n localHeaderOffset: number;\n}\n\n/**\n * Parse ZIP entries without decompressing\n *\n * Uses central directory for reliable size information, as some ZIP writers\n * (including Python's zipfile module used by NumPy) set local header sizes to\n * 0xFFFFFFFF when streaming.\n */\nfunction parseZipEntries(buffer: ArrayBuffer | Uint8Array): RawZipEntry[] {\n const bytes = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const entries: RawZipEntry[] = [];\n\n // Find end of central directory\n let eocdOffset = -1;\n for (let i = bytes.length - 22; i >= 0; i--) {\n if (view.getUint32(i, true) === ZIP_END_SIGNATURE) {\n eocdOffset = i;\n break;\n }\n }\n\n if (eocdOffset === -1) {\n throw new Error('Invalid ZIP file: end of central directory not found');\n }\n\n // Read central directory location\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n const numEntries = view.getUint16(eocdOffset + 10, true);\n\n // Parse central directory entries first to get reliable sizes\n const centralEntries: CentralDirEntry[] = [];\n let cdOffset = centralDirOffset;\n\n for (let i = 0; i < numEntries; i++) {\n const signature = view.getUint32(cdOffset, true);\n if (signature !== 0x02014b50) {\n // Central directory signature\n break;\n }\n\n const compressionMethod = view.getUint16(cdOffset + 10, true);\n const crc32 = view.getUint32(cdOffset + 16, true);\n const compressedSize = view.getUint32(cdOffset + 20, true);\n const uncompressedSize = view.getUint32(cdOffset + 24, true);\n const fileNameLength = view.getUint16(cdOffset + 28, true);\n const extraFieldLength = view.getUint16(cdOffset + 30, true);\n const commentLength = view.getUint16(cdOffset + 32, true);\n const localHeaderOffset = view.getUint32(cdOffset + 42, true);\n\n const fileNameBytes = bytes.slice(cdOffset + 46, cdOffset + 46 + fileNameLength);\n const fileName = new TextDecoder('utf-8').decode(fileNameBytes);\n\n centralEntries.push({\n name: fileName,\n compressionMethod,\n crc32,\n compressedSize,\n uncompressedSize,\n localHeaderOffset,\n });\n\n cdOffset = cdOffset + 46 + fileNameLength + extraFieldLength + commentLength;\n }\n\n // Now extract data using local headers for data location, but central directory for sizes\n for (const ce of centralEntries) {\n const localOffset = ce.localHeaderOffset;\n const signature = view.getUint32(localOffset, true);\n\n if (signature !== ZIP_LOCAL_SIGNATURE) {\n throw new Error(`Invalid local file header at offset ${localOffset}`);\n }\n\n const fileNameLength = view.getUint16(localOffset + 26, true);\n const extraFieldLength = view.getUint16(localOffset + 28, true);\n\n const dataStart = localOffset + 30 + fileNameLength + extraFieldLength;\n const compressedData = bytes.slice(dataStart, dataStart + ce.compressedSize);\n\n entries.push({\n name: ce.name,\n compressedData,\n compressionMethod: ce.compressionMethod,\n crc32: ce.crc32,\n compressedSize: ce.compressedSize,\n uncompressedSize: ce.uncompressedSize,\n });\n }\n\n return entries;\n}\n\n/**\n * Decompress a single ZIP entry\n */\nasync function decompressEntry(entry: RawZipEntry): Promise<Uint8Array> {\n if (entry.compressionMethod === ZIP_STORED) {\n return entry.compressedData;\n }\n\n if (entry.compressionMethod === ZIP_DEFLATED) {\n return await inflateRaw(entry.compressedData);\n }\n\n throw new Error(`Unsupported compression method: ${entry.compressionMethod}`);\n}\n\n/**\n * Decompress raw DEFLATE data using DecompressionStream\n */\nasync function inflateRaw(data: Uint8Array): Promise<Uint8Array> {\n // Check if DecompressionStream is available\n if (typeof DecompressionStream === 'undefined') {\n throw new Error(\n 'DecompressionStream is not available. ' +\n 'This environment does not support the Compression Streams API. ' +\n 'Please use a modern browser or Node.js 18+.'\n );\n }\n\n // DEFLATE in ZIP is \"raw\" DEFLATE (no zlib header)\n // DecompressionStream expects the \"deflate-raw\" format\n const ds = new DecompressionStream('deflate-raw');\n\n // Create a copy to ensure we have a clean ArrayBuffer (avoids SharedArrayBuffer issues)\n const dataCopy = new Uint8Array(data.length);\n dataCopy.set(data);\n\n const writer = ds.writable.getWriter();\n void writer.write(dataCopy);\n void writer.close();\n\n const reader = ds.readable.getReader();\n const chunks: Uint8Array[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Concatenate chunks\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n", "/**\n * NPZ file parser\n *\n * NPZ is a ZIP archive containing multiple .npy files.\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { parseNpy } from '../npy/parser';\nimport { UnsupportedDTypeError } from '../npy/format';\nimport { readZip, readZipSync } from '../zip/reader';\n\n/**\n * Options for parsing NPZ files\n */\nexport interface NpzParseOptions {\n /**\n * If true, skip arrays with unsupported dtypes instead of throwing an error.\n * Skipped arrays will not be included in the result.\n * Default: false\n */\n force?: boolean;\n}\n\n/**\n * Result of parsing an NPZ file\n */\nexport interface NpzParseResult {\n /** Successfully parsed arrays */\n arrays: Map<string, NDArray>;\n /** Names of arrays that were skipped due to unsupported dtypes (only when force=true) */\n skipped: string[];\n /** Error messages for skipped arrays */\n errors: Map<string, string>;\n}\n\n/**\n * Parse an NPZ file from bytes\n *\n * @param buffer - The NPZ file contents\n * @param options - Parse options\n * @returns Promise resolving to parsed arrays\n */\nexport async function parseNpz(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): Promise<NpzParseResult> {\n const force = options.force ?? false;\n const files = await readZip(buffer);\n return parseNpzFromFiles(files, force);\n}\n\n/**\n * Synchronously parse an NPZ file (only works if not DEFLATE compressed)\n *\n * @param buffer - The NPZ file contents\n * @param options - Parse options\n * @returns Parsed arrays\n */\nexport function parseNpzSync(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): NpzParseResult {\n const force = options.force ?? false;\n const files = readZipSync(buffer);\n return parseNpzFromFiles(files, force);\n}\n\n/**\n * Parse NPZ from already-extracted files\n */\nfunction parseNpzFromFiles(files: Map<string, Uint8Array>, force: boolean): NpzParseResult {\n const arrays = new Map<string, NDArray>();\n const skipped: string[] = [];\n const errors = new Map<string, string>();\n\n for (const [fileName, data] of files) {\n // NPZ entries should have .npy extension\n if (!fileName.endsWith('.npy')) {\n continue;\n }\n\n // Extract array name (remove .npy extension)\n const name = fileName.slice(0, -4);\n\n try {\n const arr = parseNpy(data);\n arrays.set(name, arr);\n } catch (error) {\n if (error instanceof UnsupportedDTypeError && force) {\n // Skip this array but continue processing others\n skipped.push(name);\n errors.set(name, error.message);\n } else {\n // Re-throw all other errors, or UnsupportedDTypeError if force is false\n throw error;\n }\n }\n }\n\n return { arrays, skipped, errors };\n}\n\n/**\n * Convenience function to get arrays as a plain object\n *\n * @param buffer - The NPZ file contents\n * @param options - Parse options\n * @returns Promise resolving to object with array names as keys\n */\nexport async function loadNpz(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): Promise<Record<string, NDArray>> {\n const result = await parseNpz(buffer, options);\n return Object.fromEntries(result.arrays);\n}\n\n/**\n * Synchronous version of loadNpz\n */\nexport function loadNpzSync(\n buffer: ArrayBuffer | Uint8Array,\n options: NpzParseOptions = {}\n): Record<string, NDArray> {\n const result = parseNpzSync(buffer, options);\n return Object.fromEntries(result.arrays);\n}\n", "/**\n * Minimal ZIP file writer\n *\n * Creates ZIP files with optional DEFLATE compression.\n * Uses the Compression Streams API (built into modern browsers and Node.js 18+).\n */\n\nimport {\n ZIP_LOCAL_SIGNATURE,\n ZIP_CENTRAL_SIGNATURE,\n ZIP_END_SIGNATURE,\n ZIP_STORED,\n ZIP_DEFLATED,\n crc32,\n} from './types';\n\n/**\n * Options for writing a ZIP file\n */\nexport interface ZipWriteOptions {\n /** Whether to compress files (default: false for NPZ compatibility) */\n compress?: boolean;\n}\n\n/**\n * Create a ZIP file from a map of file names to data\n *\n * @param files - Map of file names to their data\n * @param options - Write options\n * @returns ZIP file as Uint8Array\n */\nexport async function writeZip(\n files: Map<string, Uint8Array>,\n options: ZipWriteOptions = {}\n): Promise<Uint8Array> {\n const compress = options.compress ?? false;\n const entries: {\n name: string;\n data: Uint8Array;\n compressedData: Uint8Array;\n crc: number;\n compressionMethod: number;\n offset: number;\n }[] = [];\n\n // Prepare entries\n for (const [name, data] of files) {\n const crc = crc32(data);\n let compressedData: Uint8Array;\n let compressionMethod: number;\n\n if (compress) {\n compressedData = await deflateRaw(data);\n // Only use compression if it actually makes the data smaller\n if (compressedData.length < data.length) {\n compressionMethod = ZIP_DEFLATED;\n } else {\n compressedData = data;\n compressionMethod = ZIP_STORED;\n }\n } else {\n compressedData = data;\n compressionMethod = ZIP_STORED;\n }\n\n entries.push({\n name,\n data,\n compressedData,\n crc,\n compressionMethod,\n offset: 0, // Will be set during writing\n });\n }\n\n // Calculate total size\n let localHeadersSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n localHeadersSize += 30 + nameBytes.length + entry.compressedData.length;\n }\n\n let centralDirSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n centralDirSize += 46 + nameBytes.length;\n }\n\n const eocdSize = 22;\n const totalSize = localHeadersSize + centralDirSize + eocdSize;\n\n // Allocate buffer\n const output = new Uint8Array(totalSize);\n const view = new DataView(output.buffer);\n\n // Write local file headers and data\n let offset = 0;\n for (const entry of entries) {\n entry.offset = offset;\n offset = writeLocalHeader(output, view, offset, entry);\n }\n\n // Write central directory\n const centralDirOffset = offset;\n for (const entry of entries) {\n offset = writeCentralHeader(output, view, offset, entry);\n }\n\n // Write end of central directory\n writeEndOfCentralDirectory(view, offset, entries.length, centralDirSize, centralDirOffset);\n\n return output;\n}\n\n/**\n * Create a ZIP file synchronously (no compression)\n *\n * @param files - Map of file names to their data\n * @returns ZIP file as Uint8Array\n */\nexport function writeZipSync(files: Map<string, Uint8Array>): Uint8Array {\n const entries: {\n name: string;\n data: Uint8Array;\n compressedData: Uint8Array;\n crc: number;\n compressionMethod: number;\n offset: number;\n }[] = [];\n\n // Prepare entries (no compression in sync mode)\n for (const [name, data] of files) {\n const crc = crc32(data);\n entries.push({\n name,\n data,\n compressedData: data,\n crc,\n compressionMethod: ZIP_STORED,\n offset: 0,\n });\n }\n\n // Calculate total size\n let localHeadersSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n localHeadersSize += 30 + nameBytes.length + entry.compressedData.length;\n }\n\n let centralDirSize = 0;\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n centralDirSize += 46 + nameBytes.length;\n }\n\n const eocdSize = 22;\n const totalSize = localHeadersSize + centralDirSize + eocdSize;\n\n // Allocate buffer\n const output = new Uint8Array(totalSize);\n const view = new DataView(output.buffer);\n\n // Write local file headers and data\n let offset = 0;\n for (const entry of entries) {\n entry.offset = offset;\n offset = writeLocalHeader(output, view, offset, entry);\n }\n\n // Write central directory\n const centralDirOffset = offset;\n for (const entry of entries) {\n offset = writeCentralHeader(output, view, offset, entry);\n }\n\n // Write end of central directory\n writeEndOfCentralDirectory(view, offset, entries.length, centralDirSize, centralDirOffset);\n\n return output;\n}\n\n/**\n * Write a local file header and data\n */\nfunction writeLocalHeader(\n output: Uint8Array,\n view: DataView,\n offset: number,\n entry: {\n name: string;\n compressedData: Uint8Array;\n data: Uint8Array;\n crc: number;\n compressionMethod: number;\n }\n): number {\n const nameBytes = new TextEncoder().encode(entry.name);\n\n // Signature\n view.setUint32(offset, ZIP_LOCAL_SIGNATURE, true);\n offset += 4;\n\n // Version needed to extract (2.0 for DEFLATE)\n view.setUint16(offset, entry.compressionMethod === ZIP_DEFLATED ? 20 : 10, true);\n offset += 2;\n\n // General purpose bit flag\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Compression method\n view.setUint16(offset, entry.compressionMethod, true);\n offset += 2;\n\n // Last mod time (use a fixed value)\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Last mod date (use a fixed value)\n view.setUint16(offset, 0x21, true); // Jan 1, 1980\n offset += 2;\n\n // CRC-32\n view.setUint32(offset, entry.crc, true);\n offset += 4;\n\n // Compressed size\n view.setUint32(offset, entry.compressedData.length, true);\n offset += 4;\n\n // Uncompressed size\n view.setUint32(offset, entry.data.length, true);\n offset += 4;\n\n // File name length\n view.setUint16(offset, nameBytes.length, true);\n offset += 2;\n\n // Extra field length\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // File name\n output.set(nameBytes, offset);\n offset += nameBytes.length;\n\n // File data\n output.set(entry.compressedData, offset);\n offset += entry.compressedData.length;\n\n return offset;\n}\n\n/**\n * Write a central directory header\n */\nfunction writeCentralHeader(\n output: Uint8Array,\n view: DataView,\n offset: number,\n entry: {\n name: string;\n compressedData: Uint8Array;\n data: Uint8Array;\n crc: number;\n compressionMethod: number;\n offset: number;\n }\n): number {\n const nameBytes = new TextEncoder().encode(entry.name);\n\n // Signature\n view.setUint32(offset, ZIP_CENTRAL_SIGNATURE, true);\n offset += 4;\n\n // Version made by\n view.setUint16(offset, 20, true);\n offset += 2;\n\n // Version needed to extract\n view.setUint16(offset, entry.compressionMethod === ZIP_DEFLATED ? 20 : 10, true);\n offset += 2;\n\n // General purpose bit flag\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Compression method\n view.setUint16(offset, entry.compressionMethod, true);\n offset += 2;\n\n // Last mod time\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Last mod date\n view.setUint16(offset, 0x21, true);\n offset += 2;\n\n // CRC-32\n view.setUint32(offset, entry.crc, true);\n offset += 4;\n\n // Compressed size\n view.setUint32(offset, entry.compressedData.length, true);\n offset += 4;\n\n // Uncompressed size\n view.setUint32(offset, entry.data.length, true);\n offset += 4;\n\n // File name length\n view.setUint16(offset, nameBytes.length, true);\n offset += 2;\n\n // Extra field length\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // File comment length\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Disk number start\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Internal file attributes\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // External file attributes\n view.setUint32(offset, 0, true);\n offset += 4;\n\n // Relative offset of local header\n view.setUint32(offset, entry.offset, true);\n offset += 4;\n\n // File name\n output.set(nameBytes, offset);\n offset += nameBytes.length;\n\n return offset;\n}\n\n/**\n * Write end of central directory record\n */\nfunction writeEndOfCentralDirectory(\n view: DataView,\n offset: number,\n numEntries: number,\n centralDirSize: number,\n centralDirOffset: number\n): void {\n // Signature\n view.setUint32(offset, ZIP_END_SIGNATURE, true);\n offset += 4;\n\n // Number of this disk\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Disk where central directory starts\n view.setUint16(offset, 0, true);\n offset += 2;\n\n // Number of central directory records on this disk\n view.setUint16(offset, numEntries, true);\n offset += 2;\n\n // Total number of central directory records\n view.setUint16(offset, numEntries, true);\n offset += 2;\n\n // Size of central directory\n view.setUint32(offset, centralDirSize, true);\n offset += 4;\n\n // Offset of central directory\n view.setUint32(offset, centralDirOffset, true);\n offset += 4;\n\n // Comment length\n view.setUint16(offset, 0, true);\n}\n\n/**\n * Compress data using raw DEFLATE\n */\nasync function deflateRaw(data: Uint8Array): Promise<Uint8Array> {\n // Check if CompressionStream is available\n if (typeof CompressionStream === 'undefined') {\n throw new Error(\n 'CompressionStream is not available. ' +\n 'This environment does not support the Compression Streams API. ' +\n 'Please use a modern browser or Node.js 18+.'\n );\n }\n\n const cs = new CompressionStream('deflate-raw');\n\n // Create a copy to ensure we have a clean ArrayBuffer (avoids SharedArrayBuffer issues)\n const dataCopy = new Uint8Array(data.length);\n dataCopy.set(data);\n\n const writer = cs.writable.getWriter();\n void writer.write(dataCopy);\n void writer.close();\n\n const reader = cs.readable.getReader();\n const chunks: Uint8Array[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Concatenate chunks\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n", "/**\n * NPZ file serializer\n *\n * Serializes multiple NDArrays to NPZ format (ZIP archive of .npy files).\n */\n\nimport { NDArray } from '../../core/ndarray';\nimport { serializeNpy } from '../npy/serializer';\nimport { writeZip, writeZipSync } from '../zip/writer';\n\n/**\n * Input type for arrays - supports:\n * - Array of NDArrays (positional, named arr_0, arr_1, etc.)\n * - Map of names to NDArrays\n * - Object with names as keys\n */\nexport type NpzArraysInput = NDArray[] | Map<string, NDArray> | Record<string, NDArray>;\n\n/**\n * Options for serializing NPZ files\n */\nexport interface NpzSerializeOptions {\n /**\n * Whether to compress the NPZ file using DEFLATE.\n * Default: false (matches np.savez behavior; use true for np.savez_compressed behavior)\n */\n compress?: boolean;\n}\n\n/**\n * Serialize multiple arrays to NPZ format\n *\n * @param arrays - Arrays to save. Can be:\n * - An array of NDArrays (named arr_0, arr_1, etc. like np.savez positional args)\n * - A Map of names to NDArrays\n * - An object with names as keys (like np.savez keyword args)\n * @param options - Serialization options\n * @returns Promise resolving to NPZ file as Uint8Array\n *\n * @example\n * // Positional arrays (named arr_0, arr_1)\n * await serializeNpz([arr1, arr2])\n *\n * // Named arrays\n * await serializeNpz({ x: arr1, y: arr2 })\n */\nexport async function serializeNpz(\n arrays: NpzArraysInput,\n options: NpzSerializeOptions = {}\n): Promise<Uint8Array> {\n const files = prepareNpzFiles(arrays);\n return writeZip(files, { compress: options.compress ?? false });\n}\n\n/**\n * Synchronously serialize multiple arrays to NPZ format (no compression)\n *\n * @param arrays - Arrays to save (same input types as serializeNpz)\n * @returns NPZ file as Uint8Array\n */\nexport function serializeNpzSync(arrays: NpzArraysInput): Uint8Array {\n const files = prepareNpzFiles(arrays);\n return writeZipSync(files);\n}\n\n/**\n * Prepare NPY files for ZIP packaging\n */\nfunction prepareNpzFiles(arrays: NpzArraysInput): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n\n // Handle array input (positional arrays get named arr_0, arr_1, etc.)\n if (Array.isArray(arrays)) {\n for (let i = 0; i < arrays.length; i++) {\n const arr = arrays[i]!;\n const npyData = serializeNpy(arr);\n files.set(`arr_${i}.npy`, npyData);\n }\n return files;\n }\n\n // Handle both Map and plain object\n const entries = arrays instanceof Map ? arrays.entries() : Object.entries(arrays);\n\n for (const [name, arr] of entries) {\n // Validate array name\n if (typeof name !== 'string' || name.length === 0) {\n throw new Error('Array names must be non-empty strings');\n }\n\n // Serialize to NPY format\n const npyData = serializeNpy(arr);\n\n // Add .npy extension\n const fileName = name.endsWith('.npy') ? name : `${name}.npy`;\n files.set(fileName, npyData);\n }\n\n return files;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["index_exports", "__export", "DTYPE_TO_DESCR", "InvalidNpyError", "NDArray", "SUPPORTED_DTYPES", "UnsupportedDTypeError", "__version__", "absolute", "append", "arange", "arccos", "arccosh", "arcsin", "arcsinh", "arctan", "arctan2", "arctanh", "array", "array_equal", "array_equiv", "array_split", "asanyarray", "asarray", "ascontiguousarray", "asfortranarray", "atleast_1d", "atleast_2d", "atleast_3d", "average", "bitwise_and", "bitwise_not", "bitwise_or", "bitwise_xor", "broadcast_arrays", "broadcast_shapes", "broadcast_to", "cbrt", "choose", "column_stack", "compress", "concatenate", "copy", "cos", "cosh", "cumprod", "cumsum", "deg2rad", "degrees", "delete_", "diag", "diag_indices", "diag_indices_from", "diagflat", "diagonal", "divmod", "dot", "dsplit", "dstack", "einsum", "empty", "empty_like", "expand_dims", "eye", "fabs", "flip", "fliplr", "flipud", "floor_divide", "frombuffer", "fromfile", "fromfunction", "fromiter", "fromstring", "full", "full_like", "geomspace", "heaviside", "hsplit", "hstack", "hypot", "identity", "indices", "inner", "insert", "invert", "ix_", "kron", "left_shift", "linspace", "loadNpz", "loadNpzSync", "logspace", "mask_indices", "median", "meshgrid", "mod", "moveaxis", "nanargmax", "nanargmin", "nancumprod", "nancumsum", "nanmax", "nanmean", "nanmedian", "nanmin", "nanprod", "nanstd", "nansum", "nanvar", "negative", "ones", "ones_like", "outer", "packbits", "pad", "parseNpy", "parseNpyData", "parseNpyHeader", "parseNpz", "parseNpzSync", "percentile", "place", "positive", "power", "ptp", "put", "put_along_axis", "putmask", "quantile", "rad2deg", "radians", "ravel", "ravel_multi_index", "reciprocal", "remainder", "repeat", "reshape", "resize", "right_shift", "roll", "rollaxis", "rot90", "row_stack", "select", "serializeNpy", "serializeNpz", "serializeNpzSync", "sign", "sin", "sinh", "split", "sqrt", "square", "squeeze", "stack", "swapaxes", "take", "take_along_axis", "tan", "tanh", "tensordot", "tile", "trace", "transpose", "tri", "tril", "tril_indices", "tril_indices_from", "triu", "triu_indices", "triu_indices_from", "unpackbits", "unravel_index", "vander", "vsplit", "vstack", "zeros", "zeros_like", "__toCommonJS", "parseSlice", "sliceStr", "index", "parts", "start", "stop", "step", "normalizeSlice", "spec", "size", "isIndex", "normalizedStart", "DEFAULT_DTYPE", "getTypedArrayConstructor", "dtype", "getDTypeSize", "isIntegerDType", "isFloatDType", "isBigIntDType", "promoteDTypes", "dtype1", "dtype2", "isFloatDType", "intDtype", "isSigned1", "isSigned2", "isUnsigned1", "isUnsigned2", "getSize", "dtype", "size1", "size2", "maxSize", "ArrayStorage", "_ArrayStorage", "data", "shape", "strides", "offset", "dtype", "a", "b", "ndim", "expectedStride", "i", "linearIndex", "remaining", "bufferIndex", "dimSize", "j", "idx", "value", "indices", "size", "Constructor", "getTypedArrayConstructor", "newData", "isBigIntDType", "src", "dst", "finalStrides", "finalOffset", "DEFAULT_DTYPE", "stride", "computeStrides", "broadcastShapes", "shapeA", "shapeB", "ndimA", "ndimB", "ndim", "result", "i", "dimA", "dimB", "broadcastStrides", "shape", "strides", "targetShape", "targetNdim", "targetIdx", "dim", "targetDim", "broadcastTo", "storage", "broadcastedStrides", "ArrayStorage", "elementwiseBinaryOp", "a", "b", "op", "opName", "outputShape", "aBroadcast", "bBroadcast", "resultDtype", "promoteDTypes", "resultData", "size", "isBigIntDType", "resultTyped", "aRaw", "bRaw", "aVal", "bVal", "needsConversion", "elementwiseComparisonOp", "elementwiseUnaryOp", "preserveDtype", "dtype", "inputData", "val", "canUseFastPath", "a", "b", "dim", "i", "add", "addScalar", "addArraysFast", "elementwiseBinaryOp", "x", "y", "dtype", "promoteDTypes", "result", "ArrayStorage", "size", "aData", "bData", "resultData", "isBigIntDType", "resultTyped", "aVal", "bVal", "aTyped", "bTyped", "subtract", "subtractScalar", "subtractArraysFast", "multiply", "multiplyScalar", "multiplyArraysFast", "divide", "divideScalar", "aIsFloat64", "bIsFloat64", "aIsFloat32", "bIsFloat32", "aFloat", "convertToFloatDType", "bFloat", "storage", "targetDtype", "srcData", "dstData", "scalar", "shape", "data", "thisTyped", "scalarBig", "resultDtype", "absolute", "val", "negative", "sign", "mod", "modScalar", "divisor", "divisorBig", "floorDivide", "floorDivideScalar", "positive", "reciprocal", "cbrt", "fabs", "divmod", "quotient", "remainder", "square", "bigData", "bigResultData", "heaviside", "x1", "x2", "x2Data", "x2Shape", "d", "x2Idx", "computeBroadcastShape", "shapes", "maxNdim", "s", "result", "i", "dim", "shape", "shapeIdx", "shapeDim", "broadcastStrides", "shape", "strides", "targetShape", "ndim", "targetNdim", "result", "i", "targetIdx", "dim", "targetDim", "broadcastTo", "storage", "broadcastedStrides", "ArrayStorage", "broadcastShapes", "shapes", "result", "computeBroadcastShape", "shapeStrs", "s", "greater", "a", "b", "greaterScalar", "elementwiseComparisonOp", "x", "y", "greaterEqual", "greaterEqualScalar", "less", "lessScalar", "lessEqual", "lessEqualScalar", "equal", "equalScalar", "notEqual", "notEqualScalar", "isclose", "rtol", "atol", "iscloseScalar", "diff", "threshold", "allclose", "closeResult", "data", "i", "arrayEquiv", "a1", "a2", "shapes", "broadcastShape", "computeBroadcastShape", "b1", "broadcastTo", "b2", "ndim", "size", "acc", "d", "isBigInt1", "isBigIntDType", "isBigInt2", "flatIdx", "temp", "indices", "val1", "val2", "v1", "v2", "storage", "scalar", "thisData", "ArrayStorage", "dtype", "scalarBig", "typedData", "thisTyped", "multiIndexToLinear", "indices", "shape", "linearIdx", "stride", "i", "outerIndexToMultiIndex", "outerIdx", "axis", "axisIdx", "ndim", "outputShape", "_", "remaining", "sum", "storage", "axis", "keepdims", "dtype", "shape", "ndim", "size", "data", "isBigIntDType", "typedData", "total", "i", "normalizedAxis", "outputShape", "_", "result", "ArrayStorage", "resultData", "axisSize", "outerSize", "a", "b", "resultTyped", "outerIdx", "sumVal", "axisIdx", "inputIndices", "outerIndexToMultiIndex", "linearIdx", "multiIndexToLinear", "keepdimsShape", "mean", "sumResult", "divisor", "resultDtype", "sumData", "sumTyped", "max", "maxVal", "firstIndices", "firstIdx", "val", "prod", "product", "prodVal", "min", "minVal", "argmin", "minIdx", "minAxisIdx", "argmax", "maxIdx", "maxAxisIdx", "variance", "ddof", "meanResult", "meanVal", "sumSqDiff", "diff", "meanArray", "meanData", "std", "varResult", "varData", "all", "allTrue", "any", "anyTrue", "cumsum", "strides", "stride", "totalSize", "axisStride", "cumprod", "ptp", "maxResult", "minResult", "maxStorage", "minStorage", "maxData", "minData", "median", "quantile", "percentile", "q", "values", "n", "idx", "lower", "upper", "frac", "average", "weights", "sumWeightedValues", "sumWeights", "weightData", "w", "nansum", "nanprod", "nanmean", "count", "nanvar", "sumSq", "nanstd", "varStorage", "nanmin", "nanmax", "nanargmin", "nanargmax", "nancumsum", "nancumprod", "nanmedian", "mid", "reshape", "storage", "newShape", "size", "dtype", "negIndex", "finalShape", "knownSize", "acc", "dim", "i", "inferredDim", "a", "b", "data", "ArrayStorage", "computeStrides", "flatten", "Constructor", "getTypedArrayConstructor", "newData", "isBigInt", "isBigIntDType", "value", "ravel", "transpose", "axes", "shape", "ndim", "strides", "permutation", "_", "seen", "axis", "normalizedAxis", "ax", "oldStrides", "newStrides", "squeeze", "expandDims", "insertedStride", "swapaxes", "axis1", "axis2", "normalizedAxis1", "normalizedAxis2", "moveaxis", "source", "destination", "sourceArr", "destArr", "normalizedSource", "normalized", "normalizedDest", "order", "dst", "concatenate", "storages", "first", "s", "outputShape", "totalAlongAxis", "outputSize", "outputData", "outputStrides", "offset", "axisSize", "copyToOutput", "_outputShape", "axisOffset", "sourceShape", "sourceSize", "outputOffset", "sourceData", "start", "end", "rows", "cols", "outputCols", "sourceStart", "row", "sourceRowStart", "outputRowStart", "indices", "baseOutputOffset", "outputIdx", "d", "stack", "expanded", "vstack", "prepared", "hstack", "dstack", "split", "indicesOrSections", "splitIndices", "sectionSize", "splitAtIndices", "arraySplit", "numSections", "remainder", "boundaries", "result", "sliceShape", "newOffset", "vsplit", "hsplit", "tile", "reps", "repsArr", "maxDim", "paddedShape", "paddedReps", "expandedStorage", "expandedStrides", "outputIndices", "sourceFlatIdx", "sourceIdx", "repeat", "repeats", "flatSize", "repeatsArr", "outIdx", "rep", "r", "sourceIndices", "axisPositions", "axisIdx", "baseOutIdx", "axisStride", "axisStart", "flip", "axesToFlip", "c", "sourceOffset", "rot90", "k", "axis0", "outIdx0", "outIdx1", "roll", "shift", "flatShift", "flatStorage", "shifts", "normalizedAxes", "j", "sh", "rollaxis", "normalizedStart", "dsplit", "columnStack", "resize", "storage", "newShape", "dtype", "newSize", "a", "b", "oldSize", "Constructor", "getTypedArrayConstructor", "outputData", "isBigInt", "isBigIntDType", "sourceIdx", "value", "ArrayStorage", "atleast1d", "storages", "s", "reshape", "atleast2d", "atleast3d", "dgemm", "layout", "transA", "transB", "M", "N", "K", "alpha", "A", "lda", "B", "ldb", "beta", "C", "ldc", "i", "isRowMajor", "transposeA", "transposeB", "j", "sum", "k", "dot", "a", "b", "aDim", "bDim", "aVal", "bVal", "resultDtype", "promoteDTypes", "result", "ArrayStorage", "bData", "aData", "n", "matmul", "m", "lastDimA", "bSize", "resultShape", "resultSize", "acc", "dim", "temp", "resultIdx", "d", "aIdx", "aSize", "contractAxisB", "contractDimB", "bIdxBefore", "bIdxAfter", "bIdx", "secondLastDimB", "aOuterSize", "bOuterSize", "bLastDim", "contractionDim", "k2", "computeDtype", "aStrideRow", "aStrideCol", "bStrideRow", "bStrideCol", "aIsTransposed", "bIsTransposed", "trace", "rows", "cols", "diagLen", "val", "transpose", "axes", "inner", "aLastDim", "outer", "aFlat", "ravel", "bFlat", "product", "tensordot", "aAxes", "bAxes", "_", "aAxis", "bAxis", "aFreeAxes", "bFreeAxes", "ax", "contractSize", "contractedIdx", "resIdx", "resultIndices", "aFreeIndices", "bFreeIndices", "c", "contractedIndices", "aFullIdx", "bFullIdx", "diagonal", "offset", "axis1", "axis2", "shape", "ndim", "ax1", "ax2", "dim1", "dim2", "outShape", "otherDims", "otherSize", "otherIdx", "otherIndices", "srcIndices", "otherIdx2", "dstIndices", "value", "einsum", "subscripts", "operands", "arrowMatch", "inputSubscripts", "outputSubscript", "inferOutputSubscript", "operandSubscripts", "s", "indexDims", "sub", "op", "idx", "outputIndices", "allInputIndices", "sumIndices", "sub1", "sub2", "op1", "op2", "i1", "j1", "i2", "j2", "o1", "o2", "op1T", "op2T", "computeEinsumScalar", "outputShape", "outputSize", "sumSize", "outIdx", "outMultiIdx", "flatToMulti", "indexValues", "sumIdx", "opIdx", "counts", "count", "flatIdx", "kron", "aShape", "bShape", "aNdim", "bNdim", "aPadded", "bPadded", "aIndices", "aIndicesPadded", "temp2", "bIndices", "bIndicesPadded", "outIndices", "sqrt", "a", "elementwiseUnaryOp", "power", "b", "powerScalar", "elementwiseBinaryOp", "storage", "exponent", "dtype", "shape", "data", "size", "resultDtype", "result", "ArrayStorage", "resultData", "isBigIntDType", "thisTyped", "resultTyped", "i", "sin", "a", "elementwiseUnaryOp", "cos", "tan", "arcsin", "arccos", "arctan", "arctan2", "x1", "x2", "arctan2Scalar", "arctan2Array", "shape", "size", "dtype1", "dtype2", "resultDtype", "result", "ArrayStorage", "resultData", "i", "val1", "isBigIntDType", "val2", "storage", "dtype", "data", "hypot", "hypotScalar", "hypotArray", "degrees", "factor", "x", "radians", "sinh", "a", "elementwiseUnaryOp", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", "broadcast_to", "storage", "targetShape", "shape", "ndim", "targetNdim", "broadcastedShape", "computeBroadcastShape", "i", "broadcastTo", "broadcast_arrays", "storages", "shapes", "s", "take", "storage", "indices", "axis", "shape", "ndim", "dtype", "flatSize", "idx", "normalizedIdx", "outputSize", "Constructor", "getTypedArrayConstructor", "outputData", "i", "value", "isBigIntDType", "ArrayStorage", "normalizedAxis", "axisSize", "outputShape", "a", "b", "outputStrides", "computeStrides", "outputIndices", "sourceIndices", "targetIdx", "sourceAxisIdx", "outIdx", "d", "put", "values", "valueArray", "original", "choose", "indexStorage", "choices", "indexShape", "numChoices", "shapes", "c", "broadcastedShape", "computeBroadcastShape", "broadcastedIndex", "broadcastTo", "broadcastedChoices", "choiceIdx", "array_equal", "equal_nan", "size", "aVal", "bVal", "aIsNaN", "bIsNaN", "take_along_axis", "indicesShape", "inputStrides", "indicesStrides", "multiIdx", "remaining", "indicesLinearIdx", "indexValue", "sourceMultiIdx", "srcLinearIdx", "put_along_axis", "valuesShape", "valuesStrides", "indicesSize", "valuesLinearIdx", "vidx", "destMultiIdx", "destLinearIdx", "putmask", "mask", "valueIdx", "compress", "condition", "inputData", "isBigInt", "trueCount", "maxLen", "axisMap", "strideAlongAxis", "elementsPerSlice", "srcOffset", "src", "dst", "j", "outerSize", "innerSize", "outer", "axisIdx", "inputAxisIdx", "baseOffset", "rem", "inner", "select", "condlist", "choicelist", "defaultValue", "allShapes", "defaultVal", "broadcastedConds", "place", "vals", "diag_indices", "n", "result", "diag_indices_from", "tril_indices", "k", "m", "cols", "rows", "colIndices", "tril_indices_from", "triu_indices", "triu_indices_from", "mask_indices", "mask_func", "maskShape", "dimensions", "gridSize", "sliceOffset", "gridIdx", "ix_", "args", "arr", "arrSize", "data", "ravel_multi_index", "multi_index", "dims", "mode", "strides", "stride", "flatIdx", "dimSize", "unravel_index", "order", "indicesArray", "totalSize", "coord", "validateIntegerDType", "dtype", "opName", "isIntegerDType", "canUseFastPath", "a", "b", "dim", "i", "bitwise_and", "bitwiseAndScalar", "bitwiseAndArraysFast", "elementwiseBinaryOp", "x", "y", "promoteDTypes", "result", "ArrayStorage", "size", "aData", "bData", "resultData", "isBigIntDType", "resultTyped", "aVal", "bVal", "aTyped", "bTyped", "storage", "scalar", "shape", "data", "thisTyped", "scalarBig", "bitwise_or", "bitwiseOrScalar", "bitwiseOrArraysFast", "bitwise_xor", "bitwiseXorScalar", "bitwiseXorArraysFast", "bitwise_not", "invert", "left_shift", "leftShiftScalar", "shiftVal", "leftShiftArraysFast", "shift", "shiftBig", "right_shift", "rightShiftScalar", "rightShiftArraysFast", "packbits", "axis", "bitorder", "ndim", "axisSize", "packedAxisSize", "outShape", "byte", "bit", "srcIdx", "val", "preAxisShape", "postAxisShape", "preAxisSize", "acc", "postAxisSize", "inputStrides", "computeStrides", "outputStrides", "pre", "post", "packedIdx", "axisIdx", "inputIdx", "preRemaining", "d", "dimSize", "coord", "postRemaining", "outputIdx", "unpackbits", "count", "unpackedAxisSize", "outIdx", "strides", "stride", "NDArray", "_NDArray", "storage", "base", "indices", "normalizedIndices", "idx", "dim", "normalized", "value", "currentDtype", "convertedValue", "isBigIntDType", "dtype", "copy", "shape", "size", "Constructor", "getTypedArrayConstructor", "newData", "oldData", "typedOldData", "i", "ArrayStorage", "other", "otherStorage", "resultStorage", "add", "subtract", "multiply", "divide", "mod", "floorDivide", "positive", "reciprocal", "sqrt", "exponent", "exponentStorage", "power", "absolute", "negative", "sign", "sin", "cos", "tan", "arcsin", "arccos", "arctan", "arctan2", "hypot", "degrees", "radians", "sinh", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", "greater", "greaterEqual", "less", "lessEqual", "equal", "notEqual", "rtol", "atol", "isclose", "allclose", "bitwise_and", "bitwise_or", "bitwise_xor", "bitwise_not", "invert", "shift", "shiftStorage", "left_shift", "right_shift", "axis", "keepdims", "result", "sum", "mean", "max", "min", "prod", "argmin", "argmax", "ddof", "variance", "std", "all", "any", "cumsum", "cumprod", "ptp", "median", "q", "percentile", "quantile", "weights", "average", "nansum", "nanprod", "nanmean", "nanvar", "nanstd", "nanmin", "nanmax", "nanargmin", "nanargmax", "nancumsum", "nancumprod", "nanmedian", "newShape", "reshape", "flatten", "ravel", "axes", "transpose", "squeeze", "expandDims", "axis1", "axis2", "swapaxes", "source", "destination", "moveaxis", "repeats", "repeat", "take", "values", "valuesStorage", "put", "matmul", "dot", "trace", "inner", "outer", "tensordot", "cbrt", "fabs", "divisor", "divisorStorage", "quotientStorage", "remainderStorage", "divmod", "square", "remainder", "x2", "x2Storage", "heaviside", "sliceStrs", "sliceSpecs", "str", "spec", "parseSlice", "normalizeSlice", "newStrides", "newOffset", "stride", "dimSize", "slicedStorage", "j", "start", "stop", "ndim", "buildNestedArray", "arr", "zeros", "DEFAULT_DTYPE", "ones", "inferShape", "data", "current", "containsBigInt", "item", "flattenKeepBigInt", "array", "hasBigInt", "a", "b", "actualDtype", "typedData", "flatData", "bigintData", "val", "boolData", "numData", "arange", "step", "actualStart", "actualStop", "length", "linspace", "num", "logspace", "geomspace", "signStart", "signStop", "logStart", "eye", "n", "m", "k", "cols", "empty", "full", "fill_value", "bigintValue", "identity", "asarray", "zeros_like", "ones_like", "empty_like", "full_like", "asanyarray", "ascontiguousarray", "asfortranarray", "diag", "v", "row", "col", "rows", "startRow", "startCol", "diagLength", "diagflat", "flat", "fromfunction", "fn", "d", "meshgrid", "args", "arrays", "indexing", "arg", "sizes", "outputShape", "results", "inputArr", "inputSize", "broadcastShape", "reshaped", "broadcast_to", "tri", "N", "M", "tril", "outerSize", "temp", "triu", "vander", "x", "increasing", "len", "frombuffer", "buffer", "count", "offset", "arrayBuffer", "byteOffset", "bytesPerElement", "getBytesPerElement", "availableBytes", "maxElements", "numElements", "fromfile", "file", "fromiter", "iter", "fromstring", "string", "sep", "parts", "part", "trimmed", "floor_divide", "diagonal", "kron", "x1", "deg2rad", "rad2deg", "concatenate", "storages", "stack", "vstack", "hstack", "dstack", "split", "indicesOrSections", "s", "array_split", "arraySplit", "vsplit", "hsplit", "tile", "reps", "expand_dims", "flip", "fliplr", "flipud", "rot90", "roll", "rollaxis", "atleast_1d", "atleast1d", "atleast_2d", "atleast2d", "atleast_3d", "atleast3d", "dsplit", "ary", "indices_or_sections", "column_stack", "columnStack", "row_stack", "resize", "new_shape", "append", "valArray", "flatArr", "flatValues", "delete_", "obj", "keepIndices", "normalizedAxis", "axisSize", "keepRanges", "rangeStart", "rangeEnd", "slices", "insert", "before", "after", "pad", "pad_width", "mode", "constant_values", "padWidths", "newSize", "outputData", "isBigInt", "outputIndices", "inOriginal", "sourceIndices", "padBefore", "srcIdx", "mappedIndices", "broadcast_arrays", "broadcast_shapes", "shapes", "broadcastShapes", "choose", "choices", "choiceStorages", "c", "array_equal", "equal_nan", "array_equiv", "a1", "a2", "arrayEquiv", "weightsStorage", "y", "packbits", "bitorder", "unpackbits", "einsum", "subscripts", "operands", "op", "take_along_axis", "put_along_axis", "putmask", "mask", "valuesArg", "compress", "condition", "select", "condlist", "choicelist", "defaultVal", "condStorages", "place", "vals", "diag_indices", "diag_indices_from", "tril_indices", "tril_indices_from", "triu_indices", "triu_indices_from", "mask_indices", "mask_func", "dimensions", "ix_", "ravel_multi_index", "multi_index", "dims", "unravel_index", "order", "indicesArg", "NPY_MAGIC", "SUPPORTED_DTYPES", "isSystemLittleEndian", "buffer", "DESCR_TO_DTYPE", "DTYPE_TO_DESCR", "UNSUPPORTED_DTYPE_PATTERNS", "parseDescriptor", "descr", "UnsupportedDTypeError", "endian", "typeAndSize", "typeChar", "dtype", "isLittleEndian", "dataIsLittleEndian", "dataIsBigEndian", "itemsize", "needsByteSwap", "message", "InvalidNpyError", "parseNpy", "buffer", "bytes", "metadata", "parseNpyHeader", "parseNpyData", "InvalidNpyError", "i", "NPY_MAGIC", "major", "minor", "headerLen", "headerStart", "headerEnd", "headerBytes", "headerStr", "header", "parseHeaderDict", "dataOffset", "dtype", "needsByteSwap", "itemsize", "parseDescriptor", "numElements", "a", "b", "expectedBytes", "actualBytes", "dataBuffer", "typedData", "createTypedArray", "shape", "storage", "reversedShape", "tempStorage", "ArrayStorage", "transposeStorage", "NDArray", "descrMatch", "fortranMatch", "shapeMatch", "descr", "fortran_order", "shapeStr", "s", "n", "Constructor", "getTypedArrayConstructor", "swapped", "start", "j", "ndim", "size", "newData", "newShape", "oldStrides", "computeStrides", "newStrides", "indices", "linearIdx", "remaining", "dimSize", "newLinearIdx", "isBigIntDType", "strides", "stride", "serializeNpy", "arr", "shape", "dtype", "descr", "DTYPE_TO_DESCR", "shapeStr", "headerDict", "PREFIX_LEN", "padding", "headerBytes", "headerLen", "numElements", "itemsize", "getDTypeSize", "dataSize", "totalSize", "output", "NPY_MAGIC", "dataOffset", "writeArrayData", "size", "isLittleEndian", "isSystemLittleEndian", "isBigInt", "isBigIntDType", "storage", "srcData", "srcBytes", "dataView", "i", "value", "offset", "writeBigInt64LE", "writeNumberLE", "view", "unsigned", "CRC32_TABLE", "table", "i", "c", "j", "crc32", "data", "crc", "readZip", "buffer", "entries", "parseZipEntries", "result", "entry", "data", "decompressEntry", "readZipSync", "bytes", "view", "eocdOffset", "i", "centralDirOffset", "numEntries", "centralEntries", "cdOffset", "compressionMethod", "crc32", "compressedSize", "uncompressedSize", "fileNameLength", "extraFieldLength", "commentLength", "localHeaderOffset", "fileNameBytes", "fileName", "ce", "localOffset", "dataStart", "compressedData", "inflateRaw", "ds", "dataCopy", "writer", "reader", "chunks", "done", "value", "totalLength", "sum", "chunk", "offset", "parseNpz", "buffer", "options", "force", "files", "readZip", "parseNpzFromFiles", "parseNpzSync", "readZipSync", "arrays", "skipped", "errors", "fileName", "data", "name", "arr", "parseNpy", "error", "UnsupportedDTypeError", "loadNpz", "result", "loadNpzSync", "writeZip", "files", "options", "compress", "entries", "name", "data", "crc", "crc32", "compressedData", "compressionMethod", "deflateRaw", "localHeadersSize", "entry", "nameBytes", "centralDirSize", "totalSize", "output", "view", "offset", "writeLocalHeader", "centralDirOffset", "writeCentralHeader", "writeEndOfCentralDirectory", "writeZipSync", "numEntries", "cs", "dataCopy", "writer", "reader", "chunks", "done", "value", "totalLength", "sum", "chunk", "result", "serializeNpz", "arrays", "options", "files", "prepareNpzFiles", "writeZip", "serializeNpzSync", "writeZipSync", "i", "arr", "npyData", "serializeNpy", "entries", "name", "fileName", "__version__"]
7
7
  }