haskell-igraph-0.5.0: src/IGraph/Generators.chs
{-# LANGUAGE ForeignFunctionInterface #-}
module IGraph.Generators
( full
, ErdosRenyiModel(..)
, erdosRenyiGame
, degreeSequenceGame
, rewire
) where
import Control.Monad (when)
import Data.Hashable (Hashable)
import Data.Serialize (Serialize)
import qualified Foreign.Ptr as C2HSImp
import IGraph
import IGraph.Mutable
{#import IGraph.Internal #}
{#import IGraph.Internal.Constants #}
{# import IGraph.Internal.Initialization #}
#include "haskell_igraph.h"
{#fun igraph_full as full
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `Int', `Bool', `Bool'
} -> `CInt' void- #}
data ErdosRenyiModel = GNP Int Double
| GNM Int Int
erdosRenyiGame :: Graph d
=> ErdosRenyiModel
-> d -- ^ directed
-> Bool -- ^ self-loop
-> IO (LGraph d () ())
erdosRenyiGame (GNP n p) d self = do
gp <- igraphInit >> igraphErdosRenyiGame IgraphErdosRenyiGnp n p (isD d) self
unsafeFreeze $ MLGraph gp
erdosRenyiGame (GNM n m) d self = do
gp <- igraphInit >> igraphErdosRenyiGame IgraphErdosRenyiGnm n
(fromIntegral m) (isD d) self
unsafeFreeze $ MLGraph gp
{#fun igraph_erdos_renyi_game as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `ErdosRenyi', `Int', `Double', `Bool', `Bool'
} -> `CInt' void- #}
-- | Generates a random graph with a given degree sequence.
degreeSequenceGame :: [Int] -- ^ Out degree
-> [Int] -- ^ In degree
-> IO (LGraph D () ())
degreeSequenceGame out_deg in_deg = do
out_deg' <- fromList $ map fromIntegral out_deg
in_deg' <- fromList $ map fromIntegral in_deg
gp <- igraphDegreeSequenceGame out_deg' in_deg' IgraphDegseqSimple
unsafeFreeze $ MLGraph gp
{#fun igraph_degree_sequence_game as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `Vector', `Vector', `Degseq'
} -> `CInt' void- #}
-- | Randomly rewires a graph while preserving the degree distribution.
rewire :: (Graph d, Hashable v, Serialize v, Eq v, Serialize e)
=> Int -- ^ Number of rewiring trials to perform.
-> LGraph d v e
-> IO (LGraph d v e)
rewire n gr = do
(MLGraph gptr) <- thaw gr
err <- igraphRewire gptr n IgraphRewiringSimple
when (err /= 0) $ error "failed to rewire graph!"
unsafeFreeze $ MLGraph gptr
{#fun igraph_rewire as ^ { `IGraph', `Int', `Rewiring' } -> `Int' #}