UNPKG

mathjslab

Version:

MathJSLab - An interpreter with language syntax like MATLAB®/Octave, ISBN 978-65-00-82338-7.

1,060 lines (1,059 loc) 44.1 kB
import { type ComplexType, type NumLikeType } from './Complex'; import { type ElementType, MultiArray } from './MultiArray'; type LAPACKConfig = { /** * Maximum iteration factor. */ maxIterationFactor: number; }; export declare const LAPACKConfigKeyTable: (keyof LAPACKConfig)[]; /** * # LAPACK (Linear Algebra PACKage) * * LAPACK is written in Fortran 90 and provides routines for solving systems of simultaneous linear equations, least-squares solutions of linear systems of equations, eigenvalue problems, and singular value problems. The associated matrix factorizations (LU, Cholesky, QR, SVD, Schur, generalized Schur) are also provided, as are related computations such as reordering of the Schur factorizations and estimating condition numbers. Dense and banded matrices are handled, but not general sparse matrices. In all areas, similar functionality is provided for real and complex matrices, in both single and double precision. * * ## References * - [Wikipedia — LAPACK](https://en.wikipedia.org/wiki/LAPACK) * - [LAPACK — Linear Algebra PACKage — Netlib reference implementation](https://www.netlib.org/lapack/) * - [LAWNs — LAPACK Working Notes](https://www.netlib.org/lapack/lawns/downloads/) * - [LAPACK GitHub repository](https://github.com/Reference-LAPACK/lapack) * - [The LAPACKE C Interface to LAPACK](https://www.netlib.org/lapack/lapacke.html#_function_list) * - https://github.com/Reference-LAPACK/lapack/tree/master/SRC */ declare abstract class LAPACK { /** * `LAPACK` default settings. */ static readonly defaultSettings: LAPACKConfig; /** * `LAPACK` current settings. */ static readonly settings: LAPACKConfig; /** * Set configuration options for `LAPACK`. * @param config Configuration options. */ static readonly set: (config: Partial<LAPACKConfig>) => void; /** * Test whether a matrix is Hermitian: M = Mᴴ * * @param M Matrix in row-major order (ComplexType[][]) * @returns true if Hermitian within tolerance */ static readonly isHermitian: (M: ComplexType[][]) => boolean; /** * Test whether a matrix is Hermitian positive definite. * * This function attempts an unblocked Cholesky factorization. * If it succeeds without encountering a non-positive pivot, * the matrix is considered positive definite. * * @param M Hermitian matrix (ComplexType[][]) * @returns true if positive definite */ static readonly isPositiveDefinite: (M: ComplexType[][]) => boolean; /** * Apply a sequence of row interchanges to a MultiArray. * LAPACK-like signature: laswp(A, k1, k2, ipiv, incx, colStart = 0, colEnd = numCols-1) * @param A Multidimensional matrix. * @param dim Array of dimensions of A. * @param k1 1-based start index of rows to process (inclusive). * @param k2 1-based end index of rows to process (inclusive). * @param ipiv Integer array of pivot indices (LAPACK convention: 1-based). The routine will auto-detect if ipiv looks 0-based and adapt. * @param incx Increment (typically +1 or -1). When incx > 0 loop i=k1..k2 step incx; when incx<0 loop i=k1..k2 step incx. * @param colStart Optional 0-based column start to which the swaps are applied (inclusive). * @param colEnd Optional 0-based column end to which the swaps are applied (inclusive). * @returns */ static readonly laswp: (A: ComplexType[][], dim: number[], k1: number, k2: number, ipiv: number[], incx: number, colStart?: number, colEnd?: number) => void; /** * Swap two rows of an N-dimensional MultiArray across all pages in place. * It is `LAPACK.laswp` for a single pivot applied across slices). `row1`, * `row2` are 0-based indices within the first dimension. * @param M Matrix. * @param row1 First row index to swap. * @param row2 Second row index to swap. */ static readonly laswp_rows: (M: ComplexType[][], dim: number[], row1: number, row2: number) => void; /** * Swap two columns of an N-dimensional MultiArray across all pages in * place. There is no direct equivalent to LAPACK, but it is symmetrical * to `laswp_rows`. * @param M Matrix. * @param col1 First column index to swap. * @param col2 Second column index to swap. */ static readonly laswp_cols: (M: ComplexType[][], dim: number[], col1: number, col2: number) => void; /** * Returns a 2D or ND-aware identity matrix (`ComplexType[][]`), row-major. * Optimized for internal `BLAS`/`LAPACK` operations. * Supports arbitrary number of dimensions. * * Usage: * `LAPACK.eye(2,3,5,4)` -> MultiArray with dims [2,3,5,4] * `LAPACK.eye([2,3,5,4])` -> same as above * * Diagonal filled with `1` (`Complex.one()`), rest zeros. * Each 2-D page `[m,n]` in `ND` array gets its own identity. * @param dims `number[] | ...number` */ static readonly eye: (...dims: any[]) => ComplexType[][]; static readonly fillFactory: (fill: (_: any) => ComplexType) => ((...dims: any[]) => ComplexType[][]); /** * Returns a 2D or ND-aware null matrix (`ComplexType[][]`), row-major. * Optimized for internal `BLAS`/`LAPACK` operations. * Supports arbitrary number of dimensions. * * Usage: * `LAPACK.zeros(2,3,5,4)` -> MultiArray with dims [2,3,5,4] * `LAPACK.zeros([2,3,5,4])` -> same as above * * All elements filled with `0` (`Complex.zero()`). * @param dims `number[] | ...number` * @returns */ static readonly zeros: (...dims: any[]) => ComplexType[][]; static readonly ones: (...dims: any[]) => ComplexType[][]; static readonly diag: (diag: ComplexType[], k?: number, ...dims: any[]) => ComplexType[][]; static readonly from_diag: (array: ComplexType[][], k?: number) => ComplexType[]; /** * Computes the scaled sum of squares of the elements of a matrix. * * This routine implements the LAPACK LASSQ algorithm, which is designed * to accumulate the sum of squares in a numerically stable way, avoiding * unnecessary overflow and underflow. * * Given a matrix A, it computes two real non-negative values `scale` and * `sumsq` such that: * * (scale^2) * sumsq = sum_{i,j} |A_{i,j}|^2 * * The Frobenius norm of A can then be obtained as: * * ||A||_F = scale * sqrt(sumsq) * * This function supports complex-valued matrices, using the modulus of * each element. Zero elements are skipped to reduce unnecessary operations. * * @param A - Input matrix (possibly complex-valued) * @returns An object containing: * - scale: the scaling factor (real, non-negative) * - sumsq: the scaled sum of squares (real, non-negative) */ static readonly lassq: (A: MultiArray) => { scale: ComplexType; sumsq: ComplexType; }; /** * Computes selected norms of a matrix. * * This routine is analogous to the LAPACK LANGE function, supporting * computation of matrix norms based on the specified norm type. * * Supported norms: * * - 'F': Frobenius norm * Defined as sqrt(sum_{i,j} |A_{i,j}|^2). * Computed using the numerically stable LASSQ algorithm. * * - 'M': Maximum absolute value norm * Defined as max_{i,j} |A_{i,j}|. * * The matrix may contain complex values; in all cases, the modulus of * each element is used. * * @param norm - Norm selector ('F' for Frobenius, 'M' for max-abs) * @param A - Input matrix (possibly complex-valued) * @returns The requested matrix norm as a real-valued ComplexType * * @throws Error if the requested norm is not implemented */ static readonly lange: (norm: "F" | "M", A: MultiArray) => ComplexType; /** * Zero the lower triangular part (i > j), keeping only the upper triangle. LAPACK-like TRIU operation. * @param M */ static readonly triu_inplace: (M: MultiArray) => void; /** * Zero the upper triangular part (j > i), keeping only the lower triangle. LAPACK-like TRIL operation. * @param M */ static readonly tril_inplace: (M: MultiArray) => void; /** * Solve for X in U * X = B where U is upper triangular k x k stored at * A[kblock]. We implement in-place update of Bblock (A12 region). Block * target at rows k..k+kb-1, cols k+kb..n-1 * @param A full MultiArray; U is at rows k..k+kb-1, cols k..k+kb-1 * @param k * @param kb */ static readonly trsm_left_upper_block: (A: ComplexType[][], k: number, kb: number) => void; /** * Build an explicit permutation matrix P from a LAPACK-style pivot array jpvt. * * The pivot array jpvt encodes a column permutation such that: * * P(i, j) = 1 if i === jpvt[j] * 0 otherwise * * This permutation matrix satisfies: * * A * P -> permutes the columns of A according to jpvt * Pᵀ * A -> permutes the rows of A according to jpvt * * This routine does NOT apply the permutation to a matrix; it only constructs * the explicit permutation matrix corresponding to jpvt. * * @param jpvt Pivot array encoding a column permutation (LAPACK convention). * @returns Permutation matrix P as a MultiArray. */ static readonly lapmt_matrix: (jpvt: number[]) => MultiArray; /** * Apply a LAPACK-style column permutation to a matrix in place. * * Given a matrix A and a pivot array jpvt, this routine permutes * the columns of A according to jpvt, such that after execution: * * A(:, j) <- A_old(:, jpvt[j]) * * This is equivalent to right-multiplication by the permutation * matrix P constructed from jpvt: * * A_new = A_old * P * * The operation is performed in place and follows the semantics * of LAPACK's xLAPMT routine (column permutation). * * @param A Matrix whose columns will be permuted (modified in place) * @param jpvt Pivot array encoding the column permutation */ static readonly lapmt_apply: (A: MultiArray, jpvt: number[]) => void; /** * Generate a Householder reflector for a vector x (length m). * Produces tau, v (with v[0] = 1) and alpha (the value to write at x[0]). * * This is the vector-version of larfg. It does NOT read or write a matrix: * it only uses the vector x (ComplexType[]) and returns the reflector data. * * Conventions match LAPACK ZLARFG: alpha = -phi * ||x||, tau = (alpha - x0)/alpha, * v[0] = 1, v[i] = x[i] / (x0 - alpha) for i>=1. If sigma == 0 then tau = 0. */ static readonly larfg_original: (x: ComplexType[]) => { tau: ComplexType; v: ComplexType[]; phi: ComplexType; alpha: ComplexType; }; /** * ## LAPACK.larfg (complex) * Construct a complex Householder reflector H = I - tau * v * vᴴ * such that: * * H * [ alpha ] = [ beta ] * [ x ] [ 0 ] * * v is stored as: * v[0] = 1 * v[1:] overwrites x * * This implementation is faithful to LAPACK ZLARFG. * * @param alpha Complex scalar (modified in-place to beta) * @param x Vector below alpha (modified in-place to v[1:]) * @returns beta as alpha and tau both Complex scalar */ static larfg_complex(alpha: ComplexType, x: ComplexType[]): { alpha: ComplexType; tau: ComplexType; }; /** * Computes the Hermitian dot product of the tail of a column of A with itself. * * Evaluates: * sigma = sum_{i = startRow+1}^{m-1} conj(A[i, col]) * A[i, col] * * Implemented as a BLAS.dotc on the extracted subvector. * * It is equivalent to the BLAS operation ZDOTC applied to the subvector * A[startRow+1 : m-1, col], and is typically used in the construction of * complex Householder reflectors (e.g., in LAPACK's xLARFG). * @param A MultiArray representing the matrix. * @param col Column index to operate on. * @param startRow Row index whose tail (startRow+1 .. end) is used. * @returns The Hermitian dot product as a Complex value. */ static readonly dotc_col: (A: MultiArray, col: number, startRow: number) => ComplexType; /** * Computes the Hermitian dot product of the tail of a row of A with itself. * * This function evaluates: * sigma = sum_{j = startCol+1}^{n-1} conj(A[row, j]) * A[row, j] * * Implemented as a BLAS.dotc on the extracted subvector. * * It is equivalent to the BLAS operation ZDOTC applied to the subvector * A[row, startCol+1 : n-1], and is typically used in the construction of * complex Householder reflectors for right-side operations (e.g., LAPACK's xLARFG). * * @param A MultiArray representing the matrix. * @param row Row index to operate on. * @param startCol Column index whose tail (startCol+1 .. end) is used. * @returns The Hermitian dot product as a Complex value. */ static readonly dotc_row: (A: MultiArray, row: number, startCol: number) => ComplexType; /** * ## `LAPACK.larfg_left` * LAPACK-style LARFG - Compute Householder vector and tau for complex * vectors `x = A[k:m-1, k]`. It's a complex householder generator for * left-side application. Generates `tau`, `v`, `phi` and `alpha` for * `H = I - tau*v*vᴴ`. * ### Notes: * - Uses `BLAS.dotc_col(A, k, k)` to compute `sigma = sum_{i>k} |x_i|^2`. * - Follows the ZLARFG convention (`alpha = -phi * ||x||`, with `phi = x0/|x0|` when `x0!=0`). * * NOTE: v is returned unscaled; callers (geqr2/geqp2/geqp3) are responsible for storing tau * v if needed. * * @param A Target MultiArray (only used for shape reference). * @param m Number of rows * @param k Start index of reflector * @returns object { tau, v, phi, alpha } where: * - `v` is a ComplexType[] with `v[0] = 1` and `length = m-k`. * - `tau` is ComplexType. * - `phi` is ComplexType. * - `alpha` is the resulting leading value (the value that replaces `A[k,k]`) */ static readonly larfg_left: (A: MultiArray, dim: number, k: number) => { tau: ComplexType; v: ComplexType[]; phi: ComplexType; alpha: ComplexType; }; /** * LAPACK-style LARFG - build a Householder reflector acting **on the right** (row-wise). * * Computes tau, v, phi, alpha for the row vector * x = A[k, k:n-1]ᵀ * * Generates H = I - tau * v * vᴴ such that H * x = [alpha, 0, ...]. * * Householder conventions follow LAPACK ZLARFG: * - alpha = -phi * ||x||, phi = x0/|x0| if x0!=0, else 1 * - tau = (alpha - x0)/alpha * - v[0] = 1, v[j>0] = x[j] / (x0 - alpha) * * @param A MultiArray (row-wise target) * @param n number of columns * @param k start index of reflector (column) * @returns { tau, v, phi, alpha }: * - v: ComplexType[] with v[0]=1, length = n-k * - tau: ComplexType * - phi: ComplexType * - alpha: ComplexType (replaces A[k][k]) */ static readonly larfg_right: (A: MultiArray, n: number, k: number) => { tau: ComplexType; v: ComplexType[]; phi: ComplexType; alpha: ComplexType; }; /** * ## LAPACK.larfg * * Generates a LAPACK-style Householder reflector H such that: * * H = I - tau * v * vᴴ * * where: * - For side = 'L' (left): H * x = [alpha, 0, ..., 0]ᵀ * - For side = 'R' (right): x * H = [alpha, 0, ..., 0] * * The vector x is extracted from matrix A starting at index `k`: * - side = 'L': x = A[k:m-1, k] (column) * - side = 'R': x = A[k, k:n-1] (row) * * The Householder vector `v` is returned as a 1D array (ComplexType[]). * It is the caller's responsibility to interpret it as a column or row vector: * - side = 'L' → v is conceptually a column vector * - side = 'R' → v is conceptually a row vector * * ### LAPACK ZLARFG conventions * - phi = x0 / |x0| if x0 != 0, else 1 * - alpha = -phi * ||x||_2 * - tau = (alpha - x0) / alpha * - v[0] = 1 * * Special case: * - If the tail of x is zero (sigma = 0), tau = 0 and H = I (identity reflector) * * @param side 'L' for left (column-wise) or 'R' for right (row-wise) application * @param A Target matrix (MultiArray) * @param dim Dimension of the subvector (m for 'L', n for 'R') * @param k Start index of the reflector in A * @returns Object containing: * - `tau` (ComplexType): scalar factor of the reflector * - `v` (ComplexType[]): Householder vector with v[0] = 1 * - `phi` (ComplexType): phase factor used to define alpha * - `alpha` (ComplexType): resulting leading element after applying H * * ### Notes * - `v` is always normalized such that v[0] = 1; the remaining entries are scaled accordingly. * - The caller decides whether `v` is treated as a column or row vector when constructing H. * - Follows LAPACK-style handling of complex vectors. */ static readonly larfg_old: (side: "L" | "R", A: MultiArray, dim: number, k: number) => { tau: ComplexType; v: ComplexType[]; phi: ComplexType; alpha: ComplexType; }; static readonly larfg: (side: "L" | "R", A: MultiArray, dim: number, k: number) => { tau: ComplexType; v: ComplexType[]; phi: ComplexType; alpha: ComplexType; }; static readonly larfgLQ: (A: MultiArray, k: number, n: number) => { tau: ComplexType; v: ComplexType[]; alpha: ComplexType; }; /** * Apply an elementary reflector H = I - tau * v * vᴴ to a matrix A from the left. * Equivalent to A := H * A for rows rowStart..m-1 and columns colStart..n-1. * * Implements LAPACK xLARF (left-application): * * A := (I - tau * v * vᴴ) * A * * restricted to rows rowStart.. and columns colStart.. * * @param A Matrix to modify in-place. * @param v Householder vector (ComplexType[]), v[0] == 1, length = m - rowStart. * @param tau Complex scalar (possibly 0). * @param rowStart Row index k (start of the reflector). * @param colStart Column index (first column to update; usually k+1 or 0). */ static readonly larf_left: (A: MultiArray, v: ComplexType[], tau: ComplexType, rowStart: number, colStart: number) => void; /** * ## LAPACK.larf * * Applies a complex Householder reflector * * H = I - tau * v * vᴴ * * to a matrix C, either from the LEFT or from the RIGHT. * * LEFT ('L'): C := (I - tau * v * vᴴ) * C * RIGHT ('R'): C := C * (I - tau * v * vᴴ) * * This implementation follows the LAPACK ZLARF convention exactly. * * Notes: * - v is a 1D vector (ComplexType[]) with v[0] = 1 by convention. * - Interpretation of v as row or column is the responsibility of the consumer. * - tau is complex. * - Updates are applied in-place. * * @param side 'L' (left) or 'R' (right) * @param C Target matrix (modified in-place) * @param v Householder vector, v[0] = 1 * @param tau Householder scalar * @param i0 Starting row index in C * @param j0 Starting column index in C */ static larf(side: 'L' | 'R', C: MultiArray, v: ComplexType[], tau: ComplexType, i0: number, j0: number): void; /** * Apply a Householder reflector from the RIGHT:Vamos mapear ZGEMV/ZGERC do LAPACK e alinhar com nosso código. * * A := A * (I - tau * v * vᴴ) * * Where: * - A is the target matrix * - v is the Householder vector (length = block size) * - tau is the scalar * - rowStart is the first row of the block * - colStart is the first column of the block * * This exactly matches LAPACK xLARF(side='R') behavior. */ static readonly larf_right: (C: MultiArray, v: ComplexType[], tau: ComplexType, i0: number, j0: number) => void; /** * Apply a Householder reflector from the RIGHT in its **adjoint form** (Hᴴ = I - conj(tau) * v * vᴴ) * * Equivalent to LAPACK xLARF with TRANS='C'. * * @param A Target matrix (MultiArray), modified in-place. * @param v Householder vector (v[0] = 1) * @param tau Scalar tau of the reflector * @param rowStart Start row for application (usually 0) * @param colStart Start column for application (usually k..n-1) */ static readonly larf_right_adjoint: (A: MultiArray, v: ComplexType[], tau: ComplexType, rowStart: number, colStart: number) => void; /** * Apply Householder reflector H = I - tau * v * vᴴ to A from the left, * in a blocked fashion: * * A[rowStart..m-1, colStart..n-1] := H * A[rowStart..m-1, colStart..n-1] * * v is ComplexType[] of length = m - rowStart (v[0] == 1). * * Uses temporary block buffers and BLAS.gemm_block to compute * S = vᴴ * A_block and then A_block -= tau * v * S */ static readonly larf_left_block: (A: MultiArray, v: ComplexType[], tau: ComplexType, rowStart: number, colStart: number, blockSize?: number) => void; /** * geqr2 — QR factorization (unblocked, complex, no pivoting). * * Computes the QR factorization of a complex m×n matrix A using * Householder reflectors, following LAPACK GEQR2 semantics with * MATLAB/Octave-compatible compact storage. * * The factorization is: * A = Q * R * * Outputs: * - R: a copy of A overwritten in-place: * * R[k,k] stores the reflector scalar alpha * * R[k+1:m,k] stores tau * v[1:], i.e. the Householder vector * compactly below the diagonal (MATLAB/Octave style) * * the upper triangle contains the R factor after completion * - taus[k]: scalar tau for each Householder reflector, used by orgqr * - phis[k]: phase factors returned by larfg_left (stored but not applied) * * Algorithm (for k = 0 .. min(m,n)-1): * 1) Generate Householder reflector H = I - tau * v * vᴴ * acting on column k (via larfg_left) * 2) Store alpha at R[k,k] * 3) Store tau * v[1:] below the diagonal in column k * 4) Apply H to the remaining trailing columns (via larf_left) * * No pivoting is performed. * Q is not formed explicitly; it must be generated using orgqr. */ static readonly geqr2: (A: MultiArray) => { R: MultiArray; taus: ComplexType[]; phis: ComplexType[]; }; /** * QR factorization with column pivoting (GEQP2 equivalent). * A is overwritten with: * - Householder vectors in the lower trapezoid * - R in the upper triangle * * NOTE: We store tau * v (LAPACK-compatible layout) to allow reuse of orgqr * * Returns: * R : MultiArray containing Householder vectors + R * taus: Householder scalars * jpvt: column permutation vector */ static readonly geqp2: (A: MultiArray) => { R: MultiArray; taus: ComplexType[]; phis: ComplexType[]; jpvt: number[]; }; /** * Computes the QR factorization of a real or complex matrix A with * column pivoting, using Householder reflectors (LAPACK-style GEQP3). * * Given an m-by-n matrix A, this routine computes a factorization * * `A * P = Q * R` * * where: * - `Q` is an m-by-m unitary/orthogonal matrix represented implicitly * by a sequence of Householder reflectors defined by the vectors * stored in the lower trapezoid of R and the scalar factors `taus`; * * - `R` is the m-by-n upper-triangular (or upper-trapezoidal) factor * returned explicitly in the output array; * * - `P` is an n-by-n permutation matrix encoded by the pivot array `jpvt`, * representing the reordering of columns chosen via column pivoting; * * - `taus[k]` is the scalar coefficient of the k-th Householder * reflector `Hₖ = I − τ v vᴴ`, where `v` is stored in column `k` of the * modified `A` matrix (now part of `R`); * * - `phis[k]` corresponds to the signed norm (or “alpha”) returned by * the Householder generator for the k-th reflector, matching LAPACK’s * internal convention for reconstructing the reflector explicitly. * * The routine follows the numerical strategy of xGEQP3 in LAPACK: * - Computes initial column norms; * - Uses partial column norm downdating to avoid recomputation; * - Selects pivot columns based on remaining norms; * - Applies Householder reflectors to update the trailing matrix. * * @param A The input matrix (real or complex), given as a `MultiArray`. * It is overwritten in-place with the `R` factor and the * Householder vectors in its lower trapezoid. * @returns An object containing: * - `R`: The resulting `R` factor (with embedded Householder vectors). * - `taus`: The array of Householder scalar factors τₖ. * - `phis`: The signed norm/alpha values for each step of the factorization. * - `jpvt`: The pivot array encoding the column permutation matrix `P`. */ static readonly geqp3: (A: MultiArray) => { R: MultiArray; taus: ComplexType[]; phis: ComplexType[]; jpvt: number[]; }; static readonly gelq2_final: (A: MultiArray) => { L: MultiArray; taus: ComplexType[]; }; /** * ## `LAPACK.gelq2` * LQ factorization without pivoting (LAPACK GELQ2). * * Factorizes A as: * A = L * Q * * where: * - L is lower trapezoidal * - Q is unitary * * Householder vectors are stored row-wise in A, * and scalars in `taus`. * * The pseudocode of this function is following: * * for k = 0 .. min(m,n)-1 * Generate reflector H_k to the right from line k. * store alpha in A[k,k] * store v in A[k, k+1 ..] * Apply H_k to the right on lines k+1 .. m-1 * end * * @param A MultiArray * @returns { L, taus } */ static readonly gelq2: (A: MultiArray) => { L: MultiArray; taus: ComplexType[]; phis: ComplexType[]; }; static readonly gelq2_nova: (A: MultiArray) => { L: MultiArray; taus: ComplexType[]; }; static readonly gelq2_nao_funciona: (A: MultiArray) => { L: MultiArray; taus: ComplexType[]; }; /** * ## `LAPACK.orgqr` * Construct `Q` explicitly from `R` (with MATLAB/Octave-style storage * `tau*v` in subdiagonal) and `taus[]` produced by `LAPACK.geqr2`. * We reconstruct each `v` from `R` (`v[0]=1`, `v[1..]` from `R[k+1..,k]`) then * apply `Q := Q * Hᴴ` using accumulation. Adapted to row-major * MultiArray and using `LAPACK.larf` for left application. * * IMPORTANT: loop in reverse order (`kMax-1` downto `0`) applying `H = I - tau * v * vᴴ` to match LAPACK * ZUNGQR semantics. * @param R * @param taus * @returns Q matrix */ static readonly orgqr: (R: MultiArray, taus: ComplexType[]) => MultiArray; /** * ## LAPACK.orglq (BLAS-based) * Reconstruct unitary matrix Q from L (output de gelq2) e taus[]. * Versão baseada em blocos (pseudo-BLAS) para preparar futura implementação BLAS real. * @param L Matriz m×n (retornada por gelq2) * @param taus Array de fatores tau (Householder) * @param blockSize Tamanho de bloco (opcional, padrão 32) * @returns Q unitária n×n */ /** * ## LAPACK.orglq * * Reconstrói explicitamente a matriz unitária Q a partir da saída de `gelq2`. * * Assume: * - L armazena os vetores de Householder v diretamente em L[k][k+1..] * - taus[k] contém os coeficientes escalares tau * * Reconstrói: * Q = H₀ᴴ · H₁ᴴ · ... · H_{k−1}ᴴ * * onde: * H_k = I − tau[k] · v · vᴴ * * @param L matriz retornada por gelq2 * @param taus coeficientes de Householder * @returns Q matriz unitária */ static readonly orglq: (L: MultiArray, taus: ComplexType[]) => MultiArray; /** * Unblocked LU factorization (panel) - modifies A in place. * A is m x n stored as ComplexType[][] (row-major physical layout). * Performs LU on A[k..m-1, k..n-1] and writes pivots into piv starting at offset k. * Returns number of pivots performed (panel width) or info. * * This is analogous to LAPACK's xGETF2 applied to the submatrix. * * This routine will update A in-place (compact LU) and fill piv[k..k+panelWidth-1] (global, zero-based). * * @param A ComplexType[][] (m x n) (modified in-place) * @param k starting column/row index for panel * @param panelWidth number of columns to factor (<= min(m-k, n-k)) * @param piv number[] global pivot array, receives zero-based pivot row indices, length >= min(m,n) * @param swapsObj { swaps: number } (accumulates swaps) * @param infoObj { info: number } (LAPACK-style 1-based info) */ static readonly getf2: (A: ComplexType[][], k: number, panelWidth: number, piv: number[], swapsObj?: { swaps: number; }, infoObj?: { info: number; }) => void; /** * Blocked GETRF for complex matrices (LU with partial pivoting). * This routine will modify A in-place, writing LU (L below diag, U on and above diag). * @param A * @returns { LU: MultiArray (same reference as input A, modified), piv: number[], swaps: number } */ static readonly getrf: (A: ComplexType[][], blockSize?: number) => { LU: ComplexType[][]; piv: number[]; swaps: number; info: number; }; /** * Blocked LU factorization that calls getf2 for panel factorization, * then solves and updates the trailing submatrix. * @param A * @returns Object { LU: A, piv, info, swaps } */ static readonly getrf_blocked: (A: ComplexType[][], blockSize?: number) => { LU: ComplexType[][]; piv: number[]; swaps: number; info: number; }; /** * Compute A22 := A22 - A21 * A12 (standard update in GETRF). * All indices are absolute within A.array. * A21: rows (k+kb .. m-1) x cols (k .. k+kb-1) * A12: rows (k .. k+kb-1) x cols (k+kb .. n-1) * A22: rows (k+kb .. m-1) x cols (k+kb .. n-1) * @param A * @param k * @param kb * @param blockSizeInner */ static readonly gemm_blocked: (A: ComplexType[][], k: number, kb: number, blockSizeInner?: number) => void; /** * Solve systems A X = B given LU factorization in-place and pivots. * This follows LAPACK GETRS semantics (no transpose). * @param LU ComplexType[][] containing LU as returned by getrf * @param piv pivot vector (zero-based) length = min(m,n) * @param B ComplexType[][] of size m x nrhs (modified in place) * @returns new ComplexType[][] (`B`) with solution */ static readonly getrs: (LU: ComplexType[][], piv: number[], B: ComplexType[][]) => ComplexType[][]; /** * Solve linear system A X = B using LU factorization with partial pivoting. * LAPACK-style GESV. * * @param A ComplexType[][] (m x n), not modified * @param B ComplexType[][] (m x nrhs) * @returns { X, info } */ static readonly gesv: (A: ComplexType[][], B: ComplexType[][]) => { X: ComplexType[][]; info: number; }; /** * Solve A X = B for Hermitian positive definite A. * LAPACK POSV semantics (first version). * * NOTE: * This initial implementation falls back to GETRF + GETRS. * Later, it should be replaced by POTRF + POTRS. * * MATLAB equivalent: * X = A \\ B (A Hermitian positive definite) */ static readonly posv: (A: ComplexType[][], B: ComplexType[][]) => ComplexType[][]; /** * BLAS/LAPACK-like Cholesky factorization (Potrf) — MathJSLab version * * Computes A = L*L^H if uplo='lower', or A = U^H*U if uplo='upper'. * * Returns a copy of A with the chosen triangle overwritten with the Cholesky factor, * and the other triangle zeroed. * * @param A MultiArray square Hermitian (complex) or symmetric (real) positive-definite * @param opts.uplo 'lower' or 'upper' (default: 'lower') */ static readonly potrf: (A: MultiArray, opts?: { uplo?: "lower" | "upper"; }) => MultiArray; /** * Solve A X = B for Hermitian/symmetric indefinite A. * LAPACK SYSV semantics (first version). * * NOTE: * This initial implementation falls back to GETRF + GETRS. * Later, it should be replaced by SYTRF + SYTRS (or HETRF + HETRS). * * MATLAB equivalent: * X = A \\ B (A symmetric or Hermitian, indefinite allowed) */ static readonly sysv: (A: ComplexType[][], B: ComplexType[][]) => ComplexType[][]; /** * Matrix left division (A \ B), LAPACK-style dispatcher. * * Selects the most appropriate solver according to matrix properties: * - Hermitian positive definite -> POSV * - Hermitian (indefinite) -> SYSV * - General matrix -> GESV * * This mirrors MATLAB / Octave internal behavior conceptually. */ static readonly mldivide: (A: MultiArray, B: MultiArray) => { X: MultiArray; info: number; solver: "gesv" | "posv" | "sysv"; }; /** * Reduce a Hermitian matrix A to real symmetric tridiagonal form T: * * A = Q · T · Qᴴ * * using Householder reflectors, following exactly the LAPACK ZHETRD * unblocked algorithm (lower triangle variant). * * On exit: * - diag[k] = T[k,k] * - offdiag[k] = T[k+1,k] (real in exact arithmetic) * - taus[k] = Householder scalar τₖ * * Storage convention (LAPACK-compatible): * - The Householder vector vₖ is stored in A[k+1:n-1, k] * - vₖ[0] = 1 is implicit (not stored) * * @param A Hermitian matrix (n×n), modified in-place * @param her2_left_update Function that applies a reflector from the left (Hermitian-aware) */ static readonly sytrd: (A: MultiArray, her2_left_update: (A: MultiArray, v: ComplexType[], tau: ComplexType, rowStart: number, colStart: number) => void) => { diag: ComplexType[]; offdiag: ComplexType[]; taus: ComplexType[]; }; /** * Apply a Hermitian Householder reflector from the left: * * > `A := (I - tau * v * vᴴ) * A` * * Only the Hermitian trailing submatrix A[rowStart:, colStart:] is updated (Hermitian rank-2 update). * * v is assumed to satisfy v[0] = 1 and corresponds to rows starting at rowStart. * * 1. `w = tau * A * v` * 2. `alpha = -0.5 * tau * (vᴴ * w)` * 3. `w = w + alpha * v` * 4. `A = A - v*wᴴ - w*vᴴ` */ static readonly her2_zhtrd_update: (A: MultiArray, v: ComplexType[], tau: ComplexType, rowStart: number, colStart: number) => void; static readonly hetrd: (A: MultiArray) => { diag: ComplexType[]; offdiag: ComplexType[]; taus: ComplexType[]; }; /** * Generate the unitary matrix Q from a Hermitian tridiagonal reduction. * * This routine reconstructs * * Q = H₀ H₁ ... Hₙ₋₂ * * where each Householder reflector is * * Hₖ = I − τₖ vₖ vₖᴴ * * with vₖ stored exactly as produced by sytrd (UPLO = 'L'): * * vₖ = [1; A[k+2:n-1, k]] * * @param A Matrix containing Householder vectors (output of sytrd) * @param TAU Householder scalar factors * @returns Unitary matrix Q */ static readonly ungtr: (A: MultiArray, TAU: ComplexType[]) => MultiArray; /** * Blocked reduction of a Hermitian matrix A to tridiagonal form * using LAPACK-style panel accumulation with matrix W. * * Householder vectors are stored in the lower triangle of A (v[0] at A[k+1,k]) * taus[k] stores the scalar for the k-th reflector. * * @param A Hermitian MultiArray (n x n), modified in-place * @param blockSize block size (panel width) * @returns { diag, offdiag, taus } */ static readonly sytrd_blocked_w: (A: MultiArray, blockSize?: number) => { diag: ComplexType[]; offdiag: ComplexType[]; taus: ComplexType[]; }; /** * Construct a dense Hermitian matrix from its tridiagonal representation (diag, offdiag). * * Given: * - diag[i] = T(i,i) * - offdiag[i] = T(i,i+1) * * The resulting matrix satisfies: * - T(i,i) = diag[i] * - T(i,i+1) = offdiag[i] * - T(i+1,i) = conj(offdiag[i]) * * @param diag Main diagonal entries (length n) * @param offdiag Sub/superdiagonal entries (length n-1) * @returns Dense Hermitian matrix T (n x n) */ static readonly tridiagonal_hermitian_to_dense: (diag: ComplexType[], offdiag: ComplexType[]) => ComplexType[][]; /** * Transformação Hermitiana → Real 2n×2n * @param H * @returns */ static readonly hermitian_to_real2n: (H: ComplexType[][]) => ComplexType[][]; /** * Reconstrói autovetores complexos * @param Q * @returns */ static readonly real2n_to_complex_eigenvectors: (Q: ComplexType[][]) => ComplexType[][]; static readonly real2n_to_complex_eigenvalues: (D2n: ComplexType[]) => ComplexType[]; /** * Cyclic Jacobi eigenvalue algorithm for real symmetric dense matrices. * Educational baseline. O(n³). * Not LAPACK DSTEQR. * @param T Symmetric real matrix (imag = 0). * @param maxSweeps Maximum number of Jacobi's sweeps (default = 1e3). * @param tol Target off-diagonal norm tolerance (default = 1e-14). * @returns An object containing two fields: * - D: Eigenvalues. * - V: Eigenvectors. */ static readonly jacobi_real_symmetric_dense: (T: ComplexType[][], maxSweeps?: NumLikeType, tol?: NumLikeType) => { D: ComplexType[]; V: ComplexType[][]; }; /** * Jacobi cyclic for Hermitian matrices. `T` is mutated in-place during the algorithm. * @param T * @param maxSweeps * @param tol * @returns */ static readonly jacobi_symmetric_hermitian: (T: ComplexType[][], maxSweeps?: number, tol?: number) => { D: ComplexType[]; V: ComplexType[][]; }; /** * Find the element with the highest magnitude in the column (pivot). * @param array Row-major order bidimensional MultiArray structure. * @param column Column to find the pivot. * @param rowStart Row start (to deal with multidimensional operations and functions). Default is `0`. * @param rowEnd Row end (to deal with multidimensional operations and functions). Default is `array.length`. * @returns An object containing: * - pivotRow - Row index of pivot element (relative to rowStart). * - pivotAbs - Absolute value of pivot. * - pivotIsZero - `true` if pivot element is zero (improbable null column.). */ static readonly column_pivot: (array: ComplexType[][], column: number, rowStart?: number, rowEnd?: number) => { pivotRow: number; pivotAbs: ComplexType; pivotIsZero: boolean; }; /** * Normalize eigenvector phases so that pivot element in each column becomes real positive. * Modifies V in-place (ComplexType[][]). * @param V * @param pivotPositive */ static readonly normalize_eigenvector_phases: (V: ComplexType[][], pivotPositive?: boolean) => void; static readonly steqr_vectors: (diag: ComplexType[], offdiag: ComplexType[], maxIter?: number) => { D: ComplexType[]; V: ComplexType[][]; complex: boolean; }; /** * Implicit-shift QR algorithm for Hermitian tridiagonal matrices. * LAPACK-style DSTEQR (conceptual equivalent). * O(n²). * Supports real and complex Hermitian cases via ComplexType. * * D: diagonal entries (Hermitian ⇒ real-valued, but kept as ComplexType) * E: subdiagonal entries (ComplexType, length n-1) */ static readonly steqr_vectors_tridiagonal: (D: ComplexType[], E: ComplexType[], maxIts?: number) => { D: ComplexType[]; V: ComplexType[][]; }; /** * Compute eigenvalues of a symmetric tridiagonal matrix T given by * diag[] and offdiag[]. * @param diag ComplexType[] - diagonal elements of T * @param offdiag ComplexType[] - sub/super diagonal (e1...e[n-1]) * @param maxIter optional - default 1000*n * @returns */ static readonly steqr_values: (diag: ComplexType[], offdiag: ComplexType[], maxIter?: number) => ComplexType[]; /** * Reconstruct unitary/orthogonal matrix Q from the output of sytrd. * A is assumed to contain the Householder vectors in the strict lower * triangle in the same convention used by sytrd (v[0] stored at A[k+1,k]). * * @param A MultiArray (n x n) as returned/modified by sytrd * @param taus ComplexType[] of length n (Householder scalars) * @returns Q MultiArray (n x n) unitary/orthogonal */ static readonly orgtr: (A: MultiArray, taus: ComplexType[]) => MultiArray; /** * Blocked reconstruction of Q from the Householder vectors stored by sytrd_blocked. * Mirrors orgtr but applies reflectors in reverse order and uses block application * to exploit locality. * * @param A MultiArray after sytrd_blocked (n x n) containing stored v in lower triangle * @param taus ComplexType[] as returned by sytrd_blocked * @param blockSize block size matching the one used in sytrd_blocked (default 32) * @returns Q MultiArray (n x n) unitary/orthogonal */ static readonly orgtr_blocked: (A: MultiArray, taus: ComplexType[], blockSize?: number) => MultiArray; /** * Reconstruct Q from the output of sytrd_blocked_w (Hermitian to tridiagonal reduction) * using LAPACK-style blocked panel accumulation with matrix W. * * @param A MultiArray containing Householder vectors in lower triangle * @param taus ComplexType[] scalars for each reflector (from sytrd_blocked_w) * @param blockSize block size (panel width, same as sytrd_blocked_w) * @returns Q unitary MultiArray (n x n) */ static readonly orgtr_blocked_w: (A: MultiArray, taus: ComplexType[], blockSize?: number) => MultiArray; static readonly eig_symmetric: (A: MultiArray, computeVectors?: boolean) => { D: MultiArray; V?: MultiArray; }; static readonly eig_hermitian: (A: MultiArray, computeVectors?: boolean) => { D: MultiArray; V?: MultiArray; }; static readonly functions: { [F in keyof LAPACK]: Function; }; } export type { ElementType }; export { LAPACK }; declare const _default: { LAPACK: typeof LAPACK; }; export default _default;