Una vez revisé las características de las bibliotecas de matrices de Haskell que me importan y compilé una tabla de comparación (solo hoja de cálculo: enlace directo ). Así que intentaré responder.
¿Sobre qué base debo elegir entre Vector.Unboxed y UArray? Ambos son arreglos sin caja, pero la abstracción vectorial parece muy publicitada, en particular en torno a la fusión de bucles. ¿Vector siempre es mejor? Si no es así, ¿cuándo debería usar qué representación?
Puede preferirse UArray sobre Vector si se necesitan matrices bidimensionales o multidimensionales. Pero Vector tiene una API más agradable para manipular vectores. En general, Vector no es adecuado para simular matrices multidimensionales.
Vector.Unboxed no se puede utilizar con estrategias paralelas. Sospecho que UArray no se puede usar tampoco, pero al menos es muy fácil cambiar de UArray a Boxed Array y ver si los beneficios de la paralelización superan los costos de boxing.
Para las imágenes en color, desearé almacenar triples de enteros de 16 bits o triples de números de punto flotante de precisión simple. Para este propósito, ¿es más fácil usar Vector o UArray? ¿Más rendimiento?
Intenté usar Arrays para representar imágenes (aunque solo necesitaba imágenes en escala de grises). Para las imágenes en color, utilicé la biblioteca Codec-Image-DevIL para leer / escribir imágenes (enlaces a la biblioteca DevIL), para las imágenes en escala de grises usé la biblioteca pgm (Haskell puro).
Mi principal problema con Array fue que solo proporciona almacenamiento de acceso aleatorio, pero no proporciona muchos medios para construir algoritmos de Array ni viene con bibliotecas listas para usar de rutinas de matriz (no interactúa con bibliotecas de álgebra lineal, no no permite expresar convoluciones, fft y otras transformaciones).
Casi cada vez que se debe construir una nueva matriz a partir de la existente, se debe construir una lista intermedia de valores (como en la multiplicación de matrices de la Introducción gentil). El costo de la construcción de arreglos a menudo supera los beneficios de un acceso aleatorio más rápido, hasta el punto de que una representación basada en listas es más rápida en algunos de mis casos de uso.
STUArray podría haberme ayudado, pero no me gustaba luchar con errores de tipo críptico y los esfuerzos necesarios para escribir código polimórfico con STUArray .
Entonces, el problema con las matrices es que no son adecuadas para cálculos numéricos. Data.Packed.Vector y Data.Packed.Matrix de Hmatrix son mejores en este sentido, porque vienen con una biblioteca de matriz sólida (atención: licencia GPL). En cuanto al rendimiento, en la multiplicación de matrices, hmatrix fue lo suficientemente rápido ( solo un poco más lento que Octave ), pero con mucha memoria (consumió varias veces más que Python / SciPy).
También hay una biblioteca blas para matrices, pero no se basa en GHC7.
Todavía no tenía mucha experiencia con Repa y no entiendo bien el código de reparación. Por lo que veo, tiene un rango muy limitado de algoritmos de matriz y matriz listos para usar escritos encima, pero al menos es posible expresar algoritmos importantes por medio de la biblioteca. Por ejemplo, ya existen rutinas para la multiplicación de matrices y para la convolución en repa-algoritmos. Desafortunadamente, parece que la convolución ahora está limitada a núcleos de 7 × 7 (no es suficiente para mí, pero debería ser suficiente para muchos usos).
No probé los enlaces Haskell OpenCV. Deberían ser rápidos, porque OpenCV es realmente rápido, pero no estoy seguro de si los enlaces están completos y son lo suficientemente buenos como para ser utilizables. Además, OpenCV por su naturaleza es muy imperativo, lleno de actualizaciones destructivas. Supongo que es difícil diseñar una interfaz funcional agradable y eficiente sobre ella. Si uno sigue el camino de OpenCV, es probable que use la representación de imágenes de OpenCV en todas partes y use rutinas de OpenCV para manipularlas.
Para imágenes bitonales, necesitaré almacenar solo 1 bit por píxel. ¿Existe un tipo de datos predefinido que pueda ayudarme aquí al empaquetar varios píxeles en una palabra, o estoy solo?
Hasta donde yo sé, las matrices sin caja de Bools se encargan de empaquetar y desempacar vectores de bits. Recuerdo haber visto la implementación de matrices de Bools en otras bibliotecas y no vi esto en ningún otro lugar.
Finalmente, mis matrices son bidimensionales. Supongo que podría lidiar con la indirección adicional impuesta por una representación como "matriz de matrices" (o vector de vectores), pero preferiría una abstracción que tenga soporte de mapeo de índices. ¿Alguien puede recomendar algo de una biblioteca estándar o de Hackage?
Aparte de Vector (y listas simples), todas las demás bibliotecas de matrices son capaces de representar matrices o matrices bidimensionales. Supongo que evitan la indirecta innecesaria.