Une fois que j'ai passé en revue les caractéristiques des bibliothèques de tableaux Haskell qui sont importantes pour moi, et que j'ai compilé un tableau comparatif (uniquement feuille de calcul : lien direct ). Je vais donc essayer de répondre.
Sur quelle base devrais-je choisir entre Vector.Unboxed et UArray ? Ce sont tous deux des tableaux non encapsulés, mais l'abstraction Vector semble faire l'objet de beaucoup de publicité, en particulier pour la fusion de boucles. Vector est-il toujours meilleur ? Si ce n'est pas le cas, 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 dispose d'une API plus agréable pour manipuler les vecteurs. En général, Vector n'est pas bien adapté à la simulation de 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 à Array boxé et de voir si les avantages de la parallélisation compensent les coûts du boxage.
Pour les images en couleur, je souhaite stocker des triples d'entiers de 16 bits ou des triples de nombres à virgule flottante de simple précision. À cette fin, Vector ou UArray sont-ils plus faciles à utiliser ? Est-il plus performant ?
J'ai essayé d'utiliser des tableaux pour représenter les images (bien que je n'aie eu besoin que d'images en niveaux de gris). Pour les images en couleur, j'ai utilisé la bibliothèque Codec-Image-DevIL pour lire/écrire les images (bindings à la bibliothèque DevIL), pour les images en niveaux de gris, j'ai utilisé la bibliothèque pgm (pure Haskell).
Mon principal problème avec Array était qu'il ne fournit qu'un stockage à accès aléatoire, mais il ne fournit pas beaucoup de moyens de construire des algorithmes Array et n'est pas livré avec des bibliothèques de routines Array prêtes à l'emploi (il ne s'interface pas avec les bibliothèques d'algèbre linéaire, ne permet pas d'exprimer des convolutions, des fft et d'autres transformations).
Presque à chaque fois qu'un nouveau tableau doit être construit à partir d'un tableau existant, un tableau intermédiaire est créé. liste de valeurs doit être construit (comme dans multiplication matricielle de l'introduction douce). Le coût de la construction d'un tableau l'emporte souvent sur 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 me battre avec des erreurs de type cryptiques et les efforts nécessaires pour écrire code polymorphe avec STUArray .
Le problème des tableaux est donc 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 performance, pour la multiplication de matrices, hmatrix est suffisamment rapide ( seulement légèrement plus lent que Octave ), mais très gourmand en mémoire (il en consomme plusieurs fois plus que Python/SciPy).
Il existe aussi la bibliothèque blas pour les matrices, mais elle n'est pas construite sur GHC7.
Je n'avais 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 y a une gamme très limitée d'algorithmes de matrices et de tableaux prêts à l'emploi écrits dessus, mais il est au moins possible d'exprimer des algorithmes importants au moyen de la bibliothèque. Par exemple, il existe déjà des routines pour multiplication de matrices et pour la convolution dans les repa-algorithmes. Malheureusement, il semble que la convolution soit maintenant limité à 7×7 noyaux (ce n'est pas suffisant pour moi, mais cela 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 est par nature très impératif, plein de mises à jour destructives. Je suppose qu'il est difficile de concevoir une interface fonctionnelle agréable et efficace par-dessus. Si l'on suit la voie d'OpenCV, il est probable que l'on utilise la représentation d'image OpenCV partout, et que l'on utilise les routines OpenCV pour les manipuler.
Pour les images bitonales, je ne devrai stocker qu'un bit par pixel. Existe-t-il un type de données prédéfini qui puisse m'aider à regrouper plusieurs pixels dans un mot, ou dois-je me débrouiller tout seul ?
Pour autant que je sache, Tableaux de Bools sans boîte s'occupe de l'emballage et du déballage des 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 m'accommoder de l'indirection supplémentaire imposée par une représentation sous forme de "tableau de tableaux" (ou de vecteur de vecteurs), mais je préférerais une abstraction qui prenne en charge le mappage d'index. Quelqu'un peut-il me recommander quelque chose dans une bibliothèque standard ou dans 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'elles évitent les indirections inutiles.