我正在努力将F#中的矩阵乘法转换为Haskell(请忘记并行组件):
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
我设法整理的是
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
目的是从我的数据库中读取矩阵a和矩阵b的单元格,并进行矩阵乘法,最终可以由不同的代理分批执行。这是通过设置i,j和k的边界来控制的,但这里不相关。
我试图将上面的F#样本翻译成haskell。我正在努力解决的问题是结果不是所有内容的总和,但是在位置i,j处应该有一个结果列表(F#result。[i,j] - 单元格是结果矩阵)。我不知道如何发出正确的结果(i,j)。也许我必须进一步区分它?
答案 0 :(得分:3)
原始代码究竟在做什么?另外,my.read
的类型签名是什么?我假设它会有一个类似于Num b => (a, Int, Int) -> IO b
的签名,在这种情况下,这段代码甚至不会编译。如果{mon}中有my . read
,那么您可以将其写为:
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
我现在可以给你的最好建议是使用ghci来计算你的类型。
答案 1 :(得分:3)
尝试划分
a :: [(a,a,a)]
a = [ (i, j, k) | i <- [0..rowsA], j <- [0..colsB], k <- [0..colsA] ]
到
b :: [[(a,a,a)]]
b = [ [ (i, j, k) | k <- [0..colsA]] | i <- [0..rowsA], j <- [0..colsB] ]
你有一个“行”列表 - 矩阵
总和列表是
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