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

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.

Related

Chinese Remainder Theorem Haskell

I need to write a function or functions in Haskell that can solve the Chinese Remainder Theorem. It needs to be created with the following definition:
crt :: [(Integer, Integer)] -> (Integer, Integer)
That the answer looks like
>crt [(2,7), (0,3), (1,5)]
(51, 105)
I think I have the overall idea, I just don't have the knowledge to write it. I know that the crt function must be recursive. I have created a helper function to split the list of tuples into a tuple of two lists:
crtSplit xs = (map fst xs, product(map snd xs))
Which, in this example, gives me:
([2,0,1],105)
I think what I need to do know is create a list for each of the elements in the first list. How would I begin to do this?
Chinese remainder theorem has an algebraic solution, based on the fact that x = r1 % m1 and x = r2 % m2 can be reduced to one modular equation if m1 and m2 are coprime.
To do so you need to know what modular inverse is and how it can efficiently be calculated using extended Euclidean algorithm.
If you put these pieces together, you can solve Chinese remainder theorem with a right fold:
crt :: (Integral a, Foldable t) => t (a, a) -> (a, a)
crt = foldr go (0, 1)
where
go (r1, m1) (r2, m2) = (r `mod` m, m)
where
r = r2 + m2 * (r1 - r2) * (m2 `inv` m1)
m = m2 * m1
-- Modular Inverse
a `inv` m = let (_, i, _) = gcd a m in i `mod` m
-- Extended Euclidean Algorithm
gcd 0 b = (b, 0, 1)
gcd a b = (g, t - (b `div` a) * s, s)
where (g, s, t) = gcd (b `mod` a) a
then:
\> crt [(2,7), (0,3), (1,5)]
(51,105)
\> crt [(2,3), (3,4), (1,5)] -- wiki example
(11,60)
Without going into algebra, you can also solve this with brute force. Perhaps that's what you've been asked to do.
For your example, create a list for each mod independent of the other two (upper bound will be least common multiple of the mod, assuming they are co-prime as a precondition, product, i.e. 105). These three list should have one common element which will satisfy all constraints.
m3 = [3,6,9,12,15,...,105]
m5 = [6,11,16,21,...,101]
m7 = [9,16,23,30,...,100]
you can use Data.Set to find the intersection of these lists. Now, extend this logic to n number of terms using recursion or fold.
Update
Perhaps an easier approach is defining a filter to create a sequence with a fixed remainder for a modulus and repeatedly apply for the given pairs
Prelude> let rm (r,m) = filter (\x -> x `mod` m == r)
verify that it works,
Prelude> take 10 $ rm (1,5) [1..]
[1,6,11,16,21,26,31,36,41,46]
now, for the given example use it repeatedly,
Prelude> take 3 $ rm (1,5) $ rm (0,3) $ rm (2,7) [1..]
[51,156,261]
of course we just need the first element, change to head instead
Prelude> head $ rm (1,5) $ rm (0,3) $ rm (2,7) [1..]
51
which we can generalize with fold
Prelude> head $ foldr rm [1..] [(1,5),(0,3),(2,7)]
51

Defining an operator to access a multi-dimensional array

I got the idea of defining an operator that takes a (possibly) multidimensional list, and a list of indices, and returns the element. My proto attempt was:
(!!!) xs [i] = xs !! i
(!!!) xs (cI : restI) = (xs !! cI) !!! restI
In retrospect, this obviously has a lot of problems. I couldn't figure out a type signature first off, then I realized that in line 2, the return type of (xs !! cI) will constantly change, and may not always even be a list (on the last "iteration")
I realized that to access a multi-dimensional array using the standard subscript operator, you can simply chain it like:
[[1,2,3],[4,5,6],[7,8,9]] !! 1 !! 1 = 5
And realized that that looks a lot like a fold, so I tried:
(!!!) xxs inds = foldl (!!) xxs inds
or simply (!!!) = foldl (!!) 
But I get the same error as my first attempt; that I'm trying to construct an infinite type.
Is this type of function even possible (through a hack or otherwise)? I'm starting to think that its type is just too up in the air to work.
Just as an example, I was aiming for the following:
[[1,2,3],[4,5,6],[7,8,9]] !!! [1,1] = 5
As long as you are not bound to using a list to store your indices, you can do this without much effort. The indices must be passed as a datatype which encodes how many indices there are in the type. The canonical length indexed list type looks something like this:
data Nat = Z | S Nat
infixr 5 :>
data Vector (n :: Nat) a where
Nil :: Vector Z a
(:>) :: a -> Vector n a -> Vector (S n) a
Then your function is
(!!!) a Nil = a
(!!!) a (i :> is) = (a !! i) !!! is
You'll notice this doesn't compile. This is because the types of a in the first and second lines are different. The type of a must depend on the type of the indices, and you must tell the compiler exactly how they depend on it. The dependence is quite straightforward; when there are n indices, there must be a list of n dimensions:
type family Dimension (n :: Nat) (v :: * -> *) (x :: *) :: * where
Dimension Z v x = x
Dimension (S n) v x = v (Dimension n v x)
Then the type of the above is quite simply
(!!!) :: Dimension n [] a -> Vector n Int -> a
I don't know how familiar you are with the more advanced features of the Haskell type system, but the above requires type families and data kinds.

Is there an indexed list in Haskell and is it good or bad?

I am a new comer to the Haskell world and I am wondering if there is something like this:
data IndexedList a = IList Int [a]
findIndex::(Int->Int)->IndexedList a->(a,IndexedList a)
findIndex f (IList x l) = (l!!(f x), IList (f x) l)
next::IndexedList a->(a,IndexedList a)
next x = findIndex (+1) x
I've noticed that this kind of list is not purely functional but kind of useful for some applications. Should it be considered harmful?
Thanks,
Bob
It's certainly useful to have a list that comes equipped with a pointed to a particular location in the list. However, the way it's usually done in Haskell is somewhat different - rather than using an explicit pointer, we tend to use a zipper.
The list zipper looks like this
data ListZipper a = LZ [a] a [a] deriving (Show)
You should think of the middle field a as being the element that is currently pointed to, the first field [a] as being the elements before the current position, and the final field [a] as being the elements after the current position.
Usually we store the elements before the current one in reverse order, for efficiency, so that the list [0, 1, 2, *3*, 4, 5, 6] with a pointer to the middle element, would be stored as
LZ [2,1,0] 3 [4,5,6]
You can define functions that move the pointer to the left or right
left (LZ (a:as) b bs) = LZ as a (b:bs)
right (LZ as a (b:bs)) = LZ (a:as) b bs
If you want to move to the left or right n times, then you can do that with the help of a function that takes another function, and applies it n times to its argument
times n f = (!!n) . iterate f
so that to move left three times, you could use
>> let lz = LZ [2,1,0] 3 [4,5,6]
>> (3 `times` left) lz
LZ [] 0 [1,2,3,4,5,6]
Your two functions findIndex and next can be written as
next :: ListZipper a -> (a, ListZipper a)
next = findIndex 1
findIndex :: Int -> ListZipper a -> (a, ListZipper a)
findIndex n x = let y#(LZ _ a _) = (n `times` right) x in (a, y)
Contrary to what you think this list is in fact purely functional. The reason is that IList (f x) l creates a new list (and does not, as you may think, modify the current IndexedList). It is in general not that easy to create non-purely functional data structures or functions in Haskell, as long as you stay away from unsafePerformIO.
The reason I would recommend against using the IndexedList is that there is no assurance that the index is less than the length of the list. In this case the lookup l!!(f x) will fail with an exception, which is generally considered bad style in Haskell. An alternative could be to use a safe lookup, which returns a Maybe a like the following:
findIndex :: (Int -> Int) -> IndexedList a -> (Maybe a, IndexedList a)
findIndex f (IList i l) = (maybe_x, IList new_i l)
where
new_i = f i
maybe_x = if new_i < length l
then Just (l !! newI)
else Nothing
I can also not think of a usecase where such a list would be useful, but I guess I am limited by my creativity ;)

Haskell: How To Fix Error With "add An Instance Declaration For (Unbox A)" When Using Unboxed Vectors?

I have written some code in which a small part of the code takes a large one dimensional Unboxed.Vector and returns them as a Vector (Vector a).
A part of the code is giving an error. Here is a sample piece of code that is similar to the actual code and gives the same error.
import Data.Vector.Unboxed as D
xs = [0,1,2,3,4,5,6,7,8,9,10,11]
rows = 3
cols = 4
sb = D.fromList xs
takeRows::Int -> Int -> Vector Int -> Vector (Vector Int)
takeRows rows cols x0 = D.map (\x -> D.slice x (fromIntegral cols) x0) starts
where
starts = D.enumFromStepN 0 cols rows
-- takeRowsList::Int -> Int -> Vector Int -> [Vector Int]
-- takeRowsList rows cols x0 = Prelude.map (\x -> D.slice x (fromIntegral cols) x0) starts
-- where
-- starts = D.toList . D.enumFromStepN 0 cols $ rows
the error is
No instance for (Unbox (Vector Int))
arising from a use of `D.map'
Possible fix: add an instance declaration for (Unbox (Vector Int))
In the expression:
D.map (\ x -> slice x (fromIntegral cols) x0) starts
In an equation for `takeRows':
takeRows rows cols x0
= D.map (\ x -> slice x (fromIntegral cols) x0) starts
where
starts = enumFromStepN 0 cols rows
I have written a similar function takeRowsList, which makes the outer Vector as a List and this doesn't suffer from the same problem. I've also included it above but commented it out, to demonstrate my problem.
I understand that some functions need type definitions, when, I use them with Unboxed Vectors. But in this case I am stumped as to where to put a type definition. I've tried pretty much type defining everything and I keep getting the above error.
Thanks in advance for your help.
Unboxed vectors need to know the size of their elements, and that size must be constant. Vectors can have different sizes, so they can't be elements of unboxed vectors. They could be elements of boxed vectors, though, so if lists aren't good for what you do, you can make it a boxed vector (import qualified Data.Vector as B and qualify the relevant functions with B instead of D).
You cannot have an unboxed vector contain another vector. Only certain primitive datatypes can be unboxed, namely the ones for which Unbox instances are defined. Vectors are not primitive datatypes.
What you can do is have your function return a normal (boxed) vector of unboxed vectors.

Repa nested array definitions resulting in "Performing nested parallel computation sequentially..."

As part of a larger problem, I am trying to define an array inside an array like so:
import Data.Array.Repa
type Arr = Array DIM2 Int
arr = force $ fromList (Z :. 5 :. 5) [1..25] :: Arr
combined :: Arr
combined = arr `deepSeqArray`
traverse arr (\_ -> Z :. 4 :. 4 :: DIM2) (\f (Z :. x :. y) ->
let reg = force $ extract f (x,y) (2,2)
in reg `deepSeqArray` sumAll reg)
extract :: (DIM2 -> Int) -> (Int,Int) -> (Int,Int) -> Arr
extract lookup (x0,y0) (width,height) = fromFunction bounds
$ \sh -> offset lookup sh
where
bounds = Z :. width :. height
offset :: (DIM2 -> Int) -> DIM2 -> Int
offset f (Z :. x :. y) = f (Z :. x + x0 :. y + y0)
main = print combined
The extract function is using fromFunction and the lookup function provided to it, but it could also use traverse and arr ! ... for the same effect. Despite using force and deepSeqArray everywhere as early as possible, the console is filled with the message here, followed by the correct result:
Data.Array.Repa: Performing nested parallel computation sequentially.
You've probably called the 'force' function while another instance was
already running. This can happen if the second version was suspended due
to lazy evaluation. Use 'deepSeqArray' to ensure each array is fully
evaluated before you 'force' the next one.
While I haven't constructed a version with lists to compare the speeds, in the larger version performance is suffering.
Is this simply a consequence of nested array definitions and thus I should restructure my program for either the inner or outer definition to be lists? Is my extract function horrible and the cause of the problems?
The tips from this question were useful to get this far but I haven't yet gone crawling through the compiled code.
It's because 'print' implicitly forces the array as well. The inner 'force' and 'sumAll' functions invoke parallel computation, but does 'print', so you have nested parallelism. That fact that this is so non-obvious is a great sadness in the Repa 2 API.
Repa 3 addresses these sort of issues by exporting both sequential and parallel versions of 'force' and 'sumAll' etc. It also adds a tag to the array type to indicate whether the array is delayed or manifest. Repa 3 isn't finished yet, but you could use the head version on http://code.ouroborus.net/repa. It should be out shorty after GHC 7.4 later this year.
Here is a Repa 3 version of your example that runs without giving the warning about nested parallelism. Note that 'force' is now 'compute'.
import Data.Array.Repa
arr :: Array U DIM2 Int
arr = fromListUnboxed (Z :. 5 :. 5) [1..25]
combined :: Array U DIM2 Int
combined
= computeP $ traverse arr (\_ -> Z :. 4 :. 4 :: DIM2)
$ \f (Z :. x :. y) -> sumAllS $ extract f (x,y) (2,2)
extract :: (DIM2 -> Int) -> (Int,Int) -> (Int,Int) -> Array D DIM2 Int
extract lookup (x0,y0) (width,height)
= fromFunction bounds
$ \sh -> offset lookup sh
where
bounds = Z :. width :. height
offset :: (DIM2 -> Int) -> DIM2 -> Int
offset f (Z :. x :. y) = f (Z :. x + x0 :. y + y0)
main = print combined

Resources