Clojure矩阵表示

7
什么是Clojure中矩阵的良好表示方式?我对处理浮点数的密集矩阵很感兴趣。想到了“列表的列表”表示法,但是否有更好的方法呢?
一些好的表示方式标准包括:
- 效率:它们不会被用于大数据集的常量处理,但我不想花费几个小时计算结果,如果有更好的设计只需要几分钟就能完成。 - Java互操作性:可以轻松地在两种语言之间传递数据。 - 易于并行化:如果我可以通过将map替换为pmap来使用所有可用的内核,那将是很好的。 - 适合使用reduce:看起来我正在做的很多计算都非常适合使用reduce。 - 能够以矩阵行的形式表示图像扫描线:不是非常重要,但这将是很好的。
有什么想法吗?

你想用这些矩阵进行什么样的操作?将它们表示为列表的形式对于某些操作来说是一个不错的选择,但如果你需要频繁访问数组的任意元素,那么这种方法会让你死得很惨。 - Pillsy
8个回答

10

Incanter 提供了对一些Parallel Colt 的封装,其中包括看起来相当不错的快速并行稠密矩阵实现,可与Clojure的基于seq的库进行接口交互。我没有使用过它,但它应该是您正在寻找的。

示例


1
注意:此答案现在已经过时。Incanter现在使用Clatrix,并且有新的更高级的矩阵实现可用(请参见core.matrix及其各种实现,例如vectorz-clj)。 - mikera

5
我正在编写一个矩阵库,它封装了 jblas,暂时叫做 Clatrix。虽然它还缺少很多我想要添加的功能,但它已经有了大部分你可能需要的功能。请查看 http://github.com/tel/clatrix

4

2
截至2014年3月,我已经将其开发成一个相当全面的数组编程系统,称为“core.matrix”。 - mikera

2

目前我在cryptovide中采用了列表的列表方法,因为对于这个应用程序来说保持懒惰非常重要。我也考虑切换到更有效的方法,只要它至少保持外部表示懒惰。


0

Rich Hickey的Clojure是一种基于JVM的Lisp,它使用32分支树来表示PersistentVector(而不是PersistentList)。

如果您想编写自己的矩阵类型,我会使用PersistentVector,否则最好选择Parallel Colt与Incanter一起使用。


0

我最近编写了一些需要矩阵数学的代码,最初使用的是向量嵌套、映射和约简。但是当我回到这段代码时发现很难理解(我对Clojure不太熟悉)。使用Incanter让相同的代码变得非常简洁易懂(标准矩阵运算),而且速度也快了很多。


0

答案可能需要更新,因为已经过去了8年。快速的谷歌搜索显示,如果你需要与Clojure core.matrix API兼容,你可以使用core.matrix本身或其他实现,比如vectorz-clj。

此外,我还发现了Neanderthal,它是针对GPU进行优化的。


-1

我不是专家,但这是我的意见 :)

list-of-lists 可能是表示矩阵最自然的 Clojure 习惯用语。这种结构也很适合 map/reduce 类型的操作。Clojure 处理序列的效率也相当高 - 可能比大多数替代方案都要好。

我不能保证这一点,但我认为我看到过 Clojure 在我的 3 或 4 个 CPU 上工作,这些程序风格是函数式的,但没有尝试并行处理。我怀疑编译器正在自己找到一些并行处理的机会。

我认为 Clojure 创建的序列类型将作为 Java 中的 Lists,或者至少是 Iterable。对于你想要的东西来说,这可能已经足够好了,尽管如果你尝试将这些结构视为可修改的 Java 对象时,可能会遇到问题。

Lists 最好按顺序访问。如果你计划在矩阵中跳来跳去,使用 vector-of-vectors 可能会更好一些,从性能上讲。我怀疑这比使用 nth 函数要好。

作为一名前C程序员,我曾经简要考虑过可以将矩阵实现为一维结构(即直接序列或更好的向量),并进行自己的索引计算以找到正确的元素。您可以使用partition函数遍历它... 嗯,虽然这可能被处理,但我怀疑有非常充分的理由不这样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接