Core vector and matrix operations including creation, manipulation, arithmetic operations, and format conversions. The library provides both dense and sparse implementations with automatic optimization for storage efficiency and computational performance.
Factory methods for creating vectors in dense and sparse formats with various initialization patterns.
import java.lang.{Double => JavaDouble, Integer => JavaInteger, Iterable => JavaIterable}
object Vectors {
@varargs
def dense(firstValue: Double, otherValues: Double*): Vector
def dense(values: Array[Double]): Vector
def sparse(size: Int, indices: Array[Int], values: Array[Double]): Vector
def sparse(size: Int, elements: Seq[(Int, Double)]): Vector
def sparse(size: Int, elements: JavaIterable[(JavaInteger, JavaDouble)]): Vector
def zeros(size: Int): Vector
def norm(vector: Vector, p: Double): Double
def sqdist(v1: Vector, v2: Vector): Double
}Usage examples:
import org.apache.spark.ml.linalg._
// Dense vector creation
val dense1 = Vectors.dense(1.0, 2.0, 3.0, 4.0)
val dense2 = Vectors.dense(Array(1.0, 2.0, 3.0, 4.0))
// Sparse vector creation
val sparse1 = Vectors.sparse(4, Array(0, 2), Array(1.0, 3.0))
val sparse2 = Vectors.sparse(4, Seq((0, 1.0), (2, 3.0)))
// Zero vector
val zeros = Vectors.zeros(4)Mathematical operations on vectors including norms, distances, and element access.
// Vector trait methods
trait Vector {
def size: Int
def toArray: Array[Double]
def apply(i: Int): Double
def copy: Vector
def foreachActive(f: (Int, Double) => Unit): Unit
def numActives: Int
def numNonzeros: Int
def toSparse: SparseVector
def toDense: DenseVector
def compressed: Vector
def argmax: Int
def dot(v: Vector): Double
}
// Static utility methods
object Vectors {
def norm(vector: Vector, p: Double): Double
def sqdist(v1: Vector, v2: Vector): Double
}Usage examples:
val v1 = Vectors.dense(1.0, 2.0, 3.0)
val v2 = Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0))
// Element access
val element = v1(1) // Returns 2.0
// Vector properties
val size = v1.size
val nnz = v1.numNonzeros
val actives = v1.numActives
// Vector operations
val l2Norm = Vectors.norm(v1, 2.0)
val l1Norm = Vectors.norm(v1, 1.0)
val distance = Vectors.sqdist(v1, v2)
val dotProduct = v1.dot(v2)
// Format conversions
val dense = v2.toDense
val sparse = v1.toSparse
val compressed = v1.compressed
// Find maximum element index
val maxIdx = v1.argmaxFactory methods for creating matrices in dense and sparse formats with support for various initialization patterns and random generation.
import java.util.Random
object Matrices {
def dense(numRows: Int, numCols: Int, values: Array[Double]): Matrix
def sparse(numRows: Int, numCols: Int, colPtrs: Array[Int], rowIndices: Array[Int], values: Array[Double]): Matrix
def zeros(numRows: Int, numCols: Int): Matrix
def ones(numRows: Int, numCols: Int): Matrix
def eye(n: Int): Matrix
def speye(n: Int): Matrix
def rand(numRows: Int, numCols: Int, rng: Random): Matrix
def sprand(numRows: Int, numCols: Int, density: Double, rng: Random): Matrix
def randn(numRows: Int, numCols: Int, rng: Random): Matrix
def sprandn(numRows: Int, numCols: Int, density: Double, rng: Random): Matrix
def diag(vector: Vector): Matrix
def horzcat(matrices: Array[Matrix]): Matrix
def vertcat(matrices: Array[Matrix]): Matrix
}
object DenseMatrix {
def zeros(numRows: Int, numCols: Int): DenseMatrix
def ones(numRows: Int, numCols: Int): DenseMatrix
def eye(n: Int): DenseMatrix
def rand(numRows: Int, numCols: Int, rng: Random): DenseMatrix
def randn(numRows: Int, numCols: Int, rng: Random): DenseMatrix
def diag(vector: Vector): DenseMatrix
}
object SparseMatrix {
def fromCOO(numRows: Int, numCols: Int, entries: Iterable[(Int, Int, Double)]): SparseMatrix
def speye(n: Int): SparseMatrix
def sprand(numRows: Int, numCols: Int, density: Double, rng: Random): SparseMatrix
def sprandn(numRows: Int, numCols: Int, density: Double, rng: Random): SparseMatrix
def spdiag(vector: Vector): SparseMatrix
}Usage examples:
import org.apache.spark.ml.linalg._
import java.util.Random
// Dense matrix creation
val dense = Matrices.dense(2, 3, Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
val zeros = Matrices.zeros(3, 3)
val ones = Matrices.ones(2, 2)
val identity = Matrices.eye(3)
// Sparse matrix creation
val sparse = Matrices.sparse(3, 3, Array(0, 1, 2, 3), Array(0, 1, 2), Array(1.0, 2.0, 3.0))
val sparseIdentity = Matrices.speye(3)
// Random matrices
val rng = new Random(42)
val randDense = Matrices.rand(3, 3, rng)
val randSparse = Matrices.sprand(3, 3, 0.3, rng)
// Diagonal matrices
val diagVec = Vectors.dense(1.0, 2.0, 3.0)
val diagMatrix = Matrices.diag(diagVec)
// Matrix concatenation
val m1 = Matrices.ones(2, 2)
val m2 = Matrices.zeros(2, 2)
val horizontal = Matrices.horzcat(Array(m1, m2))
val vertical = Matrices.vertcat(Array(m1, m2))
// COO format creation
val entries = Seq((0, 0, 1.0), (1, 1, 2.0), (2, 2, 3.0))
val coo = SparseMatrix.fromCOO(3, 3, entries)Operations on matrices including element access, arithmetic operations, transposition, and format conversions.
trait Matrix {
def numRows: Int
def numCols: Int
val isTransposed: Boolean
def toArray: Array[Double]
def colIter: Iterator[Vector]
def rowIter: Iterator[Vector]
def apply(i: Int, j: Int): Double
def copy: Matrix
def transpose: Matrix
def multiply(y: DenseMatrix): DenseMatrix
def multiply(y: DenseVector): DenseVector
def multiply(y: Vector): DenseVector
def toString(maxLines: Int, maxLineWidth: Int): String
def foreachActive(f: (Int, Int, Double) => Unit): Unit
def numNonzeros: Int
def numActives: Int
def toSparseColMajor: SparseMatrix
def toSparseRowMajor: SparseMatrix
def toSparse: SparseMatrix
def toDense: DenseMatrix
def toDenseRowMajor: DenseMatrix
def toDenseColMajor: DenseMatrix
def compressedColMajor: Matrix
def compressedRowMajor: Matrix
def compressed: Matrix
}Usage examples:
val matrix = Matrices.dense(2, 3, Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
val vector = Vectors.dense(1.0, 2.0, 3.0)
// Matrix properties
val rows = matrix.numRows
val cols = matrix.numCols
val isTransposed = matrix.isTransposed
// Element access
val element = matrix(0, 1)
// Matrix operations
val transposed = matrix.transpose
val copy = matrix.copy
// Matrix-vector multiplication
val result1 = matrix.multiply(vector)
// Matrix-matrix multiplication
val other = DenseMatrix.ones(3, 2)
val result2 = matrix.multiply(other)
// Format conversions
val sparse = matrix.toSparse
val denseColMajor = matrix.toDenseColMajor
val compressed = matrix.compressed
// Iteration over columns/rows
matrix.colIter.foreach { col =>
println(s"Column: ${col.toArray.mkString(", ")}")
}
// Apply function to active elements
matrix.foreachActive { (i, j, value) =>
println(s"matrix($i, $j) = $value")
}
// Statistics
val nnz = matrix.numNonzeros
val actives = matrix.numActivesDense and sparse vector implementations with different storage characteristics.
class DenseVector(val values: Array[Double]) extends Vector {
// Inherits all Vector methods
// Direct array access for maximum performance
}
class SparseVector(
override val size: Int,
val indices: Array[Int],
val values: Array[Double]
) extends Vector {
// Inherits all Vector methods
// Compressed storage for sparse data
}Dense and sparse matrix implementations supporting different storage layouts.
class DenseMatrix(
val numRows: Int,
val numCols: Int,
val values: Array[Double],
override val isTransposed: Boolean = false
) extends Matrix {
// Convenience constructor
def this(numRows: Int, numCols: Int, values: Array[Double]) =
this(numRows, numCols, values, false)
}
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 {
// Convenience constructor
def this(numRows: Int, numCols: Int, colPtrs: Array[Int],
rowIndices: Array[Int], values: Array[Double]) =
this(numRows, numCols, colPtrs, rowIndices, values, false)
}Basic Linear Algebra Subprograms providing optimized implementations of fundamental linear algebra operations.
object BLAS {
// Level 1: Vector-Vector operations
def axpy(a: Double, x: Vector, y: Vector): Unit
def dot(x: Vector, y: Vector): Double
def copy(x: Vector, y: Vector): Unit
def scal(a: Double, x: Vector): Unit
// Level 2: Matrix-Vector operations
def gemv(alpha: Double, A: Matrix, x: Vector, beta: Double, y: DenseVector): Unit
def gemv(alpha: Double, A: Matrix, x: Array[Double], beta: Double, y: Array[Double]): Unit
def spr(alpha: Double, v: Vector, U: DenseVector): Unit
def spr(alpha: Double, v: Vector, U: Array[Double]): Unit
def syr(alpha: Double, x: Vector, A: DenseMatrix): Unit
def dspmv(n: Int, alpha: Double, A: DenseVector, x: DenseVector, beta: Double, y: DenseVector): Unit
// Level 3: Matrix-Matrix operations
def gemm(alpha: Double, A: Matrix, B: DenseMatrix, beta: Double, C: DenseMatrix): Unit
def gemm(alpha: Double, A: Matrix, B: DenseMatrix, beta: Double, CValues: Array[Double]): Unit
}Usage examples:
import org.apache.spark.ml.linalg._
val x = Vectors.dense(1.0, 2.0, 3.0)
val y = Vectors.dense(4.0, 5.0, 6.0).copy.asInstanceOf[DenseVector]
// Level 1 operations
val dotProduct = BLAS.dot(x, y) // Compute x · y
BLAS.scal(2.0, y) // Scale y by 2.0: y = 2.0 * y
BLAS.axpy(1.5, x, y) // Compute y = 1.5 * x + y
// Level 2 operations
val A = Matrices.dense(2, 3, Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
val result = Vectors.zeros(2).asInstanceOf[DenseVector]
BLAS.gemv(1.0, A, x, 0.0, result) // result = A * x
// Level 3 operations
val B = Matrices.dense(3, 2, Array(1.0, 0.0, 0.0, 1.0, 1.0, 0.0)).asInstanceOf[DenseMatrix]
val C = DenseMatrix.zeros(2, 2)
BLAS.gemm(1.0, A, B, 0.0, C) // C = A * B