sto implementando Smith-Waterman algoritmo in Haskell, ma sto ottenendo un errore di runtime: <<loop>>
Gli array Haskell sono troppo rigidi?
Nella mia applicazione, sto cercando di usare la natura pigra di Haskell, quindi utilizzare un array immutabili resarray
per memorizzare stub pigri e ricorsivi che fanno riferimento anche alla matrice stessa (in una catena di dipendenze resarray
dipende da zippedList
che dipende da cellDef
che dipende da cell
che dipende da resarray
). Ogni cella si riferisce a una cella con indici minori, quindi il calcolo dovrebbe essere fattibile ... anche se non si comporta in questo modo.
Come una prova di concetto, ho provato quanto segue in ghci:
let arr = listArray (0,3) [0, arr ! 0, arr ! 1, arr ! 2 ]
e ha funzionato. Tuttavia il mio calcolo più lungo finisce per essere rigido per qualche motivo sconosciuto.
Ecco il mio codice (la versione completa, insieme a uno script di test, è here):
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
Come posso risolvere il problema?
la mia ipotesi è che non sei riuscito a "legare il nodo" correttamente. Controlla i casi di base e verifica che i tuoi argomenti ricorsivi stiano diminuendo. – cdk