haskell-igraph-0.1.0: src/IGraph/Structure.hs
module IGraph.Structure
( inducedSubgraph
, closeness
, betweenness
, eigenvectorCentrality
, pagerank
, personalizedPagerank
) where
import Control.Monad
import Foreign
import Foreign.C.Types
import System.IO.Unsafe (unsafePerformIO)
import qualified Data.HashMap.Strict as M
import Data.Hashable (Hashable)
import IGraph
import IGraph.Mutable
import IGraph.Internal.Graph
import IGraph.Internal.Data
import IGraph.Internal.Selector
import IGraph.Internal.Structure
import IGraph.Internal.Arpack
import IGraph.Internal.Constants
import IGraph.Internal.Attribute
inducedSubgraph :: (Hashable v, Eq v, Read v) => LGraph d v e -> [Int] -> LGraph d v e
inducedSubgraph gr vs = unsafePerformIO $ do
vs' <- listToVector $ map fromIntegral vs
vsptr <- igraphVsVector vs'
mallocForeignPtrBytes 160 >>= \gptr -> withForeignPtr gptr $ \p -> do
igraphInducedSubgraph (_graph gr) p vsptr IgraphSubgraphCreateFromScratch
let g' = IGraphPtr gptr
labToId = M.fromListWith (++) $ zip labels $ map return [0..nV-1]
nV = igraphVcount g'
labels = map (read . igraphCattributeVAS g' vertexAttr) [0 .. nV-1]
return $ LGraph g' labToId
-- | closeness centrality
closeness :: [Int] -- ^ vertices
-> LGraph d v e
-> Maybe [Double] -- ^ optional edge weights
-> Neimode
-> Bool -- ^ whether to normalize
-> [Double]
closeness vs gr ws mode normal = unsafePerformIO $ do
vs' <- listToVector $ map fromIntegral vs
vsptr <- igraphVsVector vs'
vptr <- igraphVectorNew 0
ws' <- case ws of
Just w -> listToVector w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr
igraphCloseness (_graph gr) vptr vsptr mode ws' normal
vectorPtrToList vptr
-- | betweenness centrality
betweenness :: [Int]
-> LGraph d v e
-> Maybe [Double]
-> [Double]
betweenness vs gr ws = unsafePerformIO $ do
vs' <- listToVector $ map fromIntegral vs
vsptr <- igraphVsVector vs'
vptr <- igraphVectorNew 0
ws' <- case ws of
Just w -> listToVector w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr
igraphBetweenness (_graph gr) vptr vsptr True ws' False
vectorPtrToList vptr
-- | eigenvector centrality
eigenvectorCentrality :: LGraph d v e
-> Maybe [Double]
-> [Double]
eigenvectorCentrality gr ws = unsafePerformIO $ do
vptr <- igraphVectorNew 0
ws' <- case ws of
Just w -> listToVector w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr
arparck <- igraphArpackNew
igraphEigenvectorCentrality (_graph gr) vptr nullPtr True True ws' arparck
vectorPtrToList vptr
-- | Google's PageRank
pagerank :: Graph d
=> LGraph d v e
-> Maybe [Double] -- ^ edge weights
-> Double -- ^ damping factor, usually around 0.85
-> [Double]
pagerank gr ws d = unsafePerformIO $ alloca $ \p -> do
vptr <- igraphVectorNew 0
vsptr <- igraphVsAll
ws' <- case ws of
Just w -> listToVector w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr
igraphPagerank (_graph gr) IgraphPagerankAlgoPrpack vptr p vsptr
(isDirected gr) d ws' nullPtr
vectorPtrToList vptr
personalizedPagerank :: Graph d
=> LGraph d v e
-> [Double] -- ^ reset probability
-> Maybe [Double]
-> Double
-> [Double]
personalizedPagerank gr reset ws d = unsafePerformIO $ alloca $ \p -> do
vptr <- igraphVectorNew 0
vsptr <- igraphVsAll
ws' <- case ws of
Just w -> listToVector w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr
reset' <- listToVector reset
igraphPersonalizedPagerank (_graph gr) IgraphPagerankAlgoPrpack vptr p vsptr
(isDirected gr) d reset' ws' nullPtr
vectorPtrToList vptr