Is it possible to compute an array which depends on the past value(s) (i.e., lesser indexes), in Repa? Initial part(s) of the array (e.g., a[0]
) is given. (Note that I am using C-like notation to indicate an element of array; please don't confuse.)
I read the tutorial and quickly check the hackage but I could not find a function to do it.
(I guess doing this kind of computation in 1D array does not make sence in Repa because you can't parallelize it. But I think you can parallelize it in 2 or more dimensional case.)
EDIT:
Probably I should be more specific about what kind of f
I want to use. As there is no way to parallelize in the case a[i]
is a scalar, let's focus on the case a[i]
is a N dim vector. I don't need a[i]
to be higher dimensional (such as matrix) because you can "unroll" it to a vector. So, f
is a function which maps R^N to R^N.
Most of the case, it's like this:
b = M a[i-1]
a[i][j] = g(b)[j]
where b
is a N dim vector, M
is a N by N matrix (no assumption for sparseness), and g
is some nonlinear function. And I want to compute it for i=1,..N-1
given a[0]
, g
and M
. My hope is that there are some generic way to (1) parallelize this type of calculation and (2) make allocation of intermediate variables such as b
efficient (in C-like language, you can just reuse it, it would be nice if Repa or similar library can do it like a magic without breaking purity).
I cannot see a Repa way of doing this. But there is for Vector: Data.Vector.iterateN builds the vector you want. Then Data.Array.Repa.fromUnboxed to convert it from Vector to Repa.
iterateN :: Int -> (a -> a) -> a -> Vector aSource
O(n) Apply function n times to value. Zeroth element is original value.
Edit: Actually, I think I misinterpreted the question. I'll leave my answer here, in case it's useful for someone else...
You can use traverse
http://hackage.haskell.org/packages/archive/repa/3.2.1.1/doc/html/Data-Array-Repa.html#v:traverse:
Prelude Data.Array.Repa R> let x = fromListUnboxed (Z :. 10 :: DIM1) [1..10]
Prelude Data.Array.Repa R> R.computeUnboxedS $ R.traverse x (\ (Z :. i) -> (Z :. (i - 1))) (\f (Z :. i) -> f (Z :. (i + 1)) - f (Z :. i))
AUnboxed (Z :. 9) (fromList [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0])
Dissecting it:
R.computeUnboxedS $ -- force the vector to be "real"
R.traverse x -- traverse the vector
(\ (Z :. i) -> (Z :. (i - 1))) -- function to get the shape of the result
(\f (Z :. i) -> f (Z :. (i + 1)) - f (Z :. i)) -- actual "stencil"
Extending it to multi-dimensional array should be trivial.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With