UNPKG

mathjslab

Version:

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

450 lines (449 loc) 16.4 kB
import { ComplexType } from './Complex'; import { type ElementType, MultiArray } from './MultiArray'; type BLASConfig = { /** * Minimal value for block multiplication version. Tune as needed. */ blockThreshold: number; /** * Block size. */ blockSize: number; }; export declare const BLASConfigKeyTable: (keyof BLASConfig)[]; /** * # BLAS (Basic Linear Algebra Subprograms) * * The BLAS (Basic Linear Algebra Subprograms) are routines that provide * standard building blocks for performing basic vector and matrix operations. * The Level 1 BLAS perform scalar, vector and vector-vector operations, the * Level 2 BLAS perform matrix-vector operations, and the Level 3 BLAS perform * matrix-matrix operations. * * ## References * - [Wikipedia — Basic Linear Algebra Subprograms](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) * - [BLAS (Basic Linear Algebra Subprograms) — Netlib reference implementation](https://www.netlib.org/blas/) * - [BLAS Quick Reference Guide](https://www.netlib.org/blas/blas.pdf) * - https://github.com/Reference-LAPACK/lapack/tree/master/BLAS/SRC * * ## MathJSLab — BLAS / LAPACK Internal Data Layout Conventions * * This file implements BLAS-like routines adapted to the internal * data representation of the MathJSLab engine. * * **IMPORTANT — DATA LAYOUT AND SEMANTIC CONVENTIONS** * * ### 1) Matrix storage (ComplexType[][]) * * - All matrices are stored in ROW-MAJOR order. * - A matrix entry A[i][j] corresponds to: * row = i * column = j * - This is the opposite of MATLAB / Octave, which use column-major * storage. No implicit transpositions are performed. * * - The canonical matrix type used by BLAS routines is: * ComplexType[][] * * - MultiArray is considered a higher-level container and should * not be used as a primary BLAS argument unless strictly necessary. * * ### 2) Vector storage (ComplexType[]) * * - Vectors are stored as plain one-dimensional arrays: * ComplexType[] * * - A ComplexType[] DOES NOT carry an intrinsic orientation. * Its mathematical interpretation (row or column vector) * is defined EXCLUSIVELY by the BLAS routine that receives it. * * - Every BLAS routine that accepts vectors MUST document whether * each vector is interpreted as: * - a column vector (m x 1), or * - a row vector (1 x n) * * * ### 3) Vector ↔ Matrix correspondence (row-major logic) * * Given a vector v: ComplexType[] of length m: * * - Column vector (m x 1): * V = v.map(value => [value]) * * - Row vector (1 x m): * V = [ v ] * * **NOTE**: * - This construction is the logical inverse of MATLAB / Octave * due to the row-major layout. * * * ### 4) BLAS Level-2 and Level-3 semantics * * - Level-2 routines (gemv, ger, trsv, etc.) interpret vectors * according to the mathematical operation being implemented. * * Examples: * - gemv: * A: m x n * x: length n, interpreted as column vector * y: length m, interpreted as column vector * * - ger / geru / gerc: * x: length m, interpreted as column vector * y: length n, interpreted as row vector * * - Level-3 routines (gemm, trsm, etc.) operate exclusively on * matrices and are independent of column-major vs row-major * storage, provided indexing is consistent. * * * ### 5) Design goal * * These conventions are mandatory and must be preserved across * all BLAS and LAPACK implementations in MathJSLab in order to: * * - avoid implicit transpositions, * - prevent MATLAB/Octave mental-model leakage, * - ensure correctness of higher-level linear algebra algorithms, * - allow predictable performance and cache-friendly access patterns. * * Any new BLAS or LAPACK routine added to this file MUST comply * with the conventions stated above. */ declare abstract class BLAS { /** * BLAS default settings. */ static readonly defaultSettings: BLASConfig; /** * BLAS current settings. */ static readonly settings: BLASConfig; /** * Set configuration options for BLAS. * @param config Configuration options. */ static readonly set: (config: Partial<BLASConfig>) => void; /** * ===================================== * Level 1 BLAS: vector, O(n) operations * ===================================== */ /** * BLAS AXPY: Y ← alpha * X + Y * @param alpha Complex scalar * @param X ComplexType[][] * @param Y ComplexType[][] (modified in place) * @returns Y */ static readonly axpy: (alpha: ComplexType, X: ComplexType[][], Y: ComplexType[][]) => ComplexType[][]; /** * BLAS SCAL: scales a vector by a scalar. * * Performs the operation: * x[i] ← alpha * x[i], i = start, ..., end - 1 * * The operation is performed in-place. * * NOTE: * - The vector x is interpreted as a column vector (n×1), * stored in row-major order. * * @param alpha Complex scalar multiplier * @param x Vector to be scaled (in-place) * @param start Starting index (inclusive) * @param end Ending index (exclusive) */ static readonly scal: (alpha: ComplexType, x: ComplexType[], start: number, end: number) => void; /** * * @param A * @returns */ static readonly copy: (A: ComplexType[][] | ComplexType[]) => ComplexType[][] | ComplexType[]; /** * Unconjugated dot product of two complex vectors. * * Computes: * sum_{i=0}^{n-1} x[i] * y[i] * * This corresponds to the BLAS routine ZDOTU. * * @param x Complex vector * @param y Complex vector * @returns Complex dot product */ static readonly dotu: (x: ComplexType[], y: ComplexType[]) => ComplexType; /** * Dot product of two vectors. * * Computes: * sum_{i=0}^{n-1} x[i] * y[i] * * NOTE: * In the MathJSLab engine, this function is an alias of DOTU. * For real vectors, DOT, DOTU and DOTC are numerically equivalent. * * This corresponds to: * - SDOT / DDOT (real BLAS) * - ZDOTU / CDOTU (complex BLAS) * * @param x Vector * @param y Vector * @returns Dot product */ static readonly dot: (x: ComplexType[], y: ComplexType[]) => ComplexType; /** * BLAS DOTC: Conjugated dot product of two complex vectors. * * Computes: * sum_{i=0}^{n-1} conj(x[i]) * y[i] * * This corresponds to the BLAS routine ZDOTC. * * @param x Complex vector (conjugated) * @param y Complex vector * @returns Complex dot product */ static readonly dotc: (x: ComplexType[], y: ComplexType[]) => ComplexType; /** * Return the squared Euclidean norm of the slice R[startRow..m-1, col]. * Result is returned as a ComplexType whose imaginary part is zero (real value). * * Equivalent (conceptually) to (ZNRM2(R[startRow: m-1, col]))^2 but computed directly. * * @param R MultiArray * @param col column index * @param startRow starting row (inclusive) * @param m number of rows in R (or row limit) * @returns ComplexType representing the real value sum_i |R[i,col]|^2 */ static readonly nrm2sq: (R: MultiArray, col: number, startRow: number, m: number) => ComplexType; /** * Return the Euclidean norm (sqrt of sum |x_i|^2) as a ComplexType whose imaginary part is zero. * This is the direct analogue of LAPACK's ZNRM2. * * TODO: implement using `LAPACK.lassq`. * * @param R MultiArray * @param col column index * @param startRow starting row (inclusive) * @param m number of rows in R (or row limit) */ /** * BLAS NRM2: Computes the Euclidean norm of a vector using scaling * to avoid overflow and underflow. * * For a complex vector x: * nrm2(x) = sqrt( sum_i |x_i|^2 ) * * This implementation follows the LAPACK/BLAS LASSQ strategy. * * @param x Vector of ComplexType * @returns Euclidean norm as a real ComplexType */ static readonly nrm2: (x: ComplexType[]) => ComplexType; /** * ============================================= * Level 2 BLAS: matrix-vector, O(n²) operations * ============================================= */ /** * Complex general matrix-vector multiplication (ZGEMV, NoTrans). * * Computes: * y := alpha * A * x + beta * y * * Matrix A is row-major (ComplexType[][]). * Vectors x and y are ComplexType[]. * Offsets allow operating on submatrices and subvectors (LAPACK-style). * * @param A Matrix (row-major) * @param m Number of rows of submatrix A * @param n Number of columns of submatrix A * @param rowA Starting row offset in A * @param colA Starting column offset in A * @param x Input vector * @param rowX Offset in x * @param y In/out vector * @param rowY Offset in y * @param alpha Scalar multiplier for A*x * @param beta Scalar multiplier for y */ static readonly gemv: (A: ComplexType[][], m: number, n: number, rowA: number, colA: number, x: ComplexType[], rowX: number, y: ComplexType[], rowY: number, alpha: ComplexType, beta: ComplexType, trans?: "N" | "T" | "C") => void; /** * Solve a triangular system: * * A * x = b (transA = 'N') * A^T * x = b (transA = 'T') * A^H * x = b (transA = 'C') * * where A is triangular and x is a vector. * * This is the BLAS Level-2 TRSV analogue. * * NOTE: * - x is interpreted as a column vector (n×1), even though it is stored * as a 1D array in row-major order. * * @param A Triangular matrix (n × n), row-major * @param x Right-hand side vector (length n), interpreted as column * @param opts Options: uplo, transA, unitDiagonal * @returns Solution vector x (length n) */ static readonly trsv: (A: ComplexType[][], x: ComplexType[], opts: { uplo: "lower" | "upper"; transA: "N" | "T" | "C"; unitDiagonal: boolean; }) => ComplexType[]; /** * Rank-1 update `A := A + alpha * x * y^H` * For complex-case conjugate on second vector (gerc style). * A: m x n as ComplexType[][], x length m, y length n * * @param A ComplexType[][] contendo matriz base * @param startRow linha inicial do bloco `A` a ser atualizado * @param startCol coluna inicial do bloco `A` a ser atualizado * @param m Comprimento do vetor `x` * @param n comprimento do vetor `y` * @param alpha * @param xA ComplexType[][] contendo o vetor `x` (parte real) * @param xRow linha inicial do vetor `x` * @param xCol coluna inicial do vetor `x` * @param yA ComplexType[][] contendo o vetor `y` (parte imaginária) * @param yRow linha inicial do vetor `y` * @param yCol coluna inicial do vetor `y` */ static readonly ger: (A: ComplexType[][], startRow: number, startCol: number, m: number, n: number, alpha: ComplexType, xA: ComplexType[][], xRow: number, xCol: number, yA: ComplexType[][], yRow: number, yCol: number) => void; /** * Rank-1 update (no conjugation): * C[i0+i][j0+j] += alpha * x[i] * y[j] * * This corresponds to BLAS GERU. */ static readonly geru: (x: ComplexType[], y: ComplexType[], alpha: ComplexType, C: ComplexType[][], i0: number, j0: number) => void; /** * Complex rank-1 update with conjugation on `y` * > > `C := C + alpha * x * y^H` * * @param x `ComplexType[]` vetor (`m`) * @param y `ComplexType[]` vetor (`n`) * @param C `ComplexType[][]` [`m x n`] (complex) */ static readonly gerc: (x: ComplexType[], y: ComplexType[], alpha: ComplexType, C: ComplexType[][], rowOffset?: number, colOffset?: number) => void; /** * Complex rank-1 update with conjugation on `x` * > > `C := C + conj(x) * y^H` * Notes: * - `x` and `y` can be 1D MultiArrays with arbitrary strides * - Result is stored in `C` * @param x `MultiArray` (vector) * @param y `MultiArray` (vector) * @param C `MultiArray` [`m x n`] */ static readonly gerc_nd: (x: MultiArray, y: MultiArray, C: MultiArray) => void; /** * ND-aware, direct: * > > `C := C + conj(x) * y^H` * Notes: * - No flattening/copying; uses MultiArray linear <-> row/col conversion * - `x` and `y` can be slices from higher-dim MultiArrays * @param x 1D `MultiArray` (vector) * @param y 1D `MultiArray` (vector) * @param C 2D `MultiArray` [`m x n`] */ static readonly gerc_nd_direct: (x: MultiArray, y: MultiArray, C: MultiArray) => void; /** * ========================== * Level 2 BLAS: band storage * ========================== */ /** * ============================ * Level 2 BLAS: packed storage * ============================ */ /** * ============================================= * Level 3 BLAS: matrix-matrix, O(n³) operations * ============================================= */ /** * Blocked multiplication kernel for complex matrices. * Multiply a sub-block of `A` and `B` and accumulate into `R`. * * Computes the block: * `R[ii:iMax-1][jj:jMax-1] += A[ii:iMax-1, kk:kMax-1] * B[kk:kMax-1, jj:jMax-1]` * * @param A left matrix (`m x k`) * @param B right matrix (`k x n`) * @param R result matrix (`m x n`), updated in-place * @param ii..iMax row range in `A` and `R` (`i`) * @param jj..jMax col range in `B` and `R` / resulting columns (`j`) * @param kk..kMax inner dimension range (columns of `A` / rows of `B`) */ static readonly gemm_kernel: (A: ComplexType[][], B: ComplexType[][], R: ComplexType[][], ii: number, iMax: number, jj: number, jMax: number, kk: number, kMax: number) => void; /** * Complex general matrix-matrix multiplication. Hybrid * implementation: simple for small matrices, blocked for large ones. Uses * `ComplexType` elements with fully preallocated rows. * * Computes: * > > `C := alpha * A * B + beta * C` * * Uses blocked multiplication for large matrices and simple triple loop for small ones. * * A: `m x k`, B: `k x n`, C: `m x n` - all raw `ComplexType[][]` * Uses blocking on k dimension and on i/j using `BLAS.settings.blockSize`. * * @param alpha scalar multiplier for `A*B` * @param A left matrix (`m x k`) * @param m number of rows of `A` * @param k number of columns of `A` (and rows of `B`) * @param B right matrix (`k x n`) * @param n number of columns of `B` * @param beta scalar multiplier for `C` * @param C result matrix (`m x n`), updated in-place */ static readonly gemm: (alpha: ComplexType, A: ComplexType[][], m: number, k: number, B: ComplexType[][], n: number, beta: ComplexType, C: ComplexType[][], blockSize?: number) => void; /** * Blocked matrix multiply (row-major): * * > > C := alpha * A * B + beta * C * * - A: m x k * - B: k x n * - C: m x n * * All matrices are raw ComplexType[][] in row-major order. * * blockSize controls the cache-tile size. */ static readonly gemm_block: (A: ComplexType[][], B: ComplexType[][], C: ComplexType[][], alpha: ComplexType, beta: ComplexType, blockSize?: number) => void; /** * Core BLAS TRSM (row-major). * * Solves: * side = 'left' : op(A) * X = B * side = 'right' : X * op(A) = B * * A must be square. * B is overwritten and returned as X. */ static readonly trsm: (A: ComplexType[][], B: ComplexType[][], opts?: { side?: "left" | "right"; uplo?: "upper" | "lower"; transA?: "N" | "T" | "C"; unitDiagonal?: boolean; }) => ComplexType[][]; static readonly functions: { [F in keyof BLAS]: Function; }; } export type { ElementType }; export { BLAS }; declare const _default: { BLAS: typeof BLAS; }; export default _default;