haskell-igraph 0.7.0 → 0.7.1
raw patch · 6 files changed
+88/−33 lines, 6 files
Files
- ChangeLog.md +4/−0
- haskell-igraph.cabal +1/−1
- src/IGraph/Algorithms/Centrality.chs +36/−22
- src/IGraph/Algorithms/Generators.chs +24/−2
- src/IGraph/Algorithms/Structure.chs +22/−7
- tests/Test/Algorithms.hs +1/−1
ChangeLog.md view
@@ -1,6 +1,10 @@ Revision history for haskell-igraph =================================== +v0.7.1 -- 2018-XX-XX++* Add a few more functions.+ v0.7.0 -- 2018-05-23 --------------------
haskell-igraph.cabal view
@@ -1,5 +1,5 @@ name: haskell-igraph-version: 0.7.0+version: 0.7.1 synopsis: Haskell interface of the igraph library. description: igraph<"http://igraph.org/c/"> is a library for creating and manipulating large graphs. This package provides the Haskell
src/IGraph/Algorithms/Centrality.chs view
@@ -24,15 +24,20 @@ -- | The normalized closeness centrality of a node is the average length of the -- shortest path between the node and all other nodes in the graph.-closeness :: [Int] -- ^ vertices+closeness :: Serialize e+ => [Int] -- ^ vertices -> Graph d v e- -> Maybe [Double] -- ^ optional edge weights -> Bool -- ^ whether to normalize the results+ -> Maybe (e -> Double) -- ^ Function to get edge weights -> [Double]-closeness nds gr ws normal = unsafePerformIO $ allocaVector $ \result ->+closeness nds gr normal getEdgeW = unsafePerformIO $ allocaVector $ \result -> withVerticesList nds $ \vs -> withListMaybe ws $ \ws' -> do igraphCloseness (_graph gr) result vs IgraphOut ws' normal toList result+ where+ ws = case getEdgeW of+ Nothing -> Nothing+ Just f -> Just $ map (f . snd) $ labEdges gr {#fun igraph_closeness as ^ { `IGraph' , castPtr `Ptr Vector'@@ -43,14 +48,19 @@ -- | Betweenness centrality-betweenness :: [Int]+betweenness :: Serialize e+ => [Int] -> Graph d v e- -> Maybe [Double]+ -> Maybe (e -> Double) -- ^ Function to get edge weights -> [Double]-betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->+betweenness nds gr getEdgeW = unsafePerformIO $ allocaVector $ \result -> withVerticesList nds $ \vs -> withListMaybe ws $ \ws' -> do igraphBetweenness (_graph gr) result vs True ws' False toList result+ where+ ws = case getEdgeW of+ Nothing -> Nothing+ Just f -> Just $ map (f . snd) $ labEdges gr {#fun igraph_betweenness as ^ { `IGraph' , castPtr `Ptr Vector'@@ -60,13 +70,18 @@ , `Bool' } -> `CInt' void- #} -- | Eigenvector centrality-eigenvectorCentrality :: Graph d v e- -> Maybe [Double]+eigenvectorCentrality :: Serialize e+ => Graph d v e+ -> Maybe (e -> Double) -- ^ Function to get edge weights -> [Double]-eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->+eigenvectorCentrality gr getEdgeW = unsafePerformIO $ allocaArpackOpt $ \arparck -> allocaVector $ \result -> withListMaybe ws $ \ws' -> do igraphEigenvectorCentrality (_graph gr) result nullPtr True True ws' arparck toList result+ where+ ws = case getEdgeW of+ Nothing -> Nothing+ Just f -> Just $ map (f . snd) $ labEdges gr {#fun igraph_eigenvector_centrality as ^ { `IGraph' , castPtr `Ptr Vector'@@ -77,18 +92,15 @@ , castPtr `Ptr ArpackOpt' } -> `CInt' void- #} -- | Google's PageRank algorithm, with option to-pagerank :: SingI d+pagerank :: (SingI d, Serialize v, Serialize e) => Graph d v e- -> 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+ -> Maybe (v -> Double) -- ^ Node weights or reset probability. If provided,+ -- the personalized PageRank will be used+ -> Maybe (e -> Double) -- ^ Edge weights -> [Double]-pagerank gr reset ws d- | n == 0 = []- | isJust ws && length (fromJust ws) /= m = error "incorrect length of edge weight vector"- | isJust reset && length (fromJust reset) /= n = error- "incorrect length of node weight vector"+pagerank gr d getNodeW getEdgeW+ | nNodes gr == 0 = [] | fmap (foldl' (+) 0) reset == Just 0 = error "sum of node weight vector must be non-zero" | otherwise = unsafePerformIO $ alloca $ \p -> allocaVector $ \result -> withVerticesAll $ \vs -> withListMaybe ws $ \ws' -> do@@ -100,9 +112,12 @@ (isDirected gr) d reset'' ws' nullPtr toList result where- n = nNodes gr- m = nEdges gr-+ reset = case getNodeW of+ Nothing -> Nothing+ Just f -> Just $ map (f . snd) $ labNodes gr+ ws = case getEdgeW of+ Nothing -> Nothing+ Just f -> Just $ map (f . snd) $ labEdges gr {#fun igraph_pagerank as ^ { `IGraph' , `PagerankAlgo'@@ -114,7 +129,6 @@ , castPtr `Ptr Vector' , id `Ptr ()' } -> `CInt' void- #}- {#fun igraph_personalized_pagerank as ^ { `IGraph' , `PagerankAlgo'
src/IGraph/Algorithms/Generators.chs view
@@ -8,6 +8,7 @@ , ErdosRenyiModel(..) , erdosRenyiGame , degreeSequenceGame+ , rewireEdges , rewire ) where @@ -15,6 +16,7 @@ import Data.Singletons (SingI, Sing, sing, fromSing) import System.IO.Unsafe (unsafePerformIO) import qualified Data.Map.Strict as M+import Control.Monad.Primitive (RealWorld) import qualified Foreign.Ptr as C2HSImp import Foreign@@ -75,8 +77,11 @@ , `Bool' } -> `CInt' void- #} -data ErdosRenyiModel = GNP Int Double- | GNM Int Int+data ErdosRenyiModel = GNP Int Double -- ^ G(n,p) graph, every possible edge is+ -- included in the graph with probability p.+ | GNM Int Int -- ^ G(n,m) graph, m edges are selected+ -- uniformly randomly in a graph with n+ -- vertices. erdosRenyiGame :: forall d. SingI d => ErdosRenyiModel@@ -115,6 +120,22 @@ , castPtr `Ptr Vector', castPtr `Ptr Vector', `Degseq' } -> `CInt' void- #} ++-- | Rewire the edges of a graph with constant probability.+rewireEdges :: MGraph RealWorld d v e+ -> Double -- ^ The rewiring probability a constant between zero and+ -- one (inclusive).+ -> Bool -- ^ whether loop edges are allowed in the new graph, or not.+ -> Bool -- ^ whether multiple edges are allowed in the new graph.+ -> IO ()+rewireEdges gr p loop multi = igraphRewireEdges (_mgraph gr) p loop multi+{#fun igraph_rewire_edges as ^ + { `IGraph'+ , `Double'+ , `Bool'+ , `Bool'+ } -> `CInt' void- #}+ -- | Randomly rewires a graph while preserving the degree distribution. rewire :: (Serialize v, Ord v, Serialize e) => Int -- ^ Number of rewiring trials to perform.@@ -125,3 +146,4 @@ igraphRewire (_mgraph gr') n IgraphRewiringSimple unsafeFreeze gr' {#fun igraph_rewire as ^ { `IGraph', `Int', `Rewiring' } -> `CInt' void-#}+
src/IGraph/Algorithms/Structure.chs view
@@ -2,7 +2,7 @@ {-# LANGUAGE DataKinds #-} module IGraph.Algorithms.Structure ( -- * Shortest Path Related Functions- getShortestPath+ shortestPath , inducedSubgraph , isConnected , isStronglyConnected@@ -40,12 +40,18 @@ -- Calculates and returns a single unweighted shortest path from a given vertex -- to another one. If there are more than one shortest paths between the two -- vertices, then an arbitrary one is returned.-getShortestPath :: Graph d v e- -> Node -- ^ The id of the source vertex.- -> Node -- ^ The id of the target vertex.- -> [Node]-getShortestPath gr s t = unsafePerformIO $ allocaVector $ \path -> do- igraphGetShortestPath (_graph gr) path nullPtr s t IgraphOut+shortestPath :: Serialize e+ => Graph d v e+ -> Node -- ^ The id of the source vertex.+ -> Node -- ^ The id of the target vertex.+ -> Maybe (e -> Double) -- ^ A function to retrieve edge weights. If provied,+ -- the Dijkstra's algorithm will be used.+ -> [Node]+shortestPath gr s t getEdgeW = unsafePerformIO $ allocaVector $ \path -> do+ case getEdgeW of+ Nothing -> igraphGetShortestPath (_graph gr) path nullPtr s t IgraphOut+ Just f -> withList (map (f . snd) $ labEdges gr) $ \ws ->+ igraphGetShortestPathDijkstra (_graph gr) path nullPtr s t ws IgraphOut map truncate <$> toList path {#fun igraph_get_shortest_path as ^ { `IGraph'@@ -53,6 +59,15 @@ , castPtr `Ptr Vector' , `Int' , `Int'+ , `Neimode'+ } -> `CInt' void- #}+{#fun igraph_get_shortest_path_dijkstra as ^+ { `IGraph'+ , castPtr `Ptr Vector'+ , castPtr `Ptr Vector'+ , `Int'+ , `Int'+ , castPtr `Ptr Vector' , `Neimode' } -> `CInt' void- #}
tests/Test/Algorithms.hs view
@@ -93,4 +93,4 @@ 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+ pagerank gr 0.85 Nothing Nothing