我对Clojure有很多麻烦,因为我是新手。我试图从矩阵[[i,j,k],[5,2,3],[8,3,2]]求解一个正规矢量。我知道算法是什么,但我很困惑何时使用原子和变量。结果,我继续得到错误。有人可以指出我做错了什么以及如何改进代码?
下面列出的代码是错误。
(defn solve [& rows]
(let [orthanormal-vector (atom [])]
(let [dimension-range (range (count rows))
determinant-argument (atom [])]
(doseq [[i row] (map list dimension-range rows)]
(let [row-range (range (count row))
determinant-vector (atom [])]
(doseq [[j e] (map list row-range (seq row))]
(if-not (= i j) (swap! determinant-vector (conj determinant-vector e)) (println "Do nothing")))
(var-set determinant-argument (conj determinant-argument determinant-vector)))
(def determinant-result (incanter-core/det (incanter-core/matrix (vec determinant-argument))))
(swap! orthanormal-vector (conj orthanormal-vector determinant-result))
))))
java.lang.ClassCastException: clojure.lang.Atom cannot be cast to clojure.lang.IPersistentCollection
core.clj:83 clojure.core/conj
/Users/chriskim/Desktop/promethix/src/promethix/orthanormal/solver.clj:14 promethix.orthanormal.solver/solve
RestFn.java:436 clojure.lang.RestFn.invoke
/Users/chriskim/Desktop/promethix/src/promethix/orthanormal/solver.clj:24 promethix.orthanormal.solver/eval16321
Compiler.java:6703 clojure.lang.Compiler.eval
Compiler.java:6666 clojure.lang.Compiler.eval
core.clj:2927 clojure.core/eval
eval.clj:77 lighttable.nrepl.eval/->result
AFn.java:156 clojure.lang.AFn.applyToHelper
AFn.java:144 clojure.lang.AFn.applyTo
core.clj:626 clojure.core/apply
core.clj:2468 clojure.core/partial[fn]
RestFn.java:408 clojure.lang.RestFn.invoke
core.clj:2559 clojure.core/map[fn]
LazySeq.java:40 clojure.lang.LazySeq.sval
LazySeq.java:49 clojure.lang.LazySeq.seq
RT.java:484 clojure.lang.RT.seq
core.clj:133 clojure.core/seq
core.clj:2595 clojure.core/filter[fn]
LazySeq.java:40 clojure.lang.LazySeq.sval
LazySeq.java:49 clojure.lang.LazySeq.seq
Cons.java:39 clojure.lang.Cons.next
RT.java:598 clojure.lang.RT.next
core.clj:64 clojure.core/next
core.clj:2856 clojure.core/dorun
core.clj:2871 clojure.core/doall
eval.clj:126 lighttable.nrepl.eval/eval-clj
RestFn.java:442 clojure.lang.RestFn.invoke
eval.clj:192 lighttable.nrepl.eval/eval10834[fn]
AFn.java:152 clojure.lang.AFn.applyToHelper
AFn.java:144 clojure.lang.AFn.applyTo
core.clj:624 clojure.core/apply
core.clj:1862 clojure.core/with-bindings*
RestFn.java:425 clojure.lang.RestFn.invoke
eval.clj:177 lighttable.nrepl.eval/eval10834[fn]
eval.clj:176 lighttable.nrepl.eval/eval10834[fn]
MultiFn.java:227 clojure.lang.MultiFn.invoke
core.clj:98 lighttable.nrepl.core/queued[fn]
core.clj:2402 clojure.core/comp[fn]
interruptible_eval.clj:138 clojure.tools.nrepl.middleware.interruptible-eval/run-next[fn]
AFn.java:22 clojure.lang.AFn.run
ThreadPoolExecutor.java:895 java.util.concurrent.ThreadPoolExecutor$Worker.runTask
ThreadPoolExecutor.java:918 java.util.concurrent.ThreadPoolExecutor$Worker.run
Thread.java:680 java.lang.Thread.run
答案 0 :(得分:1)
导致clojure.lang.Atom cannot be cast to clojure.lang.IPersistentCollection
的具体错误是:
(swap! determinant-vector (conj determinant-vector e))
shoudl写道:
(swap! determinant-vector conj e)
交换!将原子作为第一个参数,将函数作为第二个参数。然后,它通过将atom中的当前值作为该函数的第一个参数传递并在此之后附加其余参数来构建函数调用。这将被翻译成函数调用,有点像这样:
(conj @determinant-vector e)
ps:@是一个读取器宏,用于调用deref
以从其中一个可变状态类型中获取当前值。
PPS:Charles Duffy认为循环/重复是很多更好的工具,而不是使用原子。它应该快约100倍,至少在开销方面。
答案 1 :(得分:1)