Предположим, у меня есть матрица 3х3Способы быстрого обновления элемента матрицы в Incanter, Clojure?
(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
я могу использовать $, чтобы получить элемент, скажем, второй строке первого столбца
($ 1 0 myMatrix) ; --> 3
Есть ли метод API для быстрого обновления элемента, а затем возвращают матрица? например
(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))))