How do you calculate [i] = f (a [i-1]) in Repa?

Is it possible to compute an array that depends on past values ​​(i.e. smaller indices) in Repa? The initial part of the array is given (for example, a[0] ). (Note that I am using C-shaped notation to indicate an element of an array, please do not confuse.)

I read the tutorial and quickly checked the hack, but I could not find a function for this.

(I think that such a calculation in a 1D array does not make sense in Repa, because you cannot parallelize it, but I think you can parallelize it in the two-dimensional case.)

EDIT : Probably I should be more specific about which f I want to use. Since it is not possible to parallelize in the case a[i] is a scalar, the focus on the case a[i] is an N-dimensional vector. I do not need a[i] be a higher size (for example, a matrix), because you can "expand" it onto a vector. So f is a function that maps R ^ N to R ^ N.

In most cases, it looks like this:

 b = M a[i-1] a[i][j] = g(b)[j] 

where b is an N-dimensional vector, M is the matrix N by N (without the assumption of sparseness), and g is some nonlinear function. And I want to calculate it for i=1,..N-1 , taking into account a[0] , g and M I hope that there is some general way (1) to parallelize this type of computation and (2) to make the selection of intermediate variables such as b efficient (in a C-like language you can just reuse it, it would be nice if Turnip or a similar library can do it like magic without breaking purity).

+6
source share
2 answers

I do not see Repa's way of doing this. But there is for Vector: Data.Vector.iterateN builds the vector that you want. Then Data.Array.Repa.fromUnboxed to convert it from Vector to Repa.

 iterateN :: Int -> (a -> a) -> a -> Vector aSource 

O (n) Apply the function n times to the value. The Zeroth element is the original value.

+3
source

Edit: Actually, I think I misinterpreted the question. I will leave my answer here if it is 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]) 

Dispersion:

  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 a multidimensional array should be trivial.

+1
source

Source: https://habr.com/ru/post/919138/


All Articles