{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module Math.Graph.Types where
import Data.List (sort)
import qualified Data.Eigen.SparseMatrix as E
import qualified Data.Map.Strict as Map
import qualified Data.Graph.Inductive as G
import qualified Data.Sparse.Common as S
import qualified Data.Vector.Unboxed as V
import qualified Math.Clustering.Spectral.Dense as D
import qualified Numeric.LinearAlgebra as H
import qualified Numeric.LinearAlgebra.Sparse as S
import qualified Math.Clustering.Spectral.Dense as D
import qualified Math.Clustering.Spectral.Eigen.AdjacencyMatrix as E
import qualified Math.Clustering.Spectral.Sparse as S
orderedEdges :: G.Gr Int a -> [(Int, Int, a)]
orderedEdges gr =
fmap (\(!i, !j, !v) -> (getUpdate i, getUpdate j, v)) . G.labEdges $ gr
where
nodeMap = Map.fromList . flip zip [0..] . sort . G.nodes $ gr
getUpdate = flip ( Map.findWithDefault
(error "Unexpected missing node in orderedEdges.")
)
nodeMap
class Graphable a where
toGraph :: a -> G.Gr Int Double
fromGraph :: G.Gr Int Double -> a
instance Graphable D.AdjacencyMatrix where
toGraph mat = G.mkGraph (zip [0 .. H.rows mat - 1] [0 .. H.rows mat - 1])
. filter (\(_, _, x) -> x /= 0)
. concatMap (\(!i, !xs) -> fmap (\(!j, !v) -> (i, j, v)) xs)
. zip [0..]
. fmap (zip [0..] . H.toList)
. H.toRows
$ mat
fromGraph gr = H.assoc (G.noNodes gr, G.noNodes gr) 0
. fmap (\(!i, !j, !v) -> ((i, j), v))
. orderedEdges
$ gr
instance Graphable S.AdjacencyMatrix where
toGraph mat = G.mkGraph (zip [0 .. S.nrows mat - 1] [0 .. S.nrows mat - 1])
. filter (\(_, _, x) -> x /= 0)
. S.toListSM
$ mat
fromGraph gr = S.fromListSM (G.noNodes gr, G.noNodes gr) . orderedEdges $ gr
instance Graphable E.AdjacencyMatrix where
toGraph mat = G.mkGraph (zip [0 .. E.rows mat - 1] [0 .. E.rows mat - 1])
. filter (\(_, _, x) -> x /= 0)
. E.toList
$ mat
fromGraph gr = E.fromList (G.noNodes gr) (G.noNodes gr) . orderedEdges $ gr