一旦我回顾了对我而言至关重要的Haskell数组库的功能,并编译了一个比较表(仅电子表格:直接链接)。所以我会尽力回答。
我应该在什么基础上选择Vector.Unboxed和UArray?它们都是未装箱的数组,但是Vector抽象似乎广为宣传,尤其是在循环融合方面。Vector总是更好吗?如果不是,我什么时候应该使用哪种表示形式?
如果需要二维或多维数组,则最好使用UArray而不是Vector。但是Vector有更好的API来处理向量。通常,Vector不太适合模拟多维数组。
Vector.Unboxed不能与并行策略一起使用。我怀疑不能同时使用UArray,但至少很容易从UArray切换到盒装Array,看看并行化是否带来的好处超过了装箱成本。
对于彩色图像,我希望存储三位16位整数或三位单精度浮点数。为此,Vector或UArray是否更易于使用?表现更好?
我尝试使用数组来表示图像(尽管我只需要灰度图像)。对于彩色图像,我使用Codec-Image-DevIL库读取/写入图像(绑定到DevIL库),对于灰度图像,我使用pgm库(纯Haskell)。
我对Array的主要问题是,它仅提供随机访问存储,但是它不提供许多构建Array算法的方法,也没有随便使用数组例程库(不与线性代数库接口,不允许表达卷积,fft和其他变换)。
几乎每次必须从现有阵列中构建一个新数组时,都必须构造一个中间值列表(就像Gentle Introduction 中的矩阵乘法一样)。数组构建的成本通常超过了更快的随机访问带来的好处,以至于在我的一些用例中,基于列表的表示更快。
STUArray可以为我提供帮助,但我不喜欢与神秘的类型错误以及使用STUArray编写多态代码所需的工作抗争。
因此,数组的问题在于它们不适用于数值计算。在这方面,Hmatrix的Data.Packed.Vector和Data.Packed.Matrix更好,因为它们带有固态矩阵库(注意:GPL许可证)。在性能方面,就矩阵乘法而言,hmatrix足够快(仅比Octave稍慢),但是却非常耗内存(消耗的时间是Python / SciPy的几倍)。
也有用于矩阵的blas库,但它不是基于GHC7建立的。
我对Repa并没有太多的经验,而且我不太了解repa代码。从我的角度来看,它可以使用的矩阵和数组算法的使用范围非常有限,但是至少可以通过该库来表达重要的算法。例如,已经存在用于矩阵乘法和用于 REPA算法中的卷积的例程。不幸的是,似乎卷积现在仅限于7×7内核(对我来说这还不够,但足以满足许多用途)。
我没有尝试过Haskell OpenCV绑定。它们应该很快,因为OpenCV确实非常快,但是我不确定绑定是否完整和足够好以至于无法使用。而且,OpenCV本质上是非常必要的,充满破坏性的更新。我想很难在其上设计一个美观而有效的功能接口。如果采用OpenCV方式,他很可能会在任何地方使用OpenCV图像表示形式,并使用OpenCV例程对其进行操作。
对于双色调图像,每个像素仅需要存储1位。是否有预定义的数据类型可以通过将多个像素打包到一个单词中来帮助我,还是我自己一个人?
据我所知,布尔的非装箱数组负责打包和解包位向量。我记得在其他库中看过布尔数组的实现,在其他地方也没有看到。
最后,我的数组是二维的。我想我可以处理表示形式为“数组数组”(或向量的向量)带来的额外间接,但我更喜欢具有索引映射支持的抽象。谁能推荐标准库或Hackage中的任何内容?
除了Vector(和简单列表)之外,所有其他数组库都能够表示二维数组或矩阵。我想他们避免不必要的间接访问。