我使用的矩阵如下
(require '[clojure.core.matrix :as ccm])
(def M (ccm/matrix [[1 2] [3 4]]))
(ccm/mset! M 0 0 10)
但是这会引发错误
IllegalArgumentException No implementation of method: :set-2d! of protocol: #'clojure.core.matrix.protocols/PIndexedSettingMutable found for class: clojure.lang.PersistentVector clojure.core/-cache-protocol-fn (core_deftype.clj:568)
然而,这应该根据维基 https://mikera.github.io/core.matrix/doc/clojure.core.matrix.html#var-mset.21 起作用
最佳答案
core.matrix 可以使用不同的底层矩阵实现。默认情况下,它使用 persistent-vector
实现,这意味着矩阵只是包含 Clojure 向量的 Clojure 向量。然而,Clojure 向量是不可变的,所以 mset!
不会对他们起作用。这是预期的行为。
使用 mset!
,您需要使用可以生成可变矩阵的 core.matrix 实现之一。 ndarray
是默认情况下在 core.matrix 中始终可用的矩阵实现,但您必须告诉 core.matrix 您要使用它。
user=> (use 'clojure.core.matrix)
nil
user=> (matrix [[1 2] [3 4]])
[[1 2] [3 4]]
这就是持久向量矩阵的样子。
您可以通过向
matrix
传递一个额外的关键字来创建一个 ndarray 矩阵。功能:user=> (def M (matrix :ndarray [[1 2] [3 4]]))
#'user/M
user=> M
#object[clojure.core.matrix.impl.ndarray_object.NDArray 0x561ddbde "[[1 2] [3 4]]"]
现在
mset!
将工作:user=> (mset! M 0 0 10)
10
user=> M
#object[clojure.core.matrix.impl.ndarray_object.NDArray 0x561ddbde "[[10 2] [3 4]]"]
注意右边的元素。您也可以使用
pm
创建更好的表示:user=> (pm M)
[[10 2]
[ 3 4]]
要使 ndarray 成为默认值,请使用
set-current-implementation
:user=> (set-current-implementation :ndarray)
:ndarray
user=> (def M (matrix [[1 2] [3 4]]))
#'user/M
user=> M
#object[clojure.core.matrix.impl.ndarray_object.NDArray 0x5cd44e57 "[[1 2] [3 4]]"]
user=> (mset! M 0 0 10)
10
user=> M
#object[clojure.core.matrix.impl.ndarray_object.NDArray 0x5cd44e57 "[[10 2] [3 4]]"]
如果您将它们设置为依赖项(例如,在您的 Leiningen project.clj 中),还有其他几种可用的实现。其中一些支持可变和不可变矩阵。
顺便说一句,正如 amalloy 所建议的,您可以通过将不可变矩阵传递给
mutable
来从不可变矩阵中获取可变矩阵。 .如果使用持久向量矩阵执行此操作,则返回的矩阵将不是持久向量矩阵,因为不存在可变的持久向量矩阵。新矩阵将是来自不同实现的矩阵。使用哪种实现取决于您当前的环境,但如果您没有做任何特别的事情,返回的应该是 ndarray 矩阵。
关于matrix - clojure.core.matrix::改变矩阵中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43472070/