Skip to content

Matrix functions

jcanny edited this page Dec 28, 2014 · 15 revisions

Table of Contents

Element-wise Functions

Currently, the only (non-scientific) functions in this category are max and min (most element-wise functions are listed under scientific functions later, and element-wise operators are list under Matrix algebra). max(A,B) for equal-sized A and B computes the element-wise max of the matrices. Just as for matrix operators, matrix functions also work in these cases:

  • A or B is a scalar, in which case that value is applied against all values in the other matrix.
  • A or B is a 1 x 1 matrix, in which case the value is treated as a scalar as above.
  • A or B is a vector whose length matches the corresponding dimension of the other matrix. In that case, each value in the vector is applied against all the elements in the other matrix in the corresponding row or column.

Reducing Functions

Reducing functions apply a binary operator cumulatively to rows or columns of the input matrix, and produce either a vector output (standard reducing functions) or a same-size matrix (cumulative reducing functions). The standard reducing functions are

  • maxi(A, n), mini(A, n), sum(A, n), mean(A, n), variance(A, n), sdev(A, n)
Each of these reduces along the dimension specified by n. e.g. maxi(A,1) computes a row vector which is the max of each column, while maxi(A,2) computes a column vector whose values are the row-wise maximum values of A.

All of these functions can be called without a dimension argument, which is a convenience form intended for vector arguments. So e.g. sum(A) for a vector A reduces along the long dimension of A. Calling sum(A) without the dimension argument for a non-vector A will reduce along dimension 1.

The cumulative reducing functions right now are:

  • cumsum(A, n)
which computes the cumulative sum along dimension n, and returns every partial sum. cumsum(A) for vector A works along the long dimension of A.

The following function constructs dense matrices from tuples of indices.

  • accum(inds:IMat, vals:DMat, nrows, ncols)
sums all the values for a given index value, and stores the result in that location. The inds matrix can be either a vector of single indices, or a 2 x n matrix whose columns are row and column indices respectively. If called without dimension arguments: accum(inds, vals) the matrix is sized to fit the largest row and column indices.

Sorting Functions

The sort functions sorts columns of a matrix in ascending order. sort2(A) returns both the a sorted version of A and a permutation matrix P such that for each i, B(?,i) = A(P(?,i),i). Or if we add column offsets to P, POFF, then we have that B=A(P+POFF).

scala> a
res16: BIDMat.DMat =
   0.14771   0.53622   0.85483  0.042617
   0.96534   0.41199   0.63428  0.014676
   0.66535  0.029090   0.85247   0.61777
   0.38885   0.50339   0.81829   0.77564

scala> val (b, p) = sort2(a)
b: BIDMat.DMat =
   0.14771  0.029090   0.63428  0.014676
   0.38885   0.41199   0.81829  0.042617
   0.66535   0.50339   0.85247   0.61777
   0.96534   0.53622   0.85483   0.77564

p: BIDMat.IMat =
   0   2   1   1
   3   1   3   0
   2   3   2   2
   1   0   0   3

scala> val poff = iones(4,1)*irow(0 to 12 by 4)
poff: BIDMat.IMat =
   0   4   8  12
   0   4   8  12
   0   4   8  12
   0   4   8  12

scala> a(p + poff)
res21: BIDMat.DMat =
   0.14771  0.029090   0.63428  0.014676
   0.38885   0.41199   0.81829  0.042617
   0.66535   0.50339   0.85247   0.61777
   0.96534   0.53622   0.85483   0.77564

scala> b
res22: BIDMat.DMat =
   0.14771  0.029090   0.63428  0.014676
   0.38885   0.41199   0.81829  0.042617
   0.66535   0.50339   0.85247   0.61777
   0.96534   0.53622   0.85483   0.77564

sort and sort2 always sort in ascending order. For descending sorts, there are functions sortdown and sortdown2.

To sort each row, use sort(A,2) or sortdown(A,2).

To sort rows of a matrix (in lexicographic order), there are two functions sortlex(A) and sortrows(A). sortlex returns only the permutation matrix for the sort. sortrows returns both the permutation matrix and the matrix itself.

scala> a
a: BIDMat.DMat =
   0.083308  0.0053793    0.60398
    0.75904    0.91294    0.43385
    0.53446    0.91638    0.59250
    0.39092    0.65965   0.020080

scala> val (aa, ii) = sortrows(a)
aa: BIDMat.DMat =
   0.083308  0.0053793    0.60398
    0.39092    0.65965   0.020080
    0.53446    0.91638    0.59250
    0.75904    0.91294    0.43385

ii: BIDMat.IMat =
   0
   3
   2
   1

scala> a(ii,?)
res26: BIDMat.DMat =
   0.083308  0.0053793    0.60398
    0.39092    0.65965   0.020080
    0.53446    0.91638    0.59250
    0.75904    0.91294    0.43385

Finally, for descending sorts there are functions sortlexdown and sortrowsdown.

Set Functions

unique, unique3 and uniquerows. The unique takes a single argument matrix (which should be a vector) a and returns the unique values:

> val a = round(4*rand(1,28))
3,1,0,3,1,3,4,3,2,4,2,0,0,3,4,0,2,1,2,3,0,3,2,1,3,1,0,4
> val b = unique(a)
> b.t
> 0,1,2,3,4
unique3 takes a single argument matrix a and returns 3 matrices values:
> val a = round(4*rand(1,28))
3,1,0,3,1,3,4,3,2,4,2,0,0,3,4,0,2,1,2,3,0,3,2,1,3,1,0,4
> val (b, ii, jj) = unique3(a)
> b.t
0,1,2,3,4
> ii.t
2,1,8,0,6
> jj.t
3,1,0,3,1,3,4,3,2,4,2,0,0,3,4,0,2,1,2,3,0,3,2,1,3,1,0,4

From the three returned values, the value b is the set of distinct values in a, in sorted order. ii(i) holds the position of the first occurrence of b(i) in a. That is a(ii) = b, and each element of ii is the smallest value for which this holds. jj gives the index in B for each element of a, so that b(jj) = a. In summary:

if (b, ii, jj) = unique3(a), then
a(ii) = b   where each ii(i) is the smallest such value
b(jj) = a

The uniquerows function is very similarly to unique, but normally takes a matrix input which it treats as a vector of rows. The output B contains the distinct rows, sorted in lexicographic order. That is, it satisfies the relations:

if (b, ii, jj) = uniquerows(a), then
every row of B is distinct
a(ii,?) = b   where each ii(i) is the smallest such value
b(jj,?) = a

as an example:

> val a = round(0.5+2*rand(8,2))
   2   1
   1   2
   1   2
   2   1
   1   1
   2   2
   2   2
   2   1
> val (b, ii, jj) = uniquerows(a)
> b
   1   1
   1   2
   2   1
   2   2
> ii
   4
   1
   0
   5
> jj
   2
   1
   1
   2
   0
   3
   3
   2