Commit 74612b98 authored by Kai Zhang's avatar Kai Zhang

refactoring

parent 0ed52e97
#include <igraph/igraph.h> #include <igraph/igraph.h>
#include "haskell_attributes.h" #include "haskell_attributes.h"
igraph_integer_t igraph_get_eid_(igraph_t* graph, igraph_integer_t pfrom, igraph_integer_t pto,
igraph_bool_t directed, igraph_bool_t error)
{
igraph_integer_t eid;
igraph_get_eid(graph, &eid, pfrom, pto, directed, error);
return eid;
}
char** igraph_strvector_get_(igraph_strvector_t* s, long int i)
{
char** x = (char**) malloc (sizeof(char*));
igraph_strvector_get(s, i, x);
return x;
}
igraph_arpack_options_t* igraph_arpack_new()
{
igraph_arpack_options_t *arpack = (igraph_arpack_options_t*) malloc(sizeof(igraph_arpack_options_t));
igraph_arpack_options_init(arpack);
return arpack;
}
void igraph_arpack_destroy(igraph_arpack_options_t* arpack)
{
if (arpack)
free(arpack);
arpack = NULL;
}
const igraph_attribute_table_t igraph_haskell_attribute_table={ const igraph_attribute_table_t igraph_haskell_attribute_table={
&igraph_haskell_attribute_init, &igraph_haskell_attribute_destroy, &igraph_haskell_attribute_init, &igraph_haskell_attribute_destroy,
&igraph_haskell_attribute_copy, &igraph_haskell_attribute_add_vertices, &igraph_haskell_attribute_copy, &igraph_haskell_attribute_add_vertices,
......
...@@ -3,15 +3,6 @@ ...@@ -3,15 +3,6 @@
#include <igraph/igraph.h> #include <igraph/igraph.h>
igraph_integer_t igraph_get_eid_(igraph_t* graph, igraph_integer_t pfrom, igraph_integer_t pto,
igraph_bool_t directed, igraph_bool_t error);
char** igraph_strvector_get_(igraph_strvector_t* s, long int i);
igraph_arpack_options_t* igraph_arpack_new();
void igraph_arpack_destroy(igraph_arpack_options_t* arpack);
void haskelligraph_init(); void haskelligraph_init();
#endif #endif
...@@ -23,6 +23,7 @@ Flag graphics ...@@ -23,6 +23,7 @@ Flag graphics
library library
exposed-modules: exposed-modules:
IGraph.Internal.Initialization IGraph.Internal.Initialization
IGraph.Internal.C2HS
IGraph.Internal.Constants IGraph.Internal.Constants
IGraph.Internal.Arpack IGraph.Internal.Arpack
IGraph.Internal.Data IGraph.Internal.Data
......
...@@ -51,7 +51,7 @@ class MGraph d => Graph d where ...@@ -51,7 +51,7 @@ class MGraph d => Graph d where
isD :: d -> Bool isD :: d -> Bool
nNodes :: LGraph d v e -> Int nNodes :: LGraph d v e -> Int
nNodes (LGraph g _) = igraphVcount g nNodes (LGraph g _) = unsafePerformIO $ igraphVcount g
{-# INLINE nNodes #-} {-# INLINE nNodes #-}
nodes :: LGraph d v e -> [Int] nodes :: LGraph d v e -> [Int]
...@@ -59,7 +59,7 @@ class MGraph d => Graph d where ...@@ -59,7 +59,7 @@ class MGraph d => Graph d where
{-# INLINE nodes #-} {-# INLINE nodes #-}
nEdges :: LGraph d v e -> Int nEdges :: LGraph d v e -> Int
nEdges (LGraph g _) = igraphEcount g nEdges (LGraph g _) = unsafePerformIO $ igraphEcount g
{-# INLINE nEdges #-} {-# INLINE nEdges #-}
edges :: LGraph d v e -> [Edge] edges :: LGraph d v e -> [Edge]
...@@ -69,9 +69,9 @@ class MGraph d => Graph d where ...@@ -69,9 +69,9 @@ class MGraph d => Graph d where
{-# INLINE edges #-} {-# INLINE edges #-}
hasEdge :: LGraph d v e -> Edge -> Bool hasEdge :: LGraph d v e -> Edge -> Bool
hasEdge (LGraph g _) (fr, to) hasEdge (LGraph g _) (fr, to) = unsafePerformIO $ do
| igraphGetEid g fr to True False < 0 = False i <- igraphGetEid g fr to True False
| otherwise = True return $ i >= 0
{-# INLINE hasEdge #-} {-# INLINE hasEdge #-}
nodeLab :: Serialize v => LGraph d v e -> Node -> v nodeLab :: Serialize v => LGraph d v e -> Node -> v
...@@ -80,8 +80,9 @@ class MGraph d => Graph d where ...@@ -80,8 +80,9 @@ class MGraph d => Graph d where
{-# INLINE nodeLab #-} {-# INLINE nodeLab #-}
nodeLabMaybe :: Serialize v => LGraph d v e -> Node -> Maybe v nodeLabMaybe :: Serialize v => LGraph d v e -> Node -> Maybe v
nodeLabMaybe gr@(LGraph g _) i = nodeLabMaybe gr@(LGraph g _) i = unsafePerformIO $ do
if igraphHaskellAttributeHasAttr g IgraphAttributeVertex vertexAttr x <- igraphHaskellAttributeHasAttr g IgraphAttributeVertex vertexAttr
return $ if x
then Just $ nodeLab gr i then Just $ nodeLab gr i
else Nothing else Nothing
{-# INLINE nodeLabMaybe #-} {-# INLINE nodeLabMaybe #-}
...@@ -92,13 +93,14 @@ class MGraph d => Graph d where ...@@ -92,13 +93,14 @@ class MGraph d => Graph d where
edgeLab :: Serialize e => LGraph d v e -> Edge -> e edgeLab :: Serialize e => LGraph d v e -> Edge -> e
edgeLab (LGraph g _) (fr,to) = unsafePerformIO $ edgeLab (LGraph g _) (fr,to) = unsafePerformIO $
igraphHaskellAttributeEAS g edgeAttr (igraphGetEid g fr to True True) >>= igraphGetEid g fr to True True >>=
fromBS igraphHaskellAttributeEAS g edgeAttr >>= fromBS
{-# INLINE edgeLab #-} {-# INLINE edgeLab #-}
edgeLabMaybe :: Serialize e => LGraph d v e -> Edge -> Maybe e edgeLabMaybe :: Serialize e => LGraph d v e -> Edge -> Maybe e
edgeLabMaybe gr@(LGraph g _) i = edgeLabMaybe gr@(LGraph g _) i = unsafePerformIO $ do
if igraphHaskellAttributeHasAttr g IgraphAttributeEdge edgeAttr x <- igraphHaskellAttributeHasAttr g IgraphAttributeEdge edgeAttr
return $ if x
then Just $ edgeLab gr i then Just $ edgeLab gr i
else Nothing else Nothing
{-# INLINE edgeLabMaybe #-} {-# INLINE edgeLabMaybe #-}
...@@ -157,12 +159,12 @@ fromLabeledEdges es = mkGraph labels es' ...@@ -157,12 +159,12 @@ fromLabeledEdges es = mkGraph labels es'
unsafeFreeze :: (Hashable v, Eq v, Serialize v, PrimMonad m) unsafeFreeze :: (Hashable v, Eq v, Serialize v, PrimMonad m)
=> MLGraph (PrimState m) d v e -> m (LGraph d v e) => MLGraph (PrimState m) d v e -> m (LGraph d v e)
unsafeFreeze (MLGraph g) = return $ LGraph g labToId unsafeFreeze (MLGraph g) = unsafePrimToPrim $ do
where nV <- igraphVcount g
labToId = M.fromListWith (++) $ zip labels $ map return [0..nV-1] labels <- forM [0 .. nV - 1] $ \i ->
nV = igraphVcount g
labels = unsafePerformIO $ forM [0 .. nV - 1] $ \i ->
igraphHaskellAttributeVAS g vertexAttr i >>= fromBS igraphHaskellAttributeVAS g vertexAttr i >>= fromBS
return $ LGraph g $ M.fromListWith (++) $ zip labels $ map return [0..nV-1]
where
freeze :: (Hashable v, Eq v, Serialize v, PrimMonad m) freeze :: (Hashable v, Eq v, Serialize v, PrimMonad m)
=> MLGraph (PrimState m) d v e -> m (LGraph d v e) => MLGraph (PrimState m) d v e -> m (LGraph d v e)
...@@ -253,8 +255,8 @@ emap :: (Graph d, Serialize v, Hashable v, Eq v, Serialize e1, Serialize e2) ...@@ -253,8 +255,8 @@ emap :: (Graph d, Serialize v, Hashable v, Eq v, Serialize e1, Serialize e2)
emap fn gr = unsafePerformIO $ do emap fn gr = unsafePerformIO $ do
(MLGraph g) <- thaw gr (MLGraph g) <- thaw gr
forM_ (edges gr) $ \(fr, to) -> do forM_ (edges gr) $ \(fr, to) -> do
i <- igraphGetEid g fr to True True
let label = fn ((fr,to), edgeLabByEid gr i) let label = fn ((fr,to), edgeLabByEid gr i)
i = igraphGetEid g fr to True True
asBS label $ \bs -> asBS label $ \bs ->
with bs (igraphHaskellAttributeEASSet g edgeAttr i) with bs (igraphHaskellAttributeEASSet g edgeAttr i)
unsafeFreeze (MLGraph g) unsafeFreeze (MLGraph g)
...@@ -17,7 +17,7 @@ cliques :: LGraph d v e ...@@ -17,7 +17,7 @@ cliques :: LGraph d v e
cliques gr (lo, hi) = unsafePerformIO $ do cliques gr (lo, hi) = unsafePerformIO $ do
vpptr <- igraphVectorPtrNew 0 vpptr <- igraphVectorPtrNew 0
_ <- igraphCliques (_graph gr) vpptr lo hi _ <- igraphCliques (_graph gr) vpptr lo hi
(map.map) truncate <$> vectorPPtrToList vpptr (map.map) truncate <$> toLists vpptr
maximalCliques :: LGraph d v e maximalCliques :: LGraph d v e
-> (Int, Int) -- ^ Minimum and maximum size of the cliques to be returned. -> (Int, Int) -- ^ Minimum and maximum size of the cliques to be returned.
...@@ -26,4 +26,4 @@ maximalCliques :: LGraph d v e ...@@ -26,4 +26,4 @@ maximalCliques :: LGraph d v e
maximalCliques gr (lo, hi) = unsafePerformIO $ do maximalCliques gr (lo, hi) = unsafePerformIO $ do
vpptr <- igraphVectorPtrNew 0 vpptr <- igraphVectorPtrNew 0
_ <- igraphMaximalCliques (_graph gr) vpptr lo hi _ <- igraphMaximalCliques (_graph gr) vpptr lo hi
(map.map) truncate <$> vectorPPtrToList vpptr (map.map) truncate <$> toLists vpptr
...@@ -50,8 +50,8 @@ findCommunity :: LGraph U v e -> CommunityOpt -> [[Int]] ...@@ -50,8 +50,8 @@ findCommunity :: LGraph U v e -> CommunityOpt -> [[Int]]
findCommunity gr opt = unsafePerformIO $ do findCommunity gr opt = unsafePerformIO $ do
result <- igraphVectorNew 0 result <- igraphVectorNew 0
ws <- case _weights opt of ws <- case _weights opt of
Just w -> listToVector w Just w -> fromList w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr _ -> liftM Vector $ newForeignPtr_ $ castPtr nullPtr
case _method opt of case _method opt of
LeadingEigenvector -> do LeadingEigenvector -> do
...@@ -68,4 +68,4 @@ findCommunity gr opt = unsafePerformIO $ do ...@@ -68,4 +68,4 @@ findCommunity gr opt = unsafePerformIO $ do
IgraphSpincommImpOrig 1.0 IgraphSpincommImpOrig 1.0
liftM ( map (fst . unzip) . groupBy ((==) `on` snd) liftM ( map (fst . unzip) . groupBy ((==) `on` snd)
. sortBy (comparing snd) . zip [0..] ) $ vectorPtrToList result . sortBy (comparing snd) . zip [0..] ) $ toList result
...@@ -37,8 +37,8 @@ degreeSequenceGame :: [Int] -- ^ Out degree ...@@ -37,8 +37,8 @@ degreeSequenceGame :: [Int] -- ^ Out degree
-> [Int] -- ^ In degree -> [Int] -- ^ In degree
-> IO (LGraph D () ()) -> IO (LGraph D () ())
degreeSequenceGame out_deg in_deg = do degreeSequenceGame out_deg in_deg = do
out_deg' <- listToVector $ map fromIntegral out_deg out_deg' <- fromList $ map fromIntegral out_deg
in_deg' <- listToVector $ map fromIntegral in_deg in_deg' <- fromList $ map fromIntegral in_deg
gp <- igraphDegreeSequenceGame out_deg' in_deg' IgraphDegseqSimple gp <- igraphDegreeSequenceGame out_deg' in_deg' IgraphDegseqSimple
unsafeFreeze $ MLGraph gp unsafeFreeze $ MLGraph gp
......
...@@ -7,6 +7,7 @@ import Foreign.C.Types ...@@ -7,6 +7,7 @@ import Foreign.C.Types
#include "haskell_igraph.h" #include "haskell_igraph.h"
{#pointer *igraph_arpack_options_t as ArpackOptPtr foreign finalizer igraph_arpack_destroy newtype#} {#pointer *igraph_arpack_options_t as ArpackOpt foreign newtype#}
{#fun igraph_arpack_new as ^ { } -> `ArpackOptPtr' #} {#fun igraph_arpack_options_init as igraphArpackNew
{ + } -> `ArpackOpt' #}
...@@ -24,12 +24,12 @@ asBS :: Serialize a => a -> (BSLen -> IO b) -> IO b ...@@ -24,12 +24,12 @@ asBS :: Serialize a => a -> (BSLen -> IO b) -> IO b
asBS x fn = unsafeUseAsCStringLen (encode x) (fn . BSLen) asBS x fn = unsafeUseAsCStringLen (encode x) (fn . BSLen)
{-# INLINE asBS #-} {-# INLINE asBS #-}
asBSVector :: Serialize a => [a] -> (BSVectorPtr -> IO b) -> IO b asBSVector :: Serialize a => [a] -> (BSVector -> IO b) -> IO b
asBSVector values fn = loop [] values asBSVector values fn = loop [] values
where where
loop acc (x:xs) = unsafeUseAsCStringLen (encode x) $ \ptr -> loop acc (x:xs) = unsafeUseAsCStringLen (encode x) $ \ptr ->
loop (BSLen ptr : acc) xs loop (BSLen ptr : acc) xs
loop acc _ = listToBSVector (reverse acc) >>= fn loop acc _ = toBSVector (reverse acc) >>= fn
{-# INLINE asBSVector #-} {-# INLINE asBSVector #-}
fromBS :: Serialize a => Ptr BSLen -> IO a fromBS :: Serialize a => Ptr BSLen -> IO a
...@@ -42,12 +42,12 @@ fromBS ptr = do ...@@ -42,12 +42,12 @@ fromBS ptr = do
{-# INLINE fromBS #-} {-# INLINE fromBS #-}
mkStrRec :: CString -- ^ name of the attribute mkStrRec :: CString -- ^ name of the attribute
-> BSVectorPtr -- ^ values of the attribute -> BSVector -- ^ values of the attribute
-> AttributeRecord -> AttributeRecord
mkStrRec name xs = AttributeRecord name 2 xs mkStrRec name xs = AttributeRecord name 2 xs
{-# INLINE mkStrRec #-} {-# INLINE mkStrRec #-}
data AttributeRecord = AttributeRecord CString Int BSVectorPtr data AttributeRecord = AttributeRecord CString Int BSVector
instance Storable AttributeRecord where instance Storable AttributeRecord where
sizeOf _ = {#sizeof igraph_attribute_record_t #} sizeOf _ = {#sizeof igraph_attribute_record_t #}
...@@ -57,27 +57,27 @@ instance Storable AttributeRecord where ...@@ -57,27 +57,27 @@ instance Storable AttributeRecord where
<*> liftM fromIntegral ({#get igraph_attribute_record_t->type #} p) <*> liftM fromIntegral ({#get igraph_attribute_record_t->type #} p)
<*> ( do ptr <- {#get igraph_attribute_record_t->value #} p <*> ( do ptr <- {#get igraph_attribute_record_t->value #} p
fptr <- newForeignPtr_ . castPtr $ ptr fptr <- newForeignPtr_ . castPtr $ ptr
return $ BSVectorPtr fptr ) return $ BSVector fptr )
poke p (AttributeRecord name t vptr) = do poke p (AttributeRecord name t vptr) = do
{#set igraph_attribute_record_t.name #} p name {#set igraph_attribute_record_t.name #} p name
{#set igraph_attribute_record_t.type #} p $ fromIntegral t {#set igraph_attribute_record_t.type #} p $ fromIntegral t
withBSVectorPtr vptr $ \ptr -> withBSVector vptr $ \ptr ->
{#set igraph_attribute_record_t.value #} p $ castPtr ptr {#set igraph_attribute_record_t.value #} p $ castPtr ptr
{#fun pure igraph_haskell_attribute_has_attr as ^ { `IGraphPtr', `AttributeElemtype', `String' } -> `Bool' #} {#fun igraph_haskell_attribute_has_attr as ^ { `IGraph', `AttributeElemtype', `String' } -> `Bool' #}
{#fun igraph_haskell_attribute_GAN_set as ^ { `IGraphPtr', `String', `Double' } -> `Int' #} {#fun igraph_haskell_attribute_GAN_set as ^ { `IGraph', `String', `Double' } -> `Int' #}
{#fun pure igraph_haskell_attribute_GAN as ^ { `IGraphPtr', `String' } -> `Double' #} {#fun igraph_haskell_attribute_GAN as ^ { `IGraph', `String' } -> `Double' #}
{#fun igraph_haskell_attribute_VAS as ^ { `IGraphPtr', `String', `Int' } -> `Ptr BSLen' castPtr #} {#fun igraph_haskell_attribute_VAS as ^ { `IGraph', `String', `Int' } -> `Ptr BSLen' castPtr #}
{#fun pure igraph_haskell_attribute_EAN as ^ { `IGraphPtr', `String', `Int' } -> `Double' #} {#fun igraph_haskell_attribute_EAN as ^ { `IGraph', `String', `Int' } -> `Double' #}
{#fun igraph_haskell_attribute_EAS as ^ { `IGraphPtr', `String', `Int' } -> `Ptr BSLen' castPtr #} {#fun igraph_haskell_attribute_EAS as ^ { `IGraph', `String', `Int' } -> `Ptr BSLen' castPtr #}
{#fun igraph_haskell_attribute_EAS_setv as ^ { `IGraphPtr', `String', `BSVectorPtr' } -> `Int' #} {#fun igraph_haskell_attribute_EAS_setv as ^ { `IGraph', `String', `BSVector' } -> `Int' #}
{#fun igraph_haskell_attribute_VAS_set as ^ { `IGraphPtr', `String', `Int', castPtr `Ptr BSLen' } -> `Int' #} {#fun igraph_haskell_attribute_VAS_set as ^ { `IGraph', `String', `Int', castPtr `Ptr BSLen' } -> `Int' #}
{#fun igraph_haskell_attribute_EAS_set as ^ { `IGraphPtr', `String', `Int', castPtr `Ptr BSLen' } -> `Int' #} {#fun igraph_haskell_attribute_EAS_set as ^ { `IGraph', `String', `Int', castPtr `Ptr BSLen' } -> `Int' #}
module IGraph.Internal.C2HS (
-- * Conversion between C and Haskell types
cIntConv, cFloatConv, cToBool, cFromBool, cToEnum, cFromEnum,
-- * Composite marshalling functions
peekIntConv, peekFloatConv,
) where
-- system
import Control.Monad
import Foreign
import Foreign.C
-- Conversions -----------------------------------------------------------------
--
-- | Integral conversion
--
{-# INLINE cIntConv #-}
cIntConv :: (Integral a, Integral b) => a -> b
cIntConv = fromIntegral
-- | Floating conversion
--
{-# INLINE [1] cFloatConv #-}
cFloatConv :: (RealFloat a, RealFloat b) => a -> b
cFloatConv = realToFrac
-- As this conversion by default goes via `Rational', it can be very slow...
{-# RULES
"cFloatConv/Float->Float" forall (x::Float). cFloatConv x = x;
"cFloatConv/Double->Double" forall (x::Double). cFloatConv x = x;
"cFloatConv/Float->CFloat" forall (x::Float). cFloatConv x = CFloat x;
"cFloatConv/CFloat->Float" forall (x::Float). cFloatConv CFloat x = x;
"cFloatConv/Double->CDouble" forall (x::Double). cFloatConv x = CDouble x;
"cFloatConv/CDouble->Double" forall (x::Double). cFloatConv CDouble x = x
#-}
-- | Obtain C value from Haskell 'Bool'.
--
{-# INLINE cFromBool #-}
cFromBool :: Num a => Bool -> a
cFromBool = fromBool
-- | Obtain Haskell 'Bool' from C value.
--
{-# INLINE cToBool #-}
cToBool :: (Eq a, Num a) => a -> Bool
cToBool = toBool
-- | Convert a C enumeration to Haskell.
--
{-# INLINE cToEnum #-}
cToEnum :: (Integral i, Enum e) => i -> e
cToEnum = toEnum . cIntConv
-- | Convert a Haskell enumeration to C.
--
{-# INLINE cFromEnum #-}
cFromEnum :: (Enum e, Integral i) => e -> i
cFromEnum = cIntConv . fromEnum
-- | Marshalling of numerals
--
{-# INLINE peekIntConv #-}
peekIntConv :: (Storable a, Integral a, Integral b) => Ptr a -> IO b
peekIntConv = liftM cIntConv . peek
{-# INLINE peekFloatConv #-}
peekFloatConv :: (Storable a, RealFloat a, RealFloat b) => Ptr a -> IO b
peekFloatConv = liftM cFloatConv . peek
...@@ -12,6 +12,6 @@ import Foreign.C.Types ...@@ -12,6 +12,6 @@ import Foreign.C.Types
#include "igraph/igraph.h" #include "igraph/igraph.h"
{#fun igraph_cliques as ^ { `IGraphPtr', `VectorPPtr', `Int', `Int' } -> `Int' #} {#fun igraph_cliques as ^ { `IGraph', `VectorPtr', `Int', `Int' } -> `Int' #}
{#fun igraph_maximal_cliques as ^ { `IGraphPtr', `VectorPPtr', `Int', `Int' } -> `Int' #} {#fun igraph_maximal_cliques as ^ { `IGraph', `VectorPtr', `Int', `Int' } -> `Int' #}
...@@ -12,12 +12,12 @@ import Foreign.C.Types ...@@ -12,12 +12,12 @@ import Foreign.C.Types
#include "igraph/igraph.h" #include "igraph/igraph.h"
{#fun igraph_community_spinglass as ^ {#fun igraph_community_spinglass as ^
{ `IGraphPtr' { `IGraph'
, `VectorPtr' , `Vector'
, id `Ptr CDouble' , id `Ptr CDouble'
, id `Ptr CDouble' , id `Ptr CDouble'
, `VectorPtr' , `Vector'
, id `Ptr VectorPtr' , id `Ptr Vector'
, `Int' , `Int'
, `Bool' , `Bool'
, `Double' , `Double'
...@@ -30,25 +30,25 @@ import Foreign.C.Types ...@@ -30,25 +30,25 @@ import Foreign.C.Types
} -> `Int' #} } -> `Int' #}
{#fun igraph_community_leading_eigenvector as ^ {#fun igraph_community_leading_eigenvector as ^
{ `IGraphPtr' { `IGraph'
, `VectorPtr' , `Vector'
, id `Ptr MatrixPtr' , id `Ptr Matrix'
, `VectorPtr' , `Vector'
, `Int' , `Int'
, `ArpackOptPtr' , `ArpackOpt'
, id `Ptr CDouble' , id `Ptr CDouble'
, `Bool' , `Bool'
, id `Ptr Vector'
, id `Ptr VectorPtr' , id `Ptr VectorPtr'
, id `Ptr VectorPPtr' , id `Ptr Vector'
, id `Ptr VectorPtr'
, id `T' , id `T'
, id `Ptr ()' , id `Ptr ()'
} -> `Int' #} } -> `Int' #}
type T = FunPtr ( Ptr VectorPtr type T = FunPtr ( Ptr Vector
-> CLong -> CLong
-> CDouble -> CDouble
-> Ptr VectorPtr -> Ptr Vector
-> FunPtr (Ptr CDouble -> Ptr CDouble -> CInt -> Ptr () -> IO CInt) -> FunPtr (Ptr CDouble -> Ptr CDouble -> CInt -> Ptr () -> IO CInt)
-> Ptr () -> Ptr ()
-> Ptr () -> Ptr ()
......
This diff is collapsed.
...@@ -6,6 +6,7 @@ import Foreign ...@@ -6,6 +6,7 @@ import Foreign
import Foreign.C.Types import Foreign.C.Types
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
import IGraph.Internal.C2HS
{#import IGraph.Internal.Initialization #} {#import IGraph.Internal.Initialization #}
{#import IGraph.Internal.Data #} {#import IGraph.Internal.Data #}
{#import IGraph.Internal.Constants #} {#import IGraph.Internal.Constants #}
...@@ -16,59 +17,61 @@ import System.IO.Unsafe (unsafePerformIO) ...@@ -16,59 +17,61 @@ import System.IO.Unsafe (unsafePerformIO)
-- Graph Constructors and Destructors -- Graph Constructors and Destructors
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
{#pointer *igraph_t as IGraphPtr foreign finalizer igraph_destroy newtype#} {#pointer *igraph_t as IGraph foreign finalizer igraph_destroy newtype#}
{#fun igraph_empty as igraphNew' { +, `Int', `Bool' } -> `IGraphPtr' #} {#fun igraph_empty as igraphNew' { +, `Int', `Bool' } -> `IGraph' #}
{#fun igraph_copy as ^ { +, `IGraphPtr' } -> `IGraphPtr' #} {#fun igraph_copy as ^ { +, `IGraph' } -> `IGraph' #}
-- | Create a igraph object and attach a finalizer -- | Create a igraph object and attach a finalizer
igraphNew :: Int -> Bool -> HasInit -> IO IGraphPtr igraphNew :: Int -> Bool -> HasInit -> IO IGraph
igraphNew n directed _ = do igraphNew n directed _ = igraphNew' n directed
IGraphPtr ptr <- igraphNew' n directed
addForeignPtrFinalizer igraph_destroy ptr
return $ IGraphPtr ptr
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Basic Query Operations -- Basic Query Operations
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
{#fun pure igraph_vcount as ^ { `IGraphPtr' } -> `Int' #} {#fun igraph_vcount as ^ { `IGraph' } -> `Int' #}
{#fun pure igraph_ecount as ^ { `IGraphPtr' } -> `Int' #} {#fun igraph_ecount as ^ { `IGraph' } -> `Int' #}
{#fun pure igraph_get_eid_ as igraphGetEid { `IGraphPtr', `Int', `Int', `Bool', `Bool' } -> `Int' #} {#fun igraph_get_eid as ^
{ `IGraph'
, alloca- `Int' peekIntConv*
, `Int'
, `Int'
, `Bool'
, `Bool'
} -> `CInt' void-#}
{#fun igraph_edge as igraphEdge' { `IGraphPtr', `Int', id `Ptr CInt', id `Ptr CInt' } -> `Int' #} {#fun igraph_edge as ^
igraphEdge :: IGraphPtr -> Int -> IO (Int, Int) { `IGraph'
igraphEdge g i = alloca $ \fr -> alloca $ \to -> do , `Int'
igraphEdge' g i fr to , alloca- `Int' peekIntConv*
fr' <- peek fr , alloca- `Int' peekIntConv*
to' <- peek to } -> `CInt' void-#}
return (fromIntegral fr', fromIntegral to')
-- Adding and Deleting Vertices and Edges -- Adding and Deleting Vertices and Edges
{# fun igraph_add_vertices as ^ { `IGraphPtr', `Int', id `Ptr ()' } -> `()' #} {# fun igraph_add_vertices as ^ { `IGraph', `Int', id `Ptr ()' } -> `()' #}
{# fun igraph_add_edge as ^ { `IGraphPtr', `Int', `Int' } -> `()' #} {# fun igraph_add_edge as ^ { `IGraph', `Int', `Int' } -> `()' #}
{# fun igraph_add_edges as ^ { `IGraphPtr', `VectorPtr', id `Ptr ()' } -> `()' #} {# fun igraph_add_edges as ^ { `IGraph', `Vector', id `Ptr ()' } -> `()' #}
-- generators -- generators
{#fun igraph_full as ^ { +, `Int', `Bool', `Bool' } -> `IGraphPtr' #} {#fun igraph_full as ^ { +, `Int', `Bool', `Bool' } -> `IGraph' #}
{#fun igraph_erdos_renyi_game as ^ { +, `ErdosRenyi', `Int', `Double', `Bool' {#fun igraph_erdos_renyi_game as ^ { +, `ErdosRenyi', `Int', `Double', `Bool'
, `Bool' } -> `IGraphPtr' #} , `Bool' } -> `IGraph' #}
{#fun igraph_degree_sequence_game as ^ { +, `VectorPtr', `VectorPtr' {#fun igraph_degree_sequence_game as ^ { +, `Vector', `Vector'
, `Degseq' } -> `IGraphPtr' #} , `Degseq' } -> `IGraph' #}
{#fun igraph_rewire as ^ { `IGraphPtr', `Int', `Rewiring' } -> `Int' #} {#fun igraph_rewire as ^ { `IGraph', `Int', `Rewiring' } -> `Int' #}
{#fun igraph_isoclass_create as ^ { +, `Int', `Int', `Bool' } -> `IGraphPtr' #} {#fun igraph_isoclass_create as ^ { +, `Int', `Int', `Bool' } -> `IGraph' #}
...@@ -9,10 +9,10 @@ import Foreign.C.Types ...@@ -9,10 +9,10 @@ import Foreign.C.Types
#include "igraph/igraph.h" #include "igraph/igraph.h"
{#fun igraph_get_subisomorphisms_vf2 as ^ { `IGraphPtr', `IGraphPtr', {#fun igraph_get_subisomorphisms_vf2 as ^ { `IGraph', `IGraph',
id `Ptr ()', id `Ptr ()', id `Ptr ()', id `Ptr ()', `VectorPPtr', id `Ptr ()', id `Ptr ()', id `Ptr ()', id `Ptr ()', `VectorPtr',
id `FunPtr (Ptr IGraphPtr -> Ptr IGraphPtr -> CInt -> CInt -> Ptr () -> IO CInt)', id `FunPtr (Ptr IGraph -> Ptr IGraph -> CInt -> CInt -> Ptr () -> IO CInt)',
id `FunPtr (Ptr IGraphPtr -> Ptr IGraphPtr -> CInt -> CInt -> Ptr () -> IO CInt)', id `FunPtr (Ptr IGraph -> Ptr IGraph -> CInt -> CInt -> Ptr () -> IO CInt)',
id `Ptr ()'} -> `Int' #} id `Ptr ()'} -> `Int' #}
{#fun igraph_isomorphic as ^ { `IGraphPtr', `IGraphPtr', id `Ptr CInt' } -> `Int' #} {#fun igraph_isomorphic as ^ { `IGraph', `IGraph', id `Ptr CInt' } -> `Int' #}
...@@ -12,22 +12,22 @@ import Foreign.C.Types ...@@ -12,22 +12,22 @@ import Foreign.C.Types
#include "igraph/igraph.h" #include "igraph/igraph.h"
{#fun igraph_layout_kamada_kawai as ^ { `IGraphPtr' {#fun igraph_layout_kamada_kawai as ^ { `IGraph'
, `MatrixPtr' , `Matrix'
, `Int' , `Int'
, `Double' , `Double'
, `Double' , `Double'
, `Double' , `Double'
, `Double' , `Double'
, `Bool' , `Bool'
, id `Ptr VectorPtr' , id `Ptr Vector'
, id `Ptr VectorPtr' , id `Ptr Vector'
, id `Ptr VectorPtr' , id `Ptr Vector'
, id `Ptr VectorPtr' , id `Ptr Vector'
} -> `Int' #} } -> `Int' #}
{# fun igraph_layout_lgl as ^ { `IGraphPtr' {# fun igraph_layout_lgl as ^ { `IGraph'
, `MatrixPtr' , `Matrix'
, `Int' , `Int'
, `Double' , `Double'
, `Double' , `Double'
......
...@@ -13,8 +13,8 @@ import Foreign.C.Types ...@@ -13,8 +13,8 @@ import Foreign.C.Types
#include "igraph/igraph.h" #include "igraph/igraph.h"
{#fun igraph_triad_census as ^ { `IGraphPtr' {#fun igraph_triad_census as ^ { `IGraph'
, `VectorPtr' } -> `Int' #} , `Vector' } -> `Int' #}
{#fun igraph_motifs_randesu as ^ { `IGraphPtr', `VectorPtr', `Int' {#fun igraph_motifs_randesu as ^ { `IGraph', `Vector', `Int'
, `VectorPtr' } -> `Int' #} , `Vector' } -> `Int' #}
...@@ -10,28 +10,22 @@ import System.IO.Unsafe (unsafePerformIO) ...@@ -10,28 +10,22 @@ import System.IO.Unsafe (unsafePerformIO)
{#import IGraph.Internal.Graph #} {#import IGraph.Internal.Graph #}
{#import IGraph.Internal.Data #} {#import IGraph.Internal.Data #}
#include "igraph/igraph.h" #include "haskell_igraph.h"
{#pointer *igraph_vs_t as IGraphVsPtr foreign finalizer igraph_vs_destroy newtype #} {#pointer *igraph_vs_t as IGraphVs foreign finalizer igraph_vs_destroy newtype #}
{#fun igraph_vs_all as ^ { + } -> `IGraphVsPtr' #} {#fun igraph_vs_all as ^ { + } -> `IGraphVs' #}
{#fun igraph_vs_adj as ^ { +, `Int', `Neimode' } -> `IGraphVsPtr' #} {#fun igraph_vs_adj as ^ { +, `Int', `Neimode' } -> `IGraphVs' #}
{#fun igraph_vs_vector as ^ { +, `VectorPtr' } -> `IGraphVsPtr' #} {#fun igraph_vs_vector as ^ { +, `Vector' } -> `IGraphVs' #}
-- Vertex iterator -- Vertex iterator
{#pointer *igraph_vit_t as IGraphVitPtr foreign finalizer igraph_vit_destroy newtype #} {#pointer *igraph_vit_t as IGraphVit foreign finalizer igraph_vit_destroy newtype #}
#c #c
igraph_vit_t* igraph_vit_new(const igraph_t *graph, igraph_vs_t vs) {
igraph_vit_t* vit = (igraph_vit_t*) malloc (sizeof (igraph_vit_t));
igraph_vit_create(graph, vs, vit);
return vit;
}
igraph_bool_t igraph_vit_end(igraph_vit_t *vit) { igraph_bool_t igraph_vit_end(igraph_vit_t *vit) {
return IGRAPH_VIT_END(*vit); return IGRAPH_VIT_END(*vit);
} }
...@@ -45,15 +39,15 @@ igraph_integer_t igraph_vit_get(igraph_vit_t *vit) { ...@@ -45,15 +39,15 @@ igraph_integer_t igraph_vit_get(igraph_vit_t *vit) {
} }
#endc #endc
{#fun igraph_vit_new as ^ { `IGraphPtr', %`IGraphVsPtr' } -> `IGraphVitPtr' #} {#fun igraph_vit_create as igraphVitNew { `IGraph', %`IGraphVs', + } -> `IGraphVit' #}
{#fun igraph_vit_end as ^ { `IGraphVitPtr' } -> `Bool' #} {#fun igraph_vit_end as ^ { `IGraphVit' } -> `Bool' #}
{#fun igraph_vit_next as ^ { `IGraphVitPtr' } -> `()' #} {#fun igraph_vit_next as ^ { `IGraphVit' } -> `()' #}
{#fun igraph_vit_get as ^ { `IGraphVitPtr' } -> `Int' #} {#fun igraph_vit_get as ^ { `IGraphVit' } -> `Int' #}
vitToList :: IGraphVitPtr -> IO [Int] vitToList :: IGraphVit -> IO [Int]
vitToList vit = do vitToList vit = do
isEnd <- igraphVitEnd vit isEnd <- igraphVitEnd vit
if isEnd if isEnd
...@@ -67,24 +61,18 @@ vitToList vit = do ...@@ -67,24 +61,18 @@ vitToList vit = do
-- Edge Selector -- Edge Selector
{#pointer *igraph_es_t as IGraphEsPtr foreign finalizer igraph_es_destroy newtype #} {#pointer *igraph_es_t as IGraphEs foreign finalizer igraph_es_destroy newtype #}
{#fun igraph_es_all as ^ { +, `EdgeOrderType' } -> `IGraphEsPtr' #} {#fun igraph_es_all as ^ { +, `EdgeOrderType' } -> `IGraphEs' #}
{# fun igraph_es_vector as ^ { +, `VectorPtr' } -> `IGraphEsPtr' #} {# fun igraph_es_vector as ^ { +, `Vector' } -> `IGraphEs' #}
-- Edge iterator -- Edge iterator
{#pointer *igraph_eit_t as IGraphEitPtr foreign finalizer igraph_eit_destroy newtype #} {#pointer *igraph_eit_t as IGraphEit foreign finalizer igraph_eit_destroy newtype #}
#c #c
igraph_eit_t* igraph_eit_new(const igraph_t *graph, igraph_es_t es) {
igraph_eit_t* eit = (igraph_eit_t*) malloc (sizeof (igraph_eit_t));
igraph_eit_create(graph, es, eit);
return eit;
}
igraph_bool_t igraph_eit_end(igraph_eit_t *eit) { igraph_bool_t igraph_eit_end(igraph_eit_t *eit) {
return IGRAPH_EIT_END(*eit); return IGRAPH_EIT_END(*eit);
} }
...@@ -98,15 +86,15 @@ igraph_integer_t igraph_eit_get(igraph_eit_t *eit) { ...@@ -98,15 +86,15 @@ igraph_integer_t igraph_eit_get(igraph_eit_t *eit) {
} }
#endc #endc
{#fun igraph_eit_new as ^ { `IGraphPtr', %`IGraphEsPtr' } -> `IGraphEitPtr' #} {#fun igraph_eit_create as igraphEitNew { `IGraph', %`IGraphEs', + } -> `IGraphEit' #}
{#fun igraph_eit_end as ^ { `IGraphEitPtr' } -> `Bool' #} {#fun igraph_eit_end as ^ { `IGraphEit' } -> `Bool' #}
{#fun igraph_eit_next as ^ { `IGraphEitPtr' } -> `()' #} {#fun igraph_eit_next as ^ { `IGraphEit' } -> `()' #}
{#fun igraph_eit_get as ^ { `IGraphEitPtr' } -> `Int' #} {#fun igraph_eit_get as ^ { `IGraphEit' } -> `Int' #}
eitToList :: IGraphEitPtr -> IO [Int] eitToList :: IGraphEit -> IO [Int]
eitToList eit = do eitToList eit = do
isEnd <- igraphEitEnd eit isEnd <- igraphEitEnd eit
if isEnd if isEnd
...@@ -119,9 +107,9 @@ eitToList eit = do ...@@ -119,9 +107,9 @@ eitToList eit = do
-- delete vertices -- delete vertices
{# fun igraph_delete_vertices as ^ { `IGraphPtr', %`IGraphVsPtr' } -> `Int' #} {# fun igraph_delete_vertices as ^ { `IGraph', %`IGraphVs' } -> `Int' #}
-- delete edges -- delete edges
{# fun igraph_delete_edges as ^ { `IGraphPtr', %`IGraphEsPtr' } -> `Int' #} {# fun igraph_delete_edges as ^ { `IGraph', %`IGraphEs' } -> `Int' #}
...@@ -12,50 +12,50 @@ import Foreign.C.Types ...@@ -12,50 +12,50 @@ import Foreign.C.Types
#include "igraph/igraph.h" #include "igraph/igraph.h"
{#fun igraph_induced_subgraph as ^ { `IGraphPtr' {#fun igraph_induced_subgraph as ^ { `IGraph'
, id `Ptr (IGraphPtr)' , +160
, %`IGraphVsPtr' , %`IGraphVs'
, `SubgraphImplementation' } -> `Int' #} , `SubgraphImplementation' } -> `IGraph' #}
{#fun igraph_closeness as ^ { `IGraphPtr' {#fun igraph_closeness as ^ { `IGraph'
, `VectorPtr' , `Vector'
, %`IGraphVsPtr' , %`IGraphVs'
, `Neimode' , `Neimode'
, `VectorPtr' , `Vector'
, `Bool' } -> `Int' #} , `Bool' } -> `Int' #}
{#fun igraph_betweenness as ^ { `IGraphPtr' {#fun igraph_betweenness as ^ { `IGraph'
, `VectorPtr' , `Vector'
, %`IGraphVsPtr' , %`IGraphVs'
, `Bool' , `Bool'
, `VectorPtr' , `Vector'
, `Bool' } -> `Int' #} , `Bool' } -> `Int' #}
{#fun igraph_eigenvector_centrality as ^ { `IGraphPtr' {#fun igraph_eigenvector_centrality as ^ { `IGraph'
, `VectorPtr' , `Vector'
, id `Ptr CDouble' , id `Ptr CDouble'
, `Bool' , `Bool'
, `Bool' , `Bool'
, `VectorPtr' , `Vector'
, `ArpackOptPtr' } -> `Int' #} , `ArpackOpt' } -> `Int' #}
{#fun igraph_pagerank as ^ { `IGraphPtr' {#fun igraph_pagerank as ^ { `IGraph'
, `PagerankAlgo' , `PagerankAlgo'
, `VectorPtr' , `Vector'
, id `Ptr CDouble' , id `Ptr CDouble'
, %`IGraphVsPtr' , %`IGraphVs'
, `Bool' , `Bool'
, `Double' , `Double'
, `VectorPtr' , `Vector'
, id `Ptr ()' } -> `Int' #} , id `Ptr ()' } -> `Int' #}
{#fun igraph_personalized_pagerank as ^ { `IGraphPtr' {#fun igraph_personalized_pagerank as ^ { `IGraph'
, `PagerankAlgo' , `PagerankAlgo'
, `VectorPtr' , `Vector'
, id `Ptr CDouble' , id `Ptr CDouble'
, %`IGraphVsPtr' , %`IGraphVs'
, `Bool' , `Bool'
, `Double' , `Double'
, `VectorPtr' , `Vector'
, `VectorPtr' , `Vector'
, id `Ptr ()' } -> `Int' #} , id `Ptr ()' } -> `Int' #}
...@@ -25,7 +25,7 @@ getSubisomorphisms g1 g2 = unsafePerformIO $ do ...@@ -25,7 +25,7 @@ getSubisomorphisms g1 g2 = unsafePerformIO $ do
vpptr <- igraphVectorPtrNew 0 vpptr <- igraphVectorPtrNew 0
igraphGetSubisomorphismsVf2 gptr1 gptr2 nullPtr nullPtr nullPtr nullPtr vpptr igraphGetSubisomorphismsVf2 gptr1 gptr2 nullPtr nullPtr nullPtr nullPtr vpptr
nullFunPtr nullFunPtr nullPtr nullFunPtr nullFunPtr nullPtr
(map.map) truncate <$> vectorPPtrToList vpptr (map.map) truncate <$> toLists vpptr
where where
gptr1 = _graph g1 gptr1 = _graph g1
gptr2 = _graph g2 gptr2 = _graph g2
......
...@@ -68,18 +68,18 @@ getLayout gr method = do ...@@ -68,18 +68,18 @@ getLayout gr method = do
Nothing -> igraphMatrixNew 0 0 Nothing -> igraphMatrixNew 0 0
Just xs -> if length xs /= nNodes gr Just xs -> if length xs /= nNodes gr
then error "Seed error: incorrect size" then error "Seed error: incorrect size"
else listsToMatrixPtr $ (\(x,y) -> [x,y]) $ unzip xs else fromRowLists $ (\(x,y) -> [x,y]) $ unzip xs
igraphLayoutKamadaKawai gptr mptr niter (sigma n) initemp coolexp igraphLayoutKamadaKawai gptr mptr niter (sigma n) initemp coolexp
(kkconst n) (isJust seed) nullPtr nullPtr nullPtr nullPtr (kkconst n) (isJust seed) nullPtr nullPtr nullPtr nullPtr
[x, y] <- matrixPtrToColumnLists mptr [x, y] <- toColumnLists mptr
return $ zip x y return $ zip x y
LGL niter delta area coolexp repulserad cellsize -> do LGL niter delta area coolexp repulserad cellsize -> do
mptr <- igraphMatrixNew 0 0 mptr <- igraphMatrixNew 0 0
igraphLayoutLgl gptr mptr niter (delta n) (area n) coolexp igraphLayoutLgl gptr mptr niter (delta n) (area n) coolexp
(repulserad n) (cellsize n) (-1) (repulserad n) (cellsize n) (-1)
[x, y] <- matrixPtrToColumnLists mptr [x, y] <- toColumnLists mptr
return $ zip x y return $ zip x y
where where
n = nNodes gr n = nNodes gr
......
...@@ -55,6 +55,6 @@ triadCensus :: (Hashable v, Eq v, Read v) => LGraph d v e -> [Int] ...@@ -55,6 +55,6 @@ triadCensus :: (Hashable v, Eq v, Read v) => LGraph d v e -> [Int]
triadCensus gr = unsafePerformIO $ do triadCensus gr = unsafePerformIO $ do
vptr <- igraphVectorNew 0 vptr <- igraphVectorNew 0
igraphTriadCensus (_graph gr) vptr igraphTriadCensus (_graph gr) vptr
map truncate <$> vectorPtrToList vptr map truncate <$> toList vptr
-- motifsRandesu -- motifsRandesu
...@@ -8,7 +8,7 @@ module IGraph.Mutable ...@@ -8,7 +8,7 @@ module IGraph.Mutable
, vertexAttr , vertexAttr
)where )where
import Control.Monad (when) import Control.Monad (when, forM)
import Control.Monad.Primitive import Control.Monad.Primitive
import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Char8 as B
import Data.Serialize (Serialize) import Data.Serialize (Serialize)
...@@ -50,19 +50,19 @@ class MGraph d where ...@@ -50,19 +50,19 @@ class MGraph d where
| n /= length labels = error "addLVertices: incorrect number of labels" | n /= length labels = error "addLVertices: incorrect number of labels"
| otherwise = unsafePrimToPrim $ withVertexAttr $ \vattr -> | otherwise = unsafePrimToPrim $ withVertexAttr $ \vattr ->
asBSVector labels $ \bsvec -> with (mkStrRec vattr bsvec) $ \ptr -> do asBSVector labels $ \bsvec -> with (mkStrRec vattr bsvec) $ \ptr -> do
vptr <- listToVectorP [castPtr ptr] vptr <- fromPtrs [castPtr ptr]
withVectorPPtr vptr (igraphAddVertices g n . castPtr) withVectorPtr vptr (igraphAddVertices g n . castPtr)
delNodes :: PrimMonad m => [Int] -> MLGraph (PrimState m) d v e -> m () delNodes :: PrimMonad m => [Int] -> MLGraph (PrimState m) d v e -> m ()
delNodes ns (MLGraph g) = unsafePrimToPrim $ do delNodes ns (MLGraph g) = unsafePrimToPrim $ do
vptr <- listToVector $ map fromIntegral ns vptr <- fromList $ map fromIntegral ns
vsptr <- igraphVsVector vptr vsptr <- igraphVsVector vptr
igraphDeleteVertices g vsptr igraphDeleteVertices g vsptr
return () return ()
addEdges :: PrimMonad m => [(Int, Int)] -> MLGraph (PrimState m) d v e -> m () addEdges :: PrimMonad m => [(Int, Int)] -> MLGraph (PrimState m) d v e -> m ()
addEdges es (MLGraph g) = unsafePrimToPrim $ do addEdges es (MLGraph g) = unsafePrimToPrim $ do
vec <- listToVector xs vec <- fromList xs
igraphAddEdges g vec nullPtr igraphAddEdges g vec nullPtr
where where
xs = concatMap ( \(a,b) -> [fromIntegral a, fromIntegral b] ) es xs = concatMap ( \(a,b) -> [fromIntegral a, fromIntegral b] ) es
...@@ -70,9 +70,9 @@ class MGraph d where ...@@ -70,9 +70,9 @@ class MGraph d where
addLEdges :: (PrimMonad m, Serialize e) => [LEdge e] -> MLGraph (PrimState m) d v e -> m () addLEdges :: (PrimMonad m, Serialize e) => [LEdge e] -> MLGraph (PrimState m) d v e -> m ()
addLEdges es (MLGraph g) = unsafePrimToPrim $ withEdgeAttr $ \eattr -> addLEdges es (MLGraph g) = unsafePrimToPrim $ withEdgeAttr $ \eattr ->
asBSVector vs $ \bsvec -> with (mkStrRec eattr bsvec) $ \ptr -> do asBSVector vs $ \bsvec -> with (mkStrRec eattr bsvec) $ \ptr -> do
vec <- listToVector $ concat xs vec <- fromList $ concat xs
vptr <- listToVectorP [castPtr ptr] vptr <- fromPtrs [castPtr ptr]
withVectorPPtr vptr (igraphAddEdges g vec . castPtr) withVectorPtr vptr (igraphAddEdges g vec . castPtr)
where where
(xs, vs) = unzip $ map ( \(a,b,v) -> ([fromIntegral a, fromIntegral b], v) ) es (xs, vs) = unzip $ map ( \(a,b,v) -> ([fromIntegral a, fromIntegral b], v) ) es
...@@ -82,23 +82,23 @@ instance MGraph U where ...@@ -82,23 +82,23 @@ instance MGraph U where
new n = unsafePrimToPrim $ igraphInit >>= igraphNew n False >>= return . MLGraph new n = unsafePrimToPrim $ igraphInit >>= igraphNew n False >>= return . MLGraph
delEdges es (MLGraph g) = unsafePrimToPrim $ do delEdges es (MLGraph g) = unsafePrimToPrim $ do
vptr <- listToVector $ map fromIntegral eids eids <- forM es $ \(fr, to) -> igraphGetEid g fr to False True
vptr <- fromList $ map fromIntegral eids
esptr <- igraphEsVector vptr esptr <- igraphEsVector vptr
igraphDeleteEdges g esptr igraphDeleteEdges g esptr
return () return ()
where where
eids = flip map es $ \(fr, to) -> igraphGetEid g fr to False True
instance MGraph D where instance MGraph D where
new n = unsafePrimToPrim $ igraphInit >>= igraphNew n True >>= return . MLGraph new n = unsafePrimToPrim $ igraphInit >>= igraphNew n True >>= return . MLGraph
delEdges es (MLGraph g) = unsafePrimToPrim $ do delEdges es (MLGraph g) = unsafePrimToPrim $ do
vptr <- listToVector $ map fromIntegral eids eids <- forM es $ \(fr, to) -> igraphGetEid g fr to True True
vptr <- fromList $ map fromIntegral eids
esptr <- igraphEsVector vptr esptr <- igraphEsVector vptr
igraphDeleteEdges g esptr igraphDeleteEdges g esptr
return () return ()
where where
eids = flip map es $ \(fr, to) -> igraphGetEid g fr to True True
setNodeAttr :: (PrimMonad m, Serialize v) setNodeAttr :: (PrimMonad m, Serialize v)
=> Int -- ^ Node id => Int -- ^ Node id
......
...@@ -27,16 +27,13 @@ import IGraph.Mutable ...@@ -27,16 +27,13 @@ import IGraph.Mutable
inducedSubgraph :: (Hashable v, Eq v, Serialize v) => LGraph d v e -> [Int] -> LGraph d v e inducedSubgraph :: (Hashable v, Eq v, Serialize v) => LGraph d v e -> [Int] -> LGraph d v e
inducedSubgraph gr vs = unsafePerformIO $ do inducedSubgraph gr vs = unsafePerformIO $ do
vs' <- listToVector $ map fromIntegral vs vs' <- fromList $ map fromIntegral vs
vsptr <- igraphVsVector vs' vsptr <- igraphVsVector vs'
mallocForeignPtrBytes 160 >>= \gptr -> withForeignPtr gptr $ \p -> do g' <- igraphInducedSubgraph (_graph gr) vsptr IgraphSubgraphCreateFromScratch
igraphInducedSubgraph (_graph gr) p vsptr IgraphSubgraphCreateFromScratch nV <- igraphVcount g'
let g' = IGraphPtr gptr labels <- forM [0 .. nV - 1] $ \i ->
labToId = M.fromListWith (++) $ zip labels $ map return [0..nV-1] igraphHaskellAttributeVAS g' vertexAttr i >>= fromBS
nV = igraphVcount g' return $ LGraph g' $ M.fromListWith (++) $ zip labels $ map return [0..nV-1]
labels = unsafePerformIO $ forM [0 .. nV - 1] $ \i ->
igraphHaskellAttributeVAS g' vertexAttr i >>= fromBS
return $ LGraph g' labToId
-- | closeness centrality -- | closeness centrality
closeness :: [Int] -- ^ vertices closeness :: [Int] -- ^ vertices
...@@ -46,14 +43,14 @@ closeness :: [Int] -- ^ vertices ...@@ -46,14 +43,14 @@ closeness :: [Int] -- ^ vertices
-> Bool -- ^ whether to normalize -> Bool -- ^ whether to normalize
-> [Double] -> [Double]
closeness vs gr ws mode normal = unsafePerformIO $ do closeness vs gr ws mode normal = unsafePerformIO $ do
vs' <- listToVector $ map fromIntegral vs vs' <- fromList $ map fromIntegral vs
vsptr <- igraphVsVector vs' vsptr <- igraphVsVector vs'
vptr <- igraphVectorNew 0 vptr <- igraphVectorNew 0
ws' <- case ws of ws' <- case ws of
Just w -> listToVector w Just w -> fromList w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr _ -> liftM Vector $ newForeignPtr_ $ castPtr nullPtr
igraphCloseness (_graph gr) vptr vsptr mode ws' normal igraphCloseness (_graph gr) vptr vsptr mode ws' normal
vectorPtrToList vptr toList vptr
-- | betweenness centrality -- | betweenness centrality
betweenness :: [Int] betweenness :: [Int]
...@@ -61,14 +58,14 @@ betweenness :: [Int] ...@@ -61,14 +58,14 @@ betweenness :: [Int]
-> Maybe [Double] -> Maybe [Double]
-> [Double] -> [Double]
betweenness vs gr ws = unsafePerformIO $ do betweenness vs gr ws = unsafePerformIO $ do
vs' <- listToVector $ map fromIntegral vs vs' <- fromList $ map fromIntegral vs
vsptr <- igraphVsVector vs' vsptr <- igraphVsVector vs'
vptr <- igraphVectorNew 0 vptr <- igraphVectorNew 0
ws' <- case ws of ws' <- case ws of
Just w -> listToVector w Just w -> fromList w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr _ -> liftM Vector $ newForeignPtr_ $ castPtr nullPtr
igraphBetweenness (_graph gr) vptr vsptr True ws' False igraphBetweenness (_graph gr) vptr vsptr True ws' False
vectorPtrToList vptr toList vptr
-- | eigenvector centrality -- | eigenvector centrality
eigenvectorCentrality :: LGraph d v e eigenvectorCentrality :: LGraph d v e
...@@ -77,11 +74,11 @@ eigenvectorCentrality :: LGraph d v e ...@@ -77,11 +74,11 @@ eigenvectorCentrality :: LGraph d v e
eigenvectorCentrality gr ws = unsafePerformIO $ do eigenvectorCentrality gr ws = unsafePerformIO $ do
vptr <- igraphVectorNew 0 vptr <- igraphVectorNew 0
ws' <- case ws of ws' <- case ws of
Just w -> listToVector w Just w -> fromList w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr _ -> liftM Vector $ newForeignPtr_ $ castPtr nullPtr
arparck <- igraphArpackNew arparck <- igraphArpackNew
igraphEigenvectorCentrality (_graph gr) vptr nullPtr True True ws' arparck igraphEigenvectorCentrality (_graph gr) vptr nullPtr True True ws' arparck
vectorPtrToList vptr toList vptr
-- | Google's PageRank -- | Google's PageRank
pagerank :: Graph d pagerank :: Graph d
...@@ -97,11 +94,11 @@ pagerank gr ws d ...@@ -97,11 +94,11 @@ pagerank gr ws d
ws' <- case ws of ws' <- case ws of
Just w -> if length w /= m Just w -> if length w /= m
then error "pagerank: incorrect length of edge weight vector" then error "pagerank: incorrect length of edge weight vector"
else listToVector w else fromList w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr _ -> liftM Vector $ newForeignPtr_ $ castPtr nullPtr
igraphPagerank (_graph gr) IgraphPagerankAlgoPrpack vptr p vsptr igraphPagerank (_graph gr) IgraphPagerankAlgoPrpack vptr p vsptr
(isDirected gr) d ws' nullPtr (isDirected gr) d ws' nullPtr
vectorPtrToList vptr toList vptr
where where
n = nNodes gr n = nNodes gr
m = nEdges gr m = nEdges gr
...@@ -121,12 +118,12 @@ personalizedPagerank gr reset ws d ...@@ -121,12 +118,12 @@ personalizedPagerank gr reset ws d
ws' <- case ws of ws' <- case ws of
Just w -> if length w /= m Just w -> if length w /= m
then error "pagerank: incorrect length of edge weight vector" then error "pagerank: incorrect length of edge weight vector"
else listToVector w else fromList w
_ -> liftM VectorPtr $ newForeignPtr_ $ castPtr nullPtr _ -> liftM Vector $ newForeignPtr_ $ castPtr nullPtr
reset' <- listToVector reset reset' <- fromList reset
igraphPersonalizedPagerank (_graph gr) IgraphPagerankAlgoPrpack vptr p vsptr igraphPersonalizedPagerank (_graph gr) IgraphPagerankAlgoPrpack vptr p vsptr
(isDirected gr) d reset' ws' nullPtr (isDirected gr) d reset' ws' nullPtr
vectorPtrToList vptr toList vptr
where where
n = nNodes gr n = nNodes gr
m = nEdges gr m = nEdges gr
...@@ -13,10 +13,10 @@ data U = U ...@@ -13,10 +13,10 @@ data U = U
data D = D data D = D
-- | Mutable labeled graph -- | Mutable labeled graph
newtype MLGraph m d v e = MLGraph IGraphPtr newtype MLGraph m d v e = MLGraph IGraph
-- | graph with labeled nodes and edges -- | graph with labeled nodes and edges
data LGraph d v e = LGraph data LGraph d v e = LGraph
{ _graph :: IGraphPtr { _graph :: IGraph
, _labelToNode :: M.HashMap v [Node] , _labelToNode :: M.HashMap v [Node]
} }
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