Mahout-Samsara’s In-Core Linear Algebra DSL Reference
Imports
The following imports are used to enable Mahout-Samsara’s Scala DSL bindings for in-core Linear Algebra:
import org.apache.mahout.math._
import scalabindings._
import RLikeOps._
Inline initalization
Dense vectors:
val densVec1: Vector = (1.0, 1.1, 1.2)
val denseVec2 = dvec(1, 0, 1,1 ,1,2)
Sparse vectors:
val sparseVec1: Vector = (5 -> 1.0) :: (10 -> 2.0) :: Nil
val sparseVec1 = svec((5 -> 1.0) :: (10 -> 2.0) :: Nil)
// to create a vector with specific cardinality
val sparseVec1 = svec((5 -> 1.0) :: (10 -> 2.0) :: Nil, cardinality = 20)
Inline matrix initialization, either sparse or dense, is always done row wise.
Dense matrices:
val A = dense((1, 2, 3), (3, 4, 5))
Sparse matrices:
val A = sparse(
(1, 3) :: Nil,
(0, 2) :: (1, 2.5) :: Nil
)
Diagonal matrix with constant diagonal elements:
Diagonal matrix with main diagonal backed by a vector:
Identity matrix:
####Slicing and Assigning
Getting a vector element:
Setting a vector element:
Getting a matrix element:
Setting a matrix element:
Getting a matrix row or column:
val rowVec = M(3, ::)
val colVec = M(::, 3)
Setting a matrix row or column via vector assignment:
M(3, ::) := (1, 2, 3)
M(::, 3) := (1, 2, 3)
Setting a subslices of a matrix row or column:
Setting a subslices of a matrix row or column via vector assignment:
Getting a matrix as from matrix contiguous block:
val B = A(2 to 3, 3 to 4)
Assigning a contiguous block to a matrix:
A(0 to 1, 1 to 2) = dense((3, 2), (3 ,3))
Assigning a contiguous block to a matrix using the matrix assignment operator:
A(o to 1, 1 to 2) := dense((3, 2), (3, 3))
Assignment operator used for copying between vectors or matrices:
Assignment operator using assignment through a functional literal for a matrix:
M := ((row, col, x) => if (row == col) 1 else 0
Assignment operator using assignment through a functional literal for a vector:
vec := ((index, x) => sqrt(x)
BLAS-like operations
Plus/minus either vector or numeric with assignment or not:
a + b
a - b
a + 5.0
a - 5.0
Hadamard (elementwise) product, either vector or matrix or numeric operands:
Operations with assignment:
a += b
a -= b
a += 5.0
a -= 5.0
a *= b
a *= 5
Some nuanced rules:
1/x in R (where x is a vector or a matrix) is elementwise inverse. In scala it would be expressed as:
and R’s 5.0 - x would be:
note: All assignment operations, including :=, return the assignee just like in C++:
assigns a - b to b (in-place) and returns b. Similarly for a /=: b or 1 /=: v
Dot product:
Matrix and vector equivalency (or non-equivalency). Dangerous, exact equivalence is rarely useful, better to use norm comparisons with an allowance of small errors.
Matrix multiply:
Optimized Right Multiply with a diagonal matrix:
Optimized Left Multiply with a diagonal matrix:
Second norm, of a vector or matrix:
Transpose:
note: Transposition is currently handled via view, i.e. updating a transposed matrix will be updating the original. Also computing something like \(\mathbf{X^\top}\mathbf{X}\)
:
will not therefore incur any additional data copying.
Decompositions
Matrix decompositions require an additional import:
import org.apache.mahout.math.decompositions._
All arguments in the following are matricies.
Cholesky decomposition
SVD
EigenDecomposition
QR decomposition
Rank: Check for rank deficiency (runs rank-revealing QR)
In-core SSVD
Val (U, V, s) = ssvd(A, k = 50, p = 15, q = 1)
Solving linear equation systems and matrix inversion: fully similar to R semantics; there are three forms of invocation:
Solve \(\mathbf{AX}=\mathbf{B}\)
:
Solve \(\mathbf{Ax}=\mathbf{b}\)
:
Compute \(\mathbf{A^{-1}}\)
:
Misc
Vector cardinality:
Matrix cardinality:
Means and sums:
m.colSums
m.colMeans
m.rowSums
m.rowMeans
Copy-By-Value:
Random Matrices
\(\mathcal{U}\)
(0,1) random matrix view:
val incCoreA = Matrices.uniformView(m, n, seed)
\(\mathcal{U}\)
(-1,1) random matrix view:
val incCoreA = Matrices.symmetricUniformView(m, n, seed)
\(\mathcal{N}\)
(-1,1) random matrix view:
val incCoreA = Matrices.gaussianView(m, n, seed)
Iterators
Mahout-Math already exposes a number of iterators. Scala code just needs the following imports to enable implicit conversions to scala iterators.
import collection._
import JavaConversions._
Iterating over rows in a Matrix:
for (row <- m) {
... do something with row
}
For more information including information on Mahout-Samsara’s out-of-core Linear algebra bindings see: Mahout Scala Bindings and Mahout Spark Bindings for Linear Algebra Subroutines