Skip to content
Browse files

Merge pull request #74 from marciosilva/master

Reduce the amount of reflection involved in matrix ops
  • Loading branch information...
2 parents bd6315b + db46b87 commit a4dd75982f2a00d88c6a113b0eac33fc21d04def @alexott alexott committed May 1, 2012
Showing with 78 additions and 61 deletions.
  1. +3 −3 modules/incanter-core/src/incanter/core.clj
  2. +75 −58 modules/incanter-core/src/incanter/internal.clj
View
6 modules/incanter-core/src/incanter/core.clj
@@ -432,7 +432,7 @@
"
([& args] (if (= (count args) 1)
- (combine-with 0 (first args) clojure.core/- minus)
+ (combine-with (Integer. 0) (first args) clojure.core/- minus)
(reduce (fn [A B] (combine-with A B clojure.core/- minus)) args))))
@@ -478,7 +478,7 @@
"
([& args] (if (= (count args) 1)
- (combine-with 1 (first args) clojure.core// div)
+ (combine-with (Integer. 1) (first args) clojure.core// div)
(reduce (fn [A B] (combine-with A B clojure.core// div)) args))))
@@ -722,7 +722,7 @@
"
([^Matrix A & B]
(if B
- (Matrix. (.solve (DenseDoubleAlgebra.) A (first B)))
+ (Matrix. (.solve (DenseDoubleAlgebra.) A ^Matrix (first B)))
(Matrix. (.inverse (DenseDoubleAlgebra.) A)))))
View
133 modules/incanter-core/src/incanter/internal.clj
@@ -28,84 +28,101 @@
(defn is-matrix
" Test if obj is 'derived' from ::matrix (e.g. class incanter.Matrix)."
- ([obj] (isa? (class obj) ::matrix)))
+ ([obj] (instance? Matrix obj)))
+(def double_arr_type (Class/forName "[D"))
(defn make-matrix
([data]
- (cond
+ (cond
+ (instance? double_arr_type data)
+ (Matrix. ^"[D" data)
(coll? (first data))
- (Matrix. (into-array (map double-array data)))
+ (Matrix. ^"[[D" (into-array (map double-array data)))
(number? (first data))
(Matrix. (double-array data))))
([data ncol]
(cond
+ (instance? double_arr_type data)
+ (Matrix. ^"[D" data (int ncol))
(or (coll? data) (.isArray (class data)))
- (Matrix. (double-array data) ncol)
+ (Matrix. (double-array data) (int ncol))
(number? data)
- (Matrix. data ncol))) ; data is the number of rows in this case
+ (Matrix. (int data) (int ncol)))) ; data is the number of rows in this case
([init-val rows cols]
- (Matrix. rows cols init-val)))
+ (Matrix. (int rows) (int cols) ^Number init-val)))
+(defmacro hint
+ "Applies a type hint to a body"
+ [type body]
+ `~(with-meta body {:tag type}))
(defmacro ^Matrix transform-with [A op fun]
- `(cond
- (is-matrix ~A)
- (.assign (.copy ~A) (. DoubleFunctions ~fun))
- (and (coll? ~A) (coll? (first ~A)))
- (.assign ^Matrix (make-matrix ~A) (. DoubleFunctions ~fun))
- (coll? ~A)
- (map ~op ~A)
- (number? ~A)
- (~op ~A)))
+ (let [mA (with-meta (gensym "A") {:tag "Matrix"})
+ df (with-meta (gensym "fun") {:tag "DoubleFunction"})]
+ `(let [~df (. DoubleFunctions ~fun)]
+ (cond
+ (is-matrix ~A)
+ (let [~mA ~A]
+ (.assign (hint "Matrix" (.copy ~mA)) ~df))
+ (and (coll? ~A) (coll? (first ~A)))
+ (let [~mA (make-matrix ~A)]
+ (.assign ~mA ~df))
+ (coll? ~A)
+ (map ~op ~A)
+ (number? ~A)
+ (~op ~A)))))
(defmacro combine-with [A B op fun]
- `(cond
- (and (number? ~A) (number? ~B))
- (~op ~A ~B)
- (and (is-matrix ~A) (is-matrix ~B))
- (.assign ^Matrix (.copy ^Matrix ~A)
- ^Matrix ~B
- ^DoubleDoubleFunction (. DoubleFunctions ~fun))
- (and (is-matrix ~A) (number? ~B))
- (.assign ^Matrix (.copy ^Matrix ~A)
- (make-matrix ~B (.rows ~A) (.columns ~A))
- ^DoubleDoubleFunction (. DoubleFunctions ~fun))
- (and (number? ~A) (is-matrix ~B))
- (.assign ^Matrix (make-matrix ~A (.rows ~B) (.columns ~B))
- ^Matrix ~B
- ^DoubleDoubleFunction (. DoubleFunctions ~fun))
- (and (coll? ~A) (is-matrix ~B))
- (.assign ^Matrix (make-matrix ~A (.columns ~B))
- ^Matrix (make-matrix ~B)
- ^DoubleDoubleFunction (. DoubleFunctions ~fun))
- (and (is-matrix ~A) (coll? ~B))
- (.assign ^Matrix (.copy ~A)
- ^Matrix (make-matrix ~B)
- ^DoubleDoubleFunction (. DoubleFunctions ~fun))
- (and (coll? ~A) (coll? ~B) (coll? (first ~A)))
- (.assign (make-matrix ~A)
- (make-matrix ~B)
- (. DoubleFunctions ~fun))
- (and (coll? ~A) (number? ~B) (coll? (first ~A)))
- (.assign (make-matrix ~A)
- (make-matrix ~B)
- (. DoubleFunctions ~fun))
- ;;(. DoubleFunctions (~fun ~B)))
- (and (number? ~A) (coll? ~B) (coll? (first ~B)))
- (.assign (make-matrix ~A (.rows ~B) (.columns ~B))
- (make-matrix ~B)
- (. DoubleFunctions ~fun))
- (and (coll? ~A) (coll? ~B))
- (map ~op ~A ~B)
- (and (number? ~A) (coll? ~B))
- (map ~op (replicate (count ~B) ~A) ~B)
- (and (coll? ~A) (number? ~B))
- (map ~op ~A (replicate (count ~A) ~B))
- ))
+ (let [mA (with-meta (gensym "A") {:tag "Matrix"})
+ mB (with-meta (gensym "B") {:tag "Matrix"})
+ df (with-meta (gensym "fun") {:tag "DoubleDoubleFunction"})]
+ `(let [~df (. DoubleFunctions ~fun)]
+ (cond
+ (and (number? ~A) (number? ~B))
+ (~op ~A ~B)
+ (and (is-matrix ~A) (is-matrix ~B))
+ (let [~mA ~A
+ ~mB ~B]
+ (.assign (hint "Matrix" (.copy ~mA)) ~mB ~df))
+ (and (is-matrix ~A) (number? ~B))
+ (let [~mA ~A
+ ~mB (make-matrix ~B (.rows ~mA) (.columns ~mA))]
+ (.assign (hint "Matrix" (.copy ~mA)) ~mB ~df))
+ (and (number? ~A) (is-matrix ~B))
+ (let [~mB ~B
+ ~mA (make-matrix ~A (.rows ~mB) (.columns ~mB))]
+ (.assign ~mA ~mB ~df))
+ (and (coll? ~A) (is-matrix ~B))
+ (let [~mB ~B
+ ~mA (make-matrix ~A (.columns ~mB))]
+ (.assign ~mA ~mB ~df))
+ (and (is-matrix ~A) (coll? ~B))
+ (let [~mA ~A
+ ~mB (make-matrix ~B)]
+ (.assign (hint "Matrix" (.copy ~mA)) ~mB ~df))
+ (and (coll? ~A) (coll? ~B) (coll? (first ~A)))
+ (let [~mA (make-matrix ~A)
+ ~mB (make-matrix ~B)]
+ (.assign ~mA~mB ~df))
+ (and (coll? ~A) (number? ~B) (coll? (first ~A)))
+ (let [~mA (make-matrix ~A)
+ ~mB (make-matrix ~B)]
+ (.assign ~mA ~mB ~df))
+ (and (number? ~A) (coll? ~B) (coll? (first ~B)))
+ (let [~mA (make-matrix ~A (.rows ~B) (.columns ~B))
+ ~mB (make-matrix ~B)]
+ (.assign ~mA ~mB ~df))
+ (and (coll? ~A) (coll? ~B))
+ (map ~op ~A ~B)
+ (and (number? ~A) (coll? ~B))
+ (map ~op (replicate (count ~B) ~A) ~B)
+ (and (coll? ~A) (number? ~B))
+ (map ~op ~A (replicate (count ~A) ~B))
+ ))))
;; PRINT METHOD FOR COLT MATRICES

0 comments on commit a4dd759

Please sign in to comment.
Something went wrong with that request. Please try again.