or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

blas.mddistributions.mdindex.mdmatrices.mdutils.mdvectors.md
tile.json

matrices.mddocs/

Matrix Operations

Matrix data structures and operations for linear algebra computations in machine learning applications. Provides both dense and sparse implementations with format conversion capabilities and optimized operations.

Capabilities

Matrix Creation

Factory methods for creating different types of matrices.

object Matrices {
  /**
   * Creates a dense matrix in column-major format
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param values Matrix entries in column major order
   * @return Dense matrix instance
   */
  def dense(numRows: Int, numCols: Int, values: Array[Double]): Matrix
  
  /**
   * Creates a sparse matrix in Compressed Sparse Column (CSC) format
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param colPtrs Column pointers (length numCols + 1)
   * @param rowIndices Row indices of non-zero entries
   * @param values Non-zero matrix entries
   * @return Sparse matrix instance
   */
  def sparse(
    numRows: Int,
    numCols: Int,
    colPtrs: Array[Int],
    rowIndices: Array[Int],
    values: Array[Double]
  ): Matrix
  
  /**
   * Creates a zero matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @return Dense zero matrix
   */
  def zeros(numRows: Int, numCols: Int): Matrix
  
  /**
   * Creates a matrix of ones
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @return Dense matrix filled with ones
   */
  def ones(numRows: Int, numCols: Int): Matrix
  
  /**
   * Creates a dense identity matrix
   * @param n Size (n x n)
   * @return Dense identity matrix
   */
  def eye(n: Int): Matrix
  
  /**
   * Creates a sparse identity matrix
   * @param n Size (n x n)
   * @return Sparse identity matrix
   */
  def speye(n: Int): Matrix
  
  /**
   * Creates a diagonal matrix from vector
   * @param vector Values for the diagonal
   * @return Square matrix with vector values on diagonal
   */
  def diag(vector: Vector): Matrix
  
  /**
   * Creates a matrix from sequence of vectors (as rows)
   * @param vectors Sequence of vectors to use as matrix rows
   * @return Matrix with vectors as rows
   */
  private[ml] def fromVectors(vectors: Seq[Vector]): Matrix
  
  /**
   * Creates a uniform random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param rng Random number generator
   * @return Matrix with uniform random values in [0, 1)
   */
  def rand(numRows: Int, numCols: Int, rng: java.util.Random): Matrix
  
  /**
   * Creates a Gaussian random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param rng Random number generator
   * @return Matrix with N(0,1) random values
   */
  def randn(numRows: Int, numCols: Int, rng: java.util.Random): Matrix
  
  /**
   * Creates a sparse uniform random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param density Fraction of non-zero elements (0.0 to 1.0)
   * @param rng Random number generator
   * @return Sparse matrix with uniform random values
   */
  def sprand(numRows: Int, numCols: Int, density: Double, rng: java.util.Random): Matrix
  
  /**
   * Creates a sparse Gaussian random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param density Fraction of non-zero elements (0.0 to 1.0)
   * @param rng Random number generator
   * @return Sparse matrix with N(0,1) random values
   */
  def sprandn(numRows: Int, numCols: Int, density: Double, rng: java.util.Random): Matrix
}

Usage Examples:

import org.apache.spark.ml.linalg._
import java.util.Random

// Dense matrices
val dense = Matrices.dense(3, 2, Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
val zeros = Matrices.zeros(5, 5)
val ones = Matrices.ones(3, 3)

// Identity matrices
val denseId = Matrices.eye(4)
val sparseId = Matrices.speye(4)

// Sparse matrix (CSC format)
val sparse = Matrices.sparse(3, 3, 
  Array(0, 1, 2, 3),      // colPtrs
  Array(0, 1, 2),         // rowIndices  
  Array(1.0, 2.0, 3.0)    // values
)

// Diagonal matrix
val diagonal = Matrices.diag(Vectors.dense(1.0, 2.0, 3.0))

Matrix Operations

Core operations available on all matrix types.

sealed trait Matrix extends Serializable {
  /**
   * Number of rows
   * @return Row count
   */
  def numRows: Int
  
  /**
   * Number of columns
   * @return Column count
   */
  def numCols: Int
  
  /**
   * Whether matrix is transposed
   * @return True if matrix is in transposed form
   */
  def isTransposed: Boolean
  
  /**
   * Convert to array in column major order
   * @return Array containing all matrix values
   */
  def toArray: Array[Double]
  
  /**
   * Get element at position (i, j)
   * @param i Row index (0-based)
   * @param j Column index (0-based)
   * @return Value at position (i, j)
   */
  def apply(i: Int, j: Int): Double
  
  /**
   * Get deep copy of matrix
   * @return New matrix instance with copied values
   */
  def copy: Matrix
  
  /**
   * Transpose the matrix (returns new instance)
   * @return Transposed matrix sharing underlying data
   */
  def transpose: Matrix
  
  /**
   * Matrix-vector multiplication
   * @param y Vector to multiply (size must match numCols)
   * @return Result vector of size numRows
   */
  def multiply(y: Vector): DenseVector
  
  /**
   * Matrix-matrix multiplication
   * @param y Matrix to multiply (numRows must match this.numCols)
   * @return Result matrix of size (numRows x y.numCols)
   */
  def multiply(y: DenseMatrix): DenseMatrix
  
  /**
   * Number of non-zero values
   * @return Count of non-zero elements
   */
  def numNonzeros: Int
  
  /**
   * Number of stored values
   * @return Count of explicitly stored elements
   */
  def numActives: Int
  
  /**
   * Iterator over column vectors
   * @return Iterator of Vector instances (one per column)
   */
  def colIter: Iterator[Vector]
  
  /**
   * Iterator over row vectors
   * @return Iterator of Vector instances (one per row)
   */
  def rowIter: Iterator[Vector]
  
  /**
   * Apply function to all active elements
   * @param f Function taking (row, col, value) parameters
   */
  def foreachActive(f: (Int, Int, Double) => Unit): Unit
  
  /**
   * Map values using function (creates new matrix)
   * @param f Function to apply to each value
   * @return New matrix with transformed values
   */
  private[spark] def map(f: Double => Double): Matrix
  
  /**
   * Update values in-place using function
   * @param f Function to apply to each value
   * @return This matrix with updated values
   */
  private[ml] def update(f: Double => Double): Matrix
  
  /**
   * Update element at position (i, j)
   * @param i Row index
   * @param j Column index
   * @param v New value
   */
  private[ml] def update(i: Int, j: Int, v: Double): Unit
  
  /**
   * Get index for element (i, j) in backing array
   * @param i Row index
   * @param j Column index
   * @return Array index for element
   */
  private[ml] def index(i: Int, j: Int): Int
}

Format Conversion

Methods for converting between dense and sparse representations.

sealed trait Matrix extends Serializable {
  /**
   * Convert to sparse column major format
   * @return Sparse matrix in CSC format
   */
  def toSparseColMajor: SparseMatrix
  
  /**
   * Convert to sparse row major format
   * @return Sparse matrix in CSR format
   */
  def toSparseRowMajor: SparseMatrix
  
  /**
   * Convert to sparse maintaining current layout
   * @return Sparse matrix preserving row/column major order
   */
  def toSparse: SparseMatrix
  
  /**
   * Convert to dense column major format
   * @return Dense matrix in column major order
   */
  def toDenseColMajor: DenseMatrix
  
  /**
   * Convert to dense row major format
   * @return Dense matrix in row major order
   */
  def toDenseRowMajor: DenseMatrix
  
  /**
   * Convert to dense maintaining current layout
   * @return Dense matrix preserving row/column major order
   */
  def toDense: DenseMatrix
  
  /**
   * Get matrix in most compact column major format
   * @return Matrix in dense or sparse format using less storage
   */
  def compressedColMajor: Matrix
  
  /**
   * Get matrix in most compact row major format
   * @return Matrix in dense or sparse format using less storage
   */
  def compressedRowMajor: Matrix
  
  /**
   * Get matrix in optimal storage format
   * @return Matrix in format using least memory (dense or sparse)
   */
  def compressed: Matrix
}

Usage Examples:

import org.apache.spark.ml.linalg._

val matrix = Matrices.dense(3, 3, Array(1.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 3.0))

// Format conversions
val sparse = matrix.toSparse
val dense = sparse.toDense
val compressed = matrix.compressed // Automatically chooses optimal format

// Matrix operations
val vector = Vectors.dense(1.0, 2.0, 3.0)
val result = matrix.multiply(vector)

val other = Matrices.dense(3, 2, Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
val product = matrix.multiply(other.asInstanceOf[DenseMatrix])

// Iteration
matrix.foreachActive { (i, j, v) =>
  if (v != 0.0) println(s"($i, $j) = $v")
}

Dense Matrices

Dense matrix implementation storing all elements in column-major array.

class DenseMatrix(
  val numRows: Int,
  val numCols: Int,
  val values: Array[Double],
  override val isTransposed: Boolean = false
) extends Matrix {
  /**
   * Create column-major dense matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param values Matrix entries in column major order
   */
  def this(numRows: Int, numCols: Int, values: Array[Double])
}

object DenseMatrix {
  /**
   * Create zero matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @return Dense matrix filled with zeros
   */
  def zeros(numRows: Int, numCols: Int): DenseMatrix
  
  /**
   * Create matrix of ones
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @return Dense matrix filled with ones
   */
  def ones(numRows: Int, numCols: Int): DenseMatrix
  
  /**
   * Create identity matrix
   * @param n Size (n x n)
   * @return Dense identity matrix
   */
  def eye(n: Int): DenseMatrix
  
  /**
   * Create uniform random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param rng Random number generator
   * @return Dense matrix with values in [0, 1)
   */
  def rand(numRows: Int, numCols: Int, rng: java.util.Random): DenseMatrix
  
  /**
   * Create Gaussian random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param rng Random number generator
   * @return Dense matrix with N(0,1) values
   */
  def randn(numRows: Int, numCols: Int, rng: java.util.Random): DenseMatrix
  
  /**
   * Create diagonal matrix
   * @param vector Diagonal values
   * @return Square dense matrix with vector on diagonal
   */
  def diag(vector: Vector): DenseMatrix
  
  /**
   * Extract components from dense matrix (for pattern matching)
   * @param dm Dense matrix instance
   * @return Some((numRows, numCols, values, isTransposed)) or None
   */
  private[ml] def unapply(dm: DenseMatrix): Option[(Int, Int, Array[Double], Boolean)]
  
  /**
   * Create dense matrix from sequence of vectors (as rows)
   * @param vectors Sequence of vectors to use as matrix rows
   * @return Dense matrix with vectors as rows
   */
  private[ml] def fromVectors(vectors: Seq[Vector]): DenseMatrix
}

Sparse Matrices

Sparse matrix implementation using Compressed Sparse Column (CSC) format.

class SparseMatrix(
  val numRows: Int,
  val numCols: Int,
  val colPtrs: Array[Int],
  val rowIndices: Array[Int],
  val values: Array[Double],
  override val isTransposed: Boolean = false
) extends Matrix {
  /**
   * Create column-major sparse matrix in CSC format
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param colPtrs Column pointers (length numCols + 1)
   * @param rowIndices Row indices of non-zero entries
   * @param values Non-zero matrix entries
   */
  def this(
    numRows: Int,
    numCols: Int,
    colPtrs: Array[Int],
    rowIndices: Array[Int],
    values: Array[Double]
  )
}

object SparseMatrix {
  /**
   * Create sparse matrix from coordinate (COO) format
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param entries Iterable of (row, col, value) tuples
   * @return Sparse matrix in CSC format
   */
  def fromCOO(
    numRows: Int,
    numCols: Int,
    entries: Iterable[(Int, Int, Double)]
  ): SparseMatrix
  
  /**
   * Create sparse identity matrix
   * @param n Size (n x n)
   * @return Sparse identity matrix
   */
  def speye(n: Int): SparseMatrix
  
  /**
   * Create sparse uniform random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param density Fraction of non-zero elements (0.0 to 1.0)
   * @param rng Random number generator
   * @return Sparse matrix with uniform random values
   */
  def sprand(numRows: Int, numCols: Int, density: Double, rng: java.util.Random): SparseMatrix
  
  /**
   * Create sparse Gaussian random matrix
   * @param numRows Number of rows
   * @param numCols Number of columns
   * @param density Fraction of non-zero elements (0.0 to 1.0)
   * @param rng Random number generator
   * @return Sparse matrix with N(0,1) values
   */
  def sprandn(numRows: Int, numCols: Int, density: Double, rng: java.util.Random): SparseMatrix
  
  /**
   * Create sparse diagonal matrix
   * @param vector Diagonal values
   * @return Square sparse matrix with vector on diagonal
   */
  def spdiag(vector: Vector): SparseMatrix
  
  /**
   * Extract components from sparse matrix (for pattern matching)
   * @param sm Sparse matrix instance
   * @return Some((numRows, numCols, colPtrs, rowIndices, values, isTransposed)) or None
   */
  private[ml] def unapply(sm: SparseMatrix): Option[(Int, Int, Array[Int], Array[Int], Array[Double], Boolean)]
  
  /**
   * Create sparse matrix from sequence of vectors (as rows)
   * @param vectors Sequence of vectors to use as matrix rows
   * @return Sparse matrix with vectors as rows in CSR format
   */
  private[ml] def fromVectors(vectors: Seq[Vector]): SparseMatrix
}

Matrix Concatenation

Utility functions for combining matrices.

object Matrices {
  /**
   * Horizontally concatenate matrices
   * @param matrices Array of matrices (same number of rows)
   * @return Single matrix with matrices side-by-side
   */
  def horzcat(matrices: Array[Matrix]): Matrix
  
  /**
   * Vertically concatenate matrices
   * @param matrices Array of matrices (same number of columns)
   * @return Single matrix with matrices stacked vertically
   */
  def vertcat(matrices: Array[Matrix]): Matrix
}

Usage Examples:

import org.apache.spark.ml.linalg._

val m1 = Matrices.dense(2, 2, Array(1.0, 2.0, 3.0, 4.0))
val m2 = Matrices.dense(2, 2, Array(5.0, 6.0, 7.0, 8.0))

// Horizontal concatenation: [m1 m2]
val hcat = Matrices.horzcat(Array(m1, m2)) // 2x4 matrix

// Vertical concatenation: [m1; m2]
val vcat = Matrices.vertcat(Array(m1, m2)) // 4x2 matrix

Type Hierarchy

Matrix (sealed trait)
├── DenseMatrix (class)
└── SparseMatrix (class)

Storage Formats

  • Dense matrices: Column-major storage (Fortran-style) for BLAS compatibility
  • Sparse matrices: Compressed Sparse Column (CSC) format by default
  • Transposed matrices: Logical transposition without data copying
  • Format conversion: Automatic optimization between dense and sparse representations

Performance Notes

  • Dense matrices: Optimal for small to medium matrices or when most elements are non-zero
  • Sparse matrices: Optimal for large matrices with many zero elements (typically < 34% density)
  • Native acceleration: Dense operations use optimized BLAS when available
  • Memory efficiency: Use compressed method to automatically choose optimal format