Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
haskell-igraph
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-igraph
Commits
70af5ab8
Commit
70af5ab8
authored
May 10, 2018
by
Kai Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add PageRank test
parent
59904c7f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
82 additions
and
60 deletions
+82
-60
haskell-igraph.cabal
haskell-igraph.cabal
+0
-1
IGraph.hs
src/IGraph.hs
+0
-1
Generators.chs
src/IGraph/Generators.chs
+15
-0
Internal.chs
src/IGraph/Internal.chs
+13
-0
Constants.chs
src/IGraph/Internal/Constants.chs
+3
-0
Structure.chs
src/IGraph/Structure.chs
+40
-58
Structure.hs
tests/Test/Structure.hs
+11
-0
No files found.
haskell-igraph.cabal
View file @
70af5ab8
...
@@ -55,7 +55,6 @@ library
...
@@ -55,7 +55,6 @@ library
, bytestring >= 0.9
, bytestring >= 0.9
, bytestring-lexing >= 0.5
, bytestring-lexing >= 0.5
, cereal
, cereal
, cereal-conduit
, colour
, colour
, conduit >= 1.3.0
, conduit >= 1.3.0
, data-ordlist
, data-ordlist
...
...
src/IGraph.hs
View file @
70af5ab8
...
@@ -45,7 +45,6 @@ import Control.Arrow ((&&&))
...
@@ -45,7 +45,6 @@ import Control.Arrow ((&&&))
import
Control.Monad
(
forM
,
forM_
,
liftM
,
replicateM
,
when
)
import
Control.Monad
(
forM
,
forM_
,
liftM
,
replicateM
,
when
)
import
Control.Monad.Primitive
import
Control.Monad.Primitive
import
Control.Monad.ST
(
runST
)
import
Control.Monad.ST
(
runST
)
import
Data.Conduit.Cereal
import
Data.Either
(
fromRight
)
import
Data.Either
(
fromRight
)
import
Data.Hashable
(
Hashable
)
import
Data.Hashable
(
Hashable
)
import
qualified
Data.HashMap.Strict
as
M
import
qualified
Data.HashMap.Strict
as
M
...
...
src/IGraph/Generators.chs
View file @
70af5ab8
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ScopedTypeVariables #-}
module IGraph.Generators
module IGraph.Generators
( full
( full
, star
, ErdosRenyiModel(..)
, ErdosRenyiModel(..)
, erdosRenyiGame
, erdosRenyiGame
, degreeSequenceGame
, degreeSequenceGame
...
@@ -44,6 +45,20 @@ full n hasLoop = unsafePerformIO $ do
...
@@ -44,6 +45,20 @@ full n hasLoop = unsafePerformIO $ do
, `Int', `Bool', `Bool'
, `Int', `Bool', `Bool'
} -> `CInt' void- #}
} -> `CInt' void- #}
-- | Return the Star graph. The center node is always associated with id 0.
star :: Int -- ^ The number of nodes
-> Graph 'U () ()
star n = unsafePerformIO $ do
gr <- MGraph <$> igraphStar n IgraphStarUndirected 0
M.initializeNullAttribute gr
unsafeFreeze gr
{# fun igraph_star as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `Int'
, `StarMode'
, `Int'
} -> `CInt' void- #}
data ErdosRenyiModel = GNP Int Double
data ErdosRenyiModel = GNP Int Double
| GNM Int Int
| GNM Int Int
...
...
src/IGraph/Internal.chs
View file @
70af5ab8
...
@@ -55,6 +55,7 @@ module IGraph.Internal
...
@@ -55,6 +55,7 @@ module IGraph.Internal
, allocaIGraph
, allocaIGraph
, addIGraphFinalizer
, addIGraphFinalizer
, igraphNew
, igraphNew
, igraphCreate
-- * Selector and iterator for edge and vertex
-- * Selector and iterator for edge and vertex
-- ** Igraph vertex selector
-- ** Igraph vertex selector
...
@@ -370,6 +371,18 @@ addIGraphFinalizer ptr = do
...
@@ -370,6 +371,18 @@ addIGraphFinalizer ptr = do
, `IGraph'
, `IGraph'
} -> `CInt' void- #}
} -> `CInt' void- #}
{#fun igraph_create as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, castPtr `Ptr Vector' -- ^ The edges to add, the first two elements are
-- the first edge, etc.
, `Int' -- ^ The number of vertices in the graph, if smaller or equal to
-- the highest vertex id in the edges vector it will be
-- increased automatically. So it is safe to give 0 here.
, `Bool' -- ^ Whether to create a directed graph or not. If yes,
-- then the first edge points from the first vertex id in edges
-- to the second, etc.
} -> `CInt' void- #}
-- | Create a igraph object and attach a finalizer
-- | Create a igraph object and attach a finalizer
igraphNew :: Int -> Bool -> HasInit -> IO IGraph
igraphNew :: Int -> Bool -> HasInit -> IO IGraph
igraphNew n directed _ = igraphNew' n directed
igraphNew n directed _ = igraphNew' n directed
...
...
src/IGraph/Internal/Constants.chs
View file @
70af5ab8
...
@@ -30,5 +30,8 @@ module IGraph.Internal.Constants where
...
@@ -30,5 +30,8 @@ module IGraph.Internal.Constants where
{#enum igraph_rewiring_t as Rewiring {underscoreToCase}
{#enum igraph_rewiring_t as Rewiring {underscoreToCase}
deriving (Show, Read, Eq) #}
deriving (Show, Read, Eq) #}
{#enum igraph_star_mode_t as StarMode {underscoreToCase}
deriving (Show, Read, Eq) #}
{#enum igraph_degseq_t as Degseq {underscoreToCase}
{#enum igraph_degseq_t as Degseq {underscoreToCase}
deriving (Show, Read, Eq) #}
deriving (Show, Read, Eq) #}
src/IGraph/Structure.chs
View file @
70af5ab8
...
@@ -5,7 +5,6 @@ module IGraph.Structure
...
@@ -5,7 +5,6 @@ module IGraph.Structure
, betweenness
, betweenness
, eigenvectorCentrality
, eigenvectorCentrality
, pagerank
, pagerank
, personalizedPagerank
) where
) where
import Control.Monad
import Control.Monad
...
@@ -34,6 +33,12 @@ inducedSubgraph :: (Hashable v, Eq v, Serialize v)
...
@@ -34,6 +33,12 @@ inducedSubgraph :: (Hashable v, Eq v, Serialize v)
inducedSubgraph gr nds = unsafePerformIO $ withVerticesList nds $ \vs ->
inducedSubgraph gr nds = unsafePerformIO $ withVerticesList nds $ \vs ->
igraphInducedSubgraph (_graph gr) vs IgraphSubgraphCreateFromScratch >>=
igraphInducedSubgraph (_graph gr) vs IgraphSubgraphCreateFromScratch >>=
unsafeFreeze . MGraph
unsafeFreeze . MGraph
{#fun igraph_induced_subgraph as ^
{ `IGraph'
, allocaIGraph- `IGraph' addIGraphFinalizer*
, castPtr %`Ptr VertexSelector'
, `SubgraphImplementation'
} -> `CInt' void- #}
-- | Closeness centrality
-- | Closeness centrality
closeness :: [Int] -- ^ vertices
closeness :: [Int] -- ^ vertices
...
@@ -46,6 +51,14 @@ closeness nds gr ws mode normal = unsafePerformIO $ allocaVector $ \result ->
...
@@ -46,6 +51,14 @@ closeness nds gr ws mode normal = unsafePerformIO $ allocaVector $ \result ->
withVerticesList nds $ \vs -> withListMaybe ws $ \ws' -> do
withVerticesList nds $ \vs -> withListMaybe ws $ \ws' -> do
igraphCloseness (_graph gr) result vs mode ws' normal
igraphCloseness (_graph gr) result vs mode ws' normal
toList result
toList result
{#fun igraph_closeness as ^
{ `IGraph'
, castPtr `Ptr Vector'
, castPtr %`Ptr VertexSelector'
, `Neimode'
, castPtr `Ptr Vector'
, `Bool' } -> `CInt' void- #}
-- | Betweenness centrality
-- | Betweenness centrality
betweenness :: [Int]
betweenness :: [Int]
...
@@ -56,6 +69,13 @@ betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->
...
@@ -56,6 +69,13 @@ betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->
withVerticesList nds $ \vs -> withListMaybe ws $ \ws' -> do
withVerticesList nds $ \vs -> withListMaybe ws $ \ws' -> do
igraphBetweenness (_graph gr) result vs True ws' False
igraphBetweenness (_graph gr) result vs True ws' False
toList result
toList result
{#fun igraph_betweenness as ^
{ `IGraph'
, castPtr `Ptr Vector'
, castPtr %`Ptr VertexSelector'
, `Bool'
, castPtr `Ptr Vector'
, `Bool' } -> `CInt' void- #}
-- | Eigenvector centrality
-- | Eigenvector centrality
eigenvectorCentrality :: Graph d v e
eigenvectorCentrality :: Graph d v e
...
@@ -65,77 +85,39 @@ eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->
...
@@ -65,77 +85,39 @@ eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->
allocaVector $ \result -> withListMaybe ws $ \ws' -> do
allocaVector $ \result -> withListMaybe ws $ \ws' -> do
igraphEigenvectorCentrality (_graph gr) result nullPtr True True ws' arparck
igraphEigenvectorCentrality (_graph gr) result nullPtr True True ws' arparck
toList result
toList result
{#fun igraph_eigenvector_centrality as ^
{ `IGraph'
, castPtr `Ptr Vector'
, id `Ptr CDouble'
, `Bool'
, `Bool'
, castPtr `Ptr Vector'
, castPtr `Ptr ArpackOpt' } -> `CInt' void- #}
-- | Google's PageRank
-- | Google's PageRank
algorithm, with option to
pagerank :: SingI d
pagerank :: SingI d
=> Graph d v e
=> Graph d v e
-> Maybe [Double] -- ^ edge weights
-> Maybe [Double] -- ^ Node weights or reset probability. If provided,
-- the personalized PageRank will be used
-> Maybe [Double] -- ^ Edge weights
-> Double -- ^ damping factor, usually around 0.85
-> Double -- ^ damping factor, usually around 0.85
-> [Double]
-> [Double]
pagerank gr ws d
pagerank gr
reset
ws d
| n == 0 = []
| n == 0 = []
| isJust ws && length (fromJust ws) /= m = error "incorrect length of edge weight vector"
| isJust ws && length (fromJust ws) /= m = error "incorrect length of edge weight vector"
| otherwise = unsafePerformIO $ alloca $ \p -> allocaVector $ \result ->
| otherwise = unsafePerformIO $ alloca $ \p -> allocaVector $ \result ->
withVerticesAll $ \vs -> withListMaybe ws $ \ws' -> do
withVerticesAll $ \vs -> withListMaybe ws $ \ws' -> do
igraphPagerank (_graph gr) IgraphPagerankAlgoPrpack result p vs
case reset of
(isDirected gr) d ws' nullPtr
Nothing -> igraphPagerank (_graph gr) IgraphPagerankAlgoPrpack
result p vs (isDirected gr) d ws' nullPtr
Just reset' -> withList reset' $ \reset'' -> igraphPersonalizedPagerank
(_graph gr) IgraphPagerankAlgoPrpack result p vs
(isDirected gr) d reset'' ws' nullPtr
toList result
toList result
where
where
n = nNodes gr
n = nNodes gr
m = nEdges gr
m = nEdges gr
-- | Personalized PageRank.
personalizedPagerank :: SingI d
=> Graph d v e
-> [Double] -- ^ reset probability
-> Maybe [Double]
-> Double
-> [Double]
personalizedPagerank gr reset ws d
| n == 0 = []
| length reset /= n = error "incorrect length of reset vector"
| isJust ws && length (fromJust ws) /= m = error "incorrect length of edge weight vector"
| otherwise = unsafePerformIO $ alloca $ \p -> allocaVector $ \result ->
withList reset $ \reset' -> withVerticesAll $ \vs -> withListMaybe ws $ \ws' -> do
igraphPersonalizedPagerank (_graph gr) IgraphPagerankAlgoPrpack result p vs
(isDirected gr) d reset' ws' nullPtr
toList result
where
n = nNodes gr
m = nEdges gr
{#fun igraph_induced_subgraph as ^
{ `IGraph'
, allocaIGraph- `IGraph' addIGraphFinalizer*
, castPtr %`Ptr VertexSelector'
, `SubgraphImplementation'
} -> `CInt' void- #}
{#fun igraph_closeness as ^
{ `IGraph'
, castPtr `Ptr Vector'
, castPtr %`Ptr VertexSelector'
, `Neimode'
, castPtr `Ptr Vector'
, `Bool' } -> `CInt' void- #}
{#fun igraph_betweenness as ^
{ `IGraph'
, castPtr `Ptr Vector'
, castPtr %`Ptr VertexSelector'
, `Bool'
, castPtr `Ptr Vector'
, `Bool' } -> `CInt' void- #}
{#fun igraph_eigenvector_centrality as ^
{ `IGraph'
, castPtr `Ptr Vector'
, id `Ptr CDouble'
, `Bool'
, `Bool'
, castPtr `Ptr Vector'
, castPtr `Ptr ArpackOpt' } -> `CInt' void- #}
{#fun igraph_pagerank as ^
{#fun igraph_pagerank as ^
{ `IGraph'
{ `IGraph'
, `PagerankAlgo'
, `PagerankAlgo'
...
...
tests/Test/Structure.hs
View file @
70af5ab8
...
@@ -14,10 +14,12 @@ import Data.List
...
@@ -14,10 +14,12 @@ import Data.List
import
IGraph
import
IGraph
import
IGraph.Mutable
import
IGraph.Mutable
import
IGraph.Structure
import
IGraph.Structure
import
IGraph.Generators
tests
::
TestTree
tests
::
TestTree
tests
=
testGroup
"Structure property tests"
tests
=
testGroup
"Structure property tests"
[
subGraphs
[
subGraphs
,
pagerankTest
]
]
subGraphs
::
TestTree
subGraphs
::
TestTree
...
@@ -32,3 +34,12 @@ subGraphs = testGroup "generate induced subgraphs"
...
@@ -32,3 +34,12 @@ subGraphs = testGroup "generate induced subgraphs"
ns'
=
map
(
head
.
getNodes
gr
)
ns
ns'
=
map
(
head
.
getNodes
gr
)
ns
gr'
=
inducedSubgraph
gr
ns'
gr'
=
inducedSubgraph
gr
ns'
result
=
map
(
nodeLab
gr'
***
nodeLab
gr'
)
$
edges
gr'
result
=
map
(
nodeLab
gr'
***
nodeLab
gr'
)
$
edges
gr'
pagerankTest
::
TestTree
pagerankTest
=
testGroup
"PageRank"
[
testCase
"case 1"
$
ranks
@=?
ranks'
]
where
gr
=
star
11
ranks
=
[
0.47
,
0.05
,
0.05
,
0.05
,
0.05
,
0.05
,
0.05
,
0.05
,
0.05
,
0.05
,
0.05
]
ranks'
=
map
((
/
100
)
.
fromIntegral
.
round
.
(
*
100
))
$
pagerank
gr
Nothing
Nothing
0.85
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment