数か月前に開始した Haskell プロジェクトを掘り下げることにしました。疎行列ライブラリの始まりです。このコードについて、中規模の行列 (2500 x 2500 の double) に対してメモリ不足の例外をスローする原因となる明らかな何かを誰かが見ることができますか? 通常、完全なビルド可能なコードを投稿するのが最善であることを理解しています。必要に応じてさらに投稿できます。以下のコードは、ボックス化されていないベクトルを使用して SparseMatrix 型 ( IntMap (IntMap Double) ) をより効率的な SkyLine 表現に変換します。これは、小さな行列の場合にうまく機能します。foldl と foldr の使い方が関係しているのではないかと思い、切り替えてみましたが違いはないようでした。これは「スペースリーク」ですか?ありがとう。
編集:これをもう少し調べた後、問題はVector Appendだと思います。これは毎回新しいベクターを作成する必要があります。問題を解決して回答を投稿すれば、信用を取り戻すことができるかもしれません。
import Math.LinearAlgebra.Sparse hiding (mulMV,dot)
import qualified Data.IntMap as IM
import qualified Data.Vector.Unboxed as V
type IdxM = (Int,Int)
data SKYSpM = SKYSpM {val :: V.Vector Double
,rcIdx :: V.Vector (Int, Int)
,dims :: IdxM
}deriving(Show)
skySpM :: Int -> SKYSpM
skySpM i = SKYSpM (V.empty::V.Vector Double) (V.empty::V.Vector (Int,Int)) (i,i)
toSKY :: SparseMatrix Double -> SKYSpM
toSKY m = SKYSpM v' (V.snoc idxs' $ V.last idxs') d'
where (SKYSpM v' idxs' d') = foldl f (skySpM $ height m) [1..(height m)]
f (SKYSpM v idxs d) i = SKYSpM (v V.++ v') (V.snoc idxs (V.length v,jmin-1)) d
where v' = foldl (\acc x -> V.snoc acc (r ! x)) V.empty [jmin..jmax]
(jmin,_) = (IM.findMin $ vec r)
(jmax,_) = (IM.findMax $ vec r)
r = row m i