Une fois, j'ai passé en revue les fonctionnalités des bibliothèques de tableaux Haskell qui comptent pour moi, et j'ai compilé un tableau de comparaison (feuille de calcul uniquement: lien direct ). Je vais donc essayer de répondre.
Sur quelle base dois-je choisir entre Vector.Unboxed et UArray? Ce sont tous les deux des tableaux sans boîte, mais l'abstraction vectorielle semble fortement annoncée, en particulier autour de la fusion de boucles. Vector est-il toujours meilleur? Sinon, quand dois-je utiliser quelle représentation?
UArray peut être préféré à Vector si l'on a besoin de tableaux bidimensionnels ou multidimensionnels. Mais Vector a une API plus agréable pour manipuler des vecteurs. En général, Vector n'est pas bien adapté pour simuler des tableaux multidimensionnels.
Vector.Unboxed ne peut pas être utilisé avec des stratégies parallèles. Je soupçonne que UArray ne peut pas être utilisé non plus, mais au moins il est très facile de passer de UArray à Boxed Array et de voir si les avantages de la parallélisation dépassent les coûts de boxe.
Pour les images couleur, je souhaite stocker des triplets d'entiers 16 bits ou des triplets de nombres à virgule flottante simple précision. Dans ce but, est-ce que Vector ou UArray est plus facile à utiliser? Plus performant?
J'ai essayé d'utiliser des tableaux pour représenter des images (même si je n'avais besoin que d'images en niveaux de gris). Pour les images couleur, j'ai utilisé la bibliothèque Codec-Image-DevIL pour lire / écrire des images (liaisons à la bibliothèque DevIL), pour les images en niveaux de gris, j'ai utilisé la bibliothèque pgm (pure Haskell).
Mon problème majeur avec Array était qu'il ne fournit que du stockage à accès aléatoire, mais il ne fournit pas beaucoup de moyens de créer des algorithmes Array et ne vient pas avec des bibliothèques prêtes à l'emploi de routines de tableau (ne s'interface pas avec les bibliothèques d'algèbre linéaire, n'est pas 't permettent d'exprimer des convolutions, fft et autres transformations).
Presque chaque fois qu'un nouveau tableau doit être construit à partir de l'existant, une liste intermédiaire de valeurs doit être construite (comme dans la multiplication matricielle de l'introduction douce). Le coût de la construction de tableaux surpasse souvent les avantages d'un accès aléatoire plus rapide, au point qu'une représentation basée sur une liste est plus rapide dans certains de mes cas d'utilisation.
STUArray aurait pu m'aider, mais je n'aimais pas lutter contre les erreurs de type cryptique et les efforts nécessaires pour écrire du code polymorphe avec STUArray .
Le problème avec les tableaux est qu'ils ne sont pas bien adaptés aux calculs numériques. Data.Packed.Vector et Data.Packed.Matrix de Hmatrix sont meilleurs à cet égard, car ils sont accompagnés d'une solide bibliothèque de matrices (attention: licence GPL). En termes de performances, sur la multiplication de la matrice, hmatrix était suffisamment rapide ( seulement légèrement plus lente qu'Octave ), mais très gourmande en mémoire (consommée plusieurs fois plus que Python / SciPy).
Il existe également une bibliothèque blas pour les matrices, mais elle ne s'appuie pas sur GHC7.
Je n'ai pas encore beaucoup d'expérience avec Repa, et je ne comprends pas bien le code repa. D'après ce que je vois, il a une gamme très limitée d'algorithmes de matrice et de tableau prêts à l'emploi écrits dessus, mais au moins il est possible d'exprimer des algorithmes importants au moyen de la bibliothèque. Par exemple, il existe déjà des routines pour la multiplication matricielle et pour la convolution dans les algorithmes de repa. Malheureusement, il semble que la convolution soit désormais limitée aux noyaux 7 × 7 (ce n'est pas assez pour moi, mais devrait suffire pour de nombreuses utilisations).
Je n'ai pas essayé les liaisons Haskell OpenCV. Ils devraient être rapides, car OpenCV est vraiment rapide, mais je ne suis pas sûr que les liaisons soient complètes et suffisamment bonnes pour être utilisables. De plus, OpenCV de par sa nature est très impératif, plein de mises à jour destructrices. Je suppose qu'il est difficile de concevoir une interface fonctionnelle agréable et efficace en plus. Si l'on choisit OpenCV, il est susceptible d'utiliser la représentation d'image OpenCV partout, et d'utiliser les routines OpenCV pour les manipuler.
Pour les images bitonales, je n'aurai besoin de stocker que 1 bit par pixel. Existe-t-il un type de données prédéfini qui peut m'aider ici en regroupant plusieurs pixels dans un mot, ou suis-je seul?
Autant que je sache, les tableaux Unboxed de Bools prennent soin de compresser et de décompresser les vecteurs de bits. Je me souviens avoir regardé l'implémentation de tableaux de Bools dans d'autres bibliothèques, et je n'ai pas vu cela ailleurs.
Enfin, mes tableaux sont bidimensionnels. Je suppose que je pourrais gérer l'indirection supplémentaire imposée par une représentation en tant que "tableau de tableaux" (ou vecteur de vecteurs), mais je préférerais une abstraction qui prend en charge le mappage d'index. Quelqu'un peut-il recommander quelque chose d'une bibliothèque standard ou de Hackage?
En dehors de Vector (et des listes simples), toutes les autres bibliothèques de tableaux sont capables de représenter des tableaux ou des matrices à deux dimensions. Je suppose qu'ils évitent les indirections inutiles.