import type { TUnaryOperationLeftName, TBinaryOperationName } from './ComplexInterface';
import { ComplexType } from './Complex';
import { CharString } from './CharString';
import { Structure } from './Structure';
import { FunctionHandle } from './FunctionHandle';
import { NodeReturnList } from './AST';
import { Evaluator, Scope } from './Evaluator';
/**
 * MultiArray Element type.
 */
type Elements = ComplexType | CharString | Structure | FunctionHandle;
type ElementType<ELEMENT = Elements> = MultiArray | ELEMENT | null | undefined;
/**
 * Reduce factory function types.
 */
type ReduceComparisonType = 'lt' | 'gt';
type ReduceType = 'reduce' | 'cumulative' | 'cumcomparison' | 'comparison';
type ReduceElementType<ELEMENT = Elements> = ElementType<ELEMENT>;
type ReduceCallbackType = (prev: ReduceElementType, curr: ReduceElementType, index?: number) => ReduceElementType;
type ReduceCallbackOrComparisonType = ReduceCallbackType | ReduceComparisonType;
type ReduceInitialType = ReduceElementType;
type ReduceReduceHandlerType = (M: ReduceElementType, DIM?: ReduceElementType) => ReduceElementType;
type ReduceComparisonHandlerType<ELEMENT = Elements> = (...args: ElementType<ELEMENT>[]) => MultiArray<ELEMENT> | NodeReturnList | undefined;
type ReduceHandlerType = ReduceReduceHandlerType | ReduceComparisonHandlerType;
/**
 * # MultiArray
 *
 * Multimensional array library. This class represents common arrays and cell arrays.
 */
declare class MultiArray<ELEMENT = Elements> {
    /**
     * Dimensions property ([lines, columns, pages, blocks, ...]).
     */
    dimension: number[];
    /**
     * Dimensions excluding columns getter ([lines, pages, blocks, ...]).
     */
    get dimensionR(): number[];
    /**
     * Array content.
     */
    array: ElementType<ELEMENT>[][];
    /**
     * Type attribute.
     */
    type: number;
    /**
     * Test if an object is a instance of `MultiArray`.
     * @param obj Object to test.
     * @returns `true` if `obj` is an instance of `MultiArray`. `false` otherwise.
     */
    static readonly isInstanceOf: (obj: unknown) => obj is MultiArray;
    static readonly LOGICAL: number;
    static readonly REAL: number;
    static readonly COMPLEX: number;
    static readonly STRING = 3;
    static readonly STRUCTURE = 4;
    static readonly FUNCTION_HANDLE = 5;
    /**
     * True if cell array.
     */
    isCell: boolean;
    /**
     * Parent node property.
     */
    parent: any;
    /**
     * MultiArray constructor.
     * @param shape Dimensions ([rows, columns, pages, blocks, ...]).
     * @param fill Data to fill MultiArray. The same object will be put in all elements of MultiArray.
     */
    constructor(shape?: number[], fill?: ElementType | ((...dims: number[]) => ElementType) | ElementType[][], iscell?: boolean);
    /**
     * Check if object is a scalar.
     * @param obj Any object.
     * @returns `true` if object is a scalar. false otherwise.
     */
    static readonly isScalar: (obj: unknown) => boolean;
    /**
     * Check if object is a MultiArray and it is a row vector.
     * @param obj Any object.
     * @returns `true` if object is a row vector. false otherwise.
     */
    static readonly isRowVector: (obj: unknown) => boolean;
    /**
     * Converts a vector of type `ElementType[]` into a row matrix of type `MultiArray`.
     * @param vector
     * @returns
     */
    static readonly toRowVector: (vector: ElementType[]) => MultiArray;
    /**
     *
     * @param vector
     * @returns
     */
    static readonly fromRowVector: (vector: MultiArray) => ElementType[];
    /**
     * Check if object is a MultiArray and it is a row vector.
     * @param obj Any object.
     * @returns `true` if object is a row vector. false otherwise.
     */
    static readonly isColumnVector: (obj: unknown) => boolean;
    /**
     * Converts a vector of type `ElementType[]` into a column matrix of type `MultiArray`.
     * @param vector
     * @returns
     */
    static readonly toColumnVector: (vector: ElementType[]) => MultiArray;
    /**
     *
     * @param vector
     * @returns
     */
    static readonly fromColumnVector: (vector: MultiArray) => ElementType[];
    /**
     * Check if a MultiArray is a row vector or a column vector.
     * @param array MultiArray to test.
     * @returns `true` if `array` is a vector (column vector or row vector), otherwise `false`.
     */
    static readonly arrayIsVector: (array: MultiArray) => boolean;
    /**
     * Check if object is a MultiArray and it is a row vector or a column vector.
     * @param obj Any object.
     * @returns `true` if object is a row vector or a column vector. false otherwise.
     */
    static readonly isVector: (obj: unknown) => boolean;
    /**
     * * Converts a vector of type `ElementType[]` into a diagonal matrix of type `MultiArray`.
     * @param vector
     * @returns
     */
    static readonly toDiagonalMatrix: (vector: ElementType[]) => MultiArray;
    /**
     * Check if object is a scalar or a 2-D MultiArray.
     * @param obj Any object.
     * @returns `true` if object is a row vector or a column vector. false otherwise.
     */
    static readonly isMatrix: (obj: unknown) => boolean;
    /**
     * Returns `true` if `obj` any one of its dimensions is zero.
     * Returns `false` otherwise.
     * @param obj Any object.
     * @returns `true` if object is an empty array.
     */
    static readonly isEmpty: (obj: unknown) => boolean;
    /**
     * Check if object is a MultiArray and it is a cell array.
     * @param obj Any object.
     * @returns `true` if object is a cell array. false otherwise.
     */
    static readonly isCellArray: (obj: unknown) => boolean;
    /**
     *
     * @param M
     * @returns
     */
    static readonly isComplexMultiArray: (M: MultiArray) => boolean;
    /**
     * Set type property in place with maximum value of array items type.
     * @param M MultiArray to set type property.
     */
    static readonly setType: (M: MultiArray) => void;
    /**
     * Test if two array are equals.
     * @param left Array<boolean | number | string>.
     * @param right Array<boolean | number | string>.
     * @returns true if two arrays are equals. false otherwise.
     */
    static readonly arrayEquals: (a: (boolean | number | string)[], b: (boolean | number | string)[]) => boolean;
    /**
     * Returns a one-based range array ([1, 2, ..., length]).
     * @param length Length or last value of range array.
     * @returns Range array.
     */
    static readonly rangeArray: (length: number) => number[];
    /**
     * Converts linear index to subscript.
     * @param dimension Dimensions of multidimensional array ([line, column, page, block, ...]).
     * @param index Zero-based linear index.
     * @returns One-based subscript ([line, column, page, block, ...]).
     */
    static readonly linearIndexToSubscript: (dimension: number[], index: number) => number[];
    /**
     * Converts subscript to linear index.
     * @param dimension Dimensions of multidimensional array ([lines, columns, pages, blocks, ...]).
     * @param subscript One-based subscript ([line, column, page, block, ...]).
     * @returns Zero-based linear index.
     */
    static readonly subscriptToLinearIndex: (dimension: number[], subscript: number[]) => number;
    /**
     * Converts linear index to MultiArray.array subscript.
     * @param row Row dimension.
     * @param column Column dimension.
     * @param index Zero-based linear index.
     * @returns MultiArray.array subscript ([row, column]).
     */
    static readonly linearIndexToMultiArrayRowColumn: (row: number, column: number, index: number) => [number, number];
    /**
     * Converts MultiArray subscript to MultiArray.array subscript.
     * @param dimension MultiArray dimension.
     * @param subscript Subscript.
     * @returns MultiArray.array subscript ([row, column]).
     */
    static readonly subscriptToMultiArrayRowColumn: (dimension: number[], subscript: number[]) => [number, number];
    /**
     * Converts MultiArray raw row and column to MultiArray linear index.
     * @param dimension MultiArray dimension (can be only the two first dimensions)
     * @param i Raw row
     * @param j Raw column
     * @returns Linear index
     */
    static readonly rowColumnToLinearIndex: (dimension: number[], i: number, j: number) => number;
    /**
     * Converts MultiArray raw row and column to MultiArray subscript.
     * @param dimension
     * @param i
     * @param j
     * @returns
     */
    static readonly rowColumnToSubscript: (dimension: number[], i: number, j: number) => number[];
    /**
     * Compute stride vector (column-major order).
     * Example: [3,4,2] → [1, 3, 12]
     */
    static readonly computeStrides: (dim: number[]) => number[];
    /**
     *
     * @param M
     * @param dim
     * @returns
     */
    static readonly getStride: (M: MultiArray, dim: number) => number;
    /**
     * Returns a 2D slice corresponding to page k (for 3D+ arrays).
     * @param M
     * @param pageIndex
     * @returns
     */
    static readonly pageSlice: (M: MultiArray, pageIndex: number) => ComplexType[][];
    /**
     * Sets the 2D pageIndex page in an N-D (row-major) MultiArray.
     * @param M
     * @param pageIndex
     * @param pageData
     */
    static readonly setPage: (M: MultiArray, pageIndex: number, pageData: ComplexType[][]) => void;
    /**
     * Returns content as 1D array (column-major linear order), length = product(dimension).
     * @param arr
     * @returns
     */
    static readonly toFlatArray: (arr: MultiArray) => ComplexType[];
    /**
     * Reconstructs arr.array (2D physical storage) from the column-major linear vector.
     * @param arr
     * @param flat
     */
    static readonly fromFlatArray: (arr: MultiArray, flat: ComplexType[]) => void;
    /**
     * Check if two MultiArrays have the same shape, or if they are identical
     * except for one dimension d where both have size 3.
     *
     * Returns true if either:
     *  - A.dimension equals B.dimension (exact match), or
     *  - there exists an index d such that A.dimension[d] === 3 and B.dimension[d] === 3
     *    and for every i !== d we have A.dimension[i] === B.dimension[i].
     *
     * This matches the requirement of cross(A,B) where the operation dimension
     * must have length 3 while all other dimensions must match.
     * @param A
     * @param B
     * @returns
     */
    static readonly sameSizeExcept: (A: MultiArray, B: MultiArray) => boolean;
    /**
     * Base method of the ind2sub function. Returns dimension.length + 1
     * dimensions. If the index exceeds the dimensions, the last dimension
     * will contain the multiplier of the other dimensions. Otherwise it will
     * be 1.
     * @param dimension Array of dimensions.
     * @param index One-base linear index.
     * @returns One-based subscript ([line, column, page, block, ...]).
     */
    static readonly ind2subNumber: (dimension: number[], index: number) => number[];
    /**
     * Returns the number of elements in M.
     * @param M Multidimensional array.
     * @returns Number of elements in M.
     */
    static readonly linearLength: (M: MultiArray) => number;
    /**
     * Get dimension at index d of MultiArray M
     * @param M MultiArray.
     * @param d Zero-based dimension index.
     * @returns Dimension d.
     */
    static readonly getDimension: (M: MultiArray, d: number) => number;
    /**
     * Remove singleton tail of dimension array in place.
     * @param dimension Dimension array.
     */
    static readonly removeSingletonTail: (dimension: number[]) => void;
    /**
     * Append singleton tail of dimension array in place.
     * @param dimension Dimension array.
     * @param length Resulting length of dimension array.
     */
    static readonly appendSingletonTail: (dimension: number[], length: number) => void;
    /**
     * Find first non-single dimension.
     * @param M MultiArray.
     * @returns First non-single dimension of `M`.
     */
    static readonly firstNonSingleDimension: (M: MultiArray) => number;
    /**
     * Creates a MultiArray object from the first row of elements (for
     * parsing purposes).
     * @param row Array of objects.
     * @returns MultiArray with `row` parameter as first line.
     */
    static readonly firstRow: (row: ElementType[], iscell?: boolean) => MultiArray;
    /**
     * Append a row of elements to a MultiArray object (for parsing
     * purposes).
     * @param M MultiArray.
     * @param row Array of objects to append as row of MultiArray.
     * @returns MultiArray with row appended.
     */
    static readonly appendRow: (M: MultiArray, row: ElementType[]) => MultiArray;
    /**
     * Unparse MultiArray.
     * @param M MultiArray object.
     * @returns String of unparsed MultiArray.
     */
    static readonly unparse: (M: MultiArray, evaluator: Evaluator, parentPrecedence?: number) => string;
    /**
     * Create a string simple representation for a MultiArray (only dimensions).
     * @returns
     */
    toString(): string;
    /**
     * Unparse MultiArray as MathML language.
     * @param M MultiArray object.
     * @returns String of unparsed MultiArray in MathML language.
     */
    static readonly unparseMathML: (M: MultiArray, evaluator: Evaluator, parentPrecedence?: number) => string;
    /**
     * Converts CharString to MultiArray.
     * @param text CharString.
     * @returns MultiArray with character codes as integer.
     */
    static readonly fromCharString: (text: CharString) => MultiArray;
    /**
     * Linearize MultiArray in an array of ElementType using row-major
     * order.
     * @param M
     * @returns
     */
    static readonly flatten: (M: MultiArray) => ElementType[];
    /**
     * Linearize MultiArray in an array of ElementType using column-major
     * order.
     * @param M Multidimensional array.
     * @returns `ElementType[]` of multidimensional array `M` linearized.
     */
    static readonly linearize: (M: ElementType) => ElementType[];
    /**
     * Returns a empty array (0x0 matrix).
     * @returns Empty array (0x0 matrix).
     */
    static readonly emptyArray: (iscell?: boolean) => MultiArray;
    /**
     * Convert scalar to MultiArray with aditional test if it is MultiArray.
     * @param value
     * @param test
     * @returns
     */
    private static readonly scalarToMultiArrayWithTest;
    /**
     * If value is a scalar then convert to a 1x1 MultiArray. If is cell array
     * the cell is put in a 1x1 MultiArray too.
     * @param value MultiArray or scalar.
     * @returns MultiArray 1x1 if value is scalar.
     */
    static readonly scalarToMultiArray: (value: ElementType) => MultiArray;
    /**
     * If value is a scalar then convert to a 1x1 MultiArray. If is common
     * array or cell array returns `value` unchanged.
     * @param value MultiArray or scalar.
     * @returns MultiArray 1x1 if value is scalar.
     */
    static readonly scalarOrCellToMultiArray: (value: ElementType) => MultiArray;
    /**
     * If `value` parameter is a MultiArray of size 1x1 then returns as scalar.
     * @param value MultiArray or scalar.
     * @returns Scalar value if `value` parameter has all dimensions as singular.
     */
    static readonly MultiArrayToScalar: (value: ElementType) => ElementType;
    /**
     * If `value` parameter is a non empty MultiArray returns it's first element.
     * Otherwise returns `value` parameter.
     * @param value
     * @returns
     */
    static readonly firstElement: (value: ElementType) => ElementType;
    /**
     * If M is a line vector then return the line of M else return first column of M.
     * @param M
     * @returns
     */
    static readonly firstVector: (M: ElementType) => ElementType[];
    /**
     * Copy of MultiArray.
     * @param M MultiArray.
     * @returns Copy of MultiArray.
     */
    static readonly copy: (M: MultiArray) => MultiArray;
    /**
     * Copy method (for element's generics).
     * @returns
     */
    copy(): MultiArray;
    /**
     * Convert MultiArray to logical value. It's true if all elements is
     * non-null. Otherwise is false.
     * @param M
     * @returns
     */
    static readonly toLogical: (M: MultiArray) => ComplexType;
    /**
     * toLogical method (for element's generics).
     * @returns
     */
    toLogical(): ComplexType;
    /**
     * Expand Multidimensional array dimensions if dimensions in `dim` is greater than dimensions of `M`.
     * If a dimension of `M` is greater than corresponding dimension in `dim` it's unchanged.
     * The array is filled with zeros and is expanded in place.
     * @param M Multidimensional array.
     * @param dim New dimensions.
     */
    static readonly expand: (M: MultiArray, dim: number[]) => void;
    /**
     * Reshape an array acording dimensions in `dim`.
     * @param M MultiArray.
     * @param dim Result dimensions.
     * @param d Undefined dimension index (optional).
     * @returns
     */
    static readonly reshape: (M: MultiArray, dim: number[], d?: number) => MultiArray;
    /**
     * Expand range.
     * @param startNode Start of range.
     * @param stopNode Stop of range.
     * @param strideNode Optional stride value.
     * @returns MultiArray of range expanded.
     */
    static readonly expandRange: (start: ComplexType, stop: ComplexType, stride?: ComplexType | null) => MultiArray;
    /**
     * Expand colon to a column vector.
     * @param length
     * @returns
     */
    static readonly expandColon: (length: number) => MultiArray;
    /**
     * Detect whether MultiArray `M` contains any non-zero imaginary part.
     * @param M MultiArray to test.
     * @returns `true` if any element has non-zero imaginary component.
     * `false` otherwise.
     */
    static readonly haveAnyComplex: (M: MultiArray) => boolean;
    /**
     * Check if subscript is a integer number, convert Complex to
     * number.
     * @param k Index as Complex.
     * @param prefix Optional id reference of object.
     * @returns k as number, if real part is integer greater than 1 and imaginary part is 0.
     */
    static readonly testInteger: (k: ComplexType, prefix?: string, infix?: string, constraint?: number | [number, number]) => number;
    /**
     * Check if subscript is a integer number, convert Complex to
     * number.
     * @param k Index as Complex.
     * @param input Optional id reference of object.
     * @returns k as number, if real part is integer greater than 1 and imaginary part is 0.
     */
    static readonly testIndex: (k: ComplexType, input?: string) => number;
    /**
     * Check if subscript is a integer number, convert Complex to
     * number, then check if it's less than bound.
     * @param k Index as Complex.
     * @param bound Maximum acceptable value for the index
     * @param dim Dimensions (to generate error message)
     * @param input Optional string to generate error message.
     * @returns Index as number.
     */
    static readonly testIndexBound: (k: ComplexType, bound: number, dim: number[], input?: string) => number;
    /**
     * Converts subscript to linear index. Performs checks and throws
     * comprehensive errors if dimension bounds are exceeded.
     * @param dimension Dimension of multidimensional array ([line, column, page, block, ...]) as number[].
     * @param subscript Subscript ([line, column, page, block, ...]) as a Complex[].
     * @param input Input string to generate error messages (the id of array).
     * @returns linear index.
     */
    static readonly parseSubscript: (dimension: number[], subscript: ComplexType[], input?: string, evaluator?: Evaluator) => number;
    /**
     * Binary operation 'scalar `operation` array'.
     * @param op Binary operation name.
     * @param left Left operand (scalar).
     * @param right Right operand (array).
     * @returns Result of operation.
     */
    static readonly scalarOpMultiArray: (op: TBinaryOperationName, left: ComplexType, right: MultiArray) => MultiArray;
    /**
     * Binary operation 'array `operation` scalar'.
     * @param op Binary operation name.
     * @param left Left operand (array).
     * @param right Right operaand (scalar).
     * @returns Result of operation.
     */
    static readonly MultiArrayOpScalar: (op: TBinaryOperationName, left: MultiArray, right: ComplexType) => MultiArray;
    /**
     * Unary left operation.
     * @param op Unary operation name.
     * @param right Operand (array)
     * @returns Result of operation.
     */
    static readonly leftOperation: (op: TUnaryOperationLeftName, right: MultiArray) => MultiArray;
    /**
     * Binary element-wise operation with full MATLAB-compatible broadcasting.
     * Supports N-D arrays and row/column vector expansion.
     * @param op Binary operation.
     * @param left Left operand.
     * @param right Right operand.
     * @returns Binary element-wise result.
     */
    static readonly elementWiseOperation: (op: TBinaryOperationName, left: MultiArray, right: MultiArray) => MultiArray;
    /**
     * Calls a defined callback function on each element of an MultiArray,
     * and returns an MultiArray that contains the results.
     * @param M MultiArray.
     * @param callback Callback function.
     * @returns A new MultiArray with each element being the result of the callback function.
     */
    static readonly rawMap: (M: MultiArray, callback: Function) => MultiArray;
    /**
     * Calls a defined callback function on each element of an MultiArray,
     * and returns an MultiArray that contains the results. Pass indices
     * to callback function. The index parameter is the array linear index
     * of element parameter.
     * @param M MultiArray
     * @param callback Callback function.
     * @returns A new MultiArray with each element being the result of the callback function.
     */
    static readonly rawMapRowColumn: (M: MultiArray, callback: (element: ElementType, i: number, j: number) => ElementType) => MultiArray;
    /**
     * Calls a defined callback function on each element of an MultiArray,
     * and returns an MultiArray that contains the results. Pass indices
     * to callback function. The index parameter is the array linear index
     * of element parameter.
     * @param M MultiArray.
     * @param callback Callback function.
     * @returns A new MultiArray with each element being the result of the callback function.
     */
    static readonly rawMapLinearIndex: (M: MultiArray, callback: (element: ElementType, index: number, i?: number, j?: number) => ElementType) => MultiArray;
    /**
     * Calls a defined callback function on each element of an MultiArray,
     * along a specified dimension, and returns an MultiArray that contains
     * the results. Pass dimension index and MultiArray row and column to
     * callback function.
     * @param dimension Dimension to map.
     * @param M MultiArray
     * @param callback Callback function.
     * @returns A new MultiArray with each element being the result of the callback function.
     */
    static readonly alongDimensionMap: (dimension: number, M: MultiArray, callback: (element: ElementType, d: number, i: number, j: number) => ElementType) => MultiArray;
    /**
     *
     * @param M
     * @param DIM
     * @returns
     */
    static readonly sizeAlongDimension: (M: MultiArray, DIM?: ElementType) => number;
    /**
     * Returns the element at the given index along the specified dimension.
     * @param M MultiArray instance
     * @param dimension Dimension index (0-based)
     * @param index Index along the dimension (0-based)
     * @returns ElementType
     */
    static readonly getElementAlongDimension: (M: MultiArray, dimension: number, index: number) => ElementType;
    /**
     *
     * @param elem
     * @param scalar
     * @returns
     */
    static readonly divideElementByScalar: (elem: ElementType, scalar: ComplexType) => ElementType;
    /**
     *
     * @param meanElem
     * @param dim
     * @param d
     * @returns
     */
    static readonly getMeanElementForPosition: (meanElem: ElementType, dim: number, d: number) => ElementType;
    /**
     * Reduce one dimension of MultiArray putting entire dimension in one
     * element of resulting MultiArray as an Array. The resulting MultiArray
     * cannot be unparsed or used as argument of any other method of
     * MultiArray class.
     * @param dimension Dimension to reduce to Array
     * @param M MultiArray to be reduced.
     * @returns MultiArray reduced.
     */
    static readonly reduceToArray: (dimension: number, M: MultiArray) => MultiArray;
    /**
     * Contract MultiArray along `dimension` calling callback. This method is
     * analogous to the JavaScript Array.reduce function.
     * @param dimension Dimension to operate callback and contract.
     * @param M Multidimensional array.
     * @param callback Reduce function.
     * @param initial Optional initial value to set as previous in the first
     * call of callback. If not set the previous will be set to the first
     * element of dimension.
     * @returns Multiarray with `dimension` reduced using `callback`.
     */
    static readonly reduce: (dimension: number, M: MultiArray, callback: (previous: ElementType, current: ElementType, index?: number) => ElementType, initial?: ElementType) => ElementType;
    /**
     * Return the concatenation of N-D array objects, ARRAY1, ARRAY2, ...,
     * ARRAYN along `dimension` parameter (zero-based).
     * @param dimension Dimension of concatenation.
     * @param fname Function name (for error messages).
     * @param ARRAY Arrays to concatenate.
     * @returns Concatenated arrays along `dimension` parameter.
     */
    static readonly concatenate: (dimension: number, fname: string, ...ARRAY: MultiArray[]) => MultiArray;
    /**
     * Split the MultiArray in the last dimension.
     * @param M
     * @returns
     */
    private static readonly splitLastDimension;
    /**
     * Calls `splitLastDimension` and recursively calls `evaluate` for each
     * result, concatenating on the last dimension, until the array is 2-D,
     * then then concatenates the elements row by row horizontally, then
     * concatenates the rows vertically.
     * @param M MultiArray object.
     * @param evaluator Evaluator instance.
     * @param local Local context (function evaluation).
     * @param fname Function name (context).
     * @returns Evaluated MultiArray object.
     */
    private static readonly evaluateRecursive;
    /**
     * Wrapper to not pass the null array to `MultiArray.evaluatorRecursive`.
     * @param M MultiArray object.
     * @param evaluator Evaluator instance.
     * @param local Local context (function evaluation).
     * @param fname Function name (context).
     * @returns Evaluated MultiArray object.
     */
    static readonly evaluate: (M: MultiArray, evaluator?: Evaluator | null | undefined, scope?: Scope) => MultiArray;
    /**
     * # MATLAB/Octave Array Indexing - Complete Rules (Concise Specification)
     *
     * This document synthesizes the official rules of MATLAB/Octave array indexing,
     * based on MathWorks documentation and related references. It defines how arrays
     * are accessed, reshaped, and modified under all indexing modes.
     *
     * ## 1. Core Concepts
     *
     * - Arrays use **1-based indexing**.
     * - Storage and traversal follow **column-major order**.
     * - Indexing modes:
     *   - **Linear indexing** (single index)
     *   - **Subscript indexing** (multiple indices)
     *   - **Logical indexing**
     *
     * ## 2. Linear Indexing
     *
     * ```matlab
     * A(k)
     * ```
     *
     * - Treats `A` as a single column vector in column-major order.
     * - Accesses elements sequentially down columns.
     * - Result:
     *   - Same number of elements as index
     *   - Orientation follows index (row vs column)
     *
     * ### Special Case: `(:)`
     *
     * ```matlab
     * A(:)
     * ```
     *
     * - Returns all elements as a **column vector**
     * - Equivalent to full linearization
     *
     * ## 3. Subscript (Multidimensional) Indexing
     *
     * ```matlab
     * A(i,j,k,...)
     * ```
     *
     * - Each index corresponds to one dimension.
     * - Indices may be scalars, vectors, or `:`.
     * - Result size:
     *
     * ```text
     * size(A(i,j,k,...)) = [numel(i), numel(j), numel(k), ...]
     * ```

     *
     * - Colon `:` selects all elements in that dimension.
     *
     * ## 4. Index Vectors and Shape Rules
     *
     * - For `A(id)`:
     *   - Result has same number of elements as `id`
     *   - Orientation follows `A` if both are vectors
     *
     * - For `A(id1,id2)`:
     *   - Result is a matrix of size:
     *
     * ```text
     * [numel(id1), numel(id2)]
     * ```

     *
     * - General case:
     *
     * ```text
     * size = [numel(id1), numel(id2), ..., numel(idn)]
     * ```
     *
     * ## 5. Fewer Indices Than Dimensions (Dimension Folding)
     *
     * If fewer indices are provided than dimensions:
     *
     * ```matlab
     * A(i,j)   % A is N-D
     * ```
     *
     * - MATLAB **folds all remaining dimensions into the last index**.
     * - Equivalent to reshaping:
     *
     * ```matlab
     * reshape(A, dim1, dim2*dim3*...)
     * ```

     *
     * ### Consequences
     *
     * - `A(:, :)` flattens higher dimensions into columns
     * - `A(i,:)` traverses across all higher dimensions
     * - `A(:,j)` does **not** traverse higher dimensions
     *
     * ## 6. Colon Operator (`:`)
     *
     * - Selects full dimension:
     *
     * ```matlab
     * A(:,j)
     * A(i,:)
     * ```
     *
     * - Equivalent to `1:end` in that dimension
     *
     * - Also used to generate ranges:
     *
     * ```matlab
     * a:b
     * a:s:b
     * ```
     *
     * ## 7. Logical Indexing
     *
     * ```matlab
     * A(mask)
     * ```
     *
     * - `mask` is evaluated in **linear order**
     * - Must not exceed `numel(A)`
     * - Result:
     *   - Column vector of selected elements
     *
     * ## 8. The `end` Keyword
     *
     * - Refers to last index of a dimension:
     *
     * ```matlab
     * A(end)
     * A(1:end)
     * A(:,end)
     * ```
     *
     * - Evaluated independently per dimension
     *
     * ## 9. Indexed Assignment
     *
     * ```matlab
     * A(I) = B
     * ```
     *
     * ### Rules
     *
     * - If `B` is scalar → scalar expansion
     * - Otherwise:
     *
     * ```text
     * numel(B) == numel(I)
     * ```
     *
     * - Indices may be repeated (last assignment wins)
     * - Colon selects full dimension
     *
     * ## 10. Deletion via Empty Array
     *
     * ```matlab
     * A(I) = []
     * ```
     *
     * ### Rules
     *
     * - Removes elements along **one dimension only**
     * - Valid when indexing selects:
     *   - Entire rows
     *   - Entire columns
     *   - Entire slices of a single dimension
     *
     * - Invalid if assignment would produce irregular shape
     *
     * ## 11. Array Expansion
     *
     * ```matlab
     * A(10) = 5
     * ```
     *
     * - Array automatically grows
     * - Missing elements filled with default values (e.g., `0`)
     *
     * ## 12. Linear vs Subscript Distinction
     *
     * ```matlab
     * A(2)    % linear
     * A(2,:)  % subscript
     * ```
     *
     * - These operations are **fundamentally different**
     * - Linear indexing ignores dimensions
     * - Subscript indexing respects dimensional structure
     *
     * ## 13. Evaluation Order
     *
     * 1. Index expressions evaluated
     * 2. Converted to subscripts or linear indices
     * 3. Bounds checked
     * 4. Elements accessed or assigned
     *
     * ## 14. Key Behavioral Summary
     *
     * - Column-major order governs all indexing
     * - `(:)` always returns a column vector
     * - Logical indexing returns column vectors
     * - Subscript indexing defines output shape explicitly
     * - Fewer indices ⇒ dimension folding
     * - Assignment enforces size compatibility or scalar expansion
     * - Deletion is restricted to one dimension
     *
     * ## 15. MathJSLab Engine Implementation Notes
     *
     * This section documents how the MathJSLab engine concretely implements
     * the indexing semantics described above. While fully aligned with MATLAB
     * behavior, the engine introduces a **unified linear-index pipeline**
     * to simplify execution and ensure consistency across all operations.
     *
     * ### 15.1 Unified Index Resolution
     *
     * All indexing modes (linear, subscript, logical) are internally reduced to:
     *
     * ```text
     * → a list of 0-based linear indices
     * ```
     *
     * This is performed by:
     *
     * ```ts
     * resolveLinearIndices(...)
     * ```
     *
     * Responsibilities:
     * - Detect logical vs numeric indexing
     * - Normalize scalar logicals (`true` → `[1]`, `false` → `[]`)
     * - Delegate numeric interpretation to:
     *   - `computeIndexingStructure`
     *   - `iterateWithLinearIndex`
     *
     * This guarantees a **single source of truth** for index resolution.
     *
     *
     * ### 15.2 Index Normalization Pipeline
     *
     * The engine separates indexing into three distinct phases:
     *
     * 1. **Structure normalization**
     *    ```ts
     *    computeIndexingStructure(...)
     *    ```
     *    - Expands missing dimensions with `:`
     *    - Linearizes all index arguments
     *    - Computes total iteration size
     *
     * 2. **Index evaluation**
     *    ```ts
     *    iterateWithLinearIndex(...)
     *    ```
     *    - Resolves `end`
     *    - Converts subscripts → linear indices
     *    - Performs bounds validation via `parseSubscript`
     *
     * 3. **Collection**
     *    ```ts
     *    collectLinearIndices(...)
     *    ```
     *    - Produces final linear index list
     *
     *
     * ### 15.3 Selection Pipeline
     *
     * Element access follows:
     *
     * ```text
     * indices → applyLinearSelection → shape reconstruction
     * ```
     *
     * - `applyLinearSelection(...)`
     *   - Retrieves elements using `getElementByLinearIndex`
     *
     * - Shape reconstruction:
     *   - Logical indexing → column vector (or mask-shaped vector)
     *   - Linear indexing:
     *     - `(:)` → column vector
     *     - otherwise → row vector
     *   - Subscript indexing:
     *     - Uses `computeIndexingStructure`
     *     - Uses `resolveIndexPlan`
     *     - Final adjustment via `collapseResult`
     *
     *
     * ### 15.4 Assignment Pipeline
     *
     * Assignment is centralized via:
     *
     * ```ts
     * applyLinearAssignment(...)
     * ```
     *
     * Features:
     * - Scalar expansion
     * - Strict size validation
     * - Field-aware assignment (structures supported)
     * - Deterministic overwrite (last index wins)
     *
     * High-level flow:
     *
     * ```text
     * resolve indices → expand target → assign values
     * ```
     *
     * Expansion rules:
     * - Linear growth allowed only for vectors
     * - Multidimensional growth uses `expand(...)`
     *
     *
     * ### 15.5 Deletion Semantics
     *
     * Deletion is handled in two layers:
     *
     * - High-level:
     *   ```ts
     *   deleteElements(...)
     *   ```
     *   - Enforces MATLAB rule:
     *     → exactly one non-colon dimension
     *
     * - Low-level:
     *   ```ts
     *   applyDeletionFromIndices(...)
     *   ```
     *   - Removes elements using linear filtering
     *   - Preserves vector orientation when applicable
     *
     *
     * ### 15.6 Logical Indexing Implementation
     *
     * Logical indexing is treated as a specialization of linear indexing:
     *
     * ```text
     * mask → logicalToLinearIndices → linear pipeline
     * ```
     *
     * Rules:
     * - Mask is always linearized
     * - `true` selects index
     * - `false` skips index
     * - Scalar logical:
     *   - `true` → first element
     *   - `false` → empty result
     *
     * Output shape:
     * - Always column vector unless mask is a vector (row preserved)
     *
     *
     * ### 15.7 Shape Resolution Strategy
     *
     * Shape is **not derived from indices directly**, but from a plan:
     *
     * ```ts
     * resolveIndexPlan(...)
     * ```
     *
     * This determines:
     * - Linear vs multidimensional behavior
     * - Full slice detection (`:`)
     * - Scalar vs vector indexing
     * - Active dimensions
     * - Whether collapse is required
     *
     * Final shape adjustments:
     * - `collapseResult(...)`
     *   - Handles dimension folding
     *   - Preserves MATLAB-compatible edge cases:
     *     - `A(:,j)`
     *     - `A(i,:)`
     *     - N-D flattening
     *
     *
     * ### 15.8 Design Principles
     *
     * The implementation follows strict architectural rules:
     *
     * - **Single responsibility**
     *   - Index resolution, selection, assignment, and shape are separated
     *
     * - **Linear-first execution model**
     *   - All operations operate on linear indices internally
     *
     * - **MATLAB compatibility as constraint**
     *   - Edge cases explicitly preserved
     *
     * - **Deterministic behavior**
     *   - No ambiguity in index interpretation
     *
     * - **Extensibility**
     *   - Logical, numeric, and future index types share the same pipeline
     *
     *
     * ### 15.9 Summary
     *
     * The MathJSLab engine implements MATLAB indexing through:
     *
     * ```text
     * Normalize → Resolve → Linearize → Apply → Reshape
     * ```
     *
     * This unified model ensures:
     * - Correctness
     * - Maintainability
     * - Full compatibility with MATLAB semantics
     *
     * while keeping the internal execution model simple and robust.
     *
     * ## Sources
     *
     * - [MathWorks - Matrix Indexing in MATLAB](https://www.mathworks.com/company/technical-articles/matrix-indexing-in-matlab.html)
     * - [MathWorks - Array Indexing](https://www.mathworks.com/help/matlab/math/array-indexing.html)
     * - [MathWorks - Detailed Rules About Array Indexing](https://www.mathworks.com/help/matlab/learn_matlab/array-indexing.html)
     * - [MathWorks - Indexed Assignment](https://www.mathworks.com/help/matlab/math/detailed-rules-about-array-indexing.html)
     * - [MathWorks - Learn MATLAB: Array Indexing](https://www.mathworks.com/help/matlab/math/indexed-assignment.html)
     * - [TutorialsPoint - MATLAB Array Indexing](https://www.tutorialspoint.com/matlab/matlab_array_indexing.htm)
     */
    private static colon;
    /**
     * Normalize an indexing expression into a canonical structure used by
     * MultiArray get/set/delete operations.
     *
     * This function is the entry point for interpreting MATLAB-like indexing.
     * It converts the raw `indexList` (which may contain scalars, vectors,
     * or MultiArray objects) into a uniform representation that can be used
     * by iteration and linear index resolution.
     *
     * Behavior:
     * - Detects linear indexing when a single index argument is provided.
     * - Expands missing dimensions with implicit colon (:) to match the
     *   number of dimensions of the target array.
     * - Linearizes all index arguments into flat arrays.
     * - Computes the total number of indexed elements (cartesian product).
     *
     * Notes:
     * - This function does NOT validate bounds or apply indexing; it only
     *   prepares structural information.
     * - Logical indexing is NOT handled here and must be intercepted before
     *   calling this function.
     *
     * @param dimension Shape of the target MultiArray (e.g. [m, n, ...]).
     * @param indexList Raw index arguments as provided by the evaluator.
     *
     * @returns An object describing the normalized indexing plan:
     * - isLinear: true if indexing uses a single argument (linear indexing)
     * - originalIndexCount: number of indices provided by the user
     * - args: array of linearized index arrays (one per dimension)
     * - argsLength: length of each index array
     * - total: total number of indexed elements (product of argsLength)
     *
     * @throws RangeError if indexList is empty
     */
    private static readonly computeIndexingStructure;
    /**
     * Iterate over a normalized indexing structure and resolve each position
     * into a linear index of the target MultiArray.
     *
     * This function bridges the gap between:
     * - The cartesian product of index arguments (produced by computeIndexingStructure)
     * - The actual linear indices used to access elements in memory
     *
     * Behavior:
     * - Iterates over all combinations of indices (cartesian product)
     * - Converts each iteration step `n` into a multi-dimensional subscript
     *   relative to the index arguments (not the target array)
     * - Maps those subscripts into actual index values (subscriptArgs)
     * - Resolves each subscriptArgs into a linear index using MATLAB rules
     *   (including support for `end` via parseSubscript)
     * - Invokes the callback with:
     *   - subscriptArgs: the resolved indices per dimension (1-based)
     *   - linearIndex: the corresponding linear index in the target array (0-based)
     *   - n: the iteration counter (0-based)
     *
     * Notes:
     * - This function assumes `idx` was produced by computeIndexingStructure.
     * - Bounds checking and `end` resolution are delegated to parseSubscript.
     * - The iteration order follows column-major semantics (MATLAB-compatible).
     * - This function does NOT perform any read/write; it only drives iteration.
     *
     * @param idx Normalized indexing structure (args, argsLength, total).
     * @param dimension Shape of the target MultiArray.
     * @param callback Function invoked for each indexed element.
     * @param input Optional input string (used for error reporting).
     * @param evaluator Optional evaluator (used for resolving expressions like `end`).
     */
    private static readonly iterateWithLinearIndex;
    /**
     * Resolve the structural "indexing plan" for a given indexing operation.
     *
     * This function analyzes the normalized indexing structure and extracts
     * semantic information about how the result should be shaped and interpreted.
     *
     * It does NOT perform indexing itself. Instead, it provides metadata used by:
     * - getElements → to shape the output (row/column/folding)
     * - collapseResult → to decide dimensional reduction
     *
     * The plan captures both:
     * 1. Legacy compatibility flags (MATLAB-like behavior)
     * 2. Structural semantics per dimension (more expressive and future-proof)
     *
     * ------------------------------------------------------------
     * CONCEPTUAL MODEL
     * ------------------------------------------------------------
     *
     * Each dimension is classified as:
     * - full slice   → ":" (entire dimension selected)
     * - scalar index → single position (dimension collapses)
     * - partial      → subset of elements
     *
     * From this, we derive:
     * - activeDimensions → dimensions that are actually being restricted
     * - isFullSlice      → per-dimension ":" detection
     * - isScalarIndex    → per-dimension scalar selection
     *
     * ------------------------------------------------------------
     * SPECIAL CASE: LINEAR INDEXING
     * ------------------------------------------------------------
     *
     * When idx.isLinear === true:
     * - The operation ignores multi-dimensional structure
     * - The array is treated as a column-major linear vector
     * - activeDimensions is reduced to a single conceptual dimension
     *
     * ------------------------------------------------------------
     * COMPATIBILITY FLAGS (LEGACY BEHAVIOR)
     * ------------------------------------------------------------
     *
     * These flags preserve MATLAB-like shaping behavior:
     *
     * - isColonOnly:
     *   True when linear indexing selects the entire array (A(:))
     *
     * - isRowSelection:
     *   Detects A(1,:) pattern → result should be a row vector
     *
     * - isColumnSelection:
     *   Detects A(:,1) pattern → result should be a column vector
     *
     * - requiresCollapse:
     *   True when fewer indices than dimensions were provided.
     *   This triggers dimensional folding (e.g., A(2,:) on 3D arrays)
     *
     * ------------------------------------------------------------
     * NOTES
     * ------------------------------------------------------------
     *
     * - Dimension padding with ":" is applied implicitly before classification.
     * - This function is purely analytical (no data access or mutation).
     * - The returned plan is consumed downstream by shape resolution logic.
     *
     * @param dimension Shape of the target MultiArray.
     * @param idx Normalized indexing structure from computeIndexingStructure.
     *
     * @returns Indexing plan describing structural semantics of the operation.
     */
    private static readonly resolveIndexPlan;
    /**
     * Retrieve an element from a MultiArray using a 0-based linear index.
     *
     * This method provides a unified access path for both plain values and
     * structured field access. It converts the linear index into (row, column)
     * coordinates assuming column-major order (MATLAB semantics), then retrieves
     * the corresponding element.
     *
     * If a non-empty `field` path is provided, the access is delegated to
     * Structure.getField, allowing nested field resolution (e.g., A(i).field.subfield).
     *
     * @param M Source MultiArray.
     * @param linearIndex Zero-based linear index (column-major order).
     * @param field Structure field access path. If empty, returns the raw element.
     * @returns The selected element or nested field value.
     *
     * @throws RangeError If the linear index is out of bounds (indirectly via index conversion).
     *
     * @remarks
     * - Assumes that `linearIndex` has already been validated.
     * - This function is intentionally minimal and side-effect free.
     * - Used as the core primitive by higher-level selection helpers such as
     *   `applyLinearSelection` and indexing pipelines.
     */
    private static readonly getElementByLinearIndex;
    /**
     * Set element in a MultiArray using a linear index (column-major order).
     *
     * This function is the write counterpart of `getElementByLinearIndex` and
     * centralizes all element assignment at the lowest level of the indexing pipeline.
     *
     * The linear index is assumed to be **0-based** and mapped to (row, column)
     * coordinates according to MATLAB/Octave column-major semantics.
     *
     * If a field path is provided, the assignment is performed on a nested
     * structure field instead of directly replacing the element.
     *
     * @param M Target MultiArray.
     * @param linearIndex Zero-based linear index in column-major order.
     * @param value Value to assign at the specified position.
     * @param field Optional structure field access path.
     *
     * @throws RangeError If the linear index is out of bounds (indirectly via index conversion).
     * @throws Error If field access is invalid for the target element.
     */
    private static readonly setElementByLinearIndex;
    /**
     * Collapse an intermediate indexing result to its final shape according to MATLAB rules.
     *
     * After element selection, the intermediate result (`resultFull`) is typically constructed
     * as a full N-dimensional array. This function applies MATLAB's post-processing rules
     * to determine the final output shape, including dimension collapsing and vector orientation.
     *
     * Behavior:
     *
     * 1) No collapse required:
     *    - If the number of index arguments matches the array dimensionality,
     *      the result is returned as-is.
     *
     * 2) Special 2D cases (highest priority, MATLAB-compatible):
     *    - Column selection: A(:, j)
     *        → returns a column vector (n×1)
     *
     *    - Row selection: A(i, :)
     *        → returns a row vector (1×n)
     *        → also applies to higher dimensions with implicit folding
     *
     * 3) General MATLAB folding rule:
     *    - When indexing reduces dimensionality (partial indexing),
     *      higher dimensions are folded into columns.
     *    - Result becomes a 2D matrix:
     *        rows = size along first dimension
     *        cols = total elements / rows
     *
     *    - Elements are filled in column-major order (MATLAB layout).
     *
     * 4) Default:
     *    - If none of the above applies, the intermediate result is returned unchanged.
     *
     * Notes:
     * - This function enforces MATLAB-compatible shape semantics after indexing.
     * - It does not modify element values, only their arrangement.
     * - The `plan` parameter encodes structural properties of the indexing operation,
     *   but only a subset is currently used for collapse decisions.
     *
     * @param resultFull Intermediate full result (before collapse).
     * @param originalDimension Original dimensions of the source array.
     * @param idx Indexing structure (argument counts and shapes).
     * @param plan Precomputed indexing plan describing selection semantics.
     *
     * @returns Final MultiArray with correct MATLAB-compatible shape.
     */
    private static readonly collapseResult;
    /**
     * Convert a logical mask into a list of linear indices (0-based).
     *
     * MATLAB semantics:
     * - Logical indexing is interpreted in linear (column-major) order.
     * - The mask is first linearized, then applied element-wise to the
     *   linearized target array.
     * - Each `true` value selects the corresponding linear position.
     * - `false` values are ignored.
     *
     * Validation rules:
     * - The mask length must not exceed the number of elements in `M`.
     * - If the mask is shorter than `M`, it is applied only to the
     *   corresponding leading elements (MATLAB-compatible behavior).
     *
     * Notes:
     * - Returned indices are 0-based (internal engine convention).
     * - The returned list may be empty (e.g., when mask is all false).
     * - This function does NOT handle scalar logicals; those must be
     *   normalized beforehand by the caller (e.g., via `scalarToMultiArray`).
     *
     * @param M Target MultiArray being indexed.
     * @param items Logical mask as a MultiArray.
     * @param id Optional identifier (used for error messages).
     * @returns Array of selected linear indices (0-based).
     *
     * @throws EvalError If the mask length exceeds the number of elements in `M`.
     */
    private static readonly logicalToLinearIndices;
    /**
     * Normalize logical indexing input into a list of linear indices (0-based).
     *
     * This is a thin wrapper around {@link logicalToLinearIndices}, introduced to:
     * - Provide a stable abstraction point for logical index resolution
     * - Allow future extensions (e.g., scalar logical handling, special cases)
     * - Keep dispatcher and high-level indexing code decoupled from low-level logic
     *
     * The logical mask is interpreted in linear (column-major) order, following
     * MATLAB semantics:
     * - True values select corresponding linear positions
     * - False values are ignored
     * - Mask length must not exceed the number of elements in `M`
     *
     * @param M Target MultiArray being indexed.
     * @param items Logical mask as a MultiArray.
     * @param id Identifier (used for error reporting).
     * @returns Array of selected linear indices (0-based).
     */
    private static logicalMaskToIndexList;
    /**
     * Determine whether an argument represents logical indexing.
     *
     * This function identifies both supported forms of logical indices:
     *
     * 1) Logical MultiArray
     *    - e.g., A([true false true])
     *
     * 2) Logical scalar (Complex)
     *    - e.g., A(true), A(false)
     *
     * This distinction is important because scalar logicals behave differently
     * from numeric scalars:
     * - A(true)  → selects the first element (linear index 1 in MATLAB)
     * - A(false) → selects no elements (returns empty array)
     *
     * Notes:
     * - This function is used by indexing dispatchers to route execution
     *   into the logical indexing pipeline.
     * - It does not validate shape or size compatibility; it only detects type.
     * - Scalar logicals must be normalized (e.g., via scalarToMultiArray)
     *   before further processing.
     *
     * @param arg Index argument (scalar or MultiArray).
     * @returns True if the argument should be treated as logical indexing.
     */
    private static isLogicalIndex;
    /**
     * Apply linear selection on a MultiArray and return the extracted elements.
     *
     * This function performs the core data extraction step of the indexing pipeline:
     * given a list of linear indices (0-based), it retrieves the corresponding
     * elements from the source array in order.
     *
     * Selection follows MATLAB semantics:
     * - Indices refer to positions in column-major (linearized) order
     * - The output preserves the order of `indices`
     * - No reshaping is performed here (result is always a flat array)
     *
     * If a field path is provided, each selected element is resolved through
     * structure field access instead of returning the raw element.
     *
     * @param M Source MultiArray.
     * @param indices Linear indices (0-based, column-major order).
     * @param field Optional structure field access path.
     * @returns Flat array of selected elements, in the same order as `indices`.
     *
     * @remarks
     * - This function is side-effect free.
     * - It assumes indices have already been validated.
     * - Shape/orientation (row/column/matrix) is handled later in the pipeline
     *   (e.g., in getElements and collapseResult).
     * - Acts as the core primitive for both numeric and logical indexing.
     */
    private static applyLinearSelection;
    /**
     * Apply linear assignment on a MultiArray using a list of linear indices.
     *
     * This function performs the core write operation of the indexing pipeline.
     * Given a set of linear indices (0-based), it assigns values to the corresponding
     * positions in the target array, following MATLAB assignment semantics.
     *
     * Behavior:
     *
     * 1) Scalar expansion (broadcast):
     *    - If `values` contains a single element, it is assigned to all indices.
     *
     * 2) Element-wise assignment:
     *    - If `values.length > 1`, its length must match `indices.length`.
     *    - Each value is assigned to the corresponding index in order.
     *
     * 3) Structure field assignment:
     *    - If a non-empty `field` path is provided, assignment is delegated to
     *      nested structure fields instead of replacing the element itself.
     *
     * Validation:
     * - Throws if the number of values does not match the number of indices
     *   (unless scalar expansion applies).
     *
     * @param M Target MultiArray.
     * @param indices Linear indices (0-based, column-major order).
     * @param values Linearized right-hand side values.
     * @param field Optional structure field access path.
     *
     * @throws EvalError If dimensions are nonconformant.
     *
     * @remarks
     * - This function does not handle deletion (A(I) = []); that is handled upstream.
     * - Assumes indices are already validated and within bounds.
     * - Does not perform resizing or expansion of `M`; that is also handled upstream.
     * - Acts as the unified assignment primitive for both numeric and logical indexing.
     */
    private static applyLinearAssignment;
    /**
     * Resolve an index list (logical or numeric) into linear indices (0-based).
     *
     * This function is the core of the indexing engine. It normalizes all supported
     * indexing modes into a unified representation: a list of linear indices in
     * column-major order.
     *
     * It does NOT perform element access or assignment — only index resolution.
     *
     * Supported indexing modes:
     *
     * 1) Logical indexing:
     *    - Triggered when a single logical argument is provided.
     *    - Accepts both logical MultiArray and logical scalar.
     *    - Scalar logicals are normalized:
     *        true  → selects first element
     *        false → selects no elements
     *    - The mask is applied in linear (column-major) order.
     *
     * 2) Numeric indexing:
     *    - Supports linear indexing (single argument)
     *    - Supports multi-dimensional indexing (A(i,j,...))
     *    - Supports colon (:) and range expressions
     *    - Supports `end` keyword via evaluator
     *
     * Processing steps (numeric case):
     *    a) Normalize index structure via `computeIndexingStructure`
     *    b) Iterate over all index combinations
     *    c) Convert each subscript tuple into a linear index using `parseSubscript`
     *
     * Output:
     * - A flat array of 0-based linear indices
     * - Order matches MATLAB evaluation order (column-major traversal)
     *
     * @param M Target MultiArray being indexed.
     * @param id Identifier (used for error reporting and `end` resolution).
     * @param indexList Raw index arguments (scalars, arrays, or logical masks).
     * @param evaluator Optional evaluator used to resolve dynamic expressions (e.g., `end`).
     *
     * @returns Array of linear indices (0-based).
     *
     * @throws EvalError or RangeError for invalid indices or out-of-bounds access.
     *
     * @remarks
     * - This function unifies logical and numeric indexing into a single pipeline.
     * - It is side-effect free.
     * - It guarantees that downstream operations (selection or assignment)
     *   operate only on validated linear indices.
     *
     * - The returned indices may:
     *     * be empty (e.g., a(false))
     *     * contain duplicates (allowed in MATLAB)
     *     * be unordered (depending on index expressions)
     *
     * - Shape/orientation semantics are handled separately (e.g., in getElements
     *   and collapseResult).
     */
    private static resolveLinearIndices;
    /**
     * Collect linear indices from a normalized indexing structure.
     *
     * This is a convenience wrapper around {@link iterateWithLinearIndex} that
     * gathers all computed linear indices into a flat array.
     *
     * It is used in numeric indexing to convert a precomputed indexing structure
     * (`idx`) into a list of linear indices (0-based), ready for selection or
     * assignment.
     *
     * Behavior:
     * - Iterates over all index combinations defined in `idx`
     * - Converts each subscript tuple into a linear index
     * - Preserves iteration order (column-major traversal)
     *
     * @param idx Normalized indexing structure (from computeIndexingStructure).
     * @param dimension Target array dimensions.
     * @param input Optional input string (used for error reporting).
     * @param evaluator Optional evaluator (used to resolve dynamic expressions such as `end`).
     *
     * @returns Array of linear indices (0-based).
     *
     * @remarks
     * - This function is side-effect free.
     * - It does not perform validation; assumes `idx` is already normalized.
     * - Equivalent to manually accumulating results from iterateWithLinearIndex.
     * - Used to simplify and centralize index collection logic.
     */
    private static collectLinearIndices;
    /**
     * Apply deletion on a MultiArray using a list of linear indices.
     *
     * This function performs linear deletion (A(I) = []) by removing the elements
     * at the specified linear indices and compacting the remaining data.
     *
     * Behavior:
     * - The array is first linearized (column-major order)
     * - Elements at positions in `indices` are removed
     * - The remaining elements are compacted into a new linear sequence
     *
     * Shape reconstruction:
     * - If the original array is a vector:
     *     • Row vector → result remains a row vector
     *     • Column vector → result remains a column vector
     *
     * - If the original array is not a vector:
     *     • The result is converted to a column vector
     *     • This matches MATLAB behavior for ambiguous linear deletions
     *
     * Notes:
     * - Indices are assumed to be 0-based and already validated
     * - Duplicate indices are ignored (set semantics)
     * - Order of remaining elements is preserved
     *
     * @param M Target MultiArray (modified in-place).
     * @param indices Linear indices to remove (0-based).
     *
     * @remarks
     * - This function implements the core of logical and linear deletion.
     * - It does not validate index correctness or dimensional constraints;
     *   such checks must be performed upstream.
     * - Multi-dimensional structural deletions (e.g., A(:,2) = []) are handled
     *   elsewhere (e.g., in deleteElements).
     */
    private static applyDeletionFromIndices;
    /**
     * Retrieve elements from a MultiArray using MATLAB-like indexing semantics.
     *
     * This is the main entry point for element access (RHS indexing). It supports
     * both logical and numeric indexing, including multi-dimensional access,
     * linear indexing, colon expressions, and `end`.
     *
     * The indexing pipeline is divided into three stages:
     *
     * 1) Index resolution:
     *    - All index expressions are normalized into linear indices (0-based)
     *    - Performed by {@link resolveLinearIndices}
     *
     * 2) Element selection:
     *    - Elements are extracted in column-major order
     *    - Performed by {@link applyLinearSelection}
     *
     * 3) Shape reconstruction:
     *    - Result is reshaped according to MATLAB rules
     *    - Includes special handling for logical indexing and partial indexing
     *
     * Supported indexing modes:
     *
     * - Logical indexing:
     *     A(mask)
     *     • mask may be a logical array or scalar
     *     • scalar true  → selects first element
     *     • scalar false → returns empty array
     *     • result shape follows mask orientation:
     *         - vector mask → preserves row/column orientation
     *         - matrix mask → result is a column vector
     *
     * - Linear indexing:
     *     A(I)
     *     • returns row vector unless I is ":" (full selection)
     *     • A(:) → column vector
     *
     * - Multi-dimensional indexing:
     *     A(i,j,...)
     *     • supports colon (:), ranges, and `end`
     *     • result shape determined by MATLAB collapsing rules
     *
     * @param M Source MultiArray.
     * @param id Identifier (used for error reporting and `end` resolution).
     * @param field Optional structure field access path.
     * @param indexList Index arguments (numeric or logical).
     * @param evaluator Optional evaluator (used for dynamic expressions such as `end`).
     *
     * @returns Resulting element(s), as a MultiArray or scalar.
     *
     * @throws EvalError or RangeError for invalid indexing operations.
     *
     * @remarks
     * - This function is side-effect free.
     * - Logical indexing is handled as a special case due to its distinct
     *   shape semantics.
     * - Numeric indexing follows a unified pipeline using index structures
     *   and index plans.
     *
     * - Internally, all indexing is reduced to linear index operations,
     *   ensuring a consistent and extensible implementation.
     */
    static readonly getElements: (M: MultiArray, id: string, field: string[], indexList: (ComplexType | MultiArray)[], evaluator?: Evaluator) => ElementType;
    /**
     * Assign values to elements of a MultiArray using numerical (non-logical) indexing.
     *
     * This method implements MATLAB-compatible assignment semantics, including:
     *
     * • Linear indexing:
     *   A(I) = V
     *
     * • Subscript indexing:
     *   A(i, j, k, ...) = V
     *
     * • Scalar expansion (broadcasting):
     *   A(I) = scalar → scalar is replicated to match target size
     *
     * • Shape conformity:
     *   numel(V) must be either 1 or equal to the number of indexed elements
     *
     * • Automatic array expansion:
     *   - Vectors grow when indexed beyond current bounds
     *   - N-D arrays expand per-dimension when valid
     *
     * • Deletion via empty assignment:
     *   A(I) = []
     *   - Only allowed when exactly one index is non-colon
     *   - Delegated to deleteElements()
     *
     * Internal pipeline:
     *
     * 1. Linearize RHS → `linearizedRight`
     * 2. Handle deletion case early
     * 3. Normalize indexing via computeIndexingStructure()
     * 4. Validate RHS conformity
     * 5. Resolve or create target array (including expansion)
     * 6. Collect linear indices via collectLinearIndices()
     *    → fully supports `end` and N-D indexing
     * 7. Apply assignment via applyLinearAssignment()
     *
     * Notes:
     *
     * • Index validation and bounds checking are delegated to:
     *   - testIndex()
     *   - parseSubscript()
     *
     * • This function does NOT handle logical indexing.
     *   Logical indexing is resolved upstream via resolveLinearIndices().
     *
     * • Deletion logic is intentionally separated to preserve MATLAB constraints.
     *
     *
     * @param scope Execution scope (symbol table)
     * @param id Target variable name
     * @param field Structure field access path (empty if none)
     * @param indexList Raw index expressions (already evaluated)
     * @param right Right-hand side MultiArray
     * @param input Optional original expression (for error reporting / `end`)
     * @param evaluator Evaluator instance (used for `end` resolution)
     *
     * @throws RangeError If indexing is invalid or nonconformant
     * @throws EvalError If assignment dimensions are incompatible
     */
    private static readonly setElementsNumerical;
    /**
     * Unified assignment entry point for MultiArray.
     *
     * Dispatches between logical indexing and numerical indexing semantics,
     * implementing MATLAB-compatible behavior.
     *
     * Supported assignment modes:
     * - Logical indexing:     A(mask) = value
     * - Linear indexing:      A(I) = value
     * - Subscript indexing:   A(i,j,k,...) = value
     *
     * Logical indexing behavior:
     * - The mask is interpreted in linear (column-major) order
     * - Scalar logicals are promoted to a 1-element mask:
     *     - true  → selects first element
     *     - false → selects no elements
     * - Deletion is supported: A(mask) = []
     * - Shape of the mask does not need to match M exactly (linear semantics)
     *
     * Numerical indexing behavior:
     * - Delegated to setElementsNumerical
     * - Supports:
     *     - multi-dimensional indexing
     *     - `end` keyword (via evaluator)
     *     - scalar expansion (broadcasting)
     *     - automatic array expansion
     *     - deletion via []
     *
     * Deletion semantics:
     * - Logical deletion: handled here via linear filtering
     * - Numerical deletion: delegated to deleteElements (MATLAB constraints apply)
     *
     * Structure field assignment:
     * - If `field` is provided, assignment targets nested structure fields
     *
     * Error handling:
     * - Invalid variable or non-MultiArray target → EvalError
     * - Conformance and bounds errors are delegated to lower-level helpers
     *
     * @param scope     Execution scope (variable resolution)
     * @param id        Target variable name
     * @param field     Structure field access path (empty for direct assignment)
     * @param indexList Raw index expressions (logical or numeric)
     * @param right     Right-hand side value (MultiArray)
     * @param input     Optional source string (used for error reporting / `end`)
     * @param evaluator Optional evaluator for dynamic expressions (e.g., `end`)
     */
    static readonly setElements: (scope: Scope, id: string, field: string[], indexList: (ComplexType | MultiArray)[], right: MultiArray, input?: string, evaluator?: Evaluator) => void;
    /**
     * Delete elements from a MultiArray using MATLAB-compatible semantics.
     *
     * This function implements deletion via empty assignment:
     *   A(I) = []
     *
     * Supported modes:
     *
     * 1) Linear deletion
     *    - Triggered when a single index is provided (A(I))
     *    - Indices are resolved in column-major linear order
     *    - Result is a vector:
     *        - Preserves orientation if A is already a vector
     *        - Falls back to column vector otherwise
     *
     * 2) Dimension-based deletion (subscript indexing)
     *    Examples:
     *        A(:, j)   → remove columns
     *        A(i, :)   → remove rows
     *        A(:, :, k) → remove slices (N-D)
     *
     *    Rules (MATLAB-compatible):
     *    - Exactly ONE dimension may differ from a full slice (:)
     *    - All other dimensions must be complete (i.e., ":" behavior)
     *    - The size of the affected dimension is reduced accordingly
     *
     * Behavior details:
     * - Indices are first normalized via computeIndexingStructure
     * - Subscripts (including "end") are resolved via parseSubscript
     * - Linear indices are collected through iterateWithLinearIndex
     * - Deletion is performed by filtering the linearized data and rebuilding
     *   the array with updated dimensions
     *
     * Error conditions:
     * - Empty index list → RangeError
     * - More than one non-colon dimension → RangeError
     * - No effective deletion dimension → RangeError
     *
     * Notes:
     * - Linear deletion is delegated to applyDeletionFromIndices
     * - N-D deletion reconstructs the array in column-major order
     * - Structure fields are preserved during deletion
     *
     * @param M Target MultiArray (modified in-place)
     * @param indexList Raw index expressions (logical or numeric)
     * @param input Optional original input string (used for error context)
     * @param evaluator Optional evaluator (used to resolve expressions like "end")
     */
    static readonly deleteElements: (M: MultiArray, indexList: (ComplexType | MultiArray)[], input?: string, evaluator?: Evaluator) => void;
    /**
     * Factory function that creates MATLAB-compatible reduction functions
     * (e.g., sum, prod, min, max, all, any) using MultiArray.reduce.
     * @param callback Binary operation applied elementwise along dimension.
     * @param type
     * @param initial Optional initial value for reduction.
     * @returns A function (M, DIM?) -> ElementType or MultiArray
     */
    static readonly reduceFactory: (callback: ReduceCallbackOrComparisonType, type: ReduceType, initial?: ReduceInitialType) => ReduceHandlerType;
}
export { type ElementType, MultiArray };
declare const _default: {
    MultiArray: typeof MultiArray;
};
export default _default;
