Tom Savage
Tom Savage

Reputation: 3182

Expanding Repa array shapes

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).

Upvotes: 5

Views: 383

Answers (2)

idontgetoutmuch
idontgetoutmuch

Reputation: 1621

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

Upvotes: 1

Don Stewart
Don Stewart

Reputation: 137947

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

Upvotes: 6

Related Questions