packages feed

haskell-igraph 0.7.0 → 0.7.1

raw patch · 6 files changed

+88/−33 lines, 6 files

Files

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