module Math.LinearAlgebra.Sparse.Algorithms.Diagonal
(
isDiag, toDiag
)
where
import Data.Monoid
import Data.IntMap as M hiding ((!))
import Math.LinearAlgebra.Sparse.Matrix
import Math.LinearAlgebra.Sparse.Vector
import Math.LinearAlgebra.Sparse.Algorithms.Staircase
isDiag :: SparseMatrix α -> Bool
isDiag m = M.foldlWithKey' (\true i row -> true && (keys row == [i])) True (mx m)
toDiag :: Integral α => SparseMatrix α -> (SparseMatrix α, SparseMatrix α, SparseMatrix α)
toDiag m = toDiag' m (idMx (height m))
(idMx (width m))
toDiag' m t u | isZeroMx m = (m,t,u)
| height m /= height t = error "height(mM) /= height(mT)"
| width m /= width u = error "width(mM) /= width(mU)"
| otherwise =
let (s,t') = staircase' m t
in dm True s t' u
dm even s t u = case (even, isDiag s, trans s) of
(True , True , _ ) -> (s , t, u)
(False, True , s') -> (s', t, u)
(True , False, s') -> dm False s'' t u' where (s'',u') = staircase' s' u
(False, False, s') -> dm True s'' t' u where (s'',t') = staircase' s' t