Question

I'm writing a program that generates images, which I would like to bring into a Repa array. I'm currently using the type:

data Colour = Colour Double Double Double

to represent pixels, and I have a (probably inefficient but functional) function which converts a Colour into a DIM1 array:

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

An image in my program at the moment is just a [Colour] value with a (Int, Int) representing dimensions.

I can use this to build a Array V DIM2 Colour easily enough, but is there a way (using colourToRepa or otherwise) to expand this array into a Array U DIM3 Double?

With lists I could just use map but Repa's map preserves the shape of the array (I want to go from a DIM2 to a DIM3).

Was it helpful?

Solution

Remember that shapes are stored separately to data in repa, so you would be reshaping the array from DIM1 to DIM3, without changing the extent of the array.

We have a DIM1 (flat) array:

> 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]

It's extent is:

> extent x
Z :. 9

Using reshape we can 'cast' the shape of the array from 1D to 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]

And its type changes:

> :t y
y :: Array DIM3 Double

OTHER TIPS

Depending on precisely how you want to add an extra dimension can also use extend, for example:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top