I'm having some trouble grasping repa's Slice
module, and specifically how its types and families are used with the slice
function. I believe an answer to the following would clear things up for me.
Suppose x
has shape shapeOfList [m_0, m_1, …, m_{d-1}]
. Given integers i < d
and j < mi
, how do I build something with a suitable type to be slice
's second argument, that extracts a slice from x
with shape shapeOfList [m_0, …, m_{i-1}, m_{i+1}, …, m_{d-1}]
defined by freezing index number i
at j
?
Examples in the case d=2
would be:
i=0
: extract row j
i=1
: extract column j
let arr = fromListUnboxed (ix2 3 3) [0..8] :: Array U DIM2 Double
shapeOfList
transform a list to an index, for instance
shapeOfList [2,2] == (ix2 2 2) -- (Z:. 2 :.2)
xs ! shapeOfList [2,2] == 8.0
But the function slice
takes a range of indexes and this range of indexes is represented in REPA using the keywords Any
and All
. For instance, to extract the nth row from a Matrix the syntax is
nRow n =computeUnboxedS $ slice arr (Any :. n :. All) -- xs :: Array U DIM1 Double
-- nRow 2 = fromList [6.0,7.0,8.0]
To extract the nth column the Following notation is used
nCol n = computeUnboxedS $ slice arr (Any :. n ) -- xs :: Array U DIM1 Double
-- nCol 2 = fromList [2.0,5.0,8.0]
It is confusing that in the REPA vocabulary the array index (Z:. i:. i) and the range of indexes (Any :. n :. All) are both called shapes, but one represent only one element index while the other represent an array of indexes.
EDIT
to extract the ith
dimension from an array traverse
seems the right function, for instance for 3-dimensions
-- k = 3 and m = 0
fun3D_i arr = traverse arr (\(Z :. _ :. j :. k ) -> (Z:. j :. k)) (\f (Z :. j :. k ) -> f (Z :. 0 :. j :. k ))`
-- k = 3 and m = 1
fun3D_j arr = traverse arr (\(Z :. i :. _ :. k ) -> (Z:. i :. k)) (\f (Z :. i :. k ) -> f (Z :. i :. 0 :. k ))
-- k = 3 and m = 2
fun3D_k arr = traverse arr (\(Z :. i :. j :. _ ) -> (Z:. i :. j)) (\f (Z :. i :. j ) -> f (Z :. i :. j :. 0 ))
and so on for higher dimensions. On the other hand, Template Haskell could help here to select the dimension that you want to extract.