Haskell eficiente equivalente al argsort de NumPy
¿Existe un estándar de Haskell equivalente a NumPy's?argsort
¿función?
Estoy usandoHMatrix y, entonces, quisiera una función compatible conVector R
que es un alias paraData.Vector.Storable.Vector Double
. losargSort
La siguiente función es la implementación que estoy usando actualmente:
{-# LANGUAGE NoImplicitPrelude #-}
module Main where
import qualified Data.List as L
import qualified Data.Vector as V
import qualified Data.Vector.Storable as VS
import Prelude (($), Double, IO, Int, compare, print, snd)
a :: VS.Vector Double
a = VS.fromList [40.0, 20.0, 10.0, 11.0]
argSort :: VS.Vector Double -> V.Vector Int
argSort xs = V.fromList (L.map snd $ L.sortBy (\(x0, _) (x1, _) -> compare x0 x1) (L.zip (VS.toList xs) [0..]))
main :: IO ()
main = print $ argSort a -- yields [2,3,1,0]
Estoy usando explícitamente calificadoimport
s solo para dejar en claro de dónde proviene cada tipo y función.
Esta implementación no es terriblemente eficiente ya que convierte el vector de entrada en una lista y el resultado nuevamente en un vector. ¿Existe algo como esto (pero más eficiente) en alguna parte?
Actualizar
@leftaroundabout tenía una buena solución. Esta es la solución con la que terminé:
module LAUtil.Sorting
( IndexVector
, argSort
)
where
import Control.Monad
import Control.Monad.ST
import Data.Ord
import qualified Data.Vector.Algorithms.Intro as VAI
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Numeric.LinearAlgebra
type IndexVector = VU.Vector Int
argSort :: Vector R -> IndexVector
argSort xs = runST $ do
let l = VS.length xs
t0 <- VUM.new l
forM_ [0..l - 1] $
\i -> VUM.unsafeWrite t0 i (i, (VS.!) xs i)
VAI.sortBy (comparing snd) t0
t1 <- VUM.new l
forM_ [0..l - 1] $
\i -> VUM.unsafeRead t0 i >>= \(x, _) -> VUM.unsafeWrite t1 i x
VU.freeze t1
Esto se puede usar más directamente conNumeric.LinearAlgebra
ya que el vector de datos es unStorable
. Esto usa un vector sin caja para los índices.