ml-matrix

repository·main·Indexed 18 days ago

https://github.com/mljs/matrix

A comprehensive JavaScript library for matrix manipulation and mathematical computation. It supports standard operations, advanced linear algebra including QR, LU, Cholesky, and Eigenvalue decompositions, inverses, pseudo-inverses, and least squares problems. The library provides the Matrix class for element-wise math, matrix multiplication, and structural transformations, as well as specialized SymmetricMatrix and DistanceMatrix types.

Tokens
16.1K
Snippets
58
Records
81
Agent score
63%

What's inside ml-matrix

  1. Import ml-matrix as an ES module or CommonJS module

    main

    Depending on your environment, import the Matrix class using either ES module import syntax or CommonJS require syntax.

    // As an ES module
    import { Matrix } from 'ml-matrix';
    const matrix = Matrix.ones(5, 5);
    // As a CommonJS module
    const { Matrix } = require('ml-matrix');
    const matrix = Matrix.ones(5, 5);
  2. Work with Symmetric and Distance matrices

    main

    For specialized mathematical structures, use SymmetricMatrix and DistanceMatrix.

    SymmetricMatrix:

    • Represents a matrix where $A_{ij} = A_{ji}$.
    • toCompact(): Returns a 1D array of the upper-right corner (including diagonal) for efficient storage.
    • fromCompact(compact): Reconstructs a SymmetricMatrix from a compact 1D array.
    • applyMask(mask): Removes rows/columns based on a boolean/numeric mask.
    • removeCross(index) / addCross(index, array): Removes or adds a row and its corresponding column simultaneously to maintain symmetry.

    DistanceMatrix:

    • A specialized SymmetricMatrix where the diagonal is always 0.
    • toCompact(): Returns a 1D array of the upper-right corner (excluding the diagonal).
    • fromCompact(compact): Reconstructs a DistanceMatrix from a compact 1D array.
    import { SymmetricMatrix, DistanceMatrix } from 'ml-matrix';
    
    // Create a symmetric matrix from compact data
    const sym = SymmetricMatrix.fromCompact([1, 2, 3, 4]);
    
    // Create a distance matrix
    const dist = new DistanceMatrix(4);
    const compactDist = dist.toCompact();
  3. Find linear dependencies in a matrix

    main

    Use the linearDependencies(A) function to find dependencies between the rows of a matrix. It returns a matrix where each row indicates how that row can be expressed as a combination of other rows.

    const { Matrix, linearDependencies } = require('ml-matrix');
    
    var A = new Matrix([
      [2, 0, 0, 1],
      [0, 1, 6, 0],
      [0, 3, 0, 1],
      [0, 0, 1, 0],
      [0, 1, 2, 0],
    ]);
    
    var dependencies = linearDependencies(A);
  4. Perform standard matrix operations

    main

    The Matrix class provides static methods for operations between two matrices and instance methods for matrix multiplication.

    Static Operations:

    • Matrix.add(A, B): Addition
    • Matrix.sub(A, B): Subtraction
    • Matrix.mul(A, number): Scalar multiplication
    • Matrix.div(A, number): Scalar division
    • Matrix.mod(B, number): Modulo
    • Matrix.max(A, B): Element-wise maximum
    • Matrix.min(A, B): Element-wise minimum

    Instance Operations:

    • A.mmul(B): Matrix multiplication (dot product)
    const { Matrix } = require('ml-matrix');
    
    var A = new Matrix([[1, 1], [2, 2]]);
    var B = new Matrix([[3, 3], [1, 1]]);
    
    const addition       = Matrix.add(A, B);   // Matrix [[4, 4], [3, 3]]
    const subtraction    = Matrix.sub(A, B);   // Matrix [[-2, -2], [1, 1]]
    const multiplication = A.mmul(B);          // Matrix [[4, 4], [8, 8]]
    const mulByNumber    = Matrix.mul(A, 10);  // Matrix [[10, 10], [20, 20]]
    const divByNumber    = Matrix.div(A, 10);  // Matrix [[0.1, 0.1], [0.2, 0.2]]
    const modulo         = Matrix.mod(B, 2);   // Matrix [[1, 1], [1, 1]]
    const maxMatrix      = Matrix.max(A, B);   // Matrix [[3, 3], [2, 2]]
    const minMatrix      = Matrix.min(A, B);   // Matrix [[1, 1], [1, 1]]
  5. Perform inplace matrix operations

    main

    To modify an existing matrix instance directly instead of creating a new one, use the following inplace methods:

    • C.add(A): $C = C + A$
    • C.sub(A): $C = C - A$
    • C.mul(number): $C = number * C$
    • C.div(number): $C = C / number$
    • C.mod(number): $C = C % number$
    const { Matrix } = require('ml-matrix');
    const C = new Matrix([[1, 1], [1, 1]]);
    const A = new Matrix([[2, 2], [2, 2]]);
    
    C.add(A);   // C is now [[3, 3], [3, 3]]
    C.sub(A);   // C is now [[-1, -1], [-1, -1]]
    C.mul(10);  // C is now [[-10, -10], [-10, -10]]
    C.div(10);  // C is now [[-1, -1], [-1, -1]]
    C.mod(2);   // C is now [[1, 1], [1, 1]]
  6. Concatenate matrices

    main

    Combine matrices using the concat method.

    • To stack vertically (rows): M.concat([[values]]). The number of columns must match.
    • To stack horizontally (columns): M.concat(otherMatrix, 'column'). The number of rows must match.
    var M = new Matrix([[1, 2], [3, 4]]);
    
    // Stack rows
    var stacked = M.concat([[5, 6]]); // [[1, 2], [3, 4], [5, 6]]
    
    // Stack columns
    var widened = M.concat(Matrix.columnVector([5, 6]), 'column'); // [[1, 2, 5], [3, 4, 6]]
  7. Query and manipulate matrix properties and elements

    main

    Use the following methods and properties to inspect or modify the structure and content of a Matrix:

    Properties:

    • A.rows: Number of rows
    • A.columns: Number of columns
    • A.size: Total number of elements

    Element Access:

    • A.get(row, col): Get value at specific position
    • A.set(row, col, value): Set value at specific position

    Structural Checks:

    • A.isRowVector(): Returns true if it's a row vector
    • A.isColumnVector(): Returns true if it's a column vector
    • A.isSquare(): Returns true if rows == columns
    • A.isSymmetric(): Returns true if the matrix is symmetric

    Reductions and Transformations:

    • A.diag(): Returns an array of diagonal values
    • A.mean(): Returns the mean of all elements
    • A.prod(): Returns the product of all elements
    • A.norm(): Returns the Frobenius norm
    • A.transpose(): Returns the transposed matrix
    • A.applyAlongAxis(callback, axis): Applies a callback function along 'row' or 'column' axes.
    var A = new Matrix([[1, 1], [-1, -1]]);
    
    var numberRows     = A.rows;             // 2
    var numberCols     = A.columns;          // 2
    var firstValue     = A.get(0, 0);        // 1
    var numberElements = A.size;             // 4
    var isRow          = A.isRowVector();    // false
    var isColumn       = A.isColumnVector(); // false
    var isSquare       = A.isSquare();       // true
    var isSym          = A.isSymmetric();    // false
    
    A.set(1, 0, 10);                         // A becomes [[1, 1], [10, -1]]
    var diag           = A.diag();           // [1, -1]
    var m              = A.mean();           // 0.5 (based on updated A)
    var product        = A.prod();           // -10
    var norm           = A.norm();           // Frobenius norm
    var transpose      = A.transpose();      // Transposed matrix
    
    // Row/Column reductions
    var M = new Matrix([[1, 2, 3], [4, 5, 6]]);
    var sumOf = (vector) => vector.reduce((total, value) => total + value, 0);
    var rowSums    = M.applyAlongAxis(sumOf, 'row');    // [6, 15]
    var columnSums = M.applyAlongAxis(sumOf, 'column'); // [5, 7, 9]
  8. Calculate matrix inverse and pseudo-inverse

    main

    Use the inverse function for standard inversion. If a matrix is singular (non-invertible), you can pass true as the second argument to use Singular Values Decomposition (SVD) to find an approximate inverse.

    For non-square matrices, use the pseudoInverse() method on the matrix instance.

    const { Matrix, inverse } = require('ml-matrix');
    
    var A = new Matrix([[2, 3, 5], [4, 1, 6], [1, 3, 0]]);
    
    // Standard inverse
    var inverseA = inverse(A);
    
    // Approximate inverse for singular matrices using SVD
    var singularA = new Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
    var inverseA_approx = inverse(singularA, true);
    
    // Pseudo-inverse for non-square matrices
    var nonSquareA = new Matrix([[1, 2], [3, 4], [5, 6]]);
    var pseudoInverseA = nonSquareA.pseudoInverse();
  9. Solve least squares problems

    main

    To find $x$ in the equation $A.x = B$, use the solve(A, B) function.

    If $A$ is non-singular, it returns a direct solution. If $A$ is singular, you can pass true as the third argument to use SVD to find one of the many possible solutions.

    const { Matrix, solve } = require('ml-matrix');
    
    // Non-singular case
    var A = new Matrix([[3, 1], [4.25, 1], [5.5, 1], [8, 1]]);
    var B = Matrix.columnVector([4.5, 4.25, 5.5, 5.5]);
    var x = solve(A, B);
    
    // Singular case (using SVD)
    var A_singular = new Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
    var B_singular = Matrix.columnVector([8, 20, 32]);
    var x_singular = solve(A_singular, B_singular, true);
  10. Instantiate matrices with special patterns

    main

    Beyond passing a 2D array to the constructor, you can use static methods to create common matrix types:

    • Matrix.zeros(rows, cols): Matrix filled with 0s
    • Matrix.ones(rows, cols): Matrix filled with 1s
    • Matrix.eye(rows, cols): Identity matrix (1s on the diagonal, 0s elsewhere)
    var z = Matrix.zeros(3, 2); // [[0, 0], [0, 0], [0, 0]]
    var z = Matrix.ones(2, 3);  // [[1, 1, 1], [1, 1, 1]]
    var z = Matrix.eye(3, 4);   // [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]
  11. Perform matrix decompositions (QR, LU, Cholesky, Eigenvalue)

    main

    The library provides several decomposition classes to break down matrices into simpler components:

    • QrDecomposition(A): Provides orthogonalMatrix (Q) and upperTriangularMatrix (R).
    • LuDecomposition(A): Provides lowerTriangularMatrix (L), upperTriangularMatrix (U), and pivotPermutationVector (P).
    • CholeskyDecomposition(A): Provides lowerTriangularMatrix (L).
    • EigenvalueDecomposition(A): Provides realEigenvalues, imaginaryEigenvalues, and eigenvectorMatrix.
    const { 
      Matrix, 
      QrDecomposition, 
      LuDecomposition, 
      CholeskyDecomposition, 
      EigenvalueDecomposition 
    } = require('ml-matrix');
    
    var A = new Matrix([[2, 3, 5], [4, 1, 6], [1, 3, 0]]);
    
    // QR
    var QR = new QrDecomposition(A);
    var Q = QR.orthogonalMatrix;
    var R = QR.upperTriangularMatrix;
    
    // LU
    var LU = new LuDecomposition(A);
    var L = LU.lowerTriangularMatrix;
    var U = LU.upperTriangularMatrix;
    var P = LU.pivotPermutationVector;
    
    // Cholesky
    var cholesky = new CholeskyDecomposition(A);
    var L_chol = cholesky.lowerTriangularMatrix;
    
    // Eigenvalues
    var e = new EigenvalueDecomposition(A);
    var real = e.realEigenvalues;
    var vectors = e.eigenvectorMatrix;