Einmal habe ich die für mich wichtigen Funktionen der Haskell-Array-Bibliotheken überprüft und eine Vergleichstabelle erstellt (nur Tabellenkalkulation: direkter Link ). Also werde ich versuchen zu antworten.
Auf welcher Basis sollte ich zwischen Vector.Unboxed und UArray wählen? Sie sind beide Arrays ohne Box, aber die Vektorabstraktion scheint stark beworben zu sein, insbesondere im Bereich der Schleifenfusion. Ist Vector immer besser? Wenn nicht, wann sollte ich welche Darstellung verwenden?
UArray kann gegenüber Vector bevorzugt werden, wenn zweidimensionale oder mehrdimensionale Arrays benötigt werden. Aber Vector hat eine schönere API zum Manipulieren von Vektoren. Im Allgemeinen ist Vector nicht gut zum Simulieren mehrdimensionaler Arrays geeignet.
Vector.Unboxed kann nicht mit parallelen Strategien verwendet werden. Ich vermute, dass UArray auch nicht verwendet werden kann, aber es ist zumindest sehr einfach, von UArray zu Boxed Array zu wechseln und zu prüfen, ob die Vorteile der Parallelisierung die Boxkosten übersteigen.
Für Farbbilder möchte ich Tripel von 16-Bit-Ganzzahlen oder Tripel von Gleitkommazahlen mit einfacher Genauigkeit speichern. Ist zu diesem Zweck entweder Vector oder UArray einfacher zu verwenden? Performanter?
Ich habe versucht, Arrays zur Darstellung von Bildern zu verwenden (obwohl ich nur Graustufenbilder benötigte). Für Farbbilder habe ich die Codec-Image-DevIL-Bibliothek zum Lesen / Schreiben von Bildern (Bindungen an die DevIL-Bibliothek) verwendet, für Graustufenbilder habe ich die pgm-Bibliothek (reines Haskell) verwendet.
Mein Hauptproblem mit Array war, dass es nur Direktzugriffsspeicher bietet, aber nicht viele Möglichkeiten zum Erstellen von Array-Algorithmen bietet und auch keine gebrauchsfertigen Bibliotheken von Array-Routinen enthält (keine Schnittstelle zu linearen Algebra-Bibliotheken, nicht wahr? Erlaube nicht, Windungen, FFT und andere Transformationen auszudrücken.
Fast jedes Mal , wenn ein neues Array hat aus dem bestehenden gebaut werden, eine Zwischenliste von Werten muss so konstruiert werden (wie in der Matrixmultiplikation aus der sanften Einführung). Die Kosten für die Array-Konstruktion überwiegen häufig die Vorteile eines schnelleren Direktzugriffs, sodass eine listenbasierte Darstellung in einigen meiner Anwendungsfälle schneller ist.
STUArray hätte mir helfen können, aber ich mochte es nicht, mit kryptischen Typfehlern und den Anstrengungen zu kämpfen, die erforderlich waren, um mit STUArray polymorphen Code zu schreiben .
Das Problem mit Arrays ist also, dass sie für numerische Berechnungen nicht gut geeignet sind. Hmatrix 'Data.Packed.Vector und Data.Packed.Matrix sind in dieser Hinsicht besser, da sie mit einer soliden Matrixbibliothek geliefert werden (Achtung: GPL-Lizenz). In Bezug auf die Leistung war die Matrix bei der Matrixmultiplikation ausreichend schnell ( nur geringfügig langsamer als Octave ), aber sehr speicherhungrig (mehrmals mehr als Python / SciPy verbraucht).
Es gibt auch eine Blas-Bibliothek für Matrizen, die jedoch nicht auf GHC7 aufbaut.
Ich hatte noch nicht viel Erfahrung mit Repa und verstehe den Repa-Code nicht gut. Soweit ich sehe, gibt es nur eine sehr begrenzte Auswahl an gebrauchsfertigen Matrix- und Array-Algorithmen, die darüber geschrieben wurden, aber es ist zumindest möglich, wichtige Algorithmen mithilfe der Bibliothek auszudrücken. Beispielsweise gibt es bereits Routinen zur Matrixmultiplikation und zur Faltung in Repa-Algorithmen. Leider scheint die Faltung jetzt auf 7 × 7-Kernel beschränkt zu sein (es reicht mir nicht, sollte aber für viele Zwecke ausreichen).
Ich habe keine Haskell OpenCV-Bindungen ausprobiert. Sie sollten schnell sein, da OpenCV sehr schnell ist, aber ich bin mir nicht sicher, ob die Bindungen vollständig und gut genug sind, um verwendet werden zu können. Außerdem ist OpenCV von Natur aus sehr wichtig und voller destruktiver Updates. Ich nehme an, es ist schwierig, darüber eine schöne und effiziente funktionale Oberfläche zu entwerfen. Wenn jemand OpenCV-Weg geht, wird er wahrscheinlich überall OpenCV-Bilddarstellung verwenden und OpenCV-Routinen verwenden, um sie zu manipulieren.
Für bitonale Bilder muss ich nur 1 Bit pro Pixel speichern. Gibt es einen vordefinierten Datentyp, der mir hier helfen kann, indem mehrere Pixel in ein Wort gepackt werden, oder bin ich allein?
Soweit ich weiß, kümmern sich Unboxed-Arrays von Bools um das Packen und Entpacken von Bitvektoren. Ich erinnere mich, dass ich mir die Implementierung von Arrays von Bools in anderen Bibliotheken angesehen habe und dies anderswo nicht gesehen habe.
Schließlich sind meine Arrays zweidimensional. Ich nehme an, ich könnte mich mit der zusätzlichen Indirektion befassen, die durch eine Darstellung als "Array von Arrays" (oder Vektor von Vektoren) auferlegt wird, aber ich würde eine Abstraktion bevorzugen, die Index-Mapping-Unterstützung bietet. Kann jemand etwas aus einer Standardbibliothek oder von Hackage empfehlen?
Mit Ausnahme von Vector (und einfachen Listen) können alle anderen Array-Bibliotheken zweidimensionale Arrays oder Matrizen darstellen. Ich nehme an, sie vermeiden unnötige Indirektion.