gpt4 book ai didi

r - Clojure/Incanter 中的快速向量数学

转载 作者:行者123 更新时间:2023-12-03 11:19:08 29 4
gpt4 key购买 nike

我目前正在研究 Clojure 和 Incanter 作为 R 的替代品。(并不是我不喜欢 R,但尝试新语言很有趣。)我喜欢 Incanter 并发现语法很吸引人,但相比之下,矢量化操作相当慢例如到 R 或 Python。

作为一个例子,我想得到一个向量的一阶差分
使用 Incanter 向量操作、Clojure 映射和 R 。以下是所有代码和时间
版本。如您所见,R 显然更快。

Incanter 和 Clojure:

(use '(incanter core stats)) 
(def x (doall (sample-normal 1e7)))
(time (def y (doall (minus (rest x) (butlast x)))))
"Elapsed time: 16481.337 msecs"
(time (def y (doall (map - (rest x) (butlast x)))))
"Elapsed time: 16457.850 msecs"

回复:
rdiff <- function(x){ 
n = length(x)
x[2:n] - x[1:(n-1)]}
x = rnorm(1e7)
system.time(rdiff(x))
user system elapsed
1.504 0.900 2.561

所以我想知道有没有办法加速 Incanter/Clojure 中的矢量操作?也欢迎使用循环、Java 数组和/或 Clojure 库的解决方案。

我也已将此问题发布到 Incanter Google 群组,但目前没有任何回复。

更新:我已将 Jouni 的答案标记为已接受,请参阅下面的我自己的答案,其中我稍微清理了他的代码并添加了一些基准。

最佳答案

这是一个 Java 数组实现,它在我的系统上比您的 R 代码(YMMV)更快。请注意启用反射警告,这在优化性能时必不可少,以及 y 上的重复类型提示(def 上的提示似乎对 aset 没有帮助)并将所有内容转换为原始 double 值(dotime 确保i 是一个原始整数)。

(set! *warn-on-reflection* true)
(use 'incanter.stats)
(def ^"[D" x (double-array (sample-normal 1e7)))

(time
(do
(def ^"[D" y (double-array (dec (count x))))
(dotimes [i (dec (count x))]
(aset ^"[D" y
i
(double (- (double (aget x (inc i)))
(double (aget x i))))))))

关于r - Clojure/Incanter 中的快速向量数学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3814048/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com