Examples - mikera/vectorz-clj GitHub Wiki
Here are some examples of using vectorz-clj
with the core.matrix
API. These examples assume that you have use
d 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](/mikera/vectorz-clj/wiki/1-2]-[3-4)))
; => #vectorz/matrix [1.0,2.0],[3.0,4.0](/mikera/vectorz-clj/wiki/1.0,2.0],[3.0,4.0)
(shape M)
; => [2 2]
(* 2 M)
; => #vectorz/matrix [2.0,4.0],[6.0,8.0](/mikera/vectorz-clj/wiki/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](/mikera/vectorz-clj/wiki/[1-2]-[3-4) [5 6] [7 8](/mikera/vectorz-clj/wiki/5-6]-[7-8)]))
; => #vectorz/array [[1.0,2.0],[3.0,4.0](/mikera/vectorz-clj/wiki/[1.0,2.0],[3.0,4.0),[5.0,6.0],[7.0,8.0](/mikera/vectorz-clj/wiki/5.0,6.0],[7.0,8.0)]
(dimensionality A)
; => 3
(first (slices A))
; => #vectorz/matrix [1.0,2.0],[3.0,4.0](/mikera/vectorz-clj/wiki/1.0,2.0],[3.0,4.0)
(second (slices A))
; => #<Matrix22 [5.0,6.0],[7.0,8.0](/mikera/vectorz-clj/wiki/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](/mikera/vectorz-clj/wiki/3.0,4.0],[7.0,8.0)
(transpose A)
; => #vectorz/array [[1.0,5.0],[3.0,7.0](/mikera/vectorz-clj/wiki/[1.0,5.0],[3.0,7.0),[2.0,6.0],[4.0,8.0](/mikera/vectorz-clj/wiki/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](/mikera/vectorz-clj/wiki/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](/mikera/vectorz-clj/wiki/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]