## 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:

diag(3.5, 10)

Diagonal matrix with main diagonal backed by a vector:

diagv((1, 2, 3, 4, 5))

Identity matrix:

eye(10)

#### Slicing and Assigning¶

Getting a vector element:

val d = vec(5)

Setting a vector element:

vec(5) = 3.0

Getting a matrix element:

val d = m(3,5)

Setting a matrix element:

M(3,5) = 3.0

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:

a(0, 0 to 1) = (3, 5)

Setting a subslices of a matrix row or column via vector assignment:

a(0, 0 to 1) := (3, 5)

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:

vec1 := vec2 M1 := M2

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:

a * b a * 0.5

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:

val xInv = 1 /: x

and R's 5.0 - x would be:

val x1 = 5.0 -: x

*note: All assignment operations, including :=, return the assignee just like in C++*:

a -= b

assigns **a - b** to **b** (in-place) and returns **b**. Similarly for **a /=: b** or **1 /=: v**

Dot product:

a dot b

Matrix and vector equivalency (or non-equivalency). **Dangerous, exact equivalence is rarely useful, better to use norm comparisons with an allowance of small errors.**

a === b a !== b

Matrix multiply:

a %*% b

Optimized Right Multiply with a diagonal matrix:

diag(5, 5) :%*% b

Optimized Left Multiply with a diagonal matrix:

A %*%: diag(5, 5)

Second norm, of a vector or matrix:

a.norm

Transpose:

val Mt = M.t

*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}\)`

:

val XtX = X.t %*% 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**

val ch = chol(M)

**SVD**

val (U, V, s) = svd(M)

**EigenDecomposition**

val (V, d) = eigen(M)

**QR decomposition**

val (Q, R) = qr(M)

**Rank**: Check for rank deficiency (runs rank-revealing QR)

M.isFullRank

**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(A, B)

Solve `\(\mathbf{Ax}=\mathbf{b}\)`

:

solve(A, b)

Compute `\(\mathbf{A^{-1}}\)`

:

solve(A)

#### Misc¶

Vector cardinality:

a.length

Matrix cardinality:

m.nrow m.ncol

Means and sums:

m.colSums m.colMeans m.rowSums m.rowMeans

Copy-By-Value:

val b = a cloned

#### 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