edges-0.10: library/Edges/Functions.hs
module Edges.Functions
where
import Edges.Prelude
import Edges.Types
import qualified Data.Vector.Unboxed as UnboxedVector
import qualified DeferredFolds.Unfold as Unfold
import qualified DeferredFolds.UnfoldM as UnfoldM
import qualified Control.Foldl as Foldl
import qualified Edges.Functions.Folds as Foldl
import qualified Control.Monad.Par as Par
import qualified PrimitiveExtras.PrimMultiArray as PrimMultiArray
import qualified PrimitiveExtras.PrimArray as PrimArray
edgesSourceAmount :: Edges source x -> Amount source
edgesSourceAmount (Edges _ pma) = Amount (PrimMultiArray.outerLength pma)
edgesTargetAmount :: Edges x target -> Amount target
edgesTargetAmount (Edges amount _) = Amount amount
edgesUnfoldM :: Monad m => Edges a b -> UnfoldM m (Node a, Node b)
edgesUnfoldM (Edges _ mpa) =
fmap (\ (aInt, bWord32) -> (Node aInt, Node (fromIntegral bWord32))) $
PrimMultiArray.toAssocsUnfoldM mpa
edgesList :: Edges a b -> [(Node a, Node b)]
edgesList edges =
UnfoldM.fold Foldl.list (edgesUnfoldM edges)
listEdges :: [(Node a, Node b)] -> Edges a b
listEdges list =
Par.runPar $ do
aSizeFuture <- Par.spawnP $ succ $ fromMaybe 0 $ flip Foldl.fold list $ flip lmap Foldl.maximum $ \ (Node x, _) -> x
bSizeFuture <- Par.spawnP $ succ $ fromMaybe 0 $ flip Foldl.fold list $ flip lmap Foldl.maximum $ \ (_, Node x) -> x
aToBPrimFoldableFuture <- Par.spawnP $ flip fmap list $ \ (Node aInt, Node bInt) -> (aInt, fromIntegral bInt)
aSize <- Par.get aSizeFuture
bSize <- Par.get bSizeFuture
aToBEdges <- primFoldableWithAmountsEdges aSize bSize <$> Par.get aToBPrimFoldableFuture
return aToBEdges
listBipartiteEdges :: [(Node a, Node b)] -> (Edges a b, Edges b a)
listBipartiteEdges = coerce primListBipartiteEdges
primListBipartiteEdges :: [(Int, Int)] -> (Edges a b, Edges b a)
primListBipartiteEdges list =
Par.runPar $ do
aSizeFuture <- Par.spawnP $ succ $ fromMaybe 0 $ flip Foldl.fold list $ flip lmap Foldl.maximum fst
bSizeFuture <- Par.spawnP $ succ $ fromMaybe 0 $ flip Foldl.fold list $ flip lmap Foldl.maximum snd
aToBPrimFoldableFuture <- Par.spawnP $ flip fmap list $ \ (aInt, bInt) -> (aInt, fromIntegral bInt)
bToAPrimFoldableFuture <- Par.spawnP $ flip fmap list $ \ (aInt, bInt) -> (bInt, fromIntegral aInt)
aSize <- Par.get aSizeFuture
bSize <- Par.get bSizeFuture
aToBEdgesFuture <- Par.spawn_ $ primFoldableWithAmountsEdges aSize bSize <$> Par.get aToBPrimFoldableFuture
bToAEdgesFuture <- Par.spawn_ $ primFoldableWithAmountsEdges bSize aSize <$> Par.get bToAPrimFoldableFuture
aToBEdges <- Par.get aToBEdgesFuture
bToAEdges <- Par.get bToAEdgesFuture
return (aToBEdges, bToAEdges)
primFoldableWithAmountsEdges :: Foldable f => Int -> Int -> f (Int, Word32) -> Edges a b
primFoldableWithAmountsEdges aAmount bAmount foldable =
Edges bAmount $ runIdentity $ PrimMultiArray.create aAmount $ \ fold ->
Identity $ Foldl.fold fold foldable
nodeCountsList :: NodeCounts entity -> [Word64]
nodeCountsList (NodeCounts pa) = foldrPrimArray' (:) [] pa
nodeCountsUnboxedVector :: NodeCounts entity -> UnboxedVector.Vector Word64
nodeCountsUnboxedVector (NodeCounts pa) = PrimArray.toUnboxedVector pa
unindexNodeCounts :: (Eq entity, Hashable entity) => (Int -> Maybe entity) -> NodeCounts entity -> HashMap entity Int
unindexNodeCounts lookup (NodeCounts pa) = let
unfold = do
index <- Unfold.intsInRange 0 (pred (sizeofPrimArray pa))
return $ do
entity <- lookup index
return (entity, fromIntegral (indexPrimArray pa index))
in Unfold.fold (Foldl.hashMapByMapMaybe id) unfold