Reputation: 3358
I am struggling to translate this piece of a matrix multiplication in F# into Haskell (pls forget the parallel component):
Parallel.For(0, rowsA, (fun i->
for j = 0 to colsB - 1 do
for k = 0 to colsA - 1 do
result.[i,j] <- result.[i,j] + a.[i,k] * b.[k,j]))
|> ignore
All I managed to put together is
sum (map (\(i, j, k) -> (my.read (a,i,k)) * (my.read (b, k, j))) [ (i, j, k) | i <- [0..rowsA], j <- [0..colsB], k <- [0..colsA] ])
--my.read reads the values of the respective cells from 'my' database
The intention is to read the cells of matrix a and matrix b from my database and do a matrix multiplication that eventually can be carried out in portions by different agents. This is controlled by setting the boundaries for i , j and k but is not relevant here.
I have tried to translate the above F# sample into haskell. The issue I am struggling with is that the result is not the sum over everything but there should be a list of results at the position i, j(F# result.[i,j] - the cell is the result matrix). I do not see how I could emit the right result (i,j). Maybe I must further take this apart?
Upvotes: 2
Views: 466
Reputation: 1622
Try to divide
a :: [(a,a,a)]
a = [ (i, j, k) | i <- [0..rowsA], j <- [0..colsB], k <- [0..colsA] ]
into
b :: [[(a,a,a)]]
b = [ [ (i, j, k) | k <- [0..colsA]] | i <- [0..rowsA], j <- [0..colsB] ]
And you have a list of "lines" - matrix
And the list of sum is
m = [ [ (i, j, k) | k <- [0..colsA]] | i <- [0..rowsA], j <- [0..colsB] ]
listSum = map sum $ map (map (\(i,j,k) -> my_read (a,i,k) * my_read(b,k,j))) m
Upvotes: 3
Reputation: 54058
What exactly is the original code doing? Also, what is the type signature of my.read
? I assume it would have a signature similar to Num b => (a, Int, Int) -> IO b
, in which case this code will not even compile. If my . read
is in the IO monad, then you could write it as:
myfunc = do
let indices = [(i, j, k) | i <- [0..rowsA],
j <- [0..colsB],
k <- [0..colsA]]
-- Since `my . read` returns a value in the IO monad,
-- we can't just multiply the values returned.
r1 <- mapM (\(i, j, k) -> (my . read) (a, i, k)) indices
r2 <- mapM (\(i, j, k) -> (my . read) (b, k, j)) indices
-- We can multiply r1 and r2 together though,
-- since they are values extracted from the IO monad
return $ sum $ zipWith (*) r1 r2
The best advice I can give you right now is to use ghci to figure out your types.
Upvotes: 3