Imagine I want to map a function over an array, but the function has a type not just of
a -> b
but
a -> Int -> b
i.e. the function also takes an index. How do I do that?
Short answer, use traverse.
Longer example:
import qualified Data.Array.Repa as A
import qualified Data.Vector.Unboxed as U
arr1 :: A.Array A.DIM2 Double
arr1 = A.fromVector (A.Z A.:. 2 A.:. 3) $ U.fromList [1::Double,2,3,4,5,6]
arr2 :: A.Array A.DIM2 Double
arr2 = A.traverse arr1 id (\lf i#(A.Z A.:. r A.:. c) ->
(lf i) + (fromIntegral r) + (fromIntegral c))
arr1 is a 2x3 matrice. traverse is a function that takes (1) the original array, (2) a function for mapping source indices to target indices, and (3) a function that is given (i) a lookup function into the original array and (ii) an index that returns a new value.
So here arr2 modifies each of the original elements by adding the row and column indices of that particular entry.
Good question, and it wasn't documented in the Repa tutorial, so I've updated it with a new section on traversals.
In particular, traverse lets you:
change the shape of the output array
index any eleemnt
observe the current element
Meaning you can do things like:
Replace all eleemnts with their row index
> traverse a id (\_ (Z :. i :. j :. k) -> i)
[0,0,0,0,0,0,0,0,0
,1,1,1,1,1,1,1,1,1
,2,2,2,2,2,2,2,2,2]
Multiply an element by its row
> traverse a id (\f (Z :. i :. j :. k) -> f (Z :. i :. j :. k) * i)
[0,0,0,0,0,0,0,0,0
,10,11,12,13,14,15,16,17,18
,38,40,42,44,46,48,50,52,54]
And so on. travese is very powerful, and is also magically parallel.
Advanced: parallel image desaturation
Example from the Repa tutorial
Use zipWith
zipWith (\idx ele -> if even idx then div ele 2 else ele) [0..] xs
Related
I'm trying to teach myself Haskell (coming from OOP languages). Having a hard time grasping the immutable variables stuff. I'm trying to sort a 2d array in row major.
In java, for example (pseudo):
int array[3][3] = **initialize array here
for(i = 0; i<3; i++)
for(j = 0; j<3; j++)
if(array[i][j] < current_low)
current_low = array[i][j]
How can I implement this same sort of thing in Haskell? If I create a temp array to add the low values to after each iteration, I won't be able to add to it because it is immutable, correct? Also, Haskell doesn't have loops, right?
Here's some useful stuff I know in Haskell:
main = do
let a = [[10,4],[6,10],[5,2]] --assign random numbers
print (a !! 0 !! 1) --will print a[0][1] in java notation
--How can we loop through the values?
First, your Java code does not sort anything. It just finds the smallest element. And, well, there's a kind of obvious Haskell solution... guess what, the function is called minimum! Let's see what it does:
GHCi> :t minimum
minimum :: Ord a => [a] -> a
ok, so it takes a list of values that can be compared (hence Ord) and outputs a single value, namely the smallest. How do we apply this to a "2D list" (nested list)? Well, basically we need the minimum amongst all minima of the sub-lists. So we first replace the list of list with the list of minima
allMinima = map minimum a
...and then use minimum allMinima.
Written compactly:
main :: IO ()
main = do
let a = [[10,4],[6,10],[5,2]] -- don't forget the indentation
print (minimum $ map minimum a)
That's all!
Indeed "looping through values" is a very un-functional concept. We generally don't want to talk about single steps that need to be taken, rather think about properties of the result we want, and let the compiler figure out how to do it. So if we weren't allowed to use the pre-defined minimum, here's how to think about it:
If we have a list and look at a single value... under what circumstances is it the correct result? Well, if it's smaller than all other values. And what is the smallest of the other values? Exactly, the minimum amongst them.
minimum' :: Ord a => [a] -> a
minimum' (x:xs)
| x < minimum' xs = x
If it's not smaller, then we just use the minimum of the other values
minimum' (x:xs)
| x < minxs = x
| otherwise = minxs
where minxs = minimum' xs
One more thing: if we recurse through the list this way, there will at some point be no first element left to compare with something. To prevent that, we first need the special case of a single-element list:
minimum' :: Ord a => [a] -> a
minimum' [x] = x -- obviously smallest, since there's no other element.
minimum' (x:xs)
| x < minxs = x
| otherwise = minxs
where minxs = minimum' xs
Alright, well, I'll take a stab. Zach, this answer is intended to get you thinking in recursions and folds. Recursions, folds, and maps are the fundamental ways that loops are replaced in functional style. Just try to believe that in reality, the question of nested looping rarely arises naturally in functional programming. When you actually need to do it, you'll often enter a special section of code, called a monad, in which you can do destructive writes in an imperative style. Here's an example. But, since you asked for help with breaking out of loop thinking, I'm going to focus on that part of the answer instead. #leftaroundabout's answer is also very good and you fill in his definition of minimum here.
flatten :: [[a]] -> [a]
flatten [] = []
flatten xs = foldr (++) [] xs
squarize :: Int -> [a] -> [[a]]
squarize _ [] = []
squarize len xs = (take len xs) : (squarize len $ drop len xs)
crappySort :: Ord a => [a] -> [a]
crappySort [] = []
crappySort xs =
let smallest = minimum xs
rest = filter (smallest /=) xs
count = (length xs) - (length rest)
in
replicate count smallest ++ crappySort rest
sortByThrees xs = squarize 3 $ crappySort $ flatten xs
So sCount is the number of elements in the source array, iCount is the number of elements I want to remove.
let indices = Array.init iCount (fun _ -> rng.Next sCount) |> Seq.distinct |> Seq.toArray |> Array.sort
The problem with the method above is that I need to specifically remove iCount indices, and this doesn't guarantee that.
I've tried stuff like
while indices.Count < iCount do
let x = rng.Next sCount
if not (indices.Contains x) then
indices <- indices.Add x
And a few other similar things...
Every way I've tried has been extremely slow though - I'm dealing with source arrays of sizes up to 20 million elements.
What you're doing should be fine if you need a set of indices of negligible size compared to the array. Otherwise, consider doing a variation of a Knuth-Fisher-Yates shuffle to get the first i elements in a random permutation of 1 .. n:
let rndSubset i n =
let arr = Array.zeroCreate i
arr.[0] <- 0
for j in 1 .. n-1 do
let ind = rnd.Next(j+1)
if j < i then arr.[j] <- arr.[ind]
if ind < i then arr.[ind] <- j
arr
I won't give you F# code for this (because I don't know F#...), but I'll describe the approach/algorithm that you should use.
Basically, what you want to do is pick n random elements of a given list list. This can be done in pseudocode:
chosen = []
n times:
index = rng.upto(list.length)
elem = list.at(index)
list.remove-at(index)
chosen.add(elem)
Your list variable should be populated with all possible indices in the source list, and then when you pick n random values from that list of indices, you have random, distinct indices that you can do whatever you want with, including printing values, removing values, knocking yourself out with values, etc...
is iCount closer to the size of the array or closer to 0? That will change the algorithm which you will use.
If closer to 0, then keep track of the previously generated numbers and check if additional numbers have already been generated.
If closer to the size of the array then use the method as described by #feralin
let getRandomNumbers =
let rand = Random()
fun max count ->
Seq.initInfinite (fun _ -> rand.Next(max))
|> Seq.distinct
|> Seq.take count
let indices = Array.init 100 id
let numToRemove = 10
let indicesToRemove = getRandomNumbers (indices.Length - 1) numToRemove |> Seq.toList
> val indicesToRemove : int list = [32; 38; 26; 51; 91; 43; 92; 94; 18; 35]
I have a 2D list [[Int]] in Haskell and I want to check two things:
whether the list has the sam number of rows as columns
whether the rows have the sam number of elements
For instance:
[[1,2,3], [1,55,9]] has the same number of rows as columns - here 2 - and each row has the same number of elements namely 3.
But
[[1,2], [1,55], [4,7]] has the same number of elements in each row though it has unequal number of rows and columns namely 3r 2c.
yet another example:
[[1,2], [1,55], [4,7,8]] has neither the same number of rows as columns nor each row has the same number of elements.
Actually step 1 includes step 2, am I right??
My attempt:
So what I attempted so far, is this:
listIsEqual :: [[Int]] -> Bool
listIsEqual myList = (all (\x -> length x == (length myList)) )
Right now I get the following error mesage:
Couldn't match expected type `Bool' with actual type `[a0] -> Bool'
In the return type of a call of `all'
Probable cause: `all' is applied to too few arguments
In the expression: (all (\ x -> length x == (length myList)))
In an equation for `listIsEqual':
listIsEqual myList = (all (\ x -> length x == (length myList)))
Could anyone tell me where the problem is?
Is there also any other ways to solve this problem?
GHC's error messages aren't always the most helpful, but in this case it got it right.
Probable cause: `all' is applied to too few arguments
And indeed, you forgot the second argument to all:
listIsEqual myList = all (\x -> length x == length myList) myList
^^^^^^
For the second task, you can map the length of every row (the number of columns in that row) defining a function
let columnLengths rows = map length rows
Prelude> columnLengths [[1,2], [1,55], [4,7,8]]
[2,2,3]
Now that we have a list containing the lengths of the columns, we have to check whether they are all equal. The function nub in Data.List removes duplicates from a list.
let columnsLengthEqual = (==) 1 . length . nub . columnLengths
Or all together
let columnsLengthEqual = (==) 1 . length . nub . map length
Matrix respecting your criteria, are squared matrix then checking if the square of first 's row's length is equal to the number of element should be ok.
isSquaredMatrix xs#(h:_) = ((^2) . length $ h) == (length . concat $ xs)
isSquaredMatrix _ = True
But as it has been pointed out by hammar, this is incorrect since we can have positive outcome using wrong input.
# isSquaredMatrix [[1,2,3],[4,5],[6,7,8,9]]
True -- But this is false
#John,
we use # into pattern matching when we want to refer to the whole type at the same time we have break it down. An example should give you more insight,
Usually we can define an exhaustive function working on list using pattern matching as follow.
actOnList [] = -- do something when we encounter an empty list
actOnList (x:xs) = -- do something with h, and do another stuff with xs
For example,
actOnList [] = []
actOnList (x:xs) =
if (pred x)
then x:xs
else actOnList xs
Here my function consumme the list until a predicate is satisfied.
We can imagine skipUntilMeetAChar
skipUntilMeetAChar :: [Char] -> Char -> [Char]
skipUntilMeetAChar [] c = []
skipUntilMeetAChar (x:xs) c =
if (x==c)
then x:xs
else actOnList xs c
As you see when the char is met we'd like to return the list as it, not only the tail, then to do so we need to reconstruct our list using the head x and the tail xs. This can be overcome using #.
skipUntilMeetAChar :: String -> Char -> String
skipUntilMeetAChar [] c = []
skipUntilMeetAChar l#(x:xs) c =
if (x==c)
then l
else actOnList xs c
Now, regarding ($) operator, this is again some syntactic sugar.
As function application are left associative, this lead us to extensively use bracket to reorder the application of our function, as in the example below.
# f3 (f2 (f1 (f0 x)))
Then to avoid the pain of managing closing parentheses, dollars operator $ have been introduce and then our previous expression become.
# f3 $ f2 $ f1 $ f0 x
Which is definitely more readable and easiest to write.
Note that this operator is defined as follow.
($) :: (a -> b) -> a -> b
f $ x = f x
And I advise you to learn more about it consulting the following introduction material.
Sorry for the vague question, but I hope for an experienced Haskeller this is a no-brainer.
I have to represent and manipulate symmetric matrices, so there are basically three different choices for the data type:
Complete matrix storing both the (i,j) and (j,i) element, although m(i,j) = m(j,i)
Data.Array (Int, Int) Int
A map, storing only elements (i,j) with i <= j (upper triangular matrix)
Data.Map (Int, Int) Int
A vector indexed by k, storing the upper triangular matrix given some vector order f(i,j) = k
Data.Array Int Int
Many operations are going to be necessary on the matrices, updating a single element, querying for rows and columns etc. However, they will mainly act as containers, no linear algebra operations (inversion, det, etc) will be required.
Which one of the options would be the fastest one in general if the dimensionality of the matrices is going to be at around 20x20? When I understand correctly, every update (with (//) in the case of array) requires full copies, so going from 20x20=400 elements to 20*21/2 = 210 elements in the cases 2. or 3. would make a lot of sense, but access is slower for case 2. and 3. needs conversion at some point.
Are there any guidelines?
Btw: The 3rd option is not a really good one, as computing f^-1 requires square roots.
You could try using Data.Array using a specialized Ix class that only generates the upper half of the matrix:
newtype Symmetric = Symmetric { pair :: (Int, Int) } deriving (Ord, Eq)
instance Ix Symmetric where
range ((Symmetric (x1,y1)), (Symmetric (x2,y2))) =
map Symmetric [(x,y) | x <- range (x1,x2), y <- range (y1,y2), x >= y]
inRange (lo,hi) i = x <= hix && x >= lox && y <= hiy && y >= loy && x >= y
where
(lox,loy) = pair lo
(hix,hiy) = pair hi
(x,y) = pair i
index (lo,hi) i
| inRange (lo,hi) i = (x-loy)+(sum$take(y-loy)[hix-lox, hix-lox-1..])
| otherwise = error "Error in array index"
where
(lox,loy) = pair lo
(hix,hiy) = pair hi
(x,y) = pair i
sym x y
| x < y = Symmetric (y,x)
| otherwise = Symmetric (x,y)
*Main Data.Ix> let a = listArray (sym 0 0, sym 6 6) [0..]
*Main Data.Ix> a ! sym 3 2
14
*Main Data.Ix> a ! sym 2 3
14
*Main Data.Ix> a ! sym 2 2
13
*Main Data.Ix> length $ elems a
28
*Main Data.Ix> let b = listArray (sym 0 0, sym 19 19) [0..]
*Main Data.Ix> length $ elems b
210
There is a fourth option: use an array of decreasingly-large arrays. I would go with either option 1 (using a full array and just storing every element twice) or this last one. If you intend to be updating a lot of elements, I strongly recommend using a mutable array; IOArray and STArray are popular choices.
Unless this is for homework or something, you should also take a peek at Hackage. A quick look suggests the problem of manipulating matrices has been solved several times already.
I would like to manipulate matrices (full or sparse) efficiently with haskell's vector library.
Here is a matrix type
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector as V
data Link a = Full (V.Vector (U.Vector a))
| Sparse (V.Vector (U.Vector (Int,a)))
type Vector a = U.Vector a
As you can see, the matrix is a vector of unboxed vectors. Now, I would like to do a dot product between a vector and a matrix. It is fairly simple to do by combining a sum, zip and map.
But if I do that, because I'm mapping through the rows of the matrix, the result is a boxed vector, even though it could be unboxed.
propagateS output (Field src) (Full weights) = V.map (sum out) weights
where out = U.map output src
sum s w = U.sum $ zipWithFull (*) w s
propagateS output (Field src) (Sparse weights) = V.map (sum out) weights
where out = U.map output src
sum s w = U.sum $ zipWithSparse (*) w s
zipWithFull = U.zipWith
zipWithSparse f x y = U.map f' x
where f' (i,v) = f v (y U.! i)
How can I get an unboxed vector as a result efficiently ?
I don't know what your Field type is, so I don't quite understand the second snippet.
But if you represent your matrix as a boxed vector, your intermediate results will be boxed vectors. If you want to have an unboxed result, you need to convert types explicitly with U.fromList . V.toList. This an example for your dense matrix type (I omitted the sparse case for brevity):
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector as V
-- assuming row-major order
data Matrix a = Full (V.Vector (U.Vector a))
type Vector a = U.Vector a
-- matrix to vector dot product
dot :: (U.Unbox a, Num a) => (Matrix a) -> (Vector a) -> (Vector a)
(Full rows) `dot` x =
let mx = V.map (vdot x) rows
in U.fromList . V.toList $ mx -- unboxing, O(n)
-- vector to vector dot product
vdot :: (U.Unbox a, Num a) => Vector a -> Vector a -> a
vdot x y = U.sum $ U.zipWith (*) x y
instance (Show a, U.Unbox a) => Show (Matrix a) where
show (Full rows) = show $ V.toList $ V.map U.toList rows
showV = show . U.toList
main =
let m = Full $ V.fromList $ map U.fromList ([[1,2],[3,4]] :: [[Int]])
x = U.fromList ([5,6] :: [Int])
mx = m `dot` x
in putStrLn $ (show m) ++ " × " ++ (showV x) ++ " = " ++ (showV mx)
Output:
[[1,2],[3,4]] × [5,6] = [17,39]
I am not sure about performance of this approach. Probably it is much better to store the whole matrix as a single unboxed vector and access elements by index according to storage model. This way you don't need boxed vectors.
Take a look also at new repa library and its index operation.