2011-04-02 11 views
5

¿Cómo obtengo una submatriz en Haskell?Tomando sub-arrays en Haskell

+2

¿Sabes cómo obtener una matriz en primer lugar? ¿De qué biblioteca de arreglos estás hablando? Data.Vector? Data.Array? Esta pregunta realmente necesita desarrollarse. –

+0

@TomMD subArray of Data.Array – Rnet

+1

Data.Array es bastante torpe y no tiene fusión, le sugiero que busque Data.Vector para futuras necesidades de matriz. –

Respuesta

9

Creo que estás buscando es la sección 'matrices derivadas' en la documentación Data.Array: http://hackage.haskell.org/packages/archive/array/latest/doc/html/Data-Array.html#5 que alberga la función:

ixmap :: (Ix i, Ix j) => (i, i) -> (i -> j) -> Matriz je -> Matriz ie

ixmap permite transformaciones en índices de matriz. Se puede pensar que proporciona composición de funciones a la derecha con el mapeo que encarna la matriz original.

Se puede lograr una transformación similar de los valores de matriz utilizando fmap desde la instancia Array> de la clase Functor.

el siguiente código:

ixmap newBounds trans backingArray 

habría devolver una matriz con límites newBounds, y cuando indexadas con !i, la función de transformación índice se aplica sobre el índice de i antes de ser utilizado para indexar backingArray.


Ejemplo si tuviera la matriz "Hello World" (helloWorldArray abajo) y sólo desea ver "codo" como base cero (sub) serie derivada:

> let helloWorldArray = listArray (0,length str - 1) str -- 0-based array 
    where str = "Hello World" 

> let ellArray = ixmap (0,2) succ helloWorldArray   -- also 0-based array 

> ellArray ! 0 
'e' 
> ellArray ! 1 
'l' 
> ellArray ! 2 
'l' 

Aquí decimos que nuestra nueva matriz ellArray tiene índices desde 0 hasta 2. Nuestra transformación de índice es simplemente para agregar uno (succ), porque queremos asignar el rango de índice [0..2] a [1..3] en el helloWorldArray original.

Por supuesto, ixmap es lo suficientemente abstracto como para capturar cualquier transformación de índice: incluso para ver 2 matrices dimensionales como matrices de 1 dimensión y viceversa. Es mejor pensar en ello como crear una 'vista' en datos de matriz en lugar de que en una función 'sub-matriz'.

Para más ejemplos que usted puede buscar aquí: http://zvon.org/other/haskell/Outputarray/ixmap_f.html

2

No encontré ninguna forma directa de obtener una sub-matriz (es decir, una división), pero esta es una forma de hacerlo a través de una lista intermedia.

import Data.Array 

subArray :: Int -> Int -> Array -> Array 
subArray i j a = listArray (0,j-i) $ map (a!) [i..j] 
4

Tomando sub-arrays utilizando el paquete vector es probablemente el método más sencillo (asumiendo que su pregunta no es en realidad preguntando acerca de tomar sub-listas).

Las funciones relevantes de la interfaz de vectores en general/matriz es:

  • slice:: Vector v a => Int -> Int -> v a -> v a

pero también debe saber acerca de tomar y soltar. slice toma un índice y una longitud, y extrae la sub-matriz.