我曾经回顾过与我相关的Haskell数组库的特点,并编制了比较表格(只有电子表格:直接链接)。所以我会试着回答。
在什么基础上应该在Vector.Unboxed和UArray之间进行选择?它们都是非装箱数组,但Vector抽象似乎在循环融合方面广泛宣传。Vector总是更好吗?如果不是,那么应该在什么情况下使用哪种表示?
如果需要二维或多维数组,则可以优先选择UArray。但是,Vector在操作向量方面具有更好的API。一般来说,Vector不适用于模拟多维数组。
无法使用Vector.Unboxed并行策略。我怀疑UArray也无法使用,但至少从UArray切换到装箱数组非常容易,并查看并行化是否超过了装箱成本。
对于彩色图像,我希望存储16位整数或单精度浮点数的三元组。为此,使用Vector还是UArray更容易?更高效?
我尝试使用数组来表示图像(虽然我只需要灰度图像)。对于彩色图像,我使用Codec-Image-DevIL库来读写图像(绑定到DevIL库),对于灰度图像,我使用pgm库(纯Haskell)。
我的主要问题是Array仅提供随机访问存储,但它并没有提供许多构建Array算法的方法,也没有配备数组例程的现成库(不与线性代数库接口,不允许表达卷积、FFT和其他变换)。
几乎每次都需要从现有数组中构建新数组,必须构建一个中间值列表(如在
矩阵乘法中所述)。数组构造的成本经常超过更快的随机访问的好处,甚至在某些用例中基于列表的表示方法更快。
STUArray可能会帮助我,但我不喜欢与晦涩的类型错误和编写
带有STUArray的多态代码所需的努力进行斗争。
因此,数组的问题在于它们不适合进行数值计算。Hmatrix' Data.Packed.Vector和Data.Packed.Matrix在这方面更好,因为它们配备了坚实的矩阵库(注意:GPL许可证)。在矩阵乘法上,hmatrix足够快(
仅比Octave慢一点),但非常占用内存(消耗了Python/SciPy的几倍)。
还有用于矩阵的blas库,但它不能在GHC7上构建。
我对Repa没有太多经验,也不太了解repa代码。从我所看到的来看,它具有非常有限的现成矩阵和数组算法,但至少可以通过该库的手段表达重要的算法。例如,在repa-algorithms中已经有了矩阵乘法和卷积例程。不幸的是,似乎卷积现在仅限于7×7内核(对我来说不够,但对许多用途应该足够)。
我没有尝试过Haskell OpenCV绑定。它们应该很快,因为OpenCV真的很快,但我不确定绑定是否完整且好用。此外,由于OpenCV本质上是非常命令式的,充满了破坏性更新,所以我认为很难在其上面设计一个漂亮而有效的函数接口。如果一个人选择使用OpenCV,他可能会在任何地方都使用OpenCV图像表示,并使用OpenCV例程来操作它们。
对于二值图像,我只需要存储每个像素的1位。是否有预定义的数据类型可以通过将多个像素打包到一个字中来帮助我,还是我需要自己处理?
据我所知,
未打包的布尔数组 负责打包和解包位向量。我记得在其他库的布尔数组实现中看到过这个功能。
最后,我的数组是二维的。我想我可以处理由“数组的数组”(或向量的向量)表示所施加的额外间接性,但我更喜欢具有索引映射支持的抽象。有人能推荐标准库或 Hackage 中的任何内容吗?
除了 Vector(和简单列表)之外,所有其他数组库都能够表示二维数组或矩阵。我想它们避免了不必要的间接性。
Array
接口支持多维数组。你可以简单地使用一个元组作为索引。 - John LInt
元组索引的普通UArray
很容易使用,通常也足够好,但即使 GHC 的深度魔法也无法将使用其最小 API 的代码优化为与针对快速并行批量数据处理进行调整的库相竞争的东西。 - C. A. McCann