Liking cljdoc? Tell your friends :D

Matrices

Matrices

There is an extensive set of operations for manipulating matrices. Let <M>, <N> be matrix-valued expressions. The following operations are provided:

(matrix? <any>)           ;;=> <boolean>
(kind <M>)                ;;=> ::m/matrix
(exact? <M>)              ;;=> <boolean>

(matrix/num-rows <M>) ;;⇒ <n>

the number of rows in matrix M.

(matrix/num-cols <M>) ;;⇒ <n>

the number of columns in matrix M.

(dimension <M>) ;;⇒ <n>`

the number of rows (or columns) in a square matrix M. It is an error to try to get the dimension of a matrix that is not square.

(matrix/column? <M>)

is true if M is a matrix with one column. Note: neither a tuple nor a Clojure vector is a column matrix.

(matrix/row? <M>)

is true if M is a matrix with one row. Note: neither a tuple nor a Clojure vector is a row matrix.

There are general constructors for matrices:

(matrix-by-rows <row-list-1> ... <row-list-n>)

where the row lists are lists of elements that are to appear in the corresponding row of the matrix.

(matrix-by-cols <col-list-1> ... <col-list-n>)

where the column lists are lists of elements that are to appear in the corresponding column of the matrix.

(column-matrix <x1> ,,, <xn>)

returns a column matrix with the given elements.

(row-matrix <x1> ,,, <xn>)

returns a row matrix with the given elements.

Clojure’s standard get-in selector works for the elements of a matrix:

(get-in <M> <n> <m>)

returns the element in the m-th column and the n-th row of matrix M. Remember, this is zero-based indexing.

We can access various parts of a matrix like so:

(matrix/nth-col <M> <n>) ;;⇒ <up>

returns an up tuple with the elements of the n-th column of M.

(matrix/nth-row <M> <n>) ;;⇒ <up>

returns an up tuple with the elements of the n-th row of M.

(m:diagonal <M>) ;;⇒ <up>

returns an up tuple with the elements of the diagonal of the square matrix M.

(matrix/submatrix <M> <from-row> <to-row> <from-col> <to-col>)

extracts a submatrix from M, as in the following example:

(-> (m:generate 3 4
                (fn [i j]
                  (* (square i)
                     (cube j))))
    (matrix/submatrix 1 2 1 3))
;; (matrix-by-rows [1 8 27] [4 32 108])

(m:generate <n> <m> <procedure>) ;;⇒ <M>

returns the nXm (n rows by m columns) matrix whose ij-th element is the value of the procedure when applied to arguments i, j.

(let [f (fn [i j]
          (* (square i) (cube j)))]
  (m:generate 3 4 f))
;; (matrix-by-rows [0 0 0 0] [0 1 8 27] [0 4 32 108])

(matrix/with-substituted-row <M> <n> <vector>)

returns a new matrix constructed from M by substituting the Clojure vector v for the n-th row in M.

We can transpose a matrix (producing a new matrix whose columns are the rows of the given matrix and whose rows are the columns of the given matrix with:

(transpose <M>)

There are coercions between Clojure vectors and matrices:

(apply matrix/column <vector>) ;;=> <M>
(apply matrix/row    <vector>) ;;=> <M>

And similarly for up and down tuples:

(matrix/up->column-matrix <up>)      ;;=>  <M>

(column-matrix->up <M>)       ;;=>  <up>


(down->row-matrix <down>)     ;;=>  <M>

(row-matrix->down <M>)        ;;=>  <down>

Matrices can be tested with the usual tests:

(zero? <M>)
(identity? <M>)
(matrix/diagonal? <M>)

(matrix/make-zero <n>) ;;⇒ <M>

returns an nXn (square) matrix of zeros.

(m:make-zero <n> <m>) ;;⇒ <M>

returns an nXm matrix of zeros.

Useful matrices can be made easily, with the following constructors:

(zero-like <M>) ;;⇒ <N>

returns a zero matrix of the same dimensions as the given matrix.

(matrix/I <n>) ;;⇒ <M>

returns an identity matrix of dimension n.

(matrix/make-diagonal <vector>) ;;⇒ <M>

returns a square matrix with the given vector elements on the diagonal and zeros everywhere else.

Matrices have the usual unary generic operators:

negate, invert, conjugate

However the generic operators

exp, sin, cos, tan, sec,
acos, asin, atan,
cosh, sinh, tanh,
asinh, atanh

yield power series in the given matrix.

Square matrices may be exponentiated to any exact positive integer power:

(expt <M> <n>)

We may also get the determinant and the trace of a square matrix:

(determinant <M>)
(trace <M>)

The usual binary generic operators make sense when applied to matrices. However they have been extended to interact with other datatypes in a few useful ways. The componentwise operators

=, +, -

are extended so that

  • if one argument is a square matrix, M,

  • and the other is a scalar, x,

then the scalar is promoted to a diagonal matrix of the correct dimension and then the operation is done on those:

(= <M> <x>) and (= <x> <M>)  tests if M = xI
(+ <M> <x>) and (+ <x> <M>)  = M+xI
(- <M> <x>) = M-xI and (- <x> <M>) = xI-M

Multiplication, *, is extended to allow a matrix to be multiplied on either side by a scalar.

Additionally, a matrix may be multiplied on the left by a conforming down tuple, or on the right by a conforming up tuple.

Division is interpreted to mean a number of different things depending on the types of the arguments. For any matrix M and scalar x:

(/ <M> <x>)  =  (* <M> (/ 1 <x>))

If M is a square matrix then it is possible that it is invertible, so if <x> is either a scalar or a matrix, then (/ <x> <M>) = (* <x> <N>), where N is the matrix inverse of M.

In general, if M is a square matrix and v is either an up tuple or a column matrix, then (/ <v> <M>) = <w>, where w is of the same type as v and where v=Mw.

Similarly, for v a down tuple (/ <v> <M>) = <w>, where w is a down tuple and where v=wM.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close