2013-01-14 17 views
5

Sto scrivendo un programma che genera immagini, che vorrei portare in un array Repa. Attualmente sto usando il tipo:Espansione forme matrice Repa

data Colour = Colour Double Double Double 

per rappresentare pixel, e ho una funzione di (probabilmente inefficiente ma funzionale) che converte un Colour in un DIM1 array:

colourToRepa :: Colour -> Array U DIM1 Double 
colourToRepa (Colour r g b) = R.fromListUnboxed (Z :. (3::Int)) [r,g,b] 

Un'immagine a mio programma al momento è solo un valore [Colour] con un (Int, Int) che rappresenta le dimensioni.

Posso usarlo per costruire un Array V DIM2 Colour abbastanza facilmente, ma c'è un modo (usando colourToRepa o altro) per espandere questo array in un Array U DIM3 Double?

Con gli elenchi, potrei semplicemente usare map ma la mappa di Repa conserva la forma dell'array (voglio passare da un DIM2 a un DIM3).

risposta

6

Ricordare che le forme vengono memorizzate separatamente per i dati in repa, quindi sarà reshaping l'array da DIM1 a DIM3, senza modificare lo extent dell'array.

Abbiamo un DIM1 (piatta) matrice:

> let x :: Array DIM1 Double ; x = fromList (Z :. (9::Int)) [1..9] 
> x 
Array (Z :. 9) [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] 

E 'punto è:

> extent x 
Z :. 9 

Usando riplasmare ciò siamo in grado di 'lanciare' la forma della matrice da 1D a 3D:

> let y :: Array DIM3 Double ; 
     y = reshape (Z :. (3::Int) :. (3::Int) :. (1::Int)) x 
> y 
Array (Z :. 3 :. 3 :. 1) [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] 

e il suo tipo cambia:

> :t y 
y :: Array DIM3 Double 
+0

Ah. L'avevo dimenticato. Grazie! –

1

a seconda di come si desidera aggiungere un tocco in più può anche usare extend, ad esempio:

extraDim :: Source a Double => 
      Array a (Z :. Int :. Int) Double -> 
      Array D (Z :.Int :. Int :. Int) Double 
extraDim a = extend (Any :. i :. All) a 
       where (Z :. i :. j) = extent a