Skip to content
Mike Anderson edited this page Jan 1, 2016 · 11 revisions

Here are some examples of using vectorz-clj with the core.matrix API. These examples assume that you have used the key core.matrix namespaces and set vectorz-clj to be the default implementation as follows:

(use 'clojure.core.matrix)
(use 'clojure.core.matrix.operators)  ;; for +, -, * etc.
(set-current-implementation :vectorz)

Example 1: basic vector operations

(def v (array [1 2 3]))
; => #vectorz/vector [1.0,2.0,3.0]

(* v 2)
; => #vectorz/vector [2.0,4.0,6.0]

(+ v 1)
; => #vectorz/vector [2.0,3.0,4.0]

(join v v)
; => #<JoinedVector [1.0,2.0,3.0,1.0,2.0,3.0]>

(dot v v)
; => 14.0

(normalise v)
; => #vectorz/vector [0.2672612419124244,0.5345224838248488,0.8017837257372732]

Example 2: basic matrix operations

(def M (array [[1 2] [3 4]]))
; => #vectorz/matrix [[1.0,2.0],[3.0,4.0]]

(shape M)
; => [2 2]

(* 2 M)
; => #vectorz/matrix [[2.0,4.0],[6.0,8.0]]

;; matrix multiplication using mmul
;; note that core.matrix supports using a regular Clojure vector here!
(mmul M [1 1])
; => #vectorz/vector [3.0,7.0]

;; get a sequence of all the rows in the matrix
(rows M)
; => (#vectorz/vector [1.0,2.0] #vectorz/vector [3.0,4.0])

;; get a sequence of all elements in the matrix
;; these will always be Double values when using vectorz-clj
(eseq M)
; => (1.0 2.0 3.0 4.0)

Example 3: higher dimensional arrays

vectorz-clj supports arbitrary N-dimensional arrays of double values. In general, 1D and 2D matrices will have more optimised operations, but this support is here when you need it.

(def A (array [[[1 2] [3 4]] [[5 6] [7 8]]]))
; => #vectorz/array [[[1.0,2.0],[3.0,4.0]],[[5.0,6.0],[7.0,8.0]]]

(dimensionality A)
; => 3

(first (slices A))
; => #vectorz/matrix [[1.0,2.0],[3.0,4.0]]

(second (slices A))
; => #<Matrix22 [[5.0,6.0],[7.0,8.0]]>

;; get slice along dimension 1 (the second dimension)
(slice A 1 1)
; => #vectorz/array [[3.0,4.0],[7.0,8.0]]

(transpose A)
; => #vectorz/array [[[1.0,5.0],[3.0,7.0]],[[2.0,6.0],[4.0,8.0]]]

;; The mmul operator performs an inner-product with higher dimensional arrays
(mmul A [1 10])
; => #vectorz/matrix [[21.0,43.0],[65.0,87.0]]

(reshape A [2 4])
; => #vectorz/matrix [[1.0,2.0,3.0,4.0],[5.0,6.0,7.0,8.0]]

Example 4: mutating a vector

vectorz-clj vectors are mutable by default. This is a double-edged sword: normally you should not mutate vectors as it can introduce extra complexity and concurrency-related issues. However the features are there if you need them. All core.matrix API functions that mutate their operands are clearly indicated with a "!" at the end of the name, so that you can clearly tell when you are entering the danger zone.

(def v (array (range 10)))
; => #vectorz/vector [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0]

(def s (subvector v 2 5))
; => #vectorz/vector [2.0,3.0,4.0,5.0,6.0]

;; this mutates both s and v, since s is a view over a subvector of v!
;; this is why you need to be careful with mutation!!
(fill! s 3.0)
; s => #vectorz/vector [3.0,3.0,3.0,3.0,3.0]
; v => #vectorz/vector [0.0,1.0,3.0,3.0,3.0,3.0,3.0,7.0,8.0,9.0]