Commit 37f94a27 authored by Kai Zhang's avatar Kai Zhang

add decompose

parent bdaeae38
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
module IGraph.Algorithms.Generators module IGraph.Algorithms.Generators
( full ( full
, star , star
, ring
, ErdosRenyiModel(..) , ErdosRenyiModel(..)
, erdosRenyiGame , erdosRenyiGame
, degreeSequenceGame , degreeSequenceGame
...@@ -54,13 +55,28 @@ star n = unsafePerformIO $ do ...@@ -54,13 +55,28 @@ star n = unsafePerformIO $ do
gr <- MGraph <$> igraphStar n IgraphStarUndirected 0 gr <- MGraph <$> igraphStar n IgraphStarUndirected 0
M.initializeNullAttribute gr M.initializeNullAttribute gr
unsafeFreeze gr unsafeFreeze gr
{# fun igraph_star as ^ {#fun igraph_star as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer* { allocaIGraph- `IGraph' addIGraphFinalizer*
, `Int' , `Int'
, `StarMode' , `StarMode'
, `Int' , `Int'
} -> `CInt' void- #} } -> `CInt' void- #}
-- | Creates a ring graph, a one dimensional lattice.
ring :: Int -> Graph 'U () ()
ring n = unsafePerformIO $ do
igraphInit
gr <- MGraph <$> igraphRing n False False True
M.initializeNullAttribute gr
unsafeFreeze gr
{#fun igraph_ring as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `Int'
, `Bool'
, `Bool'
, `Bool'
} -> `CInt' void- #}
data ErdosRenyiModel = GNP Int Double data ErdosRenyiModel = GNP Int Double
| GNM Int Int | GNM Int Int
......
...@@ -3,6 +3,7 @@ module IGraph.Algorithms.Structure ...@@ -3,6 +3,7 @@ module IGraph.Algorithms.Structure
( -- * Shortest Path Related Functions ( -- * Shortest Path Related Functions
getShortestPath getShortestPath
, inducedSubgraph , inducedSubgraph
, decompose
, closeness , closeness
, betweenness , betweenness
, eigenvectorCentrality , eigenvectorCentrality
...@@ -70,6 +71,25 @@ inducedSubgraph gr nds = unsafePerformIO $ withVerticesList nds $ \vs -> ...@@ -70,6 +71,25 @@ inducedSubgraph gr nds = unsafePerformIO $ withVerticesList nds $ \vs ->
, `SubgraphImplementation' , `SubgraphImplementation'
} -> `CInt' void- #} } -> `CInt' void- #}
-- | Decompose a graph into connected components.
decompose :: (Hashable v, Eq v, Serialize v)
=> Graph d v e -> [Graph d v e]
decompose gr = unsafePerformIO $ allocaVectorPtr $ \ptr -> do
igraphDecompose (_graph gr) ptr IgraphWeak (-1) 1
n <- igraphVectorPtrSize ptr
forM [0..n-1] $ \i -> do
p <- igraphVectorPtrE ptr i
addIGraphFinalizer (castPtr p) >>= unsafeFreeze . MGraph
{-# INLINE decompose #-}
{#fun igraph_decompose as ^
{ `IGraph'
, castPtr `Ptr VectorPtr'
, `Connectedness'
, `Int'
, `Int'
} -> `CInt' void- #}
-- | Closeness centrality -- | Closeness centrality
closeness :: [Int] -- ^ vertices closeness :: [Int] -- ^ vertices
-> Graph d v e -> Graph d v e
......
...@@ -22,6 +22,9 @@ module IGraph.Internal ...@@ -22,6 +22,9 @@ module IGraph.Internal
, allocaVectorPtrN , allocaVectorPtrN
, withPtrs , withPtrs
, toLists , toLists
, igraphVectorPtrSize
, igraphVectorPtrE
, igraphVectorPtrSet
-- ** Customized bytestring for storing attributes -- ** Customized bytestring for storing attributes
, BSLen , BSLen
......
...@@ -24,6 +24,9 @@ module IGraph.Internal.Constants where ...@@ -24,6 +24,9 @@ module IGraph.Internal.Constants where
{#enum igraph_subgraph_implementation_t as SubgraphImplementation {underscoreToCase} {#enum igraph_subgraph_implementation_t as SubgraphImplementation {underscoreToCase}
deriving (Show, Read, Eq) #} deriving (Show, Read, Eq) #}
{#enum igraph_connectedness_t as Connectedness {underscoreToCase}
deriving (Eq) #}
{#enum igraph_pagerank_algo_t as PagerankAlgo {underscoreToCase} {#enum igraph_pagerank_algo_t as PagerankAlgo {underscoreToCase}
deriving (Show, Read, Eq) #} deriving (Show, Read, Eq) #}
......
...@@ -20,6 +20,7 @@ tests = testGroup "Algorithms" ...@@ -20,6 +20,7 @@ tests = testGroup "Algorithms"
, motifTest , motifTest
, cliqueTest , cliqueTest
, subGraphs , subGraphs
, decomposeTest
, pagerankTest , pagerankTest
] ]
...@@ -66,6 +67,25 @@ subGraphs = testGroup "generate induced subgraphs" ...@@ -66,6 +67,25 @@ subGraphs = testGroup "generate induced subgraphs"
gr' = inducedSubgraph gr ns' gr' = inducedSubgraph gr ns'
result = map (nodeLab gr' *** nodeLab gr') $ edges gr' result = map (nodeLab gr' *** nodeLab gr') $ edges gr'
decomposeTest :: TestTree
decomposeTest = testGroup "Decompose"
[ testCase "ring" $ edges (head $ decompose $ ring 10) @?=
[(0,1), (1,2), (2,3), (3,4), (4,5), (5,6), (6,7), (7,8), (8,9), (0,9)]
, testCase "1 component" $ do
gr <- erdosRenyiGame (GNP 100 (40/100)) False :: IO (Graph 'U () ())
1 @?= length (decompose gr)
, testCase "toy example" $ map (sort . edges) (decompose gr) @?=
[ [(0,1), (0,2), (1,2)]
, [(0,1), (1,2), (2,3)]
, []
, [(0,1), (1,2)] ]
]
where
es = [ (0,1), (1,2), (2,0)
, (3,4), (4,5), (5,6)
, (8,9), (9,10) ]
gr = mkGraph (replicate 11 ()) $ zip es $ repeat () :: Graph 'U () ()
pagerankTest :: TestTree pagerankTest :: TestTree
pagerankTest = testGroup "PageRank" pagerankTest = testGroup "PageRank"
[ testCase "case 1" $ ranks @=? ranks' ] [ testCase "case 1" $ ranks @=? ranks' ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment