Skip to content

Instantly share code, notes, and snippets.

@wedesoft
Last active May 23, 2023 08:04
Show Gist options
  • Save wedesoft/8d1f8646649037904f16915f4639228e to your computer and use it in GitHub Desktop.
Save wedesoft/8d1f8646649037904f16915f4639228e to your computer and use it in GitHub Desktop.
Clojure/Java matrix library comparison core.matrix vs EJML vs vectorz-clj vs fastmath
{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
net.mikera/core.matrix {:mvn/version "0.63.0"}
net.mikera/vectorz-clj {:mvn/version "0.48.0"}
org.ejml/ejml-all {:mvn/version "0.43"}
criterium/criterium {:mvn/version "0.4.6"}
generateme/fastmath {:mvn/version "2.2.2-SNAPSHOT" :exclusions [com.github.haifengl/smile-mkl org.bytedeco/openblas]}}}
; Linear algebra performance testing by wedesoft and genmeblog
(require '[clojure.math :refer (sqrt)])
(require '[clojure.core.matrix :refer (matrix mget add mul inverse det set-current-implementation dot mmul eseq)])
(require '[clojure.core.matrix.linear :refer (norm)])
(require '[criterium.core :refer :all])
(require '[fastmath.matrix :as fm])
(require '[fastmath.vector :as fv])
(import '[mikera.matrixx Matrix Matrixx])
(import '[mikera.vectorz Vector])
(import '[org.ejml.simple SimpleMatrix SimpleBase])
(import '[org.ejml.data DMatrixRMaj])
(set! *warn-on-reflection* true)
(set! *unchecked-math* true)
(set-current-implementation :vectorz)
(defmacro mybench [expr] `(do (println (quote ~expr)) (bench ~expr) (println)))
(def a (matrix [[1.0 1.0 1.0 1.0] [1.0 2.0 2.0 2.0] [2.0 2.0 4.0 4.0] [3.0 3.0 3.0 8.0]]))
(def b (SimpleMatrix. 4 4 true (double-array [1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 2.0 4.0 4.0 3.0 3.0 3.0 8.0])))
(def c (Matrixx/create [[1.0 1.0 1.0 1.0] [1.0 2.0 2.0 2.0] [2.0 2.0 4.0 4.0] [3.0 3.0 3.0 8.0]]))
(def d (fm/mat4x4 1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 2.0 4.0 4.0 3.0 3.0 3.0 8.0))
(def u (matrix [2.0 3.0 5.0 7.0]))
(def v (SimpleMatrix. 4 1 true (double-array [2.0 3.0 5.0 7.0])))
(def w (Vector/create [2.0 3.0 5.0 7.0]))
(def z (fv/vec4 2.0 3.0 5.0 7.0))
(println "--------------------------------------------------------------------------------")
(mybench (matrix [[1.0 1.0 1.0 1.0] [0.0 2.0 2.0 2.0] [0.0 0.0 4.0 4.0] [0.0 0.0 0.0 8.0]]))
(mybench (SimpleMatrix. 4 4 true (double-array [1.0 1.0 1.0 1.0 0.0 2.0 2.0 2.0 0.0 0.0 4.0 4.0 0.0 0.0 0.0 8.0])))
(mybench (Matrixx/create [[1.0 1.0 1.0 1.0] [0.0 2.0 2.0 2.0] [0.0 0.0 4.0 4.0] [0.0 0.0 0.0 8.0]]))
(mybench (fm/mat4x4 1.0 1.0 1.0 1.0 0.0 2.0 2.0 2.0 0.0 0.0 4.0 4.0 0.0 0.0 0.0 8.0))
(println "--------------------------------------------------------------------------------")
(mybench (matrix [1.0 2.0 3.0 4.0]))
(mybench (SimpleMatrix. 4 1 true (double-array [1.0 2.0 3.0 4.0])))
(mybench (Vector/create [1.0 2.0 3.0 4.0]))
(mybench (fv/vec4 2.0 3.0 5.0 7.0))
(println "--------------------------------------------------------------------------------")
(mybench (add ^Vector u ^Vector u))
(mybench (.plus ^SimpleMatrix v ^SimpleMatrix v))
(mybench (let [result (.clone ^Vector w)] (.add ^Vector result ^Vector w) result))
(mybench (fv/add z z))
(println "--------------------------------------------------------------------------------")
(mybench (inverse ^Matrix a))
(mybench (.invert ^SimpleMatrix b))
(mybench (.inverse ^Matrix c))
(mybench (fm/inverse d))
(println "--------------------------------------------------------------------------------")
(mybench (mul ^Matrix a ^Matrix a))
(mybench (.elementMult ^SimpleMatrix b ^SimpleMatrix b))
(mybench (let [result (.clone ^Matrix c)] (.multiply ^Matrix result ^Matrix c) result))
(mybench (fm/emulm d d))
(println "--------------------------------------------------------------------------------")
(mybench (mmul ^Matrix a ^Matrix a))
(mybench (.mult ^SimpleMatrix b ^SimpleMatrix b))
(mybench (.innerProduct ^Matrix c ^Matrix c))
(mybench (fm/mulm d d))
(println "--------------------------------------------------------------------------------")
(mybench (mmul ^Matrix a ^Vector u))
(mybench (.mult ^SimpleMatrix b ^SimpleMatrix v))
(mybench (.innerProduct ^Matrix c ^Vector w))
(mybench (fm/mulv d z))
(println "--------------------------------------------------------------------------------")
(mybench (dot ^Vector u ^Vector u))
(mybench (.dot ^SimpleMatrix v ^SimpleMatrix v))
(mybench (.innerProduct ^Vector w ^Vector w))
(mybench (fv/dot z z))
(println "--------------------------------------------------------------------------------")
(mybench (norm ^Matrix u))
(mybench (.normF ^SimpleMatrix v))
(mybench (fv/mag z))
(println "--------------------------------------------------------------------------------")
(mybench (det ^Matrix a))
(mybench (.determinant ^SimpleMatrix b))
(mybench (.determinant ^Matrix c))
(mybench (fm/det d))
(println "--------------------------------------------------------------------------------")
(mybench (mget ^Matrix a 1 1))
(mybench (.get ^SimpleMatrix b 1 1))
(mybench (.get ^Matrix a 1 1))
(mybench (d 1 1))
(println "--------------------------------------------------------------------------------")
(mybench (.getElements ^Matrix a))
(mybench (.data ^DMatrixRMaj (.getMatrix ^SimpleMatrix b)))
(mybench (.getElements ^Matrix c))
(mybench (fm/mat->array d))
(println "--------------------------------------------------------------------------------")
(def a3 (matrix [[1.0 1.0 1.0] [1.0 2.0 2.0] [2.0 2.0 4.0]]))
(def b3 (SimpleMatrix. 3 3 true (double-array [1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 4.0])))
(def c3 (Matrixx/create [[1.0 1.0 1.0] [1.0 2.0 2.0] [2.0 2.0 4.0]]))
(def d3 (fm/mat3x3 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 4.0))
(mybench (inverse ^Matrix a3))
(mybench (.invert ^SimpleMatrix b3))
(mybench (.inverse ^Matrix c3))
(mybench (fm/inverse d3))
(println "--------------------------------------------------------------------------------")
(def a4 (matrix [[1.0 1.0 1.0 1.0] [1.0 2.0 2.0 2.0] [2.0 2.0 4.0 4.0] [3.0 3.0 3.0 8.0]]))
(def b4 (SimpleMatrix. 4 4 true (double-array [1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 2.0 4.0 4.0 3.0 3.0 3.0 8.0])))
(def c4 (Matrixx/create [[1.0 1.0 1.0 1.0] [1.0 2.0 2.0 2.0] [2.0 2.0 4.0 4.0] [3.0 3.0 3.0 8.0]]))
(def d4 (fm/mat4x4 1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 2.0 4.0 4.0 3.0 3.0 3.0 8.0))
(mybench (inverse ^Matrix a4))
(mybench (.invert ^SimpleMatrix b4))
(mybench (.inverse ^Matrix c4))
(mybench (fm/inverse d4))
(println "--------------------------------------------------------------------------------")
(def a5 (matrix [[1.0 1.0 1.0 1.0 1.0] [1.0 2.0 2.0 2.0 2.0] [2.0 2.0 4.0 4.0 4.0] [3.0 3.0 3.0 8.0 8.0] [4.0 4.0 4.0 4.0 16.0]]))
(def b5 (SimpleMatrix. 5 5 true (double-array [1.0 1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 2.0 2.0 4.0 4.0 4.0 3.0 3.0 3.0 8.0 8.0 4.0 4.0 4.0 4.0 16.0])))
(def c5 (Matrixx/create [[1.0 1.0 1.0 1.0 1.0] [1.0 2.0 2.0 2.0 2.0] [2.0 2.0 4.0 4.0 4.0] [3.0 3.0 3.0 8.0 8.0] [4.0 4.0 4.0 4.0 16.0]]))
(mybench (inverse ^Matrix a5))
(mybench (.invert ^SimpleMatrix b5))
(mybench (.inverse ^Matrix c5))
@genmeblog
Copy link

Can you share deps as well?

@genmeblog
Copy link

genmeblog commented May 18, 2023

Line 36 adds matrix not vector

@wedesoft
Copy link
Author

wedesoft commented May 18, 2023

@wedesoft
Copy link
Author

Thanks, will fix the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment