假设我有一个3x3矩阵
(def myMatrix (matrix (range 9) 3))
; A 3x3 matrix
; -------------
; 0.00e+00 1.00e+00 2.00e+00
; 3.00e+00 4.00e+00 5.00e+00
; 6.00e+00 7.00e+00 8.00e+00
我可以使用$来获取元素,比如说第2行第1列
($ 1 0 myMatrix) ; --> 3
是否有任何API方法可以快速更新元素然后返回矩阵? e.g。
(update-matrix-by-element 2 1 myMatrix 4)
; A 3x3 matrix
; -------------
; 0.00e+00 1.00e+00 2.00e+00
; 4.00e+00 4.00e+00 5.00e+00
; 6.00e+00 7.00e+00 8.00e+00
我能找到的最接近的API方法是bind-rows和bind-columns,而我使用这两种方法的当前版本的函数是
;note i j starts from 1 rather than 0
(defn update-matrix-by-element [i j myMatrix value]
(if (or (> i (count (trans myMatrix))) (> j (count myMatrix)) (< i 1) (< j 1) (not (integer? i)) (not (integer? j)))
myMatrix
(let [n (count myMatrix)
m (count (trans myMatrix))
rangeFn #(if (== %1 %2) %1 (range %1 %2 ))
m1 (if (== (dec i) 0) []
($ (rangeFn 0 (dec i)) :all myMatrix))
m2 (if (== i m) []
($ (rangeFn i m) :all myMatrix))
matrixFn #(if (matrix? % ) % [ %])
newRow (if (== (dec j) 0)
(bind-columns [value] (matrixFn ($ (dec i) (rangeFn j n ) myMatrix)))
(if (== j n )
(bind-columns (matrixFn ($ (dec i) (rangeFn 0 (dec j) ) myMatrix)) [value] )
(bind-columns (matrixFn ($ (dec i) (rangeFn 0 (dec j) ) myMatrix)) [value] (matrixFn ($ (dec i) (rangeFn j n ) myMatrix))))
)
]
; (prn " m1 " m1 ) (prn " m2 " m2 ) (prn " newrow " newRow)
(bind-rows m1 newRow m2))))
答案 0 :(得分:2)
如果你的意思是“快速”,那么你可能会看一下core.matrix,它旨在支持快速可变矩阵运算。
使用core.matrix
的{{3}}实现的示例:
(def M (matrix [[1 2] [3 4]]))
=> #<Matrix22 [[1.0,2.0][3.0,4.0]]>
(mset! M 0 0 10)
=> #<Matrix22 [[10.0,2.0][3.0,4.0]]>
(time (dotimes [i 1000000] (mset! M 0 0 i)))
"Elapsed time: 28.895842 msecs" ;; i.e. < 30ns per mset! operation
这比其他需要构建新的可变矩阵的东西要快得多,特别是当矩阵变大/具有更高的维数时。
我正在努力使core.matrix
与Incanter整齐地整合,因此您应该能够在Incanter中透明地使用core.matrix
矩阵。