我正在Haskell中实现Smith-Waterman算法,但是遇到了一个运行时错误:
作为概念验证,我在ghci中尝试了以下内容:
<<loop>>
在我的实现中,我尝试利用Haskell的懒惰性质,因此我使用一个不可变数组resarray
来存储惰性和递归桩,这些桩也引用了数组本身(在依赖链中resarray
依赖于zippedList
,后者又依赖于cellDef
,后者再依赖于cell
,最终依赖于resarray
)。每个单元格都引用具有较小索引的单元格,因此计算应该是可行的...尽管它并没有表现出这种方式。作为概念验证,我在ghci中尝试了以下内容:
let arr = listArray (0,3) [0, arr ! 0, arr ! 1, arr ! 2 ]
它起作用了。然而,我的长时间计算由于某种未知的原因变得严格。
这是我的代码(完整版本和测试脚本在这里):
buildSWArray::
WordSequence ->
WordSequence ->
SWMatrix
buildSWArray ws1 ws2 = let
rows = arrLen ws1
cols = arrLen ws2
im = matToLinearIndex rows cols
mi = linToMatIndex rows cols
totsize = rows * cols
ixarr = [0 .. (totsize-1)]
cell i j
| i < 0 || j < 0 = 0
cell i j =
resarr ! (im i j )
cellDef k | k == 0 = (None,0)
cellDef k =
let
(i,j) = mi k
upwards = cell (i-1) j
leftwards = cell i (j-1)
diag = cell (i-1) (j-1)
-- One up if match, -5 if not match
c = if ws1 ! i == ws2 ! j then 1 else (-5)
hi = maximum [ 0, diag + c, upwards - 3, leftwards - 3]
in
-- Dirty way of guessing which one was picked up
case hi of
hi | hi == 0 -> ( None, 0)
hi | hi == upwards - 3 -> ( Upwards, hi)
hi | hi == leftwards - 3 -> ( Leftwards, hi )
hi | hi == diag + c -> (Diag, hi )
zippedList = [ cellDef k | k <- ixarr ]
resarr = IA.listArray (0,(totsize - 1)) [ score | (way,score) <- zippedList ]
wayarr = IA.listArray (0,(totsize - 1)) [ way | (way,score) <- zippedList ]
in
SWMatrix rows cols wayarr resarr
我该如何修复它?